aboutsummaryrefslogtreecommitdiff
path: root/include/ppcp7
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-02-22 10:33:18 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-02-22 10:33:18 +1100
commit7add7a0a9f5fa2afa244f686f7e99e26aa112de8 (patch)
tree1327ea3e40b5ba36505508d11f8661f6c3a6a6f8 /include/ppcp7
parent0dfcbc133666b3d6d738644e958fea169de1cc3a (diff)
downloadSLOF-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.h61
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;