mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
UefiCpuPkg: Drop ARM32 Support
edk2 is dropping support for the ARM32 architecture. This commit removes ARM32 code from UefiCpuPkg. It drops irrelevant VALID_ARCHITECTURES fields from infs that are not arch specific. Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
This commit is contained in:
parent
215e45bdb3
commit
08c27faeed
8 changed files with 3 additions and 1018 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <Uefi.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
|
||||
#include <Arm/AArch32.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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 <Uefi.h>
|
||||
#include <Arm/AArch32.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.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
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1,561 +0,0 @@
|
|||
/** @file
|
||||
* File managing the MMU for ARMv7 architecture
|
||||
*
|
||||
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmMmuLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include <Arm/AArch32.h>
|
||||
|
||||
#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
|
||||
);
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <AsmMacroLib.h>
|
||||
|
||||
.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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue