diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-01-10 22:40:12 +1100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2012-01-11 11:54:24 +1100 |
commit | 59f6d802f39f733e79850cb71eeeeecaa46a2347 (patch) | |
tree | 90c713fb911651fa654ef3f57dffa175a936ca93 | |
parent | 3a7cb8581e6fdee844d51f13c89102975a4c2529 (diff) | |
download | SLOF-59f6d802f39f733e79850cb71eeeeecaa46a2347.zip SLOF-59f6d802f39f733e79850cb71eeeeecaa46a2347.tar.gz SLOF-59f6d802f39f733e79850cb71eeeeecaa46a2347.tar.bz2 |
Fix inline asm for ci_write_xx
It was clobbering r4 and not marking it as such, causing
problems among others in virtio-blk
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | include/ppcp7/cache.h | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/include/ppcp7/cache.h b/include/ppcp7/cache.h index 64389ae..168a787 100644 --- a/include/ppcp7/cache.h +++ b/include/ppcp7/cache.h @@ -20,30 +20,42 @@ #define cache_inhibited_access(type,size) \ static inline type ci_read_##size(type * addr) \ { \ - type val; \ - register int bytes asm ("r4") = size / 8; \ - register uint64_t _addr asm ("r5") = (long)addr; \ - asm volatile(" li 3, 0x3c \n" /* H_LOGICAL_CI_LOAD */ \ + register uint64_t arg0 asm ("r3"); \ + register uint64_t arg1 asm ("r4"); \ + register uint64_t arg2 asm ("r5"); \ + \ + arg0 = 0x3c; /* H_LOGICAL_CI_LOAD*/ \ + arg1 = size / 8; \ + arg2 = (uint64_t)addr; \ + \ + asm volatile( \ ".long 0x44000022 \n" /* HVCALL */ \ - " cmpdi cr0,3,0 \n" \ - " mr %0,4 \n" \ - " beq 0f \n" \ - " li %0,-1 \n" \ - "0:\n" \ - : "=r"(val) \ - : "r"(bytes), "r"(_addr) \ - : "r3", "memory", "cr0"); \ - return val; \ + : "=&r" (arg0), "=&r"(arg1), "=&r"(arg2) \ + : "0"(arg0), "1"(arg1), "2"(arg2) \ + : "r0", "r6", "r7", "r8", "r9", "r10", "r11", \ + "r12", "memory", "cr0", "cr1", "cr5", \ + "cr6", "cr7", "ctr", "xer"); \ + return arg0 ? -1 : arg1; \ } \ static inline void ci_write_##size(type * addr, type data) \ { \ - register int bytes asm ("r4") = size / 8; \ - register uint64_t _addr asm ("r5") = (uint64_t)addr; \ - register uint64_t _data asm ("r6") = (uint64_t)data; \ - asm volatile(" li 3, 0x40 \n" /* H_LOGICAL_CI_STORE */ \ + register uint64_t arg0 asm ("r3"); \ + register uint64_t arg1 asm ("r4"); \ + register uint64_t arg2 asm ("r5"); \ + register uint64_t arg3 asm ("r6"); \ + \ + arg0 = 0x40; /* H_LOGICAL_CI_STORE*/ \ + arg1 = size / 8; \ + arg2 = (uint64_t)addr; \ + arg3 = (uint64_t)data; \ + \ + asm volatile( \ ".long 0x44000022 \n" /* HVCALL */ \ - : : "r"(bytes), "r"(_addr), "r"(_data) \ - : "r3", "memory"); \ + : "=&r"(arg0),"=&r"(arg1),"=&r"(arg2),"=&r"(arg3) \ + : "0"(arg0),"1"(arg1),"2"(arg2),"3"(arg3) \ + : "r0", "r7", "r8", "r9", "r10", "r11", \ + "r12", "memory", "cr0", "cr1", "cr5", \ + "cr6", "cr7", "ctr", "xer"); \ } cache_inhibited_access(uint8_t, 8) |