Commit 28ab0e2edb36685da7280b24e665962754d9e4ff
1 parent
b54ad049
added cpu_get_tsc()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@837 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
56 additions
and
11 deletions
hw/pc.c
| ... | ... | @@ -57,6 +57,13 @@ static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data) |
| 57 | 57 | pic_set_irq(13, 0); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | +/* TSC handling */ | |
| 61 | + | |
| 62 | +uint64_t cpu_get_tsc(CPUX86State *env) | |
| 63 | +{ | |
| 64 | + return qemu_get_clock(vm_clock); | |
| 65 | +} | |
| 66 | + | |
| 60 | 67 | /* PC cmos mappings */ |
| 61 | 68 | |
| 62 | 69 | #define REG_EQUIPMENT_BYTE 0x14 | ... | ... |
linux-user/main.c
| ... | ... | @@ -99,10 +99,50 @@ int cpu_get_pic_interrupt(CPUState *env) |
| 99 | 99 | return -1; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | +/* timers for rdtsc */ | |
| 103 | + | |
| 104 | +#if defined(__i386__) | |
| 105 | + | |
| 106 | +int64_t cpu_get_real_ticks(void) | |
| 107 | +{ | |
| 108 | + int64_t val; | |
| 109 | + asm volatile ("rdtsc" : "=A" (val)); | |
| 110 | + return val; | |
| 111 | +} | |
| 112 | + | |
| 113 | +#elif defined(__x86_64__) | |
| 114 | + | |
| 115 | +int64_t cpu_get_real_ticks(void) | |
| 116 | +{ | |
| 117 | + uint32_t low,high; | |
| 118 | + int64_t val; | |
| 119 | + asm volatile("rdtsc" : "=a" (low), "=d" (high)); | |
| 120 | + val = high; | |
| 121 | + val <<= 32; | |
| 122 | + val |= low; | |
| 123 | + return val; | |
| 124 | +} | |
| 125 | + | |
| 126 | +#else | |
| 127 | + | |
| 128 | +static uint64_t emu_time; | |
| 129 | + | |
| 130 | +int64_t cpu_get_real_ticks(void) | |
| 131 | +{ | |
| 132 | + return emu_time++; | |
| 133 | +} | |
| 134 | + | |
| 135 | +#endif | |
| 136 | + | |
| 102 | 137 | #ifdef TARGET_I386 |
| 103 | 138 | /***********************************************************/ |
| 104 | 139 | /* CPUX86 core interface */ |
| 105 | 140 | |
| 141 | +uint64_t cpu_get_tsc(CPUX86State *env) | |
| 142 | +{ | |
| 143 | + return cpu_get_real_ticks(); | |
| 144 | +} | |
| 145 | + | |
| 106 | 146 | static void write_dt(void *ptr, unsigned long addr, unsigned long limit, |
| 107 | 147 | int flags) |
| 108 | 148 | { | ... | ... |
target-i386/cpu.h
| ... | ... | @@ -443,6 +443,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
| 443 | 443 | void *puc); |
| 444 | 444 | void cpu_x86_set_a20(CPUX86State *env, int a20_state); |
| 445 | 445 | |
| 446 | +uint64_t cpu_get_tsc(CPUX86State *env); | |
| 447 | + | |
| 446 | 448 | /* will be suppressed */ |
| 447 | 449 | void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
| 448 | 450 | ... | ... |
target-i386/helper.c
| ... | ... | @@ -1775,20 +1775,11 @@ void helper_invlpg(unsigned int addr) |
| 1775 | 1775 | cpu_x86_flush_tlb(env, addr); |
| 1776 | 1776 | } |
| 1777 | 1777 | |
| 1778 | -/* rdtsc */ | |
| 1779 | -#if !defined(__i386__) && !defined(__x86_64__) | |
| 1780 | -uint64_t emu_time; | |
| 1781 | -#endif | |
| 1782 | - | |
| 1783 | 1778 | void helper_rdtsc(void) |
| 1784 | 1779 | { |
| 1785 | 1780 | uint64_t val; |
| 1786 | -#if defined(__i386__) || defined(__x86_64__) | |
| 1787 | - asm volatile ("rdtsc" : "=A" (val)); | |
| 1788 | -#else | |
| 1789 | - /* better than nothing: the time increases */ | |
| 1790 | - val = emu_time++; | |
| 1791 | -#endif | |
| 1781 | + | |
| 1782 | + val = cpu_get_tsc(env); | |
| 1792 | 1783 | EAX = val; |
| 1793 | 1784 | EDX = val >> 32; |
| 1794 | 1785 | } | ... | ... |
tests/qruncom.c
| ... | ... | @@ -55,6 +55,11 @@ int cpu_get_pic_interrupt(CPUState *env) |
| 55 | 55 | return -1; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | +uint64_t cpu_get_tsc(CPUState *env) | |
| 59 | +{ | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 58 | 63 | static void set_gate(void *ptr, unsigned int type, unsigned int dpl, |
| 59 | 64 | unsigned long addr, unsigned int sel) |
| 60 | 65 | { | ... | ... |