@@ -227,7 +227,7 @@ cpu_init_done:
* PT walks use Inner-Shareable accesses,
* PT walks are write-back, write-allocate in both cache levels,
* Full 32-bit address space goes through this table. */
- ldr r0, =0x80003500
+ ldr r0, =(TCR_RES1|TCR_SH0_IS|TCR_ORGN0_WBWA|TCR_IRGN0_WBWA|TCR_T0SZ(0))
mcr CP32(r0, HTCR)
/* Set up the HSCTLR:
@@ -224,13 +224,17 @@ skip_bss:
ldr x0, =MAIRVAL
msr mair_el2, x0
- /* Set up the HTCR:
- * PASize -- 40 bits / 1TB
+ /* Set up TCR_EL2:
+ * PS -- Based on ID_AA64MMFR0_EL1.PARange
* Top byte is used
* PT walks use Inner-Shareable accesses,
* PT walks are write-back, write-allocate in both cache levels,
* Full 64-bit address space goes through this table. */
- ldr x0, =0x80823500
+ ldr x0, =(TCR_RES1|TCR_SH0_IS|TCR_ORGN0_WBWA|TCR_IRGN0_WBWA|TCR_T0SZ(0))
+ /* ID_AA64MMFR0_EL1[3:0] (PARange) corresponds to TCR_EL2[18:16] (PS) */
+ mrs x1, ID_AA64MMFR0_EL1
+ bfi x0, x1, #16, #3
+
msr tcr_el2, x0
/* Set up the SCTLR_EL2:
@@ -6,7 +6,11 @@
#include <public/xen.h>
#include <asm/processor.h>
+#ifdef CONFIG_ARM_64
+#define PADDR_BITS 48
+#else
#define PADDR_BITS 40
+#endif
#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
#define VADDR_BITS 32
@@ -114,8 +118,8 @@ typedef struct __packed {
unsigned long ng:1; /* Not-Global */
/* The base address must be appropriately aligned for Block entries */
- unsigned long base:28; /* Base address of block or next table */
- unsigned long sbz:12; /* Must be zero */
+ unsigned long long base:36; /* Base address of block or next table */
+ unsigned long sbz:4; /* Must be zero */
/* These seven bits are only used in Block entries and are ignored
* in Table entries. */
@@ -149,8 +153,8 @@ typedef struct __packed {
unsigned long sbz4:1;
/* The base address must be appropriately aligned for Block entries */
- unsigned long base:28; /* Base address of block or next table */
- unsigned long sbz3:12;
+ unsigned long long base:36; /* Base address of block or next table */
+ unsigned long sbz3:4;
/* These seven bits are only used in Block entries and are ignored
* in Table entries. */
@@ -174,9 +178,9 @@ typedef struct __packed {
unsigned long pad2:10;
/* The base address must be appropriately aligned for Block entries */
- unsigned long base:28; /* Base address of block or next table */
+ unsigned long long base:36; /* Base address of block or next table */
- unsigned long pad1:24;
+ unsigned long pad1:16;
} lpae_walk_t;
typedef union {
@@ -84,6 +84,38 @@
#define HCR_SWIO (_AC(1,UL)<<1) /* Set/Way Invalidation Override */
#define HCR_VM (_AC(1,UL)<<0) /* Virtual MMU Enable */
+/* TCR: Stage 1 Translation Control */
+
+#define TCR_T0SZ(x) ((x)<<0)
+
+#define TCR_IRGN0_NC (_AC(0x0,UL)<<8)
+#define TCR_IRGN0_WBWA (_AC(0x1,UL)<<8)
+#define TCR_IRGN0_WT (_AC(0x2,UL)<<8)
+#define TCR_IRGN0_WB (_AC(0x3,UL)<<8)
+
+#define TCR_ORGN0_NC (_AC(0x0,UL)<<10)
+#define TCR_ORGN0_WBWA (_AC(0x1,UL)<<10)
+#define TCR_ORGN0_WT (_AC(0x2,UL)<<10)
+#define TCR_ORGN0_WB (_AC(0x3,UL)<<10)
+
+#define TCR_SH0_NS (_AC(0x0,UL)<<12)
+#define TCR_SH0_OS (_AC(0x2,UL)<<12)
+#define TCR_SH0_IS (_AC(0x3,UL)<<12)
+
+#define TCR_TG0_4K (_AC(0x0,UL)<<14)
+#define TCR_TG0_64K (_AC(0x1,UL)<<14)
+#define TCR_TG0_16K (_AC(0x2,UL)<<14)
+
+#define TCR_PS(x) ((x)<<16)
+
+#define TCR_TBI (_AC(0x1,UL)<<20)
+
+#ifdef CONFIG_ARM_64
+#define TCR_RES1 (_AC(1,UL)<<31|_AC(1,UL)<<23)
+#else
+#define TCR_RES1 (_AC(1,UL)<<31)
+#endif
+
/* HCPTR Hyp. Coprocessor Trap Register */
#define HCPTR_TTA ((_AC(1,U)<<20)) /* Trap trace registers */
#define HCPTR_CP(x) ((_AC(1,U)<<(x))) /* Trap Coprocessor x */
@@ -188,8 +220,19 @@ struct cpuinfo_arm {
uint64_t bits[2];
} aux64;
- struct {
+ union {
uint64_t bits[2];
+ struct {
+ unsigned long pa_range:4;
+ unsigned long asid_bits:4;
+ unsigned long bigend:4;
+ unsigned long secure_ns:4;
+ unsigned long bigend_el0:4;
+ unsigned long tgranule_16K:4;
+ unsigned long tgranule_64K:4;
+ unsigned long tgranule_4K:4;
+ unsigned long __res0:32;
+ };
} mm64;
struct {
This only affects Xen's own stage one paging. - Use symbolic names for TCR bits for clarity. - Update PADDR_BITS - Base field of LPAE PT structs is now 36 bits (and therefore unsigned long long for arm32 compatibility) - TCR_EL2.PS is set from ID_AA64MMFR0_EL1.PASize. - Provide decode of ID_AA64MMFR0_EL1 in CPU info Parts of this are derived from "xen/arm: Add 4-level page table for stage 2 translation" by Vijaya Kumar K. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> --- xen/arch/arm/arm32/head.S | 2 +- xen/arch/arm/arm64/head.S | 10 ++++++--- xen/include/asm-arm/page.h | 16 ++++++++------ xen/include/asm-arm/processor.h | 45 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 11 deletions(-)