> On 21 Nov 2017, at 17:49, Laszlo Ersek <ler...@redhat.com> wrote: > >> On 11/17/17 17:09, Ard Biesheuvel wrote: >> 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. > > OK, so whenever I try to look at this code, my brain crashes. This > occasion is no exception. All the more reason to clean it all up; thanks > for doing that. > > So, I guess we are talking about the following call stack. If you agree, > please add it to the commit message (IMO it's OK to exceed the preferred > 74 chars width for such sections): > > ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf [ArmVirtPkg/ArmVirtQemu.dsc] > InitializeMemory() > [ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.c] > ArmPlatformInitializeSystemMemory() > [ArmVirtPkg/Library/ArmVirtPlatformLib/Virt.c] > // > // set PcdSystemMemorySize from the DT > // > MemoryPeim() > [ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c] > InitMmu() > [ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c] > ArmPlatformGetVirtualMemoryMap() > [ArmVirtPkg/Library/ArmVirtPlatformLib/VirtMem.c] > // > // consume PcdSystemMemorySize > // > > Here we have two ArmVirtPlatformLib actions: > > - The "PCD consumption" half of that has been moved -- well, copied, for > now -- to QemuVirtMemInfoLib, in patch 12/15. > > - And we are now looking for a new home for the "PCD production" half. >
Yes >> 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() > > Hm, this claim could be true :) , but I'm not totally convinced by the > way you put it. > > First off, I notice that > "ArmVirtPkg/Library/ArmVirtPlatformLib/ArmVirtPlatformLib.inf" does not > spell out PcdLib as a dependency. This is quite bad, because it uses > PCDs. > > However, ultimately, "gEfiPeiPcdPpiGuid" does end up in the final DEPEX > of "MemoryInitPeim.inf", according to the ArmVirtQemu build report file. > This must be due to some of the library instances already pulling in > PeiPcdLib. > > Therefore, if we modify the constructor of QemuVirtMemInfoLib to parse > the DT and to set the PCD, *plus* we spell out PcdLib in the > QemuVirtMemInfoLib INF file, then the ultimate DEPEX for the > MemoryInitPeim module should remain the same. And, the PeiPcdLib > constructor should run before the QemuVirtMemInfoLib constructor > (parsing the DT and setting the PCD). > > What's wrong with this argument? > I guess you’re right. Direct dependencies between libraries with constructors are handled correctly by the tools, I simply managed to confuse myself due to the issues with transitive dependencies which you surely remember. >> 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. > > I understand what this does, but I find it very complex. > > Sometimes, whenever we want to make sure that a PCD is set dynamically > "no later than" it's consumed by a "common" module outside of > ArmVirtPkg, we create a dedicated library instance (with all the right > library dependencies spelled out in its INF file), set the PCD in its > constructor, and hook it into the consumer module via NULL class > resolution. > > In this case, we have a lib instance that is used through an actual lib > class already, so I would suggest to add a constructor function, and to > spell out the PcdLib dependency in the INF file. > > ... In fact, this is something that I missed in patch 12 -- > QemuVirtMemInfoLib already uses PCDs, but doesn't include "PcdLib" under > [LibraryClasses]. That is a bug inherited from ArmVirtPlatformLib (see > above), and should be fixed. And then we should only need the > constructor. > > What do you think? > I think you’re right. So how do you propose i go about creating two versions of QemuVirtMemInfoLib, only one of which has a constructor? Share the .c file between two infs in the same directory? > >> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> >> --- >> 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 <Library/ArmLib.h> >> + >> +#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 <PiPei.h> >> +#include <Library/ArmLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/PeiServicesLib.h> >> +#include <Ppi/ArmVirtMemInfo.h> >> + >> +/** >> + 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.<BR> >> + >> + 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 <PiPei.h> >> +#include <Library/ArmLib.h> >> +#include <Library/ArmVirtMemInfoLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/PcdLib.h> >> +#include <Library/PeiServicesLib.h> >> +#include <libfdt.h> >> +#include <Ppi/ArmVirtMemInfo.h> >> + >> +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.<BR> >> +# >> +# 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 >> > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel