diff --git a/hw/pc.c b/hw/pc.c
index 361f4bb934d5e2a5b00bce60a8f53de3e37c1a0b..898d0681e129724065f058f7de5c9cdce67380fa 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -58,10 +58,19 @@ static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
 }
 
 /* TSC handling */
-
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
-    return qemu_get_clock(vm_clock);
+    /* Note: when using kqemu, it is more logical to return the host TSC
+       because kqemu does not trap the RDTSC instruction for
+       performance reasons */
+#if USE_KQEMU
+    if (env->kqemu_enabled) {
+        return cpu_get_real_ticks();
+    } else 
+#endif
+    {
+        return cpu_get_ticks();
+    }
 }
 
 /* IRQ handling */
diff --git a/linux-user/main.c b/linux-user/main.c
index 2250b127a46920ccc8717465121b4c5e05c4d9ac..6c3d5db7ee2616ffdda450bb83bd7b1b770335bd 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -107,29 +107,7 @@ int cpu_get_pic_interrupt(CPUState *env)
 
 /* timers for rdtsc */
 
-#if defined(__i386__)
-
-int64_t cpu_get_real_ticks(void)
-{
-    int64_t val;
-    asm volatile ("rdtsc" : "=A" (val));
-    return val;
-}
-
-#elif defined(__x86_64__)
-
-int64_t cpu_get_real_ticks(void)
-{
-    uint32_t low,high;
-    int64_t val;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    val = high;
-    val <<= 32;
-    val |= low;
-    return val;
-}
-
-#else
+#if 0
 
 static uint64_t emu_time;
 
diff --git a/vl.c b/vl.c
index e8780dd08ffae54c8b9c634c8e423fdfac71f9d5..c9992d8152085c0e0154d4768b969ec3628a2902 100644
--- a/vl.c
+++ b/vl.c
@@ -482,114 +482,103 @@ int kbd_mouse_is_absolute(void)
     return qemu_put_mouse_event_absolute;
 }
 
-/***********************************************************/
-/* timers */
-
-#if defined(__powerpc__)
-
-static inline uint32_t get_tbl(void) 
+/* compute with 96 bit intermediate result: (a*b)/c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
-    uint32_t tbl;
-    asm volatile("mftb %0" : "=r" (tbl));
-    return tbl;
-}
+    union {
+        uint64_t ll;
+        struct {
+#ifdef WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif            
+        } l;
+    } u, res;
+    uint64_t rl, rh;
 
-static inline uint32_t get_tbu(void) 
-{
-	uint32_t tbl;
-	asm volatile("mftbu %0" : "=r" (tbl));
-	return tbl;
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
 }
 
-int64_t cpu_get_real_ticks(void)
-{
-    uint32_t l, h, h1;
-    /* NOTE: we test if wrapping has occurred */
-    do {
-        h = get_tbu();
-        l = get_tbl();
-        h1 = get_tbu();
-    } while (h != h1);
-    return ((int64_t)h << 32) | l;
-}
+/***********************************************************/
+/* real time host monotonic timer */
 
-#elif defined(__i386__)
+#define QEMU_TIMER_BASE 1000000000LL
 
-int64_t cpu_get_real_ticks(void)
-{
-#ifdef _WIN32
-    LARGE_INTEGER ti;
-    QueryPerformanceCounter(&ti);
-    return ti.QuadPart;
-#else
-    int64_t val;
-    asm volatile ("rdtsc" : "=A" (val));
-    return val;
-#endif
-}
+#ifdef WIN32
 
-#elif defined(__x86_64__)
+static int64_t clock_freq;
 
-int64_t cpu_get_real_ticks(void)
+static void init_get_clock(void)
 {
-    uint32_t low,high;
-    int64_t val;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    val = high;
-    val <<= 32;
-    val |= low;
-    return val;
+    ret = QueryPerformanceFrequency(&freq);
+    if (ret == 0) {
+        fprintf(stderr, "Could not calibrate ticks\n");
+        exit(1);
+    }
+    clock_freq = freq.QuadPart;
 }
 
-#elif defined(__ia64)
-
-int64_t cpu_get_real_ticks(void)
+static int64_t get_clock(void)
 {
-	int64_t val;
-	asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
-	return val;
+    LARGE_INTEGER ti;
+    QueryPerformanceCounter(&ti);
+    return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
 }
 
-#elif defined(__s390__)
+#else
 
-int64_t cpu_get_real_ticks(void)
+static int use_rt_clock;
+
+static void init_get_clock(void)
 {
-    int64_t val;
-    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
-    return val;
+    use_rt_clock = 0;
+#if defined(__linux__)
+    {
+        struct timespec ts;
+        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+            use_rt_clock = 1;
+        }
+    }
+#endif
 }
 
-#elif defined(__sparc__) && defined(HOST_SOLARIS)
-
-uint64_t cpu_get_real_ticks (void)
+static int64_t get_clock(void)
 {
-#if     defined(_LP64)
-        uint64_t        rval;
-        asm volatile("rd %%tick,%0" : "=r"(rval));
-        return rval;
-#else
-        union {
-                uint64_t i64;
-                struct {
-                        uint32_t high;
-                        uint32_t low;
-                }       i32;
-        } rval;
-        asm volatile("rd %%tick,%1; srlx %1,32,%0"
-                : "=r"(rval.i32.high), "=r"(rval.i32.low));
-        return rval.i64;
+#if defined(__linux__)
+    if (use_rt_clock) {
+        struct timespec ts;
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    } else 
 #endif
+    {
+        /* XXX: using gettimeofday leads to problems if the date
+           changes, so it should be avoided. */
+        struct timeval tv;
+        gettimeofday(&tv, NULL);
+        return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
+    }
 }
 
-#else
-#error unsupported CPU
 #endif
 
+/***********************************************************/
+/* guest cycle counter */
+
 static int64_t cpu_ticks_prev;
 static int64_t cpu_ticks_offset;
+static int64_t cpu_clock_offset;
 static int cpu_ticks_enabled;
 
-static inline int64_t cpu_get_ticks(void)
+/* return the host CPU cycle counter and handle stop/restart */
+int64_t cpu_get_ticks(void)
 {
     if (!cpu_ticks_enabled) {
         return cpu_ticks_offset;
@@ -606,11 +595,24 @@ static inline int64_t cpu_get_ticks(void)
     }
 }
 
+/* return the host CPU monotonic timer and handle stop/restart */
+static int64_t cpu_get_clock(void)
+{
+    int64_t ti;
+    if (!cpu_ticks_enabled) {
+        return cpu_clock_offset;
+    } else {
+        ti = get_clock();
+        return ti + cpu_clock_offset;
+    }
+}
+
 /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)
 {
     if (!cpu_ticks_enabled) {
         cpu_ticks_offset -= cpu_get_real_ticks();
+        cpu_clock_offset -= get_clock();
         cpu_ticks_enabled = 1;
     }
 }
@@ -621,69 +623,14 @@ void cpu_disable_ticks(void)
 {
     if (cpu_ticks_enabled) {
         cpu_ticks_offset = cpu_get_ticks();
+        cpu_clock_offset = cpu_get_clock();
         cpu_ticks_enabled = 0;
     }
 }
 
-#ifdef _WIN32
-void cpu_calibrate_ticks(void)
-{
-    LARGE_INTEGER freq;
-    int ret;
-
-    ret = QueryPerformanceFrequency(&freq);
-    if (ret == 0) {
-        fprintf(stderr, "Could not calibrate ticks\n");
-        exit(1);
-    }
-    ticks_per_sec = freq.QuadPart;
-}
-
-#else
-static int64_t get_clock(void)
-{
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000LL + tv.tv_usec;
-}
-
-void cpu_calibrate_ticks(void)
-{
-    int64_t usec, ticks;
-
-    usec = get_clock();
-    ticks = cpu_get_real_ticks();
-    usleep(50 * 1000);
-    usec = get_clock() - usec;
-    ticks = cpu_get_real_ticks() - ticks;
-    ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
-}
-#endif /* !_WIN32 */
-
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
-    union {
-        uint64_t ll;
-        struct {
-#ifdef WORDS_BIGENDIAN
-            uint32_t high, low;
-#else
-            uint32_t low, high;
-#endif            
-        } l;
-    } u, res;
-    uint64_t rl, rh;
-
-    u.ll = a;
-    rl = (uint64_t)u.l.low * (uint64_t)b;
-    rh = (uint64_t)u.l.high * (uint64_t)b;
-    rh += (rl >> 32);
-    res.l.high = rh / c;
-    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
-    return res.ll;
-}
-
+/***********************************************************/
+/* timers */
+ 
 #define QEMU_TIMER_REALTIME 0
 #define QEMU_TIMER_VIRTUAL  1
 
@@ -822,28 +769,21 @@ int64_t qemu_get_clock(QEMUClock *clock)
 {
     switch(clock->type) {
     case QEMU_TIMER_REALTIME:
-#ifdef _WIN32
-        return GetTickCount();
-#else
-        {
-            struct tms tp;
-
-            /* Note that using gettimeofday() is not a good solution
-               for timers because its value change when the date is
-               modified. */
-            if (timer_freq == 100) {
-                return times(&tp) * 10;
-            } else {
-                return ((int64_t)times(&tp) * 1000) / timer_freq;
-            }
-        }
-#endif
+        return get_clock() / 1000000;
     default:
     case QEMU_TIMER_VIRTUAL:
-        return cpu_get_ticks();
+        return cpu_get_clock();
     }
 }
 
+static void init_timers(void)
+{
+    init_get_clock();
+    ticks_per_sec = QEMU_TIMER_BASE;
+    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
+    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
+}
+
 /* save a timer */
 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
 {
@@ -985,11 +925,8 @@ static int start_rtc_timer(void)
 
 #endif /* !defined(_WIN32) */
 
-static void init_timers(void)
+static void init_timer_alarm(void)
 {
-    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
-    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
-
 #ifdef _WIN32
     {
         int count=0;
@@ -1354,7 +1291,9 @@ CharDriverState *qemu_chr_open_pipe(const char *filename)
 
 static int term_got_escape, client_index;
 static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
-int term_fifo_size;
+static int term_fifo_size;
+static int term_timestamps;
+static int64_t term_timestamps_start;
 
 void term_print_help(void)
 {
@@ -1363,6 +1302,7 @@ void term_print_help(void)
            "C-a x    exit emulator\n"
            "C-a s    save disk data back to file (if -snapshot)\n"
            "C-a b    send break (magic sysrq)\n"
+           "C-a t    toggle console timestamps\n"
            "C-a c    switch between console and monitor\n"
            "C-a C-a  send C-a\n"
            );
@@ -1409,6 +1349,10 @@ static void stdio_received_byte(int ch)
                 goto send_char;
             }
             break;
+        case 't':
+            term_timestamps = !term_timestamps;
+            term_timestamps_start = -1;
+            break;
         case TERM_ESCAPE:
             goto send_char;
         }
@@ -1466,6 +1410,39 @@ static void stdio_read(void *opaque)
         stdio_received_byte(buf[0]);
 }
 
+static int stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    FDCharDriver *s = chr->opaque;
+    if (!term_timestamps) {
+        return unix_write(s->fd_out, buf, len);
+    } else {
+        int i;
+        char buf1[64];
+
+        for(i = 0; i < len; i++) {
+            unix_write(s->fd_out, buf + i, 1);
+            if (buf[i] == '\n') {
+                int64_t ti;
+                int secs;
+
+                ti = get_clock();
+                if (term_timestamps_start == -1)
+                    term_timestamps_start = ti;
+                ti -= term_timestamps_start;
+                secs = ti / 1000000000;
+                snprintf(buf1, sizeof(buf1), 
+                         "[%02d:%02d:%02d.%03d] ",
+                         secs / 3600,
+                         (secs / 60) % 60,
+                         secs % 60,
+                         (int)((ti / 1000000) % 1000));
+                unix_write(s->fd_out, buf1, strlen(buf1));
+            }
+        }
+        return len;
+    }
+}
+
 /* init terminal so that we can grab keys */
 static struct termios oldtty;
 static int old_fd0_flags;
@@ -1511,6 +1488,7 @@ CharDriverState *qemu_chr_open_stdio(void)
         if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
             return NULL;
         chr = qemu_chr_open_fd(0, 1);
+        chr->chr_write = stdio_write;
         if (stdio_nb_clients == 0)
             qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);
         client_index = stdio_nb_clients;
@@ -5638,6 +5616,7 @@ int main(int argc, char **argv)
     SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
 #endif
     init_timers();
+    init_timer_alarm();
 
     register_machines();
     machine = first_machine;
@@ -6128,7 +6107,6 @@ int main(int argc, char **argv)
     register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
 
     init_ioports();
-    cpu_calibrate_ticks();
 
     /* terminal init */
     if (nographic) {
diff --git a/vl.h b/vl.h
index 8d6a4d95a6b9693d69f91cbf7aba0f884728a664..d97f485f3c133e2591489a864e74101497ef244b 100644
--- a/vl.h
+++ b/vl.h
@@ -390,6 +390,7 @@ int qemu_timer_pending(QEMUTimer *ts);
 extern int64_t ticks_per_sec;
 extern int pit_min_timer_count;
 
+int64_t cpu_get_ticks(void);
 void cpu_enable_ticks(void);
 void cpu_disable_ticks(void);