X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmVirtPkg%2FHighMemDxe%2FHighMemDxe.c;h=c383757364bb35d14045e129dccbe8e639c98c39;hb=9792fb0e65ff31e4a52844aa854455f778752869;hp=4963164fbd8ab213209a6d60e9140e402fc40504;hpb=68312710615c3499341f3e300b0a3921dea5a39b;p=mirror_edk2.git diff --git a/ArmVirtPkg/HighMemDxe/HighMemDxe.c b/ArmVirtPkg/HighMemDxe/HighMemDxe.c index 4963164fbd..c383757364 100644 --- a/ArmVirtPkg/HighMemDxe/HighMemDxe.c +++ b/ArmVirtPkg/HighMemDxe/HighMemDxe.c @@ -1,26 +1,20 @@ /** @file * High memory node enumeration DXE driver for ARM Virtual Machines * -* Copyright (c) 2015, Linaro Ltd. All rights reserved. +* Copyright (c) 2015-2016, Linaro Ltd. 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. +* SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #include -#include #include -#include -#include -#include #include +#include +#include + +#include +#include EFI_STATUS EFIAPI @@ -29,77 +23,102 @@ InitializeHighMemDxe ( IN EFI_SYSTEM_TABLE *SystemTable ) { - VOID *Hob; - VOID *DeviceTreeBase; - INT32 Node, Prev; - EFI_STATUS Status; - CONST CHAR8 *Type; - INT32 Len; - CONST VOID *RegProp; - UINT64 CurBase; - UINT64 CurSize; + FDT_CLIENT_PROTOCOL *FdtClient; + EFI_CPU_ARCH_PROTOCOL *Cpu; + EFI_STATUS Status, FindNodeStatus; + INT32 Node; + CONST UINT32 *Reg; + UINT32 RegSize; + UINTN AddressCells, SizeCells; + UINT64 CurBase; + UINT64 CurSize; + UINT64 Attributes; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; - Hob = GetFirstGuidHob(&gFdtHobGuid); - if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) { - return EFI_NOT_FOUND; - } - DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob); - - if (fdt_check_header (DeviceTreeBase) != 0) { - DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__, - DeviceTreeBase)); - return EFI_NOT_FOUND; - } + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, + (VOID **)&FdtClient); + ASSERT_EFI_ERROR (Status); - DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase)); + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, + (VOID **)&Cpu); + ASSERT_EFI_ERROR (Status); // - // Check for memory node and add the memory spaces expect the lowest one + // Check for memory node and add the memory spaces except the lowest one // - for (Prev = 0;; Prev = Node) { - Node = fdt_next_node (DeviceTreeBase, Prev, NULL); - if (Node < 0) { - break; - } + for (FindNodeStatus = FdtClient->FindMemoryNodeReg (FdtClient, &Node, + (CONST VOID **) &Reg, &AddressCells, + &SizeCells, &RegSize); + !EFI_ERROR (FindNodeStatus); + FindNodeStatus = FdtClient->FindNextMemoryNodeReg (FdtClient, Node, + &Node, (CONST VOID **) &Reg, &AddressCells, + &SizeCells, &RegSize)) { + ASSERT (AddressCells <= 2); + ASSERT (SizeCells <= 2); - Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); - if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { - // - // Get the 'reg' property of this node. For now, we will assume - // two 8 byte quantities for base and size, respectively. - // - RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len); - if (RegProp != NULL && Len == (2 * sizeof (UINT64))) { + while (RegSize > 0) { + CurBase = SwapBytes32 (*Reg++); + if (AddressCells > 1) { + CurBase = (CurBase << 32) | SwapBytes32 (*Reg++); + } + CurSize = SwapBytes32 (*Reg++); + if (SizeCells > 1) { + CurSize = (CurSize << 32) | SwapBytes32 (*Reg++); + } + RegSize -= (AddressCells + SizeCells) * sizeof (UINT32); - CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]); - CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]); + Status = gDS->GetMemorySpaceDescriptor (CurBase, &GcdDescriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: Region 0x%lx - 0x%lx not found in the GCD memory space map\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1)); + continue; + } + if (GcdDescriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) { + Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, CurBase, + CurSize, EFI_MEMORY_WB); - if (FixedPcdGet64 (PcdSystemMemoryBase) != CurBase) { - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeSystemMemory, - CurBase, CurSize, - EFI_MEMORY_WB | EFI_MEMORY_WC | - EFI_MEMORY_WT | EFI_MEMORY_UC); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, + "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1, Status)); + continue; + } - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, - "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n", - __FUNCTION__, CurBase, CurBase + CurSize - 1, Status)); - continue; - } + Status = gDS->SetMemorySpaceAttributes (CurBase, CurSize, + EFI_MEMORY_WB); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: gDS->SetMemorySpaceAttributes() failed on region 0x%lx - 0x%lx (%r)\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1, Status)); + } + + // + // Due to the ambiguous nature of the RO/XP GCD memory space attributes, + // it is impossible to add a memory space with the XP attribute in a way + // that does not result in the XP attribute being set on *all* UEFI + // memory map entries that are carved from it, including code regions + // that require executable permissions. + // + // So instead, we never set the RO/XP attributes in the GCD memory space + // capabilities or attribute fields, and apply any protections directly + // on the page table mappings by going through the cpu arch protocol. + // + Attributes = EFI_MEMORY_WB; + if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & + (1U << (UINT32)EfiConventionalMemory)) != 0) { + Attributes |= EFI_MEMORY_XP; + } - Status = gDS->SetMemorySpaceAttributes ( - CurBase, CurSize, - EFI_MEMORY_WB); + Status = Cpu->SetMemoryAttributes (Cpu, CurBase, CurSize, Attributes); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, - "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n", - __FUNCTION__, CurBase, CurBase + CurSize - 1, Status)); - } else { - DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n", - __FUNCTION__, CurBase, CurBase + CurSize - 1)); - } + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, + "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1, Status)); + } else { + DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1)); } } }