summaryrefslogtreecommitdiff
path: root/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c')
-rw-r--r--ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c418
1 files changed, 0 insertions, 418 deletions
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
deleted file mode 100644
index 74a7c17..0000000
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/** @file
-* File managing the MMU for ARMv7 architecture
-*
-* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
-*
-* This program and the accompanying materials
-* are licensed and made available under the terms and conditions of the BSD License
-* which accompanies this distribution. The full text of the license may be found at
-* http://opensource.org/licenses/bsd-license.php
-*
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include <Uefi.h>
-#include <Chipset/ArmV7.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/ArmLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include "ArmV7Lib.h"
-#include "ArmLibPrivate.h"
-
-UINT32
-ConvertSectionAttributesToPageAttributes (
- IN UINT32 SectionAttributes,
- IN BOOLEAN IsLargePage
- )
-{
- UINT32 PageAttributes;
-
- PageAttributes = 0;
- PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
- PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
- PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
- PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
- PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
-
- return PageAttributes;
-}
-
-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,
- 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;
-
- switch (Attributes) {
- case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
- PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
- PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
- PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
- PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
- break;
- default:
- PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
- break;
- }
-
- if (PreferNonshareableMemory ()) {
- 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) {
- // 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)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
- TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
-
- // Translate the Section Descriptor into Page Descriptor
- SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
-
- BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
-
- // 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) |
- (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
- TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
- } else {
- // We do not support the other section type (16MB Section)
- ASSERT(0);
- return;
- }
- } else {
- TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
- TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
-
- ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
-
- *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
- (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
- TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
- }
-
- PageEntry = ((UINT32 *)(TranslationTable) + ((PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT));
- Pages = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;
-
- for (Index = 0; Index < Pages; Index++) {
- *PageEntry++ = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;
- PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
- }
-
-}
-
-STATIC
-VOID
-FillTranslationTable (
- IN UINT32 *TranslationTable,
- IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
- )
-{
- UINT32 *SectionEntry;
- UINT32 Attributes;
- UINT32 PhysicalBase;
- UINT64 RemainLength;
-
- ASSERT(MemoryRegion->Length > 0);
-
- if (MemoryRegion->PhysicalBase >= SIZE_4GB) {
- return;
- }
-
- PhysicalBase = 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(0);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
- Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
- Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
- Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
- Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
- Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
- Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
- break;
- case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
- Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
- break;
- default:
- Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
- break;
- }
-
- if (PreferNonshareableMemory ()) {
- Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
- }
-
- // 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) {
- if (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;
- PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
- } else {
- // Case: Physical address aligned on the Section Size (1MB) && the length does not fill a section
- PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
-
- // It must be the last entry
- break;
- }
- } else {
- // Case: Physical address NOT aligned on the Section Size (1MB)
- PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
- // Aligned the address
- PhysicalBase = (PhysicalBase + TT_DESCRIPTOR_SECTION_SIZE) & ~(TT_DESCRIPTOR_SECTION_SIZE-1);
-
- // If it is the last entry
- if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
- break;
- }
- }
- RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
- }
-}
-
-RETURN_STATUS
-EFIAPI
-ArmConfigureMmu (
- IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
- OUT VOID **TranslationTableBase OPTIONAL,
- OUT UINTN *TranslationTableSize OPTIONAL
- )
-{
- VOID* TranslationTable;
- ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
- UINT32 TTBRAttributes;
-
- // Allocate pages for translation table.
- TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
- if (TranslationTable == NULL) {
- return RETURN_OUT_OF_RESOURCES;
- }
- TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
-
- if (TranslationTableBase != NULL) {
- *TranslationTableBase = TranslationTable;
- }
-
- if (TranslationTableSize != NULL) {
- *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
- }
-
- ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
-
- // By default, mark the translation table as belonging to a uncached region
- TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
- while (MemoryTable->Length != 0) {
- // Find the memory attribute for the Translation Table
- if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
- TranslationTableAttribute = MemoryTable->Attributes;
- }
-
- FillTranslationTable (TranslationTable, MemoryTable);
- MemoryTable++;
- }
-
- // Translate the Memory Attributes into Translation Table Register Attributes
- if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
- (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
- TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_NON_CACHEABLE : TTBR_NON_CACHEABLE;
- } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
- (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
- TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
- } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
- (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
- TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_THROUGH : TTBR_WRITE_THROUGH;
- } else {
- ASSERT (0); // No support has been found for the attributes of the memory region that the translation table belongs to.
- return RETURN_UNSUPPORTED;
- }
-
- if (TTBRAttributes & TTBR_SHAREABLE) {
- if (PreferNonshareableMemory ()) {
- 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;
- }
- }
- }
-
- ArmCleanInvalidateDataCache ();
- ArmInvalidateInstructionCache ();
-
- ArmDisableDataCache ();
- ArmDisableInstructionCache();
- // TLBs are also invalidated when calling ArmDisableMmu()
- ArmDisableMmu ();
-
- // Make sure nothing sneaked into the cache
- ArmCleanInvalidateDataCache ();
- ArmInvalidateInstructionCache ();
-
- ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
-
- //
- // 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;
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionNoExec (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionNoExec (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionReadOnly (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionReadOnly (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- return RETURN_UNSUPPORTED;
-}