diff options
-rw-r--r-- | xen/include/asm-arm/arm32/processor.h | 68 | ||||
-rw-r--r-- | xen/include/asm-arm/arm64/processor.h | 37 | ||||
-rw-r--r-- | xen/include/asm-arm/cpregs.h | 40 | ||||
-rw-r--r-- | xen/include/asm-arm/processor.h | 9 |
4 files changed, 118 insertions, 36 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: + */ diff --git a/xen/include/asm-arm/arm64/processor.h b/xen/include/asm-arm/arm64/processor.h new file mode 100644 index 0000000000..fdb0dab0ee --- /dev/null +++ b/xen/include/asm-arm/arm64/processor.h @@ -0,0 +1,37 @@ +#ifndef __ASM_ARM_ARM64_PROCESSOR_H +#define __ASM_ARM_ARM64_PROCESSOR_H + +#ifndef __ASSEMBLY__ + +#define READ_SYSREG32(name) ({ \ + uint32_t _r; \ + asm volatile("mrs %0, "#name : "=r" (_r)); \ + _r; }) +#define WRITE_SYSREG32(v, name) do { \ + uint32_t _r = v; \ + asm volatile("msr "#name", %0" : : "r" (_r)); \ +} while (0) + +#define WRITE_SYSREG64(v, name) do { \ + uint64_t _r = v; \ + asm volatile("msr "#name", %0" : : "r" (_r)); \ +} while (0) +#define READ_SYSREG64(name) ({ \ + uint64_t _r; \ + asm volatile("mrs %0, "#name : "=r" (_r)); \ + _r; }) + +#define READ_SYSREG(name) READ_SYSREG64(name) +#define WRITE_SYSREG(v, name) WRITE_SYSREG64(v, name) + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM_ARM64_PROCESSOR_H */ +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h index 2daaf8e21a..dbb5049f5f 100644 --- a/xen/include/asm-arm/cpregs.h +++ b/xen/include/asm-arm/cpregs.h @@ -3,40 +3,12 @@ #include <xen/stringify.h> -/* Co-processor registers */ - -/* 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)) ";" - -/* 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) +/* + * AArch32 Co-processor registers. + * + * Note that AArch64 requires many of these definitions in order to + * support 32-bit guests. + */ #define __HSR_CPREG_c0 0 #define __HSR_CPREG_c1 1 diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h index 0175e1153f..86e6f26aa9 100644 --- a/xen/include/asm-arm/processor.h +++ b/xen/include/asm-arm/processor.h @@ -225,8 +225,13 @@ union hsr { #define ID_PFR1_GT_MASK 0x000F0000 /* Generic Timer interface support */ #define ID_PFR1_GT_v1 0x00010000 -#define MSR(reg,val) asm volatile ("msr "#reg", %0\n" : : "r" (val)) -#define MRS(val,reg) asm volatile ("mrs %0,"#reg"\n" : "=r" (v)) +#if defined(CONFIG_ARM_32) +# include <asm/arm32/processor.h> +#elif defined(CONFIG_ARM_64) +# include <asm/arm64/processor.h> +#else +# error "unknown ARM variant" +#endif #ifndef __ASSEMBLY__ extern uint32_t hyp_traps_vector[8]; |