diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformHelper.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformHelper.S index 55c01035bb..e0c720a16d 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformHelper.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformHelper.S @@ -43,6 +43,8 @@ .set ID_AA64MMFR1_VH_MASK, 0xf << 8 .set HCR_EL2_E2H, 0x1 << 34 + .set ID_AA64MMFR0_TG4_52, 0xf << 28 + .set TCR_DS, 0x1 << 59 ASM_FUNC(ArmPlatformPeiBootAction) #ifdef CAVIUM_ERRATUM_27456 @@ -75,15 +77,21 @@ ASM_FUNC(ArmPlatformPeiBootAction) mov_i x0, mairval mov_i x1, tcrval adrp x2, idmap - orr x2, x2, #0xff << 48 // set non-zero ASID mov_i x3, sctlrval mrs x6, id_aa64mmfr0_el1 // get the supported PA range + and x4, x6, #ID_AA64MMFR0_TG4_52 // check for LPA2 support and x6, x6, #0xf // isolate PArange bits cmp x6, #6 // 0b0110 == 52 bits + csel x4, x4, xzr, eq // ignore LPA2 capability unless PArange == 52 + ccmp x4, xzr, #0, eq // permit PS == 52 bits iff LPA2 is supported sub x6, x6, #1 // subtract 1 cinc x6, x6, ne // add back 1 unless PArange == 52 bits bfi x1, x6, #32, #3 // copy updated PArange into TCR_EL1.IPS + cbz x4, 1f + orr x1, x1, #TCR_DS + adrp x2, idmap_lpa2 // switch to LPA2 idmap +1:orr x2, x2, #0xff << 48 // set non-zero ASID cmp x6, #3 // 0b0011 == 42 bits sub x6, x6, #1 // subtract 1 diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S index d9dcaae2bf..3c23957eb8 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S @@ -13,49 +13,57 @@ .set TT_MT_DEV, 0x0 << 2 // MAIR #0 .set TT_MT_MEM, (0x3 << 2) | (0x3 << 8) // MAIR #3 + .set TT_MT_MEM_LPA2, (0x3 << 2) // MAIR #3 - .set PAGE_XIP, TT_TYPE_PAGE | TT_MT_MEM | TT_AF | TT_RO | TT_NG - .set BLOCK_XIP, TT_TYPE_BLOCK | TT_MT_MEM | TT_AF | TT_RO | TT_NG - .set BLOCK_DEV, TT_TYPE_BLOCK | TT_MT_DEV | TT_AF | TT_XN | TT_NG - .set BLOCK_MEM, TT_TYPE_BLOCK | TT_MT_MEM | TT_AF | TT_XN | TT_NG + .set PAGE_XIP, TT_TYPE_PAGE | TT_AF | TT_RO | TT_NG + .set BLOCK_XIP, TT_TYPE_BLOCK | TT_AF | TT_RO | TT_NG + .set BLOCK_DEV, TT_TYPE_BLOCK | TT_AF | TT_XN | TT_NG + .set BLOCK_MEM, TT_TYPE_BLOCK | TT_AF | TT_XN | TT_NG - .globl idmap .section ".rodata.idmap", "a" .align 12 -idmap: /* level 0 */ + .macro make_idmap, name, root_levels, mt + .globl \name +\name: + .rept \root_levels .quad 1f + TT_TYPE_TABLE .fill 511, 8, 0x0 +1: + .endr -1: /* level 1 */ - .quad 20f + TT_TYPE_TABLE // 1 GB of flash and device mappings - .quad 21f + TT_TYPE_TABLE // up to 1 GB of DRAM - .fill 510, 8, 0x0 // 510 GB of remaining VA space + .quad 20f + TT_TYPE_TABLE // 1 GB of flash and device mappings + .quad 21f + TT_TYPE_TABLE // up to 1 GB of DRAM + .fill 510, 8, 0x0 // 510 GB of remaining VA space 20: /* level 2 */ - .quad 3f + TT_TYPE_TABLE // up to 2 MB of flash - .quad BLOCK_XIP | (0x1 << 21) // another 2 MB of flash - .fill 62, 8, 0x0 // 124 MB of unused flash + .quad 3f + TT_TYPE_TABLE // up to 2 MB of flash + .quad BLOCK_XIP | \mt | (0x1 << 21) // another 2 MB of flash + .fill 62, 8, 0x0 // 124 MB of unused flash .set idx, 64 .rept 448 - .quad BLOCK_DEV | (idx << 21) // 896 MB of RW- device mappings + .quad BLOCK_DEV | TT_MT_DEV | (idx << 21) // 896 MB of RW- device mappings .set idx, idx + 1 .endr 21: /* level 2 */ .set idx, 0x40000000 >> 21 .rept 64 - .quad BLOCK_MEM | (idx << 21) // 128 MB of RW- memory mappings + .quad BLOCK_MEM | \mt | (idx << 21) // 128 MB of RW- memory mappings .set idx, idx + 1 .endr .fill 448, 8, 0x0 3: /* level 3 */ - .quad 0x0 // omit first 4k page + .quad 0x0 // omit first 4k page .set idx, 1 .rept 511 - .quad PAGE_XIP | (idx << 12) // 2044 KiB of R-X flash mappings + .quad PAGE_XIP | \mt | (idx << 12) // 2044 KiB of R-X flash mappings .set idx, idx + 1 .endr + .endm + + make_idmap idmap, root_levels=1, mt=TT_MT_MEM + make_idmap idmap_lpa2, root_levels=2, mt=TT_MT_MEM_LPA2 AARCH64_BTI_NOTE()