diff mbox

Compile qemu-timer only once

Message ID f43fc5581003280851i5ee4bd18i162e2dca10955bfb@mail.gmail.com
State New
Headers show

Commit Message

Blue Swirl March 28, 2010, 3:51 p.m. UTC
Arrange various declarations so that also non-CPU code can access
them, adjust users.

Move CPU specific code to cpus.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
The patch also available in my rebased tree:
git://repo.or.cz/qemu/blueswirl.git
http://repo.or.cz/r/qemu/blueswirl.git

 Makefile.objs      |    1 +
 Makefile.target    |    1 -
 cpu-all.h          |  147 ---------------------------------------------
 cpus.c             |   16 +++++
 exec-all.h         |   14 ----
 exec.c             |    1 +
 gen-icount.h       |    2 +
 linux-user/main.c  |    2 +-
 qemu-common.h      |    8 +-
 qemu-timer.c       |   20 +------
 qemu-timer.h       |  167 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 softmmu_template.h |    2 +
 translate-all.c    |    1 +
 13 files changed, 197 insertions(+), 185 deletions(-)
diff mbox

Patch

diff --git a/Makefile.objs b/Makefile.objs
index c02f9d5..7ac8920 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -105,6 +105,7 @@  common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
 common-obj-$(CONFIG_COCOA) += cocoa.o
 common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o
 common-obj-y += notify.o
+common-obj-y += qemu-timer.o

 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
diff --git a/Makefile.target b/Makefile.target
index 5ed20ec..a90add6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -162,7 +162,6 @@  endif #CONFIG_BSD_USER
 ifdef CONFIG_SOFTMMU

 obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o
-obj-y += qemu-timer.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
diff --git a/cpu-all.h b/cpu-all.h
index 9942d49..927445c 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -771,10 +771,6 @@  void QEMU_NORETURN cpu_abort(CPUState *env, const
char *fmt, ...)
 extern CPUState *first_cpu;
 extern CPUState *cpu_single_env;

-int64_t qemu_icount_round(int64_t count);
-extern int64_t qemu_icount;
-extern int use_icount;
-
 #define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86
a20 case) */
 #define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
@@ -921,149 +917,6 @@  void dump_exec_info(FILE *f,
 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
                         uint8_t *buf, int len, int is_write);

-/*******************************************/
-/* host CPU ticks (if available) */
-
-#if defined(_ARCH_PPC)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-    int64_t retval;
-#ifdef _ARCH_PPC64
-    /* This reads timebase in one 64bit go and includes Cell workaround from:
-       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
-     */
-    __asm__ __volatile__ (
-        "mftb    %0\n\t"
-        "cmpwi   %0,0\n\t"
-        "beq-    $-8"
-        : "=r" (retval));
-#else
-    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
-    unsigned long junk;
-    __asm__ __volatile__ (
-        "mftbu   %1\n\t"
-        "mftb    %L0\n\t"
-        "mftbu   %0\n\t"
-        "cmpw    %0,%1\n\t"
-        "bne     $-16"
-        : "=r" (retval), "=r" (junk));
-#endif
-    return retval;
-}
-
-#elif defined(__i386__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-    int64_t val;
-    asm volatile ("rdtsc" : "=A" (val));
-    return val;
-}
-
-#elif defined(__x86_64__)
-
-static inline 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;
-}
-
-#elif defined(__hppa__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-    int val;
-    asm volatile ("mfctl %%cr16, %0" : "=r"(val));
-    return val;
-}
-
-#elif defined(__ia64)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-	int64_t val;
-	asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
-	return val;
-}
-
-#elif defined(__s390__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-    int64_t val;
-    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
-    return val;
-}
-
-#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) ||
defined(__sparc_v9__)
-
-static inline int64_t cpu_get_real_ticks (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;
-#endif
-}
-
-#elif defined(__mips__) && \
-      ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
-/*
- * binutils wants to use rdhwr only on mips32r2
- * but as linux kernel emulate it, it's fine
- * to use it.
- *
- */
-#define MIPS_RDHWR(rd, value) {                 \
-    __asm__ __volatile__ (                      \
-                          ".set   push\n\t"     \
-                          ".set mips32r2\n\t"   \
-                          "rdhwr  %0, "rd"\n\t" \
-                          ".set   pop"          \
-                          : "=r" (value));      \
-}
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-/* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
-    uint32_t count;
-    static uint32_t cyc_per_count = 0;
-
-    if (!cyc_per_count)
-        MIPS_RDHWR("$3", cyc_per_count);
-
-    MIPS_RDHWR("$2", count);
-    return (int64_t)(count * cyc_per_count);
-}
-
-#else
-/* The host CPU doesn't have an easily accessible cycle counter.
-   Just return a monotonically increasing value.  This will be
-   totally wrong, but hopefully better than nothing.  */
-static inline int64_t cpu_get_real_ticks (void)
-{
-    static int64_t ticks = 0;
-    return ticks++;
-}
-#endif
-
 /* profiling */
 #ifdef CONFIG_PROFILER
 static inline int64_t profile_getclock(void)
diff --git a/cpus.c b/cpus.c
index 9a8c2f7..a2e0642 100644
--- a/cpus.c
+++ b/cpus.c
@@ -771,3 +771,19 @@  void set_cpu_log(const char *optarg)
     }
     cpu_set_log(mask);
 }
+
+/* Return the virtual CPU time, based on the instruction counter.  */
+int64_t cpu_get_icount(void)
+{
+    int64_t icount;
+    CPUState *env = cpu_single_env;;
+
+    icount = qemu_icount;
+    if (env) {
+        if (!can_do_io(env)) {
+            fprintf(stderr, "Bad clock read\n");
+        }
+        icount -= (env->icount_decr.u16.low + env->icount_extra);
+    }
+    return qemu_icount_bias + (icount << icount_time_shift);
+}
diff --git a/exec-all.h b/exec-all.h
index 37da2f5..ff3b240 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -337,20 +337,6 @@  static inline tb_page_addr_t
get_page_addr_code(CPUState *env1, target_ulong add
         + env1->tlb_table[mmu_idx][page_index].addend;
     return qemu_ram_addr_from_host(p);
 }
-
-/* Deterministic execution requires that IO only be performed on the last
-   instruction of a TB so that interrupts take effect immediately.  */
-static inline int can_do_io(CPUState *env)
-{
-    if (!use_icount)
-        return 1;
-
-    /* If not executing code then assume we are ok.  */
-    if (!env->current_tb)
-        return 1;
-
-    return env->can_do_io != 0;
-}
 #endif

 typedef void (CPUDebugExcpHandler)(CPUState *env);
diff --git a/exec.c b/exec.c
index 5dc98bd..cdc46dd 100644
--- a/exec.c
+++ b/exec.c
@@ -38,6 +38,7 @@ 
 #include "hw/hw.h"
 #include "osdep.h"
 #include "kvm.h"
+#include "qemu-timer.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
 #include <signal.h>
diff --git a/gen-icount.h b/gen-icount.h
index 3268f72..8879da6 100644
--- a/gen-icount.h
+++ b/gen-icount.h
@@ -1,3 +1,5 @@ 
+#include "qemu-timer.h"
+
 /* Helpers for instruction counting code generation.  */

 static TCGArg *icount_arg;
diff --git a/linux-user/main.c b/linux-user/main.c
index e5ff8a9..ca49cc4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -32,7 +32,7 @@ 
 /* For tb_lock */
 #include "exec-all.h"

-
+#include "qemu-timer.h"
 #include "envlist.h"

 #define DEBUG_LOGFILE "/tmp/qemu.log"
diff --git a/qemu-common.h b/qemu-common.h
index d881a39..d4b5b46 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -13,6 +13,10 @@ 

 #define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];

+typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUFile QEMUFile;
+typedef struct QEMUBH QEMUBH;
+
 /* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN
in files that
    cannot include the following headers without conflicts. This condition has
    to be removed once dyngen is gone. */
@@ -96,8 +100,6 @@  static inline char *realpath(const char *path, char
*resolved_path)
 #endif /* !defined(NEED_CPU_H) */

 /* bottom halves */
-typedef struct QEMUBH QEMUBH;
-
 typedef void QEMUBHFunc(void *opaque);

 void async_context_push(void);
@@ -211,11 +213,9 @@  typedef struct CharDriverState CharDriverState;
 typedef struct MACAddr MACAddr;
 typedef struct VLANState VLANState;
 typedef struct VLANClientState VLANClientState;
-typedef struct QEMUFile QEMUFile;
 typedef struct i2c_bus i2c_bus;
 typedef struct i2c_slave i2c_slave;
 typedef struct SMBusDevice SMBusDevice;
-typedef struct QEMUTimer QEMUTimer;
 typedef struct PCIHostState PCIHostState;
 typedef struct PCIExpressHost PCIExpressHost;
 typedef struct PCIBus PCIBus;
diff --git a/qemu-timer.c b/qemu-timer.c
index e6076ca..bdc8206 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -53,16 +53,14 @@ 
 #include <mmsystem.h>
 #endif

-#include "cpu-defs.h"
 #include "qemu-timer.h"
-#include "exec-all.h"

 /* Conversion factor from emulated instructions to virtual clock ticks.  */
-static int icount_time_shift;
+int icount_time_shift;
 /* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
 #define MAX_ICOUNT_SHIFT 10
 /* Compensate for varying guest execution speed.  */
-static int64_t qemu_icount_bias;
+int64_t qemu_icount_bias;
 static QEMUTimer *icount_rt_timer;
 static QEMUTimer *icount_vm_timer;

@@ -138,20 +136,6 @@  static int64_t get_clock(void)
 }
 #endif

-/* Return the virtual CPU time, based on the instruction counter.  */
-static int64_t cpu_get_icount(void)
-{
-    int64_t icount;
-    CPUState *env = cpu_single_env;;
-    icount = qemu_icount;
-    if (env) {
-        if (!can_do_io(env))
-            fprintf(stderr, "Bad clock read\n");
-        icount -= (env->icount_decr.u16.low + env->icount_extra);
-    }
-    return qemu_icount_bias + (icount << icount_time_shift);
-}
-
 /***********************************************************/
 /* guest cycle counter */

diff --git a/qemu-timer.h b/qemu-timer.h
index fca11eb..a7eac98 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -1,6 +1,8 @@ 
 #ifndef QEMU_TIMER_H
 #define QEMU_TIMER_H

+#include "qemu-common.h"
+
 /* timers */

 typedef struct QEMUClock QEMUClock;
@@ -69,4 +71,169 @@  void ptimer_stop(ptimer_state *s);
 void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
 void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);

+/* icount */
+int64_t qemu_icount_round(int64_t count);
+extern int64_t qemu_icount;
+extern int use_icount;
+extern int icount_time_shift;
+extern int64_t qemu_icount_bias;
+int64_t cpu_get_icount(void);
+
+/*******************************************/
+/* host CPU ticks (if available) */
+
+#if defined(_ARCH_PPC)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t retval;
+#ifdef _ARCH_PPC64
+    /* This reads timebase in one 64bit go and includes Cell workaround from:
+       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
+    */
+    __asm__ __volatile__ ("mftb    %0\n\t"
+                          "cmpwi   %0,0\n\t"
+                          "beq-    $-8"
+                          : "=r" (retval));
+#else
+    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
+    unsigned long junk;
+    __asm__ __volatile__ ("mftbu   %1\n\t"
+                          "mftb    %L0\n\t"
+                          "mftbu   %0\n\t"
+                          "cmpw    %0,%1\n\t"
+                          "bne     $-16"
+                          : "=r" (retval), "=r" (junk));
+#endif
+    return retval;
+}
+
+#elif defined(__i386__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile ("rdtsc" : "=A" (val));
+    return val;
+}
+
+#elif defined(__x86_64__)
+
+static inline 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;
+}
+
+#elif defined(__hppa__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int val;
+    asm volatile ("mfctl %%cr16, %0" : "=r"(val));
+    return val;
+}
+
+#elif defined(__ia64)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
+    return val;
+}
+
+#elif defined(__s390__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
+    return val;
+}
+
+#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) ||
defined(__sparc_v9__)
+
+static inline int64_t cpu_get_real_ticks (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;
+#endif
+}
+
+#elif defined(__mips__) && \
+    ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
+/*
+ * binutils wants to use rdhwr only on mips32r2
+ * but as linux kernel emulate it, it's fine
+ * to use it.
+ *
+ */
+#define MIPS_RDHWR(rd, value) {                         \
+        __asm__ __volatile__ (".set   push\n\t"         \
+                              ".set mips32r2\n\t"       \
+                              "rdhwr  %0, "rd"\n\t"     \
+                              ".set   pop"              \
+                              : "=r" (value));          \
+    }
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
+    uint32_t count;
+    static uint32_t cyc_per_count = 0;
+
+    if (!cyc_per_count) {
+        MIPS_RDHWR("$3", cyc_per_count);
+    }
+
+    MIPS_RDHWR("$2", count);
+    return (int64_t)(count * cyc_per_count);
+}
+
+#else
+/* The host CPU doesn't have an easily accessible cycle counter.
+   Just return a monotonically increasing value.  This will be
+   totally wrong, but hopefully better than nothing.  */
+static inline int64_t cpu_get_real_ticks (void)
+{
+    static int64_t ticks = 0;
+    return ticks++;
+}
+#endif
+
+#ifdef NEED_CPU_H
+/* Deterministic execution requires that IO only be performed on the last
+   instruction of a TB so that interrupts take effect immediately.  */
+static inline int can_do_io(CPUState *env)
+{
+    if (!use_icount)
+        return 1;
+
+    /* If not executing code then assume we are ok.  */
+    if (!env->current_tb)
+        return 1;
+
+    return env->can_do_io != 0;
+}
+#endif
+
 #endif
diff --git a/softmmu_template.h b/softmmu_template.h
index ac9b9a9..2f37c34 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -16,6 +16,8 @@ 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+#include "qemu-timer.h"
+
 #define DATA_SIZE (1 << SHIFT)

 #if DATA_SIZE == 8
diff --git a/translate-all.c b/translate-all.c
index 8ef8a0b..6f8136b 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -29,6 +29,7 @@ 
 #include "exec-all.h"
 #include "disas.h"
 #include "tcg.h"
+#include "qemu-timer.h"

 /* code generation context */
 TCGContext tcg_ctx;