diff --git a/UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf b/UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf index 32577be7ea..b6818bd3e2 100644 --- a/UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf +++ b/UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf @@ -18,12 +18,6 @@ VERSION_STRING = 1.0 ENTRY_POINT = CpuMmio2Initialize -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = ARM AARCH64 LOONGARCH64 RISCV64 -# - [Sources] CpuMmio2Dxe.c diff --git a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c b/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c deleted file mode 100644 index bf3a874822..0000000000 --- a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c +++ /dev/null @@ -1,32 +0,0 @@ -/** @file -* File managing the MMU for ARMv7 architecture -* -* Copyright (c) 2011-2016, ARM Limited. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#include - -#include - -#include - -UINT32 -ConvertSectionAttributesToPageAttributes ( - IN UINT32 SectionAttributes - ) -{ - UINT32 PageAttributes; - - PageAttributes = 0; - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes); - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes); - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AF (SectionAttributes); - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes); - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes); - PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes); - - return PageAttributes; -} diff --git a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c deleted file mode 100644 index 643541dcb6..0000000000 --- a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ /dev/null @@ -1,376 +0,0 @@ -/** @file -* File managing the MMU for ARMv7 architecture -* -* Copyright (c) 2011-2016, ARM Limited. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 - -UINTN -EFIAPI -ArmReadIdMmfr0 ( - VOID - ); - -BOOLEAN -EFIAPI -ArmHasMpExtensions ( - VOID - ); - -STATIC -VOID -PopulateLevel2PageTable ( - IN UINT32 *SectionEntry, - IN UINT32 PhysicalBase, - IN UINT32 RemainLength, - IN ARM_MEMORY_REGION_ATTRIBUTES Attributes - ) -{ - UINT32 *PageEntry; - UINT32 Pages; - UINT32 Index; - UINT32 PageAttributes; - UINT32 SectionDescriptor; - UINT32 TranslationTable; - UINT32 BaseSectionAddress; - UINT32 FirstPageOffset; - - switch (Attributes) { - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK: - PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE: - PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK; - PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO: - PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK; - PageAttributes |= TT_DESCRIPTOR_PAGE_AP_NO_RO; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP: - PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK; - PageAttributes |= TT_DESCRIPTOR_PAGE_XN_MASK; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: - PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE: - PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED: - PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED; - break; - default: - PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED; - break; - } - - // Check if the Section Entry has already been populated. Otherwise attach a - // Level 2 Translation Table to it - if (*SectionEntry != 0) { - // The entry must be a page table. Otherwise it exists an overlapping in the memory map - if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (*SectionEntry)) { - TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK; - } else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) { - // Case where a virtual memory map descriptor overlapped a section entry - - // Allocate a Level2 Page Table for this Section - TranslationTable = (UINTN)AllocateAlignedPages ( - EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE), - TRANSLATION_TABLE_PAGE_ALIGNMENT - ); - - // Translate the Section Descriptor into Page Descriptor - SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry); - - BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*SectionEntry); - - // - // Make sure we are not inadvertently hitting in the caches - // when populating the page tables - // - InvalidateDataCacheRange ( - (VOID *)TranslationTable, - TRANSLATION_TABLE_PAGE_SIZE - ); - - // Populate the new Level2 Page Table for the section - PageEntry = (UINT32 *)TranslationTable; - for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { - PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (BaseSectionAddress + (Index << 12)) | SectionDescriptor; - } - - // Overwrite the section entry to point to the new Level2 Translation Table - *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | - TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; - } else { - // We do not support the other section type (16MB Section) - ASSERT (0); - return; - } - } else { - TranslationTable = (UINTN)AllocateAlignedPages ( - EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE), - TRANSLATION_TABLE_PAGE_ALIGNMENT - ); - // - // Make sure we are not inadvertently hitting in the caches - // when populating the page tables - // - InvalidateDataCacheRange ( - (VOID *)TranslationTable, - TRANSLATION_TABLE_PAGE_SIZE - ); - ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE); - - *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | - TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; - } - - FirstPageOffset = (PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; - PageEntry = (UINT32 *)TranslationTable + FirstPageOffset; - Pages = RemainLength / TT_DESCRIPTOR_PAGE_SIZE; - - ASSERT (FirstPageOffset + Pages <= TRANSLATION_TABLE_PAGE_COUNT); - - for (Index = 0; Index < Pages; Index++) { - *PageEntry++ = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (PhysicalBase) | PageAttributes; - PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE; - } - - // - // Invalidate again to ensure that any line fetches that may have occurred - // [speculatively] since the previous invalidate are evicted again. - // - ArmDataMemoryBarrier (); - InvalidateDataCacheRange ( - (UINT32 *)TranslationTable + FirstPageOffset, - RemainLength / TT_DESCRIPTOR_PAGE_SIZE * sizeof (*PageEntry) - ); -} - -STATIC -VOID -FillTranslationTable ( - IN UINT32 *TranslationTable, - IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion - ) -{ - UINT32 *SectionEntry; - UINT32 Attributes; - UINT32 PhysicalBase; - UINT64 RemainLength; - UINT32 PageMapLength; - - ASSERT (MemoryRegion->Length > 0); - - if (MemoryRegion->PhysicalBase >= SIZE_4GB) { - return; - } - - PhysicalBase = (UINT32)MemoryRegion->PhysicalBase; - RemainLength = MIN (MemoryRegion->Length, SIZE_4GB - PhysicalBase); - - switch (MemoryRegion->Attributes) { - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK: - Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE: - Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; - Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO: - Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; - Attributes |= TT_DESCRIPTOR_SECTION_AP_NO_RO; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP: - Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; - Attributes |= TT_DESCRIPTOR_SECTION_XN_MASK; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: - Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE: - Attributes = TT_DESCRIPTOR_SECTION_DEVICE; - break; - case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED: - Attributes = TT_DESCRIPTOR_SECTION_UNCACHED; - break; - default: - Attributes = TT_DESCRIPTOR_SECTION_UNCACHED; - break; - } - - // Get the first section entry for this mapping - SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS (TranslationTable, MemoryRegion->VirtualBase); - - while (RemainLength != 0) { - if ((PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0) && - (RemainLength >= TT_DESCRIPTOR_SECTION_SIZE)) - { - // Case: Physical address aligned on the Section Size (1MB) && the length - // is greater than the Section Size - *SectionEntry = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (PhysicalBase) | Attributes; - - // - // Issue a DMB to ensure that the page table entry update made it to - // memory before we issue the invalidate, otherwise, a subsequent - // speculative fetch could observe the old value. - // - ArmDataMemoryBarrier (); - ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++); - - PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE; - RemainLength -= TT_DESCRIPTOR_SECTION_SIZE; - } else { - PageMapLength = MIN ( - (UINT32)RemainLength, - TT_DESCRIPTOR_SECTION_SIZE - - (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE) - ); - - // Case: Physical address aligned on the Section Size (1MB) && the length - // does not fill a section - // Case: Physical address NOT aligned on the Section Size (1MB) - PopulateLevel2PageTable ( - SectionEntry, - PhysicalBase, - PageMapLength, - MemoryRegion->Attributes - ); - - // - // Issue a DMB to ensure that the page table entry update made it to - // memory before we issue the invalidate, otherwise, a subsequent - // speculative fetch could observe the old value. - // - ArmDataMemoryBarrier (); - ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++); - - // If it is the last entry - if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) { - break; - } - - PhysicalBase += PageMapLength; - RemainLength -= PageMapLength; - } - } -} - -RETURN_STATUS -EFIAPI -ArmConfigureMmu ( - IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, - OUT VOID **TranslationTableBase OPTIONAL, - OUT UINTN *TranslationTableSize OPTIONAL - ) -{ - VOID *TranslationTable; - UINT32 TTBRAttributes; - - TranslationTable = AllocateAlignedPages ( - EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE), - TRANSLATION_TABLE_SECTION_ALIGNMENT - ); - if (TranslationTable == NULL) { - return RETURN_OUT_OF_RESOURCES; - } - - if (TranslationTableBase != NULL) { - *TranslationTableBase = TranslationTable; - } - - if (TranslationTableSize != NULL) { - *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE; - } - - // - // Make sure we are not inadvertently hitting in the caches - // when populating the page tables - // - InvalidateDataCacheRange (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE); - ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE); - - while (MemoryTable->Length != 0) { - FillTranslationTable (TranslationTable, MemoryTable); - MemoryTable++; - } - - TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC - : TTBR_WRITE_BACK_ALLOC; - - // - // 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; - } - - ArmSetTTBR0 ((VOID *)((UINTN)TranslationTable | TTBRAttributes)); - - // - // The TTBCR register value is undefined at reset in the Non-Secure world. - // Writing 0 has the effect of: - // Clearing EAE: Use short descriptors, as mandated by specification. - // Clearing PD0 and PD1: Translation Table Walk Disable is off. - // Clearing N: Perform all translation table walks through TTBR0. - // (0 is the default reset value in systems not implementing - // the Security Extensions.) - // - ArmSetTTBCR (0); - - ArmSetDomainAccessControl ( - DOMAIN_ACCESS_CONTROL_NONE (15) | - DOMAIN_ACCESS_CONTROL_NONE (14) | - DOMAIN_ACCESS_CONTROL_NONE (13) | - DOMAIN_ACCESS_CONTROL_NONE (12) | - DOMAIN_ACCESS_CONTROL_NONE (11) | - DOMAIN_ACCESS_CONTROL_NONE (10) | - DOMAIN_ACCESS_CONTROL_NONE (9) | - DOMAIN_ACCESS_CONTROL_NONE (8) | - DOMAIN_ACCESS_CONTROL_NONE (7) | - DOMAIN_ACCESS_CONTROL_NONE (6) | - DOMAIN_ACCESS_CONTROL_NONE (5) | - DOMAIN_ACCESS_CONTROL_NONE (4) | - DOMAIN_ACCESS_CONTROL_NONE (3) | - DOMAIN_ACCESS_CONTROL_NONE (2) | - DOMAIN_ACCESS_CONTROL_NONE (1) | - DOMAIN_ACCESS_CONTROL_CLIENT (0) - ); - - ArmEnableInstructionCache (); - ArmEnableDataCache (); - ArmEnableMmu (); - return RETURN_SUCCESS; -} diff --git a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c deleted file mode 100644 index b8b8a7016d..0000000000 --- a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ /dev/null @@ -1,561 +0,0 @@ -/** @file -* File managing the MMU for ARMv7 architecture -* -* Copyright (c) 2011-2021, Arm Limited. All rights reserved.
-* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define __EFI_MEMORY_RWX 0 // no restrictions - -#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \ - EFI_MEMORY_WC | \ - EFI_MEMORY_WT | \ - EFI_MEMORY_WB | \ - EFI_MEMORY_UCE | \ - EFI_MEMORY_WP) - -STATIC -EFI_STATUS -ConvertSectionToPages ( - IN EFI_PHYSICAL_ADDRESS BaseAddress - ) -{ - UINT32 FirstLevelIdx; - UINT32 SectionDescriptor; - UINT32 PageTableDescriptor; - UINT32 PageDescriptor; - UINT32 Index; - - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - volatile ARM_PAGE_TABLE_ENTRY *PageTable; - - DEBUG ((DEBUG_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress)); - - // Obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - - // Calculate index into first level translation table for start of modification - FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // Get section attributes and convert to page attributes - SectionDescriptor = FirstLevelTable[FirstLevelIdx]; - PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor); - - // Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB) - PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1); - if (PageTable == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // Write the page table entries out - for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { - PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (BaseAddress + (Index << 12)) | PageDescriptor; - } - - // Formulate page table entry, Domain=0, NS=0 - PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; - - // Write the page table entry out, replacing section entry - FirstLevelTable[FirstLevelIdx] = PageTableDescriptor; - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -UpdatePageEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT32 EntryMask, - OUT BOOLEAN *FlushTlbs OPTIONAL - ) -{ - EFI_STATUS Status; - UINT32 EntryValue; - UINT32 FirstLevelIdx; - UINT32 Offset; - UINT32 NumPageEntries; - UINT32 Descriptor; - UINT32 p; - UINT32 PageTableIndex; - UINT32 PageTableEntry; - UINT32 CurrentPageTableEntry; - VOID *Mva; - - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - volatile ARM_PAGE_TABLE_ENTRY *PageTable; - - Status = EFI_SUCCESS; - - // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone) - // EntryValue: values at bit positions specified by EntryMask - EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE; - - // Although the PI spec is unclear on this, the GCD guarantees that only - // one Attribute bit is set at a time, so the order of the conditionals below - // is irrelevant. If no memory attribute is specified, we preserve whatever - // memory type is set in the page tables, and update the permission attributes - // only. - if ((Attributes & EFI_MEMORY_UC) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 - } else if ((Attributes & EFI_MEMORY_WC) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // map to normal non-cacheable - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 - } else if ((Attributes & EFI_MEMORY_WT) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 - } else if ((Attributes & EFI_MEMORY_WB) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 - } else if ((Attributes & CACHE_ATTRIBUTE_MASK) != 0) { - // catch unsupported memory type attributes - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - if ((Attributes & EFI_MEMORY_RP) == 0) { - EntryValue |= TT_DESCRIPTOR_PAGE_AF; - } - - if ((Attributes & EFI_MEMORY_RO) != 0) { - EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO; - } else { - EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW; - } - - if ((Attributes & EFI_MEMORY_XP) != 0) { - EntryValue |= TT_DESCRIPTOR_PAGE_XN_MASK; - } - - // Obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - - // Calculate number of 4KB page table entries to change - NumPageEntries = (UINT32)(Length / TT_DESCRIPTOR_PAGE_SIZE); - - // Iterate for the number of 4KB pages to change - Offset = 0; - for (p = 0; p < NumPageEntries; p++) { - // Calculate index into first level translation table for page table value - - FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // Read the descriptor from the first level page table - Descriptor = FirstLevelTable[FirstLevelIdx]; - - // Does this descriptor need to be converted from section entry to 4K pages? - if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (Descriptor)) { - // - // If the section mapping covers the requested region with the expected - // attributes, splitting it is unnecessary, and should be avoided as it - // may result in unbounded recursion when using a strict NX policy. - // - if ((EntryValue & ~TT_DESCRIPTOR_PAGE_TYPE_MASK & EntryMask) == - (ConvertSectionAttributesToPageAttributes (Descriptor) & EntryMask)) - { - continue; - } - - Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT); - if (EFI_ERROR (Status)) { - // Exit for loop - break; - } - - // Re-read descriptor - Descriptor = FirstLevelTable[FirstLevelIdx]; - if (FlushTlbs != NULL) { - *FlushTlbs = TRUE; - } - } - - // Obtain page table base address - PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS (Descriptor); - - // Calculate index into the page table - PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; - ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT); - - // Get the entry - CurrentPageTableEntry = PageTable[PageTableIndex]; - - // Mask off appropriate fields - PageTableEntry = CurrentPageTableEntry & ~EntryMask; - - // Mask in new attributes and/or permissions - PageTableEntry |= EntryValue; - - if (CurrentPageTableEntry != PageTableEntry) { - Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); - - // Only need to update if we are changing the entry - PageTable[PageTableIndex] = PageTableEntry; - ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva); - } - - Status = EFI_SUCCESS; - Offset += TT_DESCRIPTOR_PAGE_SIZE; - } // End first level translation table loop - - return Status; -} - -STATIC -EFI_STATUS -UpdateSectionEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT32 EntryMask - ) -{ - EFI_STATUS Status; - UINT32 EntryValue; - UINT32 FirstLevelIdx; - UINT32 NumSections; - UINT32 i; - UINT32 CurrentDescriptor; - UINT32 Descriptor; - VOID *Mva; - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - - Status = EFI_SUCCESS; - - // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone) - // EntryValue: values at bit positions specified by EntryMask - - // Make sure we handle a section range that is unmapped - EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION; - - // Although the PI spec is unclear on this, the GCD guarantees that only - // one Attribute bit is set at a time, so the order of the conditionals below - // is irrelevant. If no memory attribute is specified, we preserve whatever - // memory type is set in the page tables, and update the permission attributes - // only. - if ((Attributes & EFI_MEMORY_UC) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to strongly ordered - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 - } else if ((Attributes & EFI_MEMORY_WC) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // map to normal non-cacheable - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 - } else if ((Attributes & EFI_MEMORY_WT) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write through with no-allocate - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 - } else if ((Attributes & EFI_MEMORY_WB) != 0) { - // modify cacheability attributes - EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; - // write back (with allocate) - EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 - } else if ((Attributes & CACHE_ATTRIBUTE_MASK) != 0) { - // catch unsupported memory type attributes - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - if ((Attributes & EFI_MEMORY_RO) != 0) { - EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO; - } else { - EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW; - } - - if ((Attributes & EFI_MEMORY_XP) != 0) { - EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK; - } - - if ((Attributes & EFI_MEMORY_RP) == 0) { - EntryValue |= TT_DESCRIPTOR_SECTION_AF; - } - - // obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - - // calculate index into first level translation table for start of modification - FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; - ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); - - // calculate number of 1MB first level entries this applies to - NumSections = (UINT32)(Length / TT_DESCRIPTOR_SECTION_SIZE); - - // iterate through each descriptor - for (i = 0; i < NumSections; i++) { - CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i]; - - // has this descriptor already been converted to pages? - if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (CurrentDescriptor)) { - // forward this 1MB range to page table function instead - Status = UpdatePageEntries ( - (FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, - TT_DESCRIPTOR_SECTION_SIZE, - Attributes, - ConvertSectionAttributesToPageAttributes (EntryMask), - NULL - ); - } else { - // still a section entry - - if (CurrentDescriptor != 0) { - // mask off appropriate fields - Descriptor = CurrentDescriptor & ~EntryMask; - } else { - Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT; - } - - // mask in new attributes and/or permissions - Descriptor |= EntryValue; - - if (CurrentDescriptor != Descriptor) { - Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT); - - // Only need to update if we are changing the descriptor - FirstLevelTable[FirstLevelIdx + i] = Descriptor; - ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva); - } - - Status = EFI_SUCCESS; - } - } - - return Status; -} - -/** - Update the permission or memory type attributes on a range of memory. - - @param BaseAddress The start of the region. - @param Length The size of the region. - @param Attributes A mask of EFI_MEMORY_xx constants. - @param SectionMask A mask of short descriptor section attributes - describing which descriptor bits to update. - - @retval EFI_SUCCESS The attributes were set successfully. - @retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory. - -**/ -STATIC -EFI_STATUS -SetMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT32 SectionMask - ) -{ - EFI_STATUS Status; - UINT64 ChunkLength; - BOOLEAN FlushTlbs; - - if (BaseAddress > (UINT64)MAX_ADDRESS) { - DEBUG (( - DEBUG_ERROR, - "%a BaseAddress: 0x%llx is greater than MAX_ADDRESS: 0x%llx, fail to apply attributes!\n", - __func__, - BaseAddress, - (UINT64)MAX_ADDRESS - )); - return EFI_UNSUPPORTED; - } - - Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1); - if (Length == 0) { - return EFI_SUCCESS; - } - - FlushTlbs = FALSE; - while (Length > 0) { - if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) && - (Length >= TT_DESCRIPTOR_SECTION_SIZE)) - { - ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE; - - DEBUG (( - DEBUG_PAGE, - "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", - BaseAddress, - ChunkLength, - Attributes - )); - - Status = UpdateSectionEntries ( - BaseAddress, - ChunkLength, - Attributes, - SectionMask - ); - - FlushTlbs = TRUE; - } else { - // - // Process page by page until the next section boundary, but only if - // we have more than a section's worth of area to deal with after that. - // - ChunkLength = TT_DESCRIPTOR_SECTION_SIZE - - (BaseAddress % TT_DESCRIPTOR_SECTION_SIZE); - if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) { - ChunkLength = Length; - } - - DEBUG (( - DEBUG_PAGE, - "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n", - BaseAddress, - ChunkLength, - Attributes - )); - - Status = UpdatePageEntries ( - BaseAddress, - ChunkLength, - Attributes, - ConvertSectionAttributesToPageAttributes (SectionMask), - &FlushTlbs - ); - } - - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a failed to update attributes with status %r for BaseAddress 0x%llx of length 0x%llx\n", - __func__, - Status, - BaseAddress, - ChunkLength - )); - break; - } - - BaseAddress += ChunkLength; - Length -= ChunkLength; - } - - if (FlushTlbs) { - ArmInvalidateTlb (); - } - - return Status; -} - -/** - Set the requested memory permission attributes on a region of memory. - - BaseAddress and Length must be aligned to EFI_PAGE_SIZE. - - If Attributes contains a memory type attribute (EFI_MEMORY_UC/WC/WT/WB), the - region is mapped according to this memory type, and additional memory - permission attributes (EFI_MEMORY_RP/RO/XP) are taken into account as well, - discarding any permission attributes that are currently set for the region. - AttributeMask is ignored in this case, and must be set to 0x0. - - If Attributes contains only a combination of memory permission attributes - (EFI_MEMORY_RP/RO/XP), each page in the region will retain its existing - memory type, even if it is not uniformly set across the region. In this case, - AttributesMask may be set to a mask of permission attributes, and memory - permissions omitted from this mask will not be updated for any page in the - region. All attributes appearing in Attributes must appear in AttributeMask - as well. (Attributes & ~AttributeMask must produce 0x0) - - @param[in] BaseAddress The physical address that is the start address of - a memory region. - @param[in] Length The size in bytes of the memory region. - @param[in] Attributes Mask of memory attributes to set. - @param[in] AttributeMask Mask of memory attributes to take into account. - - @retval EFI_SUCCESS The attributes were set for the memory region. - @retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned. - Invalid combination of Attributes and - AttributeMask. - @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to - lack of system resources. - -**/ -EFI_STATUS -ArmSetMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT64 AttributeMask - ) -{ - UINT32 TtEntryMask; - - if (((BaseAddress | Length) & EFI_PAGE_MASK) != 0) { - return EFI_INVALID_PARAMETER; - } - - if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) { - // - // No memory type was set in Attributes, so we are going to update the - // permissions only. - // - if (AttributeMask != 0) { - if (((AttributeMask & ~(UINT64)(EFI_MEMORY_RP|EFI_MEMORY_RO|EFI_MEMORY_XP)) != 0) || - ((Attributes & ~AttributeMask) != 0)) - { - return EFI_INVALID_PARAMETER; - } - } else { - AttributeMask = EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP; - } - - TtEntryMask = 0; - if ((AttributeMask & EFI_MEMORY_RP) != 0) { - TtEntryMask |= TT_DESCRIPTOR_SECTION_AF; - } - - if ((AttributeMask & EFI_MEMORY_RO) != 0) { - TtEntryMask |= TT_DESCRIPTOR_SECTION_AP_MASK; - } - - if ((AttributeMask & EFI_MEMORY_XP) != 0) { - TtEntryMask |= TT_DESCRIPTOR_SECTION_XN_MASK; - } - } else { - ASSERT (AttributeMask == 0); - if (AttributeMask != 0) { - return EFI_INVALID_PARAMETER; - } - - TtEntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | - TT_DESCRIPTOR_SECTION_XN_MASK | - TT_DESCRIPTOR_SECTION_AP_MASK | - TT_DESCRIPTOR_SECTION_AF; - } - - return SetMemoryAttributes ( - BaseAddress, - Length, - Attributes, - TtEntryMask - ); -} diff --git a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S b/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S deleted file mode 100644 index 05f553aba6..0000000000 --- a/UefiCpuPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S +++ /dev/null @@ -1,29 +0,0 @@ -#------------------------------------------------------------------------------ -# -# Copyright (c) 2016, Linaro Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#------------------------------------------------------------------------------ - -#include - -.text -.align 2 - -GCC_ASM_EXPORT (ArmReadIdMmfr0) -GCC_ASM_EXPORT (ArmHasMpExtensions) - -#------------------------------------------------------------------------------ - -ASM_PFX (ArmHasMpExtensions): - mrc p15,0,R0,c0,c0,5 - // Get Multiprocessing extension (bit31) - lsr R0, R0, #31 - bx LR - -ASM_PFX(ArmReadIdMmfr0): - mrc p15, 0, r0, c0, c1, 4 @ Read ID_MMFR0 Register - bx lr - -ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf b/UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf index 9e92e2e583..ab32d45f69 100644 --- a/UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf +++ b/UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf @@ -14,8 +14,6 @@ MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = ArmMmuLib - -[Defines.AARCH64] CONSTRUCTOR = ArmMmuBaseLibConstructor [Sources.AARCH64] @@ -23,13 +21,6 @@ AArch64/ArmMmuLibCore.c AArch64/ArmMmuLibReplaceEntry.S -[Sources.ARM] - ArmMmuLibInternal.h - Arm/ArmMmuLibConvert.c - Arm/ArmMmuLibCore.c - Arm/ArmMmuLibUpdate.c - Arm/ArmMmuLibV7Support.S |GCC - [Packages] MdePkg/MdePkg.dec UefiCpuPkg/UefiCpuPkg.dec diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 3789ee9535..f23084b799 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -88,7 +88,7 @@ ## @libraryclass Provides functions for the memory management unit. CpuMmuLib|Include/Library/CpuMmuLib.h -[LibraryClasses.ARM, LibraryClasses.AARCH64] +[LibraryClasses.AARCH64] ## @libraryclass Provides a Mmu interface. # ArmMmuLib|Include/Library/ArmMmuLib.h @@ -130,7 +130,7 @@ # Include/Guid/MmAcpiS3Enable.h gMmAcpiS3EnableHobGuid = { 0xe7402821, 0x2654, 0x4c1b, { 0x99, 0x0e, 0x04, 0x8f, 0x8d, 0x82, 0xcf, 0x67 }} -[Guids.ARM, Guids.AARCH64] +[Guids.AARCH64] gArmMmuReplaceLiveTranslationEntryFuncGuid = { 0xa8b50ff3, 0x08ec, 0x4dd3, {0xbf, 0x04, 0x28, 0xbf, 0x71, 0x75, 0xc7, 0x4a} } [Protocols] diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index e011b1839d..58ccc37a23 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -224,10 +224,8 @@ UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf -[Components.ARM, Components.AARCH64] - UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf - [Components.AARCH64] + UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf UefiCpuPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf UefiCpuPkg/Library/BaseArchSupportLib/BaseArchSupportLib.inf