aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-25 10:56:48 +0000
committermalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-25 10:56:48 +0000
commit5e10fc904e8645b9ffb4b042dca65c64b65f61ee (patch)
tree110839dacc60b2bf256545c3c0129782069b3b9b
parent004c9ef410ec2f88552708cf1e01e91a91a143ed (diff)
Massage PPC version of cpu_get_real_ticks a little
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6435 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--cpu-all.h44
1 files changed, 22 insertions, 22 deletions
diff --git a/cpu-all.h b/cpu-all.h
index e71bd0601..c8c5b988c 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -996,30 +996,30 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
#if defined(_ARCH_PPC)
-static inline uint32_t get_tbl(void)
-{
- uint32_t tbl;
- asm volatile("mftb %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline uint32_t get_tbu(void)
-{
- uint32_t tbl;
- asm volatile("mftbu %0" : "=r" (tbl));
- return tbl;
-}
-
static inline 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;
+ 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__)