summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/ArmMmuLib
Commit message (Collapse)AuthorAgeFilesLines
* ArmPkg: Fix Ecc error 5007 in ArmMmuLibPierre Gondois2021-01-061-1/+3
| | | | | | | | | This patch fixes the following Ecc reported error: There should be no initialization of a variable as part of its declaration Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg: Fix Ecc error 3002 in ArmMmuLibPierre Gondois2021-01-062-16/+16
| | | | | | | | | This patch fixes the following Ecc reported error: Non-Boolean comparisons should use a compare operator (==, !=, >, < >=, <=) Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg: Format header to fix Ecc crash in ArmMmuLibPierre Gondois2021-01-061-7/+7
| | | | | | | | | | | | | | The header of the file is not formatted properly, making the Ecc tool crash when running on the ArmPkg. The following command was run: ./BaseTools/BinWrappers/PosixLike/Ecc -c BaseTools/Source/Python/Ecc/config.ini -e BaseTools/Source/Python/Ecc/exception.xml -t ArmPkg -r ArmPkgEcc.xls Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg/ArmMmuLib: Explicitly cast function pointer argumentMichael Kubacki2020-10-221-1/+1
| | | | | | | | | | | | | | | | | | | The function ArmReplaceLiveTranslationEntry () is passed as a VOID pointer to WriteBackDataCacheRange (). This produces the following warning on VS2019: warning C4152: nonstandard extension, function/data pointer conversion in expression This change explicitly casts the argument to the formal parameter type VOID*. This can be reproduced with the following build command: build -b DEBUG -a AARCH64 -t VS2019 -p ArmPkg/ArmPkg.dsc -m ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg/ArmMmuLib: Explicitly cast UINT32 data conversionsMichael Kubacki2020-10-222-4/+4
| | | | | | | | | | | | | | | | | | | | | | | REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2835 There's several occurrences of a UINT64 or an EFI_PHYSICAL_ADDRESS being assigned to a UINT32 value in ArmMmuLib. These result in warning C4244 in VS2019: warning C4244: '=': conversion from 'UINT64' to 'UINT32', possible loss of data warning C4244: '=': conversion from 'EFI_PHYSICAL_ADDRESS' to 'UINT32', possible loss of data This change explicitly casts the values to UINT32. These can be reproduced with the following build command: build -b DEBUG -a ARM -t VS2019 -p ArmPkg/ArmPkg.dsc -m ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg/ArmMmuLib: Fix implicit castPierre Gondois2020-06-271-1/+1
| | | | | | | | | | | | | | | | | | | | While building with the following command line: build -b DEBUG -a AARCH64 -t VS2017 -p MdeModulePkg\MdeModulePkg.dsc A missing cast triggers the following warning, then triggering an error: ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c(652): warning C4152: nonstandard extension, function/data pointer conversion in expression This patch first casts the function pointer to (UINTN), then to (VOID *), followowing the C99 standard s6.3.2.3 "Pointer", paragraphs 5 and 6. This suppresses the warning. Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> Suggested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
* ArmPkg/ArmMmuLib: drop unused TT_ATTR_INDX_INVALID CPP macroArd Biesheuvel2020-04-021-3/+0
| | | | | | | | | | | TT_ATTR_INDX_INVALID is #define'd but never used so drop it. Note that this leaves a CPP macro of the same name in CpuDxe, but there, it is actually being used, and although the name suggests that this value is somehow defined by the architecture, this is really not the case and it only has meaning within the scope of CpuDxe's implementation. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib: get rid of GetRootTranslationTableInfo()Ard Biesheuvel2020-04-021-16/+6
| | | | | | | | | Only a single call to GetRootTranslationTableInfo() remains, which only provides the root table level. So let's create a new static helper function that returns just this value, and use it instead. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib: drop pointless LookupAddresstoRootTable() routineArd Biesheuvel2020-04-021-34/+15
| | | | | | | | | | | | | | LookupAddresstoRootTable() uses a loop to go over its MaxAddress argument, essentially to do a log2() and determine how many bits are needed to represent it. Since the argument is the result of a shift-left expression, there is some room for improvement here, and we can simply use the bit count directly to calculate the value of T0SZ. At the same time, we can omit calling GetRootTranslationTableInfo() to determine the number of root table entries, and add a new helper that applies the trivial calculation directly. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/CpuDxe: move PageAttributeToGcdAttribute() out of ArmMmuLibArd Biesheuvel2020-04-021-45/+0
| | | | | | | | | The routine PageAttributeToGcdAttribute() is exported by ArmMmuLib but only ever used in the implementation of CpuDxe. So let's move the function there and make it STATIC. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib AARCH64: preserve attributes when replacing a table entryArd Biesheuvel2020-03-261-4/+21
| | | | | | | | | | | | | | | | | | | | | | Currently, depending on the size of the region being (re)mapped, the page table manipulation code may replace a table entry with a block entry, even if the existing table entry uses different mapping attributes to describe different parts of the region it covers. This is undesirable, and instead, we should avoid doing so unless we are disregarding the original attributes anyway. And if we make such a replacement, we should free all the page tables that have become orphaned in the process. So let's implement this, by taking the table entry path through the code for block sized regions if a table entry already exists, and the clear mask is set (which means we are preserving attributes from the existing mapping). And when we do replace a table entry with a block entry, free all the pages that are no longer referenced. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com> Reviewed-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
* ArmPkg/ArmMmuLib AARCH64: use helpers to determine table entry typesArd Biesheuvel2020-03-261-5/+35
| | | | | | | | | | | | Given how the meaning of the attribute bits for page table entry types is slightly awkward, and changes between levels, add some helpers to abstract from this. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com> Reviewed-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
* ArmPkg/ArmMmuLib AARCH64: limit recursion when freeing page tablesArd Biesheuvel2020-03-261-6/+12
| | | | | | | | | | | | | | | | | | | | FreePageTablesRecursive () traverses the page table tree depth first to free all pages that it finds, without taking into account the level at which it is operating. Since TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3, we cannot distinguish table entries from block entries unless we take the level into account, and so we may be dereferencing garbage if we happen to try and free a hierarchy of page tables that has level 3 pages in it. Let's fix this by passing the level into FreePageTablesRecursive (), and limit the recursion to levels < 3. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com> Reviewed-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Ashish Singhal <ashishsingha@nvidia.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
* ArmPkg/ArmMmuLib AARCH64: cosmetic fixupsArd Biesheuvel2020-03-101-19/+37
| | | | | | | | | | | Some cosmetic fixups to the AArch64 MMU code: - reflow overly long lines unless it hurts legibility - add/remove whitespace according to the [de facto] coding style - use camel case for goto labels Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Message-Id: <20200307091008.14918-3-ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib AARCH64: drop pointless page table memory type checkArd Biesheuvel2020-03-101-15/+0
| | | | | | | | | | | This is the AARCH64 counterpart of commit 1f3b1eb3082206e4, to remove a pointless check against the memory type of the allocations that the page tables happened to land in. On ArmV8, we use writeback cacheable exclusively for all memory. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Message-Id: <20200307091008.14918-2-ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib AARCH64: invalidate page tables before populating themArd Biesheuvel2020-03-101-0/+14
| | | | | | | | | | | | As it turns out, ARMv8 also permits accesses made with the MMU and caches off to hit in the caches, so to ensure that any modifications we make before enabling the MMU are visible afterwards as well, we should invalidate page tables right after allocation like we do now on ARM, if the MMU is still disabled at that point. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com> Message-Id: <20200307083849.8940-3-ard.biesheuvel@linaro.org>
* ArmPkg/ArmMmuLib AARCH64: rewrite page table codeArd Biesheuvel2020-03-101-238/+143
| | | | | | | | | | | | | | Replace the slightly overcomplicated page table management code with a simplified, recursive implementation that should be far easier to reason about. Note that, as a side effect, this extends the per-entry cache invalidation that we do on page table entries to block and page entries, whereas the previous change inadvertently only affected the creation of table entries. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Message-Id: <20200307083849.8940-2-ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib ARM: drop memory type check for page tablesArd Biesheuvel2020-03-051-18/+2
| | | | | | | | | | We already expect normal memory to be mapped writeback cacheable if EDK2 itself is to make use of it, so doing an early sanity check on the memory type of the allocation that the page tables happened to land in isn't very useful. So let's drop it. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib ARM: simplify assignment of TTBR0 system registerArd Biesheuvel2020-03-051-1/+1
| | | | | | | | | | | | | | | The expression passed into ArmSetTTBR0 () in ArmConfigureMmu() is sub-optimal at several levels: - TranslationTable is already aligned, and if it wasn't, doing it here wouldn't help - TTBRAttributes is guaranteed not to have any bits set outside of the 0x7f mask, so the mask operation is pointless as well, - an additional (UINTN) cast for good measure is also not needed. So simplify the expression. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib AARCH64: cache-invalidate initial page table entriesArd Biesheuvel2020-03-051-9/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the AARCH64 version of ArmMmuLib, we are currently relying on set/way invalidation to ensure that the caches are in a consistent state with respect to main memory once we turn the MMU on. Even if set/way operations were the appropriate method to achieve this, doing an invalidate-all first and then populating the page table entries creates a window where page table entries could be loaded speculatively into the caches before we modify them, and shadow the new values that we write there. So let's get rid of the blanket clean/invalidate operations, and instead, update ArmUpdateTranslationTableEntry () to invalidate each page table entry *after* it is written if the MMU is still disabled at this point. On ARMv8, it is guaranteed that memory accesses done by the page table walker are cache coherent, and so we can ignore the case where the MMU is on. Since the MMU and D-cache are already off when we reach this point, we can drop the MMU and D-cache disables as well. Maintenance of the I-cache is unnecessary, since we are not modifying any code, and the installed mapping is guaranteed to be 1:1. This means we can also leave it enabled while the page table population code is running. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib ARM: cache-invalidate initial page table entriesArd Biesheuvel2020-03-051-14/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the ARM version of ArmMmuLib, we are currently relying on set/way invalidation to ensure that the caches are in a consistent state with respect to main memory once we turn the MMU on. Even if set/way operations were the appropriate method to achieve this, doing an invalidate-all first and then populating the page table entries creates a window where page table entries could be loaded speculatively into the caches before we modify them, and shadow the new values that we write there. So let's get rid of the blanket clean/invalidate operations, and instead, invalidate each page table right after allocating it, and each section entry after it is updated (to address all the little corner cases that the ARMv7 spec permits), and invalidate sets of level 2 entries in blocks, using the generic invalidation routine from CacheMaintenanceLib On ARMv7, cache maintenance may be required also when the MMU is enabled, in case the page table walker is not cache coherent. However, the code being updated here is guaranteed to run only when the MMU is still off, and so we can disregard the case when the MMU and caches are on. Since the MMU and D-cache are already off when we reach this point, we can drop the MMU and D-cache disables as well. Maintenance of the I-cache is unnecessary, since we are not modifying any code, and the installed mapping is guaranteed to be 1:1. This means we can also leave it enabled while the page table population code is running. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib ARM: use AllocateAlignedPages() for alignmentArd Biesheuvel2020-03-051-9/+10
| | | | | | | | | | | | Instead of overallocating memory and align the resulting base address manually, use the AllocateAlignedPages () helper, which achieves the same, and might even manage that without leaking a chunk of memory of the same size as the allocation itself. While at it, fix up a variable declaration in the same hunk, and drop a comment whose contents add nothing to the following line of code. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
* ArmPkg/ArmMmuLib ARM: split ArmMmuLibCore.c into core and update codeArd Biesheuvel2020-03-054-434/+469
| | | | | | | | | | | | | | | | | | | Unlike the AArch64 implementation of ArmMmuLib, which combines the initial page table population code with the code that runs at later stages to manage permission attributes in the page tables, ARM uses two completely separate sets of routines for this. Since ArmMmuLib is a static library, we can prevent duplication of this code between different users, which usually only need one or the other. (Note that LTO should also achieve the same.) This also makes it easier to reason about modifying the cache maintenance handling, and replace the set/way ops with by-VA ops, since the code that performs the set/way ops only executes when the MMU is still off. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg/ArmMmuLib ARM: remove dummy constructorArd Biesheuvel2020-03-052-9/+2
| | | | | | | | Make the CONSTRUCTOR define in the .INF AARCH64 only, so we can drop the empty stub that exists for ARM. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
* ArmPkg: strip trailing whitespaceLeif Lindholm2019-10-041-2/+2
| | | | | | | Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
* ArmPkg: Fix various typosAntoine Cœur2019-07-042-2/+2
| | | | | | | Fix various typos in ArmPkg. Signed-off-by: Coeur <coeur@gmx.fr> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg: Replace BSD License with BSD+Patent LicenseMichael D Kinney2019-04-098-54/+8
| | | | | | | | | | | | | | | | | | | | https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib AARCH64: get rid of needless TLB invalidationArd Biesheuvel2019-01-292-17/+17
| | | | | | | | | | | | | | | | | | | Currently, we always invalidate the TLBs entirely after making any modification to the page tables. Now that we have introduced strict memory permissions in quite a number of places, such modifications occur much more often, and it is better for performance to flush only those TLB entries that are actually affected by the changes. At the same time, relax some system wide data synchronization barriers to non-shared. When running in UEFI, we don't share virtual address translations with other masters, unless we are running under virt, but in that case, the host will upgrade them as appropriate (by setting an override at EL2) Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: trim high memory regions instead of rejecting themArd Biesheuvel2019-01-281-1/+2
| | | | | | | | | | | | | | | ArmSetMemoryAttributes() still chokes in some cases, i.e., when the length of the region exceeds 4 GB, the subtraction overflows, which results in the region being misidentified as being 32-bit addressable. Let's update the logic to trim the length to what we can address with 32 bits. This fixes the issue, and also deals with the issue where an entire region is disregarded if part of it exceeds beyond what we can map with 32 bits. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib AARCH64: fix out of bounds accessArd Biesheuvel2019-01-141-1/+1
| | | | | | | | | | Take care not to dereference BlockEntry if it may be pointing past the end of the page table we are manipulating. It is only a read, and thus harmless, but HeapGuard triggers on it so let's fix it. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: disregard high memory when setting permissionsArd Biesheuvel2019-01-141-0/+4
| | | | | | | | | | | Ignore calls to ArmSetMemoryAttributes () when the region described is outside of the 32-bit addressable range. This memory is not mapped in the first place, and the current code does not deal with the high bits correctly, resulting in hangs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: fix thinko in second level page table handlingArd Biesheuvel2019-01-131-2/+2
| | | | | | | | | | | | | | | | | PopulateLevel2PageTable () is invoked for [parts of] mappings that start or end on a non-1 MB aligned address (or both). The size of the mapping depends on both the start address modulo 1 MB and the length of the mapping, but the logic that calculates this size is flawed: subtracting 'start address modulo 1 MB' could result in a negative value for the remaining length, which is obviously wrong. So instead, take either RemainLength, or the rest of the 1 MB block, whichever is smaller. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Tested-by: Eugene Cohen <eugene@hp.com>
* ArmPkg/ArmMmuLib ARM: add missing support for non-shareable cached mappingsArd Biesheuvel2019-01-131-0/+13
| | | | | | | | | | | Commit 829633e3a82 ("ArmPkg/ArmMmuLib: Add new attribute WRITE_BACK_NONSHAREABLE") introduced support for non-shareable cached mappings to the AArch64 version of ArmMmuLib, but the ARM version was left behind, so fix that. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: take MAX_ALLOC_ADDRESS into accountArd Biesheuvel2018-12-201-1/+1
| | | | | | | | | | | | | When creating the page tables for the 1:1 mapping, ensure that we don't attempt to map more than what is architecturally permitted when running with 4 KB pages, which is 48 bits of VA. This will be reflected in the value of MAX_ALLOC_ADDRESS once we override it for AArch64, so use that macro instead of MAX_ADDRESS. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: handle unmapped sections when updating permissionsArd Biesheuvel2018-12-031-2/+6
| | | | | | | | | | | | | The ARM ArmMmuLib code currently does not take into account that setting permissions on a region should take into account that a region may not be mapped yet to begin with. So when updating a section descriptor whose old value is zero, pass in the address explicitly. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: take the CPU supported maximum PA space into accountArd Biesheuvel2018-11-293-8/+9
| | | | | | | | | | | | In preparation of dropping PcdPrePiCpuMemorySize entirely, base the maximum size of the identity map on the capabilities of the CPU. Since that may exceed what is architecturally permitted when using 4 KB pages, take MAX_ADDRESS into account as well. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: fix Mva to use idx instead of table baseChris Co2018-06-211-1/+1
| | | | | | | | | | | | | Mva address calculation should use the left-shifted current section index instead of the left-shifted table base address. Using the table base address here has the side-effect of potentially causing an access violation depending on the base address value. Cc: Leif Lindholm <leif.lindholm@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Christopher Co <christopher.co@microsoft.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
* ArmPkg/ArmMmuLib ARM: assume page tables are in writeback cacheable memoryArd Biesheuvel2018-06-211-11/+3
| | | | | | | | | | | | Given that these days, our ARM port only supports ARMv7 and later, we can assume that the page table walker's memory accesses are cache coherent, and so there is no need to perform cache maintenance. It does require the page tables themselves to reside in memory mapped as writeback cacheable so ASSERT() that this is the case. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: remove cache maintenance of block mapping contentsArd Biesheuvel2018-06-211-12/+0
| | | | | | | | | | | | | | | | | | | Peculiarly enough, the current page table manipulation code takes it upon itself to write back and invalidate the memory contents covered by page and section mappings when their memory attributes change. It is not generally the case that data must be written back when such a change occurs, even when switching from cacheable to non-cacheable attributes, and in some cases, it is actually causing problems. (The cache maintenance is also performed on the PCIe MMIO regions as they get mapped by the PCI bus driver, and under virtualization, each cache maintenance operation on an emulated MMIO region triggers a round trip to the host and back) So let's just drop this code. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: fix page size granularity in initial MMU settingMichael Zimmermann2017-12-201-17/+23
| | | | | | | | | | | | | | | | | From what I can see this bug dates back to the commit from 2011 where support for this was added: 2cf4b60895f8a The first problem is that PopulateLevel2PageTable overflows the translation table buffer because it doesn't verify that the size actually fits within one level 2 page table. The second problem is that the loop in FillTranslationTable doesn't care about the PhysicalBase or the RemainLength and always substracts one section size from RemainLength. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael Zimmermann <sigmaepsilon92@gmail.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
* ArmPkg/ArmMmuLib: Add new attribute WRITE_BACK_NONSHAREABLEPeicong Li2017-11-071-0/+4
| | | | | | | | | | | | | | | | | | | Flash region needs to be set as cacheable (write back) to increase performance, if PEI is still XIP on flash or DXE FV is decompressed from flash FV. However some ARM platforms do not support to set flash as inner shareable since flash is not normal DDR memory and it will not respond to cache snoop request, which will causes system hang after MMU is enabled. So we need a new ARM memory region attribute WRITE_BACK_NONSHAREABLE for flash region on these platforms specifically. This attribute will set the region as write back but not inner shared. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Peicong Li <lipeicong@huawei.com> Signed-off-by: Heyi Guo <heyi.guo@linaro.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib ARM: implement memory permission control routinesArd Biesheuvel2017-03-071-4/+6
| | | | | | | | | | | | | | | | | Now that we have the prerequisite functionality available in ArmMmuLib, wire it up into ArmSetMemoryRegionNoExec, ArmClearMemoryRegionNoExec, ArmSetMemoryRegionReadOnly and ArmClearMemoryRegionReadOnly. This is used by the non-executable stack feature that is configured by DxeIpl. NOTE: The current implementation will not combine RO and XP attributes, i.e., setting/clearing a region no-exec will unconditionally clear the read-only attribute, and vice versa. Currently, we only use ArmSetMemoryRegionNoExec(), so for now, we should be able to live with this. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: remove VirtualMask arg from ArmSetMemoryAttributesArd Biesheuvel2017-03-072-19/+5
| | | | | | | | | | | | | We no longer make use of the ArmMmuLib 'feature' to create aliased memory ranges with mismatched attributes, and in fact, it was only wired up in the ARM version to begin with. So remove the VirtualMask argument from ArmSetMemoryAttributes()'s prototype, and remove the dead code that referred to it. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg: move ARM version of SetMemoryAttributes to ArmMmuLibArd Biesheuvel2017-03-072-1/+398
| | | | | | | | | | | | | | | ... where it belongs, since AARCH64 already keeps it there, and non DXE users of ArmMmuLib (such as DxeIpl, for the non-executable stack) may need its functionality as well. While at it, rename SetMemoryAttributes to ArmSetMemoryAttributes, and make any functions that are not exported STATIC. Also, replace an explicit gBS->AllocatePages() call [which is DXE specific] with MemoryAllocationLib::AllocatePages(). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: use correct return type for exported functionsArd Biesheuvel2017-03-072-34/+35
| | | | | | | | | | | | | | The routines ArmConfigureMmu(), SetMemoryAttributes() [*] and the various set/clear read-only/no-exec routines are declared as returning EFI_STATUS in the respective header files, so align the definitions with that. * SetMemoryAttributes() is declared in the wrong header (and defined in ArmMmuLib for AARCH64 and in CpuDxe for ARM) Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: AARCH64: enable stack alignment checkingArd Biesheuvel2017-02-221-0/+1
| | | | | | | | | | Enable the hardware stack alignment check, as mandated by the UEFI spec. This ensures that the stack pointer is 16 byte aligned at each instance where it is used as the base address in a load/store operation. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: AARCH64: add support for modifying only permissionsArd Biesheuvel2017-02-211-28/+63
| | | | | | | | | | | | | | Since the new DXE page protection for PE/COFF images may invoke EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes() with only permission attributes set, add support for this in the AARCH64 MMU code. Move the EFI_MEMORY_CACHETYPE_MASK macro to a shared location between CpuDxe and ArmMmuLib so we don't have to introduce yet another definition. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/CpuDxe: Correct EFI_MEMORY_RO usageJiewen Yao2017-02-211-1/+2
| | | | | | | | | | | Current Arm CpuDxe driver uses EFI_MEMORY_WP for write protection, according to UEFI spec, we should use EFI_MEMORY_RO for write protection. The EFI_MEMORY_WP is the cache attribute instead of memory attribute. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
* ArmPkg/ArmMmuLib: Revert "use a pool allocation for the root table"Ard Biesheuvel2017-01-201-23/+6
| | | | | | | | | | | | | | | | | | | This reverts commit d32702d2c2aa23e828363a7f88829b78ce36c3af. Using a pool allocation for the root translation table seemed like a good idea at the time, but as it turns out, such allocations are handled in a way that makes them unsuitable for this purpose: they are backed by HOBs that don't remain in the same place during the various PI phase changes, which means the address programmed into the TTBR register is no longer valid, and may refer to memory that is reported as available to the OS. So switch back to using a page based allocation. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
* ArmPkg/ArmMmuLib: support page tables in cacheable memory onlyArd Biesheuvel2016-11-301-25/+24
| | | | | | | | | | | | | | | | | Translation table walks are always cache coherent on ARMv8-A, so cache maintenance on page tables is never needed. Since there is a risk of loss of coherency when using mismatched attributes, and given that memory is mapped cacheable except for extraordinary cases (such as non-coherent DMA), restrict the page table walker to performing cacheable accesses to the translation tables. For DEBUG builds, retain some of the logic so that we can double check that the memory holding the root translation table is indeed located in memory that is mapped cacheable. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>