From: Ard Biesheuvel Date: Wed, 18 Nov 2015 15:59:22 +0000 (+0000) Subject: ArmPkg/ArmV7Mmu: introduce feature PCD to map normal memory non-shareable X-Git-Tag: edk2-stable201903~8555 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=65ceda9173e688a42a3e74c0c94f4dffc569029c;p=mirror_edk2.git ArmPkg/ArmV7Mmu: introduce feature PCD to map normal memory non-shareable Even though mapping normal memory (inner) shareable is usually the correct choice on coherent systems, it may be desirable in some cases to use non-shareable mappings for normal memory, e.g., when hardware managed coherency is not required and the memory system is not fully configured yet. So introduce a PCD PcdNormalMemoryNonshareableOverride that makes cacheable mappings of normal memory non-shareable. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18897 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 46e9894d3f..ff4531e441 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -73,6 +73,12 @@ # Define if the GICv3 controller should use the GICv2 legacy gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042 +[PcdsFeatureFlag.ARM] + # Whether to map normal memory as non-shareable. FALSE is the safe choice, but + # TRUE may be appropriate to fix performance problems if you don't care about + # hardware coherency (i.e., no virtualization or cache coherent DMA) + gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043 + [PcdsFixedAtBuild.common] gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006 diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf index 01bdfb6996..d56851a140 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf @@ -48,3 +48,6 @@ [Protocols] gEfiCpuArchProtocolGuid + +[FeaturePcd.ARM] + gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf index ac081068db..6eaf350c7b 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf @@ -48,3 +48,6 @@ [Protocols] gEfiCpuArchProtocolGuid + +[FeaturePcd.ARM] + gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c index f03f609d21..a9cb06d78e 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c @@ -80,6 +80,10 @@ PopulateLevel2PageTable ( break; } + if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) { + PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED; + } + // Check if the Section Entry has already been populated. Otherwise attach a // Level 2 Translation Table to it if (*SectionEntry != 0) { @@ -178,6 +182,10 @@ FillTranslationTable ( break; } + if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) { + Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED; + } + // Get the first section entry for this mapping SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase); @@ -266,15 +274,19 @@ ArmConfigureMmu ( } 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; + if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) { + TTBRAttributes ^= TTBR_SHAREABLE; + } else { + // + // 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; + } } }