aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-arm/arm32
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2013-02-22 08:57:48 +0000
committerIan Campbell <ian.campbell@citrix.com>2013-02-22 12:14:51 +0000
commit0d6ceac410682359e2be3689197cb38f5ebb6cd6 (patch)
tree0d78b66275ca93f3d8dbb8d9e6098ccfb1084da6 /xen/include/asm-arm/arm32
parentd2654a5568358ff0a08a1003df33087489b84d43 (diff)
downloadxen-0d6ceac410682359e2be3689197cb38f5ebb6cd6.tar.gz
xen-0d6ceac410682359e2be3689197cb38f5ebb6cd6.tar.bz2
xen-0d6ceac410682359e2be3689197cb38f5ebb6cd6.zip
xen: arm: refactor co-pro and sysreg reg handling.
AArch64 has removed the concept of co-processors replacing them with a combination of specific instructions (cache and tlb flushes etc) and system registers (which are understood by name in the assembler). However most system registers are equivalent to a particular AArch32 co-pro register and can be used by generic code in the same way. Note that the names of the registers differ (often only slightly) For consistency it would be better to use only set of names in the common code. Therefore move the {READ,WRITE}_CP{32,64} accessors into arm32/processor.h and provide {READ,WRITE}_SYSREG. Where the names differ #defines will be provided on 32-bit. HSR_CPREG and friends are required even on 64-bit in order to decode traps from 32 bit guests. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Tim Deegan <tim@xen.org>
Diffstat (limited to 'xen/include/asm-arm/arm32')
-rw-r--r--xen/include/asm-arm/arm32/processor.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/xen/include/asm-arm/arm32/processor.h b/xen/include/asm-arm/arm32/processor.h
new file mode 100644
index 0000000000..843fbd219d
--- /dev/null
+++ b/xen/include/asm-arm/arm32/processor.h
@@ -0,0 +1,68 @@
+#ifndef __ASM_ARM_ARM32_PROCESSOR_H
+#define __ASM_ARM_ARM32_PROCESSOR_H
+
+/* Layout as used in assembly, with src/dest registers mixed in */
+#define __CP32(r, coproc, opc1, crn, crm, opc2) coproc, opc1, r, crn, crm, opc2
+#define __CP64(r1, r2, coproc, opc, crm) coproc, opc, r1, r2, crm
+#define CP32(r, name...) __CP32(r, name)
+#define CP64(r, name...) __CP64(r, name)
+
+/* Stringified for inline assembly */
+#define LOAD_CP32(r, name...) "mrc " __stringify(CP32(%r, name)) ";"
+#define STORE_CP32(r, name...) "mcr " __stringify(CP32(%r, name)) ";"
+#define LOAD_CP64(r, name...) "mrrc " __stringify(CP64(%r, %H##r, name)) ";"
+#define STORE_CP64(r, name...) "mcrr " __stringify(CP64(%r, %H##r, name)) ";"
+
+#ifndef __ASSEMBLY__
+
+/* C wrappers */
+#define READ_CP32(name...) ({ \
+ register uint32_t _r; \
+ asm volatile(LOAD_CP32(0, name) : "=r" (_r)); \
+ _r; })
+
+#define WRITE_CP32(v, name...) do { \
+ register uint32_t _r = (v); \
+ asm volatile(STORE_CP32(0, name) : : "r" (_r)); \
+} while (0)
+
+#define READ_CP64(name...) ({ \
+ register uint64_t _r; \
+ asm volatile(LOAD_CP64(0, name) : "=r" (_r)); \
+ _r; })
+
+#define WRITE_CP64(v, name...) do { \
+ register uint64_t _r = (v); \
+ asm volatile(STORE_CP64(0, name) : : "r" (_r)); \
+} while (0)
+
+/*
+ * C wrappers for accessing system registers.
+ *
+ * Registers come in 3 types:
+ * - those which are always 32-bit regardless of AArch32 vs AArch64
+ * (use {READ,WRITE}_SYSREG32).
+ * - those which are always 64-bit regardless of AArch32 vs AArch64
+ * (use {READ,WRITE}_SYSREG64).
+ * - those which vary between AArch32 and AArch64 (use {READ,WRITE}_SYSREG).
+ */
+#define READ_SYSREG32(R...) READ_CP32(R)
+#define WRITE_SYSREG32(V, R...) WRITE_CP32(V, R)
+
+#define READ_SYSREG64(R...) READ_CP64(R)
+#define WRITE_SYSREG64(V, R...) WRITE_CP64(V, R)
+
+#define READ_SYSREG(R...) READ_SYSREG32(R)
+#define WRITE_SYSREG(V, R...) WRITE_SYSREG32(V, R)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_ARM32_PROCESSOR_H */
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */