11bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish/** @file
21bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish*  File managing the MMU for ARMv7 architecture
31bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish*
46f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
51bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish*
63402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  This program and the accompanying materials
73402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  are licensed and made available under the terms and conditions of the BSD License
83402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  which accompanies this distribution.  The full text of the license may be found at
93402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  http://opensource.org/licenses/bsd-license.php
103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*
113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
123402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
131bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish*
141bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish**/
151bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
163402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#include <Uefi.h>
171bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include <Chipset/ArmV7.h>
181bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include <Library/BaseMemoryLib.h>
191bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include <Library/MemoryAllocationLib.h>
201bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include <Library/ArmLib.h>
211bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include <Library/BaseLib.h>
222cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin#include <Library/DebugLib.h>
231bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include "ArmV7Lib.h"
241bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish#include "ArmLibPrivate.h"
251bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
266adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier MartinUINT32
276adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier MartinConvertSectionAttributesToPageAttributes (
286adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  IN UINT32   SectionAttributes,
296adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  IN BOOLEAN  IsLargePage
306adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  )
316adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin{
326adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  UINT32 PageAttributes;
336adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin
346adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes = 0;
356adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
366adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
376adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
386adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
396adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
406adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin
416adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin  return PageAttributes;
426adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin}
436adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin
44a3202839da599ce4a0267e5a1288eee7099af880Olivier MartinSTATIC
4546ff196fde4882fca1a0210f7df9166d8832ad06Ard BiesheuvelBOOLEAN
4646ff196fde4882fca1a0210f7df9166d8832ad06Ard BiesheuvelPreferNonshareableMemory (
4746ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  VOID
4846ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  )
4946ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel{
5046ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  UINTN   Mmfr;
5146ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  UINTN   Val;
5246ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel
5346ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  if (FeaturePcdGet (PcdNormalMemoryNonshareableOverride)) {
5446ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    return TRUE;
5546ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  }
5646ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel
5746ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  //
5846ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  // Check whether the innermost level of shareability (the level we will use
5946ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  // by default to map normal memory) is implemented with hardware coherency
6046ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  // support. Otherwise, revert to mapping as non-shareable.
6146ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  //
6246ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  Mmfr = ArmReadIdMmfr0 ();
6346ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) {
6446ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  case ID_MMFR0_SHARELVL_ONE:
6546ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    // one level of shareability
6646ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    Val = (Mmfr >> ID_MMFR0_OUTERSHR_SHIFT) & ID_MMFR0_OUTERSHR_MASK;
6746ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    break;
6846ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  case ID_MMFR0_SHARELVL_TWO:
6946ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    // two levels of shareability
7046ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    Val = (Mmfr >> ID_MMFR0_INNERSHR_SHIFT) & ID_MMFR0_INNERSHR_MASK;
7146ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    break;
7246ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  default:
7346ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    // unexpected value -> shareable is the safe option
7446ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    ASSERT (FALSE);
7546ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    return FALSE;
7646ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  }
7746ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  return Val != ID_MMFR0_SHR_IMP_HW_COHERENT;
7846ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel}
7946ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel
8046ff196fde4882fca1a0210f7df9166d8832ad06Ard BiesheuvelSTATIC
811bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfishVOID
822cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartinPopulateLevel2PageTable (
832cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  IN UINT32                         *SectionEntry,
842cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  IN UINT32                         PhysicalBase,
852cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  IN UINT32                         RemainLength,
862cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  IN ARM_MEMORY_REGION_ATTRIBUTES   Attributes
87bd6b97994ab6219c74033a7e68a503dbb8d56f9foliviermartin  )
88bd6b97994ab6219c74033a7e68a503dbb8d56f9foliviermartin{
892cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32* PageEntry;
902cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  Pages;
912cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  Index;
922cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  PageAttributes;
932cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  SectionDescriptor;
942cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  TranslationTable;
952cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  BaseSectionAddress;
962cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
972cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  switch (Attributes) {
982cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
997fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
1002cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
1012cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      break;
1022cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
1037fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
1042cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;
1052cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      break;
1062cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
1077fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
1082cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;
1092cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      break;
1102cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
1117fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
1122cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
1132cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      break;
1142cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    default:
1152cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
1162cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      break;
1172cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  }
1182cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
11946ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  if (PreferNonshareableMemory ()) {
12065ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel    PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
12165ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel  }
12265ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel
1232cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  // Check if the Section Entry has already been populated. Otherwise attach a
1242cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  // Level 2 Translation Table to it
1252cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  if (*SectionEntry != 0) {
1262cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    // The entry must be a page table. Otherwise it exists an overlapping in the memory map
1272cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) {
1282cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK;
1292cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    } else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
1302cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Case where a virtual memory map descriptor overlapped a section entry
1312cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1322cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Allocate a Level2 Page Table for this Section
1332cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
1342cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
1352cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1362cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Translate the Section Descriptor into Page Descriptor
1376adbd5b4d255b15f1f2feb2e956a2fdd0683a2e2Olivier Martin      SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
1382cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1392cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
1402cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1412cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Populate the new Level2 Page Table for the section
1422cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PageEntry = (UINT32*)TranslationTable;
1432cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
1442cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseSectionAddress + (Index << 12)) | SectionDescriptor;
1452cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      }
1462cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1472cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Overwrite the section entry to point to the new Level2 Translation Table
1482cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
1492cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin          (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
1502cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin          TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
1512cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    } else {
1522cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // We do not support the other section type (16MB Section)
1532cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      ASSERT(0);
1542cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      return;
1552cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    }
1562cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  } else {
1572cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
1582cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
1592cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1602cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
1612cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1622cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
1632cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
1642cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
1652cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  }
1662cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1672cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  PageEntry = ((UINT32 *)(TranslationTable) + ((PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT));
1682cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  Pages     = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;
1692cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1702cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  for (Index = 0; Index < Pages; Index++) {
1712cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    *PageEntry++     =  TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;
1722cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
1732cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  }
1742cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
1752cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin}
1762cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
177a3202839da599ce4a0267e5a1288eee7099af880Olivier MartinSTATIC
1782cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartinVOID
1791bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfishFillTranslationTable (
1801bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  IN  UINT32                        *TranslationTable,
1811bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion
1821bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  )
1831bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish{
1842cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  UINT32  *SectionEntry;
1851bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  UINT32  Attributes;
18655df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel  UINT32  PhysicalBase;
1872cde2696f5cd252c48fe250d44590869dae7a1e9Ard Biesheuvel  UINT64  RemainLength;
1883402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
1892cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  ASSERT(MemoryRegion->Length > 0);
1902cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
19155df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel  if (MemoryRegion->PhysicalBase >= SIZE_4GB) {
19255df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel    return;
19355df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel  }
19455df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel
19555df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel  PhysicalBase = MemoryRegion->PhysicalBase;
19655df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel  RemainLength = MIN(MemoryRegion->Length, SIZE_4GB - PhysicalBase);
19755df704dd24928b60b10bbb9dec5bfa7682910deArd Biesheuvel
1981bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  switch (MemoryRegion->Attributes) {
1991bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
2001bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
2011bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2021bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
2031bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
2041bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2051bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
2061bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
2071bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2081bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
2091bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
2101bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2117fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
2121bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
2131bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2147fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
2151bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
2161bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2177fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
2181bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
2191bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2207fffeef9bece37fe48341fcf47edb474f954e690oliviermartin    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
2211bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
2221bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2231bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    default:
2241bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
2251bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      break;
2261bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
2273402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
22846ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel  if (PreferNonshareableMemory ()) {
22965ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel    Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
23065ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel  }
23165ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel
2322cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  // Get the first section entry for this mapping
2332cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  SectionEntry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
2342cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
2352cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin  while (RemainLength != 0) {
2362cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0) {
2372cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      if (RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
2382cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        // Case: Physical address aligned on the Section Size (1MB) && the length is greater than the Section Size
2392cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        *SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
2402cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
2412cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      } else {
2422cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        // Case: Physical address aligned on the Section Size (1MB) && the length does not fill a section
243bd6b97994ab6219c74033a7e68a503dbb8d56f9foliviermartin        PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
2442cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
2452cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        // It must be the last entry
2462cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        break;
2472cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      }
2482cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    } else {
2492cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Case: Physical address NOT aligned on the Section Size (1MB)
250bd6b97994ab6219c74033a7e68a503dbb8d56f9foliviermartin      PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
2512cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // Aligned the address
2522cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      PhysicalBase = (PhysicalBase + TT_DESCRIPTOR_SECTION_SIZE) & ~(TT_DESCRIPTOR_SECTION_SIZE-1);
2532cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin
2542cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      // If it is the last entry
2552cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
2562cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin        break;
2572cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin      }
2582cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    }
2592cf4b60895f8af5be3fa33231974dc3cb143b53coliviermartin    RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
2601bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
2611bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish}
2621bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
2636f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier MartinRETURN_STATUS
2641bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfishEFIAPI
2651bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfishArmConfigureMmu (
2661bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
2676f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  OUT VOID                         **TranslationTableBase OPTIONAL,
2686f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  OUT UINTN                         *TranslationTableSize OPTIONAL
2691bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  )
2701bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish{
2716f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  VOID*                         TranslationTable;
2721bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  ARM_MEMORY_REGION_ATTRIBUTES  TranslationTableAttribute;
2731bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  UINT32                        TTBRAttributes;
2741bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
2751bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  // Allocate pages for translation table.
2766f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
2776f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  if (TranslationTable == NULL) {
2786f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    return RETURN_OUT_OF_RESOURCES;
2796f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  }
2806f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
2811bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
2821bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  if (TranslationTableBase != NULL) {
2836f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    *TranslationTableBase = TranslationTable;
2841bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
2853402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
286526099f9680c5260998a6d6066dd043aafce0a4boliviermartin  if (TranslationTableSize != NULL) {
2871bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
2881bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
2891bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
2906f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
2911bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
2926f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  // By default, mark the translation table as belonging to a uncached region
2936f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
2941bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  while (MemoryTable->Length != 0) {
2951bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    // Find the memory attribute for the Translation Table
2966f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
2971bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish      TranslationTableAttribute = MemoryTable->Attributes;
2981bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    }
2991bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
3006f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    FillTranslationTable (TranslationTable, MemoryTable);
3011bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish    MemoryTable++;
3021bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
3031bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
3041bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  // Translate the Memory Attributes into Translation Table Register Attributes
3053402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
3067fffeef9bece37fe48341fcf47edb474f954e690oliviermartin      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
30772143137f4ea558757cb7933b1f3a0c21252126bArd Biesheuvel    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_NON_CACHEABLE : TTBR_NON_CACHEABLE;
3083402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
3097fffeef9bece37fe48341fcf47edb474f954e690oliviermartin      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
31072143137f4ea558757cb7933b1f3a0c21252126bArd Biesheuvel    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
3113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
3127fffeef9bece37fe48341fcf47edb474f954e690oliviermartin      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
31372143137f4ea558757cb7933b1f3a0c21252126bArd Biesheuvel    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_THROUGH : TTBR_WRITE_THROUGH;
3141bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  } else {
3156f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    ASSERT (0); // No support has been found for the attributes of the memory region that the translation table belongs to.
3166f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin    return RETURN_UNSUPPORTED;
3171bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  }
3181bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish
31907070ecc76cff00175715f9a9534bc9216599a11Ard Biesheuvel  if (TTBRAttributes & TTBR_SHAREABLE) {
32046ff196fde4882fca1a0210f7df9166d8832ad06Ard Biesheuvel    if (PreferNonshareableMemory ()) {
32165ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      TTBRAttributes ^= TTBR_SHAREABLE;
32265ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel    } else {
32365ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      //
32465ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      // Unlike the S bit in the short descriptors, which implies inner shareable
32565ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      // on an implementation that supports two levels, the meaning of the S bit
32665ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      // in the TTBR depends on the NOS bit, which defaults to Outer Shareable.
32765ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      // However, we should only set this bit after we have confirmed that the
32865ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      // implementation supports multiple levels, or else the NOS bit is UNK/SBZP
32965ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      //
33065ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      if (((ArmReadIdMmfr0 () >> 12) & 0xf) != 0) {
33165ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel        TTBRAttributes |= TTBR_NOT_OUTER_SHAREABLE;
33265ceda9173e688a42a3e74c0c94f4dffc569029cArd Biesheuvel      }
33307070ecc76cff00175715f9a9534bc9216599a11Ard Biesheuvel    }
33407070ecc76cff00175715f9a9534bc9216599a11Ard Biesheuvel  }
33507070ecc76cff00175715f9a9534bc9216599a11Ard Biesheuvel
336ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmCleanInvalidateDataCache ();
337ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmInvalidateInstructionCache ();
338ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen
339ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmDisableDataCache ();
340ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmDisableInstructionCache();
341ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  // TLBs are also invalidated when calling ArmDisableMmu()
342ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmDisableMmu ();
343ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen
344ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  // Make sure nothing sneaked into the cache
345ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmCleanInvalidateDataCache ();
346ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen  ArmInvalidateInstructionCache ();
347ffb91edfd5eef02d0f7e0326bfa7023e8ea9bb6dEugene Cohen
3486f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
3493402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
3501bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |
3511bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE(14) |
3521bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE(13) |
3531bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE(12) |
3541bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE(11) |
3551bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE(10) |
3561bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 9) |
3571bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 8) |
3581bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 7) |
3591bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 6) |
3601bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 5) |
3611bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 4) |
3621bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 3) |
3631bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 2) |
3641bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish                             DOMAIN_ACCESS_CONTROL_NONE( 1) |
3656bc35cbaca790fc32904cbb4f1bfc30381910ed0Ard Biesheuvel                             DOMAIN_ACCESS_CONTROL_CLIENT(0));
3663402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
3671bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  ArmEnableInstructionCache();
3681bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  ArmEnableDataCache();
3691bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish  ArmEnableMmu();
3706f050ad6bf16f3f2ae2f0b62e93404230de575ccOlivier Martin  return RETURN_SUCCESS;
3711bfda055dfbc52678655ab2ded721f9f7c0cd496andrewfish}
3724d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel
3734d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelRETURN_STATUS
3744d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelArmSetMemoryRegionNoExec (
3754d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
3764d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  UINT64                    Length
3774d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  )
3784d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel{
3794d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  return RETURN_UNSUPPORTED;
3804d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel}
3814d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel
3824d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelRETURN_STATUS
3834d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelArmClearMemoryRegionNoExec (
3844d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
3854d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  UINT64                    Length
3864d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  )
3874d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel{
3884d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  return RETURN_UNSUPPORTED;
3894d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel}
3904d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel
3914d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelRETURN_STATUS
3924d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelArmSetMemoryRegionReadOnly (
3934d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
3944d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  UINT64                    Length
3954d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  )
3964d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel{
3974d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  return RETURN_UNSUPPORTED;
3984d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel}
3994d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel
4004d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelRETURN_STATUS
4014d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd BiesheuvelArmClearMemoryRegionReadOnly (
4024d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
4034d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  IN  UINT64                    Length
4044d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  )
4054d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel{
4064d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel  return RETURN_UNSUPPORTED;
4074d9a4f62cfc8d04f822edb8f3467ba2de45a16deArd Biesheuvel}
408