diff --git a/ArmPkg/Include/Chipset/ArmV7Mmu.h b/ArmPkg/Include/Chipset/ArmV7Mmu.h index 2545864775..f612154bad 100644 --- a/ArmPkg/Include/Chipset/ArmV7Mmu.h +++ b/ArmPkg/Include/Chipset/ArmV7Mmu.h @@ -29,10 +29,10 @@ #define TTBR_RGN_INNER_WRITE_THROUGH BIT0 #define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC (BIT0|BIT6) -#define TTBR_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_RGN_INNER_WRITE_THROUGH ) -#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC ) +#define TTBR_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_RGN_INNER_WRITE_THROUGH | TTBR_SHAREABLE) +#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC | TTBR_SHAREABLE) #define TTBR_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE ) -#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC ) +#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC | TTBR_SHAREABLE) #define TRANSLATION_TABLE_SECTION_COUNT 4096 diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c index 8ed763cc82..f03f609d21 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c @@ -265,6 +265,19 @@ ArmConfigureMmu ( return RETURN_UNSUPPORTED; } + if (TTBRAttributes & TTBR_SHAREABLE) { + // + // Unlike the S bit in the short descriptors, which implies inner shareable + // on an implementation that supports two levels, the meaning of the S bit + // in the TTBR depends on the NOS bit, which defaults to Outer Shareable. + // However, we should only set this bit after we have confirmed that the + // implementation supports multiple levels, or else the NOS bit is UNK/SBZP + // + if (((ArmReadIdMmfr0 () >> 12) & 0xf) != 0) { + TTBRAttributes |= TTBR_NOT_OUTER_SHAREABLE; + } + } + ArmCleanInvalidateDataCache (); ArmInvalidateInstructionCache ();