Revision 29e922b6 cpu-all.h
b/cpu-all.h | ||
---|---|---|
771 | 771 |
extern CPUState *first_cpu; |
772 | 772 |
extern CPUState *cpu_single_env; |
773 | 773 |
|
774 |
int64_t qemu_icount_round(int64_t count); |
|
775 |
extern int64_t qemu_icount; |
|
776 |
extern int use_icount; |
|
777 |
|
|
778 | 774 |
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ |
779 | 775 |
#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ |
780 | 776 |
#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */ |
... | ... | |
921 | 917 |
int cpu_memory_rw_debug(CPUState *env, target_ulong addr, |
922 | 918 |
uint8_t *buf, int len, int is_write); |
923 | 919 |
|
924 |
/*******************************************/ |
|
925 |
/* host CPU ticks (if available) */ |
|
926 |
|
|
927 |
#if defined(_ARCH_PPC) |
|
928 |
|
|
929 |
static inline int64_t cpu_get_real_ticks(void) |
|
930 |
{ |
|
931 |
int64_t retval; |
|
932 |
#ifdef _ARCH_PPC64 |
|
933 |
/* This reads timebase in one 64bit go and includes Cell workaround from: |
|
934 |
http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html |
|
935 |
*/ |
|
936 |
__asm__ __volatile__ ( |
|
937 |
"mftb %0\n\t" |
|
938 |
"cmpwi %0,0\n\t" |
|
939 |
"beq- $-8" |
|
940 |
: "=r" (retval)); |
|
941 |
#else |
|
942 |
/* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */ |
|
943 |
unsigned long junk; |
|
944 |
__asm__ __volatile__ ( |
|
945 |
"mftbu %1\n\t" |
|
946 |
"mftb %L0\n\t" |
|
947 |
"mftbu %0\n\t" |
|
948 |
"cmpw %0,%1\n\t" |
|
949 |
"bne $-16" |
|
950 |
: "=r" (retval), "=r" (junk)); |
|
951 |
#endif |
|
952 |
return retval; |
|
953 |
} |
|
954 |
|
|
955 |
#elif defined(__i386__) |
|
956 |
|
|
957 |
static inline int64_t cpu_get_real_ticks(void) |
|
958 |
{ |
|
959 |
int64_t val; |
|
960 |
asm volatile ("rdtsc" : "=A" (val)); |
|
961 |
return val; |
|
962 |
} |
|
963 |
|
|
964 |
#elif defined(__x86_64__) |
|
965 |
|
|
966 |
static inline int64_t cpu_get_real_ticks(void) |
|
967 |
{ |
|
968 |
uint32_t low,high; |
|
969 |
int64_t val; |
|
970 |
asm volatile("rdtsc" : "=a" (low), "=d" (high)); |
|
971 |
val = high; |
|
972 |
val <<= 32; |
|
973 |
val |= low; |
|
974 |
return val; |
|
975 |
} |
|
976 |
|
|
977 |
#elif defined(__hppa__) |
|
978 |
|
|
979 |
static inline int64_t cpu_get_real_ticks(void) |
|
980 |
{ |
|
981 |
int val; |
|
982 |
asm volatile ("mfctl %%cr16, %0" : "=r"(val)); |
|
983 |
return val; |
|
984 |
} |
|
985 |
|
|
986 |
#elif defined(__ia64) |
|
987 |
|
|
988 |
static inline int64_t cpu_get_real_ticks(void) |
|
989 |
{ |
|
990 |
int64_t val; |
|
991 |
asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory"); |
|
992 |
return val; |
|
993 |
} |
|
994 |
|
|
995 |
#elif defined(__s390__) |
|
996 |
|
|
997 |
static inline int64_t cpu_get_real_ticks(void) |
|
998 |
{ |
|
999 |
int64_t val; |
|
1000 |
asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc"); |
|
1001 |
return val; |
|
1002 |
} |
|
1003 |
|
|
1004 |
#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__) |
|
1005 |
|
|
1006 |
static inline int64_t cpu_get_real_ticks (void) |
|
1007 |
{ |
|
1008 |
#if defined(_LP64) |
|
1009 |
uint64_t rval; |
|
1010 |
asm volatile("rd %%tick,%0" : "=r"(rval)); |
|
1011 |
return rval; |
|
1012 |
#else |
|
1013 |
union { |
|
1014 |
uint64_t i64; |
|
1015 |
struct { |
|
1016 |
uint32_t high; |
|
1017 |
uint32_t low; |
|
1018 |
} i32; |
|
1019 |
} rval; |
|
1020 |
asm volatile("rd %%tick,%1; srlx %1,32,%0" |
|
1021 |
: "=r"(rval.i32.high), "=r"(rval.i32.low)); |
|
1022 |
return rval.i64; |
|
1023 |
#endif |
|
1024 |
} |
|
1025 |
|
|
1026 |
#elif defined(__mips__) && \ |
|
1027 |
((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__)) |
|
1028 |
/* |
|
1029 |
* binutils wants to use rdhwr only on mips32r2 |
|
1030 |
* but as linux kernel emulate it, it's fine |
|
1031 |
* to use it. |
|
1032 |
* |
|
1033 |
*/ |
|
1034 |
#define MIPS_RDHWR(rd, value) { \ |
|
1035 |
__asm__ __volatile__ ( \ |
|
1036 |
".set push\n\t" \ |
|
1037 |
".set mips32r2\n\t" \ |
|
1038 |
"rdhwr %0, "rd"\n\t" \ |
|
1039 |
".set pop" \ |
|
1040 |
: "=r" (value)); \ |
|
1041 |
} |
|
1042 |
|
|
1043 |
static inline int64_t cpu_get_real_ticks(void) |
|
1044 |
{ |
|
1045 |
/* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */ |
|
1046 |
uint32_t count; |
|
1047 |
static uint32_t cyc_per_count = 0; |
|
1048 |
|
|
1049 |
if (!cyc_per_count) |
|
1050 |
MIPS_RDHWR("$3", cyc_per_count); |
|
1051 |
|
|
1052 |
MIPS_RDHWR("$2", count); |
|
1053 |
return (int64_t)(count * cyc_per_count); |
|
1054 |
} |
|
1055 |
|
|
1056 |
#else |
|
1057 |
/* The host CPU doesn't have an easily accessible cycle counter. |
|
1058 |
Just return a monotonically increasing value. This will be |
|
1059 |
totally wrong, but hopefully better than nothing. */ |
|
1060 |
static inline int64_t cpu_get_real_ticks (void) |
|
1061 |
{ |
|
1062 |
static int64_t ticks = 0; |
|
1063 |
return ticks++; |
|
1064 |
} |
|
1065 |
#endif |
|
1066 |
|
|
1067 | 920 |
/* profiling */ |
1068 | 921 |
#ifdef CONFIG_PROFILER |
1069 | 922 |
static inline int64_t profile_getclock(void) |
Also available in: Unified diff