diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-02-22 10:33:18 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-02-22 10:33:18 +1100 |
commit | 7add7a0a9f5fa2afa244f686f7e99e26aa112de8 (patch) | |
tree | 1327ea3e40b5ba36505508d11f8661f6c3a6a6f8 /include/ppcp7 | |
parent | 0dfcbc133666b3d6d738644e958fea169de1cc3a (diff) | |
download | SLOF-7add7a0a9f5fa2afa244f686f7e99e26aa112de8.zip SLOF-7add7a0a9f5fa2afa244f686f7e99e26aa112de8.tar.gz SLOF-7add7a0a9f5fa2afa244f686f7e99e26aa112de8.tar.bz2 |
Move _FASTRMOVE implementation into headers & support new hcall
This moves _FASTREMOVE to the cache.h header, 970 uses the
existing code, p7 now uses the new memop hcall.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'include/ppcp7')
-rw-r--r-- | include/ppcp7/cache.h | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/include/ppcp7/cache.h b/include/ppcp7/cache.h index 168a787..dc68371 100644 --- a/include/ppcp7/cache.h +++ b/include/ppcp7/cache.h @@ -35,7 +35,7 @@ : "r0", "r6", "r7", "r8", "r9", "r10", "r11", \ "r12", "memory", "cr0", "cr1", "cr5", \ "cr6", "cr7", "ctr", "xer"); \ - return arg0 ? -1 : arg1; \ + return arg0 ? (type)-1 : arg1; \ } \ static inline void ci_write_##size(type * addr, type data) \ { \ @@ -63,6 +63,65 @@ cache_inhibited_access(uint16_t, 16) cache_inhibited_access(uint32_t, 32) cache_inhibited_access(uint64_t, 64) +#define _FWOVERLAP(s, d, size) ((d >= s) && ((type_u)d < ((type_u)s + size))) + +// 3.1 +#define _FWMOVE(s, d, size, t) \ + { t *s1=(t *)s, *d1=(t *)d; \ + while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } } + +#define _BWMOVE(s, d, size, t) { \ + t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); \ + while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ +} + + +#define _MOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWMOVE(s, d, size, t) else _FWMOVE(s, d, size, t) + +#define _FASTMOVE(s, d, size) \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ + case 0: _MOVE(s, d, size, type_u); break; \ + case sizeof(type_l): _MOVE(s, d, size, type_l); break; \ + case sizeof(type_w): _MOVE(s, d, size, type_w); break; \ + default: _MOVE(s, d, size, type_c); break; \ + } + +static inline void ci_rmove(void *dst, void *src, unsigned long esize, + unsigned long count) +{ + register uint64_t arg0 asm ("r3"); + register uint64_t arg1 asm ("r4"); + register uint64_t arg2 asm ("r5"); + register uint64_t arg3 asm ("r6"); + register uint64_t arg4 asm ("r7"); + register uint64_t arg5 asm ("r8"); + + arg0 = 0xf001; /* KVMPPC_H_LOGICAL_MEMOP */ + arg1 = (uint64_t)dst; + arg2 = (uint64_t)src; + arg3 = esize; + arg4 = count; + arg5 = 0; /* 0 = copy */ + + asm volatile(".long 0x44000022 \n" /* HVCALL */ + : "=&r"(arg0),"=&r"(arg1),"=&r"(arg2), + "=&r"(arg3),"=&r"(arg4),"=&r"(arg5) + : "0"(arg0),"1"(arg1),"2"(arg2), + "3"(arg3),"4"(arg4),"5"(arg5) + : "r0", "r9", "r10", "r11", + "r12", "memory", "cr0", "cr1", "cr5", + "cr6", "cr7", "ctr", "xer"); +} + +#define _FASTRMOVE(s, d, size) do { \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) {\ + case 0: ci_rmove(d,s,3,size>>3); break; \ + case sizeof(type_l): ci_rmove(d,s,2,size>>2); break; \ + case sizeof(type_w): ci_rmove(d,s,1,size>>1); break; \ + default: ci_rmove(d,s,0,size); break; \ + } \ + } while(0) + static inline uint16_t bswap16_load(uint64_t addr) { unsigned int val; |