On 8 December 2015 at 16:11, Ard Biesheuvel <[email protected]> wrote:
> Commit SVN r18778 made all mappings of normal memory (inner) shareable,
> even on hardware that implements shareability as uncached accesses.
> The original concerns that prompted the change, regarding coherent DMA
> and virt guests migrating between CPUs, do not apply to such hardware,
> so revert to the original behavior in that case.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <[email protected]>
> ---
> v2: use symbolic constants for the various shift and mask values
> default to shareable on unexpected values, but ASSERT() as well
>
Any more comment on this version? Thanks
> ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h | 14 +++++++
> ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c | 42 ++++++++++++++++++--
> 2 files changed, 53 insertions(+), 3 deletions(-)
>
> diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
> b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
> index e138613ca548..cbd3d6f654a6 100644
> --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
> +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
> @@ -15,6 +15,20 @@
> #ifndef __ARM_V7_LIB_H__
> #define __ARM_V7_LIB_H__
>
> +#define ID_MMFR0_SHARELVL_SHIFT 12
> +#define ID_MMFR0_SHARELVL_MASK 0xf
> +#define ID_MMFR0_SHARELVL_ONE 0
> +#define ID_MMFR0_SHARELVL_TWO 1
> +
> +#define ID_MMFR0_INNERSHR_SHIFT 28
> +#define ID_MMFR0_INNERSHR_MASK 0xf
> +#define ID_MMFR0_OUTERSHR_SHIFT 8
> +#define ID_MMFR0_OUTERSHR_MASK 0xf
> +
> +#define ID_MMFR0_SHR_IMP_UNCACHED 0
> +#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
> +#define ID_MMFR0_SHR_IGNORED 0xf
> +
> typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);
>
> VOID
> diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> index 23d2e43beba0..fc8ea42843b3 100644
> --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> @@ -42,6 +42,42 @@ ConvertSectionAttributesToPageAttributes (
> }
>
> STATIC
> +BOOLEAN
> +PreferNonshareableMemory (
> + VOID
> + )
> +{
> + UINTN Mmfr;
> + UINTN Val;
> +
> + if (FeaturePcdGet (PcdNormalMemoryNonshareableOverride)) {
> + return TRUE;
> + }
> +
> + //
> + // Check whether the innermost level of shareability (the level we will use
> + // by default to map normal memory) is implemented with hardware coherency
> + // support. Otherwise, revert to mapping as non-shareable.
> + //
> + Mmfr = ArmReadIdMmfr0 ();
> + switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) {
> + case ID_MMFR0_SHARELVL_ONE:
> + // one level of shareability
> + Val = (Mmfr >> ID_MMFR0_OUTERSHR_SHIFT) & ID_MMFR0_OUTERSHR_MASK;
> + break;
> + case ID_MMFR0_SHARELVL_TWO:
> + // two levels of shareability
> + Val = (Mmfr >> ID_MMFR0_INNERSHR_SHIFT) & ID_MMFR0_INNERSHR_MASK;
> + break;
> + default:
> + // unexpected value -> shareable is the safe option
> + ASSERT (FALSE);
> + return FALSE;
> + }
> + return Val != ID_MMFR0_SHR_IMP_HW_COHERENT;
> +}
> +
> +STATIC
> VOID
> PopulateLevel2PageTable (
> IN UINT32 *SectionEntry,
> @@ -80,7 +116,7 @@ PopulateLevel2PageTable (
> break;
> }
>
> - if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
> + if (PreferNonshareableMemory ()) {
> PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
> }
>
> @@ -189,7 +225,7 @@ FillTranslationTable (
> break;
> }
>
> - if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
> + if (PreferNonshareableMemory ()) {
> Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
> }
>
> @@ -281,7 +317,7 @@ ArmConfigureMmu (
> }
>
> if (TTBRAttributes & TTBR_SHAREABLE) {
> - if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
> + if (PreferNonshareableMemory ()) {
> TTBRAttributes ^= TTBR_SHAREABLE;
> } else {
> //
> --
> 1.9.1
>
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel