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
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
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 */
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)
}
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);
+}
+ 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);
#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>
+#include "qemu-timer.h"
+
/* Helpers for instruction counting code generation. */
static TCGArg *icount_arg;
/* For tb_lock */
#include "exec-all.h"
-
+#include "qemu-timer.h"
#include "envlist.h"
#define DEBUG_LOGFILE "/tmp/qemu.log"
#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. */
#endif /* !defined(NEED_CPU_H) */
/* bottom halves */
-typedef struct QEMUBH QEMUBH;
-
typedef void QEMUBHFunc(void *opaque);
void async_context_push(void);
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;
#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;
}
#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 */
#ifndef QEMU_TIMER_H
#define QEMU_TIMER_H
+#include "qemu-common.h"
+
/* timers */
typedef struct QEMUClock QEMUClock;
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
* 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
#include "exec-all.h"
#include "disas.h"
#include "tcg.h"
+#include "qemu-timer.h"
/* code generation context */
TCGContext tcg_ctx;