From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c0c::242; helo=mail-wr0-x242.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr0-x242.google.com (mail-wr0-x242.google.com [IPv6:2a00:1450:400c:c0c::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0F2F52035BB1B for ; Fri, 17 Nov 2017 08:05:37 -0800 (PST) Received: by mail-wr0-x242.google.com with SMTP id y42so2547599wrd.3 for ; Fri, 17 Nov 2017 08:09:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=elXGuBIDcJQpuC57Kto6kn/sPbmenb3984UQ8RqD/bw=; b=BOlCG2vfwf5sl4MtPd+7r3nbKqxTL+kOLaDVQ+e32qDq5vLm9w+6eBX8KstezYtI+E 4KNQ22wIiQsyc2pQ1kM6/OhtESxEDe121Sdktrig5z2KqPstfmxDcakxzALdQxss8ajz SHM7amW9qcYHc98qCQsotGrzIA7sb3CMn1w14= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=elXGuBIDcJQpuC57Kto6kn/sPbmenb3984UQ8RqD/bw=; b=qgZue1D7pg3FmTl0lkITgXqhBHgCyKLMTlAThuhx+LYawR9SZo49pnr42Br4GRJN6a fRozqnyCcu6m8LQsjSiBapl3xwuRDB1Z79/jXtFYa4bb3cxAedW1U5MvxsAMiG9uOuTB OwygQw0qJ0nofWzoCnZ1XsJurdhUd/XoI1tpSTUz+2wt4lUO13QVRWP3hzfAMMYSyOlv /TFYhspzf5bhvHUp8VU3JOD+J2XqKVoY2tYL2/SJP1SlyjBJ44gvn9oIU/nK8tvGJ8yH zVlhIpZj2m3C4tsbPNZFloTb+GGk7rjXxNzigNevTRt7ttbyInp0Yz3gb1FP9MCZgplH hSrA== X-Gm-Message-State: AJaThX5Umb4VvtB5PSK68RnusHlXxv5prPPTvPdgrkP4Kd5fN0eGcndx KpQKgyZCr6DH7Hhq63WqV2IbLeELBxo= X-Google-Smtp-Source: AGs4zMZo/eXY+UY3nYl7nvOD3SE83w9AgTQjH15+P704xiVdUmG44y2RF00YeyyY+crblJTXeqVoJw== X-Received: by 10.223.199.205 with SMTP id y13mr5095023wrg.71.1510934986176; Fri, 17 Nov 2017 08:09:46 -0800 (PST) Received: from localhost.localdomain ([160.167.170.128]) by smtp.gmail.com with ESMTPSA id p42sm5575959wrb.28.2017.11.17.08.09.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Nov 2017 08:09:45 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, lersek@redhat.com Cc: leif.lindholm@linaro.org, Ard Biesheuvel Date: Fri, 17 Nov 2017 16:09:11 +0000 Message-Id: <20171117160913.17292-14-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171117160913.17292-1-ard.biesheuvel@linaro.org> References: <20171117160913.17292-1-ard.biesheuvel@linaro.org> Subject: [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Nov 2017 16:05:37 -0000 Equivalent to the PrePi based platforms, this patch implements the newly introduced ArmVirtMemInfo library class via a separate PEIM and PPI. The reason is that ArmVirtPlatformLib has populated the ArmPlatformLib API function ArmPlatformInitializeSystemMemory () to retrieve memory information from the DT, ensuring that it will be present when MemoryPeim() is executed. This is a bit of a hack, and someting we will need to get rid of if we want to reduce our dependency on ArmPlatformLib altogether. Putting this code in a ArmVirtMemInfo library constructor is problematic as well, given that the implementation uses other libraries, among which PcdLib, and so we need to find another way to run it before MemoryPeim() So instead, create a separate PEIM that encapsulates the ArmVirtMemInfo code and exposes it via a PPI. Another ArmVirtMemInfo library class implementation is also provided that depexes on the PPI, which ensures that the code is called in the correct order. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtPkg.dec | 3 + ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h | 48 ++++++++ ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c | 46 ++++++++ ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf | 42 +++++++ ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c | 121 ++++++++++++++++++++ ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf | 60 ++++++++++ 6 files changed, 320 insertions(+) diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec index 8f656fd2739d..260849dc845c 100644 --- a/ArmVirtPkg/ArmVirtPkg.dec +++ b/ArmVirtPkg/ArmVirtPkg.dec @@ -39,6 +39,9 @@ [Guids.common] gArmVirtVariableGuid = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } } +[Ppis] + gArmVirtMemInfoPpiGuid = { 0x3b060b72, 0x8696, 0x4393, { 0xa8, 0x93, 0x34, 0x25, 0x1e, 0x3f, 0x8a, 0x6b } } + [Protocols] gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } } diff --git a/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h b/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h new file mode 100644 index 000000000000..46885d02c384 --- /dev/null +++ b/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h @@ -0,0 +1,48 @@ +/** @file + + Copyright (c) 2011-2013, ARM Limited. All rights reserved. + Copyright (c) 2017, 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. + +**/ + +#ifndef _ARM_VIRT_MEMINFO_PPI_H_ +#define _ARM_VIRT_MEMINFO_PPI_H_ + +#include + +#define ARM_VIRT_MEMINFO_PPI_GUID \ + { 0x3b060b72, 0x8696, 0x4393, { 0xa8, 0x93, 0x34, 0x25, 0x1e, 0x3f, 0x8a, 0x6b } } + +/** + Return the Virtual Memory Map of your platform + + This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU + on your platform. + + @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR + describing a Physical-to-Virtual Memory + mapping. This array must be ended by a + zero-filled entry + +**/ +typedef +VOID +(EFIAPI * GET_MEMORY_MAP) ( + OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap + ); + +typedef struct { + GET_MEMORY_MAP GetMemoryMap; +} ARM_VIRT_MEMINFO_PPI; + +extern EFI_GUID gArmVirtMemInfoPpiGuid; + +#endif diff --git a/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c new file mode 100644 index 000000000000..ad27b246f980 --- /dev/null +++ b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c @@ -0,0 +1,46 @@ +/** @file + + Copyright (c) 2014-2017, Linaro 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 +#include +#include +#include +#include + +/** + Return the Virtual Memory Map of your platform + + This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU + on your platform. + + @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR + describing a Physical-to-Virtual Memory + mapping. This array must be ended by a + zero-filled entry + +**/ +VOID +ArmVirtGetMemoryMap ( + OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap + ) +{ + ARM_VIRT_MEMINFO_PPI *MemInfo; + EFI_STATUS Status; + + Status = PeiServicesLocatePpi (&gArmVirtMemInfoPpiGuid, 0, NULL, + (VOID **)&MemInfo); + ASSERT_EFI_ERROR (Status); + + MemInfo->GetMemoryMap (VirtualMemoryMap); +} diff --git a/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf new file mode 100644 index 000000000000..b661c2f43faf --- /dev/null +++ b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf @@ -0,0 +1,42 @@ +#/* @file +# +# Copyright (c) 2011-2015, ARM Limited. All rights reserved. +# Copyright (c) 2014-2017, Linaro 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. +# +#*/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = PeiVirtMemInfoLib + FILE_GUID = 1d7bae0f-9674-4a4b-8d85-9804968cb12b + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmVirtMemInfoLib|PEIM + +[Sources] + PeiVirtMemInfoLib.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmVirtPkg/ArmVirtPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmLib + DebugLib + PeiServicesLib + +[Ppis] + gArmVirtMemInfoPpiGuid + +[Depex] + gArmVirtMemInfoPpiGuid diff --git a/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c new file mode 100644 index 000000000000..90ee552bdba0 --- /dev/null +++ b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c @@ -0,0 +1,121 @@ +/**@file + + Copyright (c) 2017, 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. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC ARM_VIRT_MEMINFO_PPI mArmVirtMeminfoPpi = { + ArmVirtGetMemoryMap +}; + +STATIC CONST EFI_PEI_PPI_DESCRIPTOR mArmVirtMeminfoPpiTable = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gArmVirtMemInfoPpiGuid, + &mArmVirtMeminfoPpi +}; + +EFI_STATUS +EFIAPI +QemuVirtMemInfoPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + VOID *DeviceTreeBase; + INT32 Node, Prev; + UINT64 NewBase, CurBase; + UINT64 NewSize, CurSize; + CONST CHAR8 *Type; + INT32 Len; + CONST UINT64 *RegProp; + RETURN_STATUS PcdStatus; + + NewBase = 0; + NewSize = 0; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // + // Make sure we have a valid device tree blob + // + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + // + // Look for the lowest memory node + // + for (Prev = 0;; Prev = Node) { + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); + if (Node < 0) { + break; + } + + // + // Check for memory node + // + 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 != 0 && Len == (2 * sizeof (UINT64))) { + + CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); + CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1)); + + DEBUG ((DEBUG_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", + __FUNCTION__, CurBase, CurBase + CurSize - 1)); + + if (NewBase > CurBase || NewBase == 0) { + NewBase = CurBase; + NewSize = CurSize; + } + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n", + __FUNCTION__)); + } + } + } + + // + // Make sure the start of DRAM matches our expectation + // + ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); + PcdStatus = PcdSet64S (PcdSystemMemorySize, NewSize); + ASSERT_RETURN_ERROR (PcdStatus); + + // + // We need to make sure that the machine we are running on has at least + // 128 MB of memory configured, and is currently executing this binary from + // NOR flash. This prevents a device tree image in DRAM from getting + // clobbered when our caller installs permanent PEI RAM, before we have a + // chance of marking its location as reserved or copy it to a freshly + // allocated block in the permanent PEI RAM in the platform PEIM. + // + ASSERT (NewSize >= SIZE_128MB); + ASSERT ( + (((UINT64)PcdGet64 (PcdFdBaseAddress) + + (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) || + ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize))); + + return PeiServicesInstallPpi (&mArmVirtMeminfoPpiTable); +} diff --git a/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf new file mode 100644 index 000000000000..ac91e065be57 --- /dev/null +++ b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf @@ -0,0 +1,60 @@ +## @file +# +# Copyright (c) 2017, 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. +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = QemuVirtMemInfoPeim + FILE_GUID = 91da13af-d0ff-4810-b9b9-b095a9ee6b09 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = QemuVirtMemInfoPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = ARM AARCH64 +# + +[Sources] + QemuVirtMemInfoPeim.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmVirtPkg/ArmVirtPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmLib + ArmVirtMemInfoLib + DebugLib + FdtLib + PeimEntryPoint + PeiServicesLib + +[Pcd] + gArmTokenSpaceGuid.PcdSystemMemorySize + +[Ppis] + gArmVirtMemInfoPpiGuid + +[FixedPcd] + gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize + +[Depex] + TRUE -- 2.11.0