Message ID | 1409235244-25783-12-git-send-email-ard.biesheuvel@linaro.org |
---|---|
State | New |
Headers | show |
On 08/28/14 16:13, Ard Biesheuvel wrote: > This is an implementation of ArmPlatformLib that discovers the size of system > DRAM from a device tree blob located at the address passed in > gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the value in > gArmTokenSpaceGuid.PcdSystemMemoryBase. > > As the device tree blob is passed in system DRAM, this library can only be used > if sufficient DRAM is available (>= 128 MB) and if not using shadowed NOR. The > reason for this is that it makes it easier to guarantee that such a device tree > blob at base of DRAM will not be clobbered before we get a chance to preserve it. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > --- > .../AARCH64/VirtHelper.S | 86 ++++++++++++ > .../ArmVirtualizationPlatformLib/ARM/VirtHelper.S | 81 +++++++++++ > .../ArmVirtualizationPlatformLib.inf | 60 ++++++++ > .../Library/ArmVirtualizationPlatformLib/Virt.c | 151 +++++++++++++++++++++ > .../Library/ArmVirtualizationPlatformLib/VirtMem.c | 107 +++++++++++++++ > 5 files changed, 485 insertions(+) > create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S > create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S > create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf > create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c > create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c > > diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S > new file mode 100644 > index 000000000000..fd0bfe4afa2d > --- /dev/null > +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S > @@ -0,0 +1,86 @@ > +# > +# Copyright (c) 2011-2013, ARM 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 <AsmMacroIoLibV8.h> > +#include <Base.h> > +#include <Library/ArmLib.h> > +#include <Library/PcdLib.h> > +#include <AutoGen.h> > + > +.text > +.align 2 > + > +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) > +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) > +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) > +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) > +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) > +GCC_ASM_EXPORT(ArmGetPhysAddrTop) > + > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) > + > +ASM_PFX(ArmPlatformPeiBootAction): > + ret > + > +//UINTN > +//ArmPlatformGetPrimaryCoreMpId ( > +// VOID > +// ); > +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): > + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0) > + ldrh w0, [x0] > + ret > + > +# IN None > +# OUT x0 = number of cores present in the system > +ASM_PFX(ArmGetCpuCountPerCluster): > + mov x0, #1 > + ret > + > +//UINTN > +//ArmPlatformIsPrimaryCore ( > +// IN UINTN MpId > +// ); > +ASM_PFX(ArmPlatformIsPrimaryCore): > + mov x0, #1 > + ret > + > +//UINTN > +//ArmPlatformGetCorePosition ( > +// IN UINTN MpId > +// ); > +// With this function: CorePos = (ClusterId * 4) + CoreId > +ASM_PFX(ArmPlatformGetCorePosition): > + and x1, x0, #ARM_CORE_MASK > + and x0, x0, #ARM_CLUSTER_MASK > + add x0, x1, x0, LSR #6 > + ret > + > +//EFI_PHYSICAL_ADDRESS > +//GetPhysAddrTop ( > +// VOID > +// ); > +ASM_PFX(ArmGetPhysAddrTop): > + mrs x0, id_aa64mmfr0_el1 > + adr x1, .LPARanges > + and x0, x0, #7 > + ldrb w1, [x1, x0] > + mov x0, #1 > + lsl x0, x0, x1 > + ret > +.LPARanges: > + .byte 32, 36, 40, 42, 44, 48, -1, -1 > + > +ASM_FUNCTION_REMOVE_IF_UNREFERENCED > diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S > new file mode 100644 > index 000000000000..dc79b982b598 > --- /dev/null > +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S > @@ -0,0 +1,81 @@ > +# > +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +# Copyright (c) 2014, 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 <AsmMacroIoLib.h> > +#include <Base.h> > +#include <Library/ArmLib.h> > +#include <Library/PcdLib.h> > +#include <AutoGen.h> > + > +.text > +.align 2 > + > +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) > +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) > +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) > +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) > +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) > +GCC_ASM_EXPORT(ArmGetPhysAddrTop) > + > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) > + > +ASM_PFX(ArmPlatformPeiBootAction): > + bx lr > + > +//UINTN > +//ArmPlatformGetPrimaryCoreMpId ( > +// VOID > +// ); > +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): > + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0) > + ldr r0, [r0] > + bx lr > + > +# IN None > +# OUT r0 = number of cores present in the system > +ASM_PFX(ArmGetCpuCountPerCluster): > + mov r0, #1 > + bx lr > + > +//UINTN > +//ArmPlatformIsPrimaryCore ( > +// IN UINTN MpId > +// ); > +ASM_PFX(ArmPlatformIsPrimaryCore): > + mov r0, #1 > + bx lr > + > +//UINTN > +//ArmPlatformGetCorePosition ( > +// IN UINTN MpId > +// ); > +// With this function: CorePos = (ClusterId * 4) + CoreId > +ASM_PFX(ArmPlatformGetCorePosition): > + and r1, r0, #ARM_CORE_MASK > + and r0, r0, #ARM_CLUSTER_MASK > + add r0, r1, r0, LSR #6 > + bx lr > + > +//EFI_PHYSICAL_ADDRESS > +//GetPhysAddrTop ( > +// VOID > +// ); > +ASM_PFX(ArmGetPhysAddrTop): > + mov r0, #0x00000000 > + mov r1, #0x10000 > + bx lr > + > +ASM_FUNCTION_REMOVE_IF_UNREFERENCED > diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf > new file mode 100644 > index 000000000000..e7d6ec536dcd > --- /dev/null > +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf > @@ -0,0 +1,60 @@ > +#/* @file > +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +# Copyright (c) 2014, 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 = 0x00010005 > + BASE_NAME = ArmVirtualizationPlatformLib > + FILE_GUID = 00214cc1-06d1-45fe-9700-dca5726ad7bf > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = ArmPlatformLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + > +[LibraryClasses] > + IoLib > + ArmLib > + PrintLib > + FdtLib > + > +[Sources.common] > + Virt.c > + VirtMem.c > + > +[Sources.AARCH64] > + AARCH64/VirtHelper.S | GCC > + > +[Sources.ARM] > + ARM/VirtHelper.S | GCC > + > +[FeaturePcd] > + gEmbeddedTokenSpaceGuid.PcdCacheEnable > + gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec > + > +[Pcd] > + gArmTokenSpaceGuid.PcdSystemMemorySize > + gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress > + > +[FixedPcd] > + gArmPlatformTokenSpaceGuid.PcdCoreCount > + gArmTokenSpaceGuid.PcdSystemMemoryBase > + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask > + gArmTokenSpaceGuid.PcdArmPrimaryCore > + gArmTokenSpaceGuid.PcdFdBaseAddress > + gArmTokenSpaceGuid.PcdFdSize > diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c > new file mode 100644 > index 000000000000..a02712274dd3 > --- /dev/null > +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c > @@ -0,0 +1,151 @@ > +/** @file > +* > +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +* Copyright (c) 2014, 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 <Library/IoLib.h> > +#include <Library/ArmPlatformLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PcdLib.h> > +#include <ArmPlatform.h> > +#include <libfdt.h> > + > +/** > + Return the current Boot Mode > + > + This function returns the boot reason on the platform > + > + @return Return the current Boot Mode of the platform > + > +**/ > +EFI_BOOT_MODE > +ArmPlatformGetBootMode ( > + VOID > + ) > +{ > + return BOOT_WITH_FULL_CONFIGURATION; > +} > + > +/** > + Initialize controllers that must setup in the normal world > + > + This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim > + in the PEI phase. > + > +**/ > +RETURN_STATUS > +ArmPlatformInitialize ( > + IN UINTN MpId > + ) > +{ > + // > + // We are relying on ArmPlatformInitializeSystemMemory () being called from > + // InitializeMemory (), which only occurs if the following feature is disabled > + // > + ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)); > + return RETURN_SUCCESS; > +} > + > +/** > + Initialize the system (or sometimes called permanent) memory > + > + This memory is generally represented by the DRAM. > + > +**/ > +VOID > +ArmPlatformInitializeSystemMemory ( > + VOID > + ) > +{ > + VOID *DeviceTreeBase; > + INT32 Node, Prev; > + UINT64 NewBase; > + UINT64 NewSize; > + > + NewBase = 0; > + NewSize = 0; > + > + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); > + ASSERT (DeviceTreeBase != NULL); > + > + // > + // Make sure we have a valid device tree blob > + // > + ASSERT (fdt_check_header (DeviceTreeBase) == 0); > + > + // > + // Look for a memory node > + // > + for (Prev = 0;; Prev = Node) { > + CONST CHAR8 *Type; > + INT32 Len; > + > + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); > + if (Node < 0) { > + break; > + } > + > + Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); > + if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { > + CONST UINT64 *RegProp; > + > + // > + // 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))) { > + > + NewBase = fdt64_to_cpu (RegProp[0]); > + NewSize = fdt64_to_cpu (RegProp[1]); > + > + // > + // Make sure the start of DRAM matches our expectation > + // > + ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); > + PcdSet64 (PcdSystemMemorySize, NewSize); > + > + DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", > + __FUNCTION__, NewBase, NewBase + NewSize - 1)); > + } else { > + DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n", > + __FUNCTION__)); > + } > + break; > + } > + } > + // > + // 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)PcdGet32 (PcdFdBaseAddress) + > + (UINT64)PcdGet32 (PcdFdSize) <= NewBase || > + (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize); > +} > + > +VOID > +ArmPlatformGetPlatformPpiList ( > + OUT UINTN *PpiListSize, > + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList > + ) > +{ > + *PpiListSize = 0; > + *PpiList = NULL; > +} > diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c > new file mode 100644 > index 000000000000..153c1d20e908 > --- /dev/null > +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c > @@ -0,0 +1,107 @@ > +/** @file > +* > +* Copyright (c) 2014, 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 <Library/ArmPlatformLib.h> > +#include <Library/DebugLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/PcdLib.h> > +#include <Library/IoLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/ArmPlatformGlobalVariableLib.h> > +#include <ArmPlatform.h> > + > +// Number of Virtual Memory Map Descriptors > +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 > + > +// DDR attributes > +#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK > +#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED > + > +EFI_PHYSICAL_ADDRESS > +ArmGetPhysAddrTop ( > + VOID > + ); > + > +/** > + 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 > +ArmPlatformGetVirtualMemoryMap ( > + IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap > + ) > +{ > + ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; > + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; > + > + ASSERT (VirtualMemoryMap != NULL); > + > + VirtualMemoryTable = AllocatePages ( > + EFI_SIZE_TO_PAGES ( > + sizeof (ARM_MEMORY_REGION_DESCRIPTOR) > + * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS > + ) > + ); > + > + if (VirtualMemoryTable == NULL) { > + DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__)); > + return; > + } > + > + if (FeaturePcdGet (PcdCacheEnable) == TRUE) { > + CacheAttributes = DDR_ATTRIBUTES_CACHED; > + } else { > + CacheAttributes = DDR_ATTRIBUTES_UNCACHED; > + } > + > + // System DRAM > + VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); > + VirtualMemoryTable[0].VirtualBase = VirtualMemoryTable[0].PhysicalBase; > + VirtualMemoryTable[0].Length = PcdGet64 (PcdSystemMemorySize); > + VirtualMemoryTable[0].Attributes = CacheAttributes; > + > + DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n" > + "\tPhysicalBase: 0x%lX\n" > + "\tVirtualBase: 0x%lX\n" > + "\tLength: 0x%lX\n", > + __FUNCTION__, > + VirtualMemoryTable[0].PhysicalBase, > + VirtualMemoryTable[0].VirtualBase, > + VirtualMemoryTable[0].Length)); > + > + // Peripheral space before DRAM > + VirtualMemoryTable[1].PhysicalBase = 0x0; > + VirtualMemoryTable[1].VirtualBase = 0x0; > + VirtualMemoryTable[1].Length = VirtualMemoryTable[0].PhysicalBase; > + VirtualMemoryTable[1].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > + > + // Peripheral space after DRAM > + VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length + VirtualMemoryTable[1].Length; > + VirtualMemoryTable[2].VirtualBase = VirtualMemoryTable[2].PhysicalBase; > + VirtualMemoryTable[2].Length = ArmGetPhysAddrTop () - VirtualMemoryTable[2].PhysicalBase; > + VirtualMemoryTable[2].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > + > + // End of Table > + ZeroMem (&VirtualMemoryTable[3], sizeof (ARM_MEMORY_REGION_DESCRIPTOR)); > + > + *VirtualMemoryMap = VirtualMemoryTable; > +} > Great! I'd like to give my R-b, but I can only manage an A-b, due to the ARM assembly, which is Greek to me, sorry. Hence only: Acked-by: Laszlo Ersek <lersek@redhat.com> Thank you! Laszlo ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/
Some trailing space issues: - ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Vir tMem.c - ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Vir t.c And line endings: - ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM /VirtHelper.S > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] > Sent: 28 August 2014 15:14 > To: lersek@redhat.com; Olivier Martin; edk2- > devel@lists.sourceforge.net; peter.maydell@linaro.org; > christoffer.dall@linaro.org; drjones@redhat.com; > ilias.biris@linaro.org; leif.lindholm@linaro.org > Cc: Ard Biesheuvel; Michael Casadevall > Subject: [PATCH v4 11/16] ArmVirtualizationPkg: add > ArmVirtualizationPlatformLib library > > This is an implementation of ArmPlatformLib that discovers the size of > system > DRAM from a device tree blob located at the address passed in > gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the > value in > gArmTokenSpaceGuid.PcdSystemMemoryBase. > > As the device tree blob is passed in system DRAM, this library can only > be used > if sufficient DRAM is available (>= 128 MB) and if not using shadowed > NOR. The > reason for this is that it makes it easier to guarantee that such a > device tree > blob at base of DRAM will not be clobbered before we get a chance to > preserve it. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > --- > .../AARCH64/VirtHelper.S | 86 ++++++++++++ > .../ArmVirtualizationPlatformLib/ARM/VirtHelper.S | 81 +++++++++++ > .../ArmVirtualizationPlatformLib.inf | 60 ++++++++ > .../Library/ArmVirtualizationPlatformLib/Virt.c | 151 > +++++++++++++++++++++ > .../Library/ArmVirtualizationPlatformLib/VirtMem.c | 107 > +++++++++++++++ > 5 files changed, 485 insertions(+) > create mode 100644 > ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi > b/AARCH64/VirtHelper.S > create mode 100644 > ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi > b/ARM/VirtHelper.S > create mode 100644 > ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi > b/ArmVirtualizationPlatformLib.inf > create mode 100644 > ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi > b/Virt.c > create mode 100644 > ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi > b/VirtMem.c > > diff --git > a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/AARCH64/VirtHelper.S > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/AARCH64/VirtHelper.S > new file mode 100644 > index 000000000000..fd0bfe4afa2d > --- /dev/null > +++ > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/AARCH64/VirtHelper.S > @@ -0,0 +1,86 @@ > +# > +# Copyright (c) 2011-2013, ARM 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 <AsmMacroIoLibV8.h> > +#include <Base.h> > +#include <Library/ArmLib.h> > +#include <Library/PcdLib.h> > +#include <AutoGen.h> > + > +.text > +.align 2 > + > +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) > +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) > +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) > +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) > +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) > +GCC_ASM_EXPORT(ArmGetPhysAddrTop) > + > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) > + > +ASM_PFX(ArmPlatformPeiBootAction): > + ret > + > +//UINTN > +//ArmPlatformGetPrimaryCoreMpId ( > +// VOID > +// ); > +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): > + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0) > + ldrh w0, [x0] > + ret > + > +# IN None > +# OUT x0 = number of cores present in the system > +ASM_PFX(ArmGetCpuCountPerCluster): > + mov x0, #1 > + ret This function is not used. > + > +//UINTN > +//ArmPlatformIsPrimaryCore ( > +// IN UINTN MpId > +// ); > +ASM_PFX(ArmPlatformIsPrimaryCore): > + mov x0, #1 > + ret > + > +//UINTN > +//ArmPlatformGetCorePosition ( > +// IN UINTN MpId > +// ); > +// With this function: CorePos = (ClusterId * 4) + CoreId > +ASM_PFX(ArmPlatformGetCorePosition): > + and x1, x0, #ARM_CORE_MASK > + and x0, x0, #ARM_CLUSTER_MASK > + add x0, x1, x0, LSR #6 > + ret > + > +//EFI_PHYSICAL_ADDRESS > +//GetPhysAddrTop ( > +// VOID > +// ); > +ASM_PFX(ArmGetPhysAddrTop): > + mrs x0, id_aa64mmfr0_el1 > + adr x1, .LPARanges > + and x0, x0, #7 > + ldrb w1, [x1, x0] > + mov x0, #1 > + lsl x0, x0, x1 > + ret > +.LPARanges: > + .byte 32, 36, 40, 42, 44, 48, -1, -1 Is this list of bytes a secret code? Would you mind to add a comment above the list of memory address space size? > + > +ASM_FUNCTION_REMOVE_IF_UNREFERENCED > diff --git > a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ARM/VirtHelper.S > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ARM/VirtHelper.S > new file mode 100644 > index 000000000000..dc79b982b598 > --- /dev/null > +++ > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ARM/VirtHelper.S > @@ -0,0 +1,81 @@ > +# > +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +# Copyright (c) 2014, 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 <AsmMacroIoLib.h> > +#include <Base.h> > +#include <Library/ArmLib.h> > +#include <Library/PcdLib.h> > +#include <AutoGen.h> > + > +.text > +.align 2 > + > +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) > +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) > +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) > +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) > +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) > +GCC_ASM_EXPORT(ArmGetPhysAddrTop) > + > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) > +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) > + > +ASM_PFX(ArmPlatformPeiBootAction): > + bx lr > + > +//UINTN > +//ArmPlatformGetPrimaryCoreMpId ( > +// VOID > +// ); > +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): > + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0) > + ldr r0, [r0] > + bx lr > + > +# IN None > +# OUT r0 = number of cores present in the system > +ASM_PFX(ArmGetCpuCountPerCluster): > + mov r0, #1 > + bx lr This function is not used. > + > +//UINTN > +//ArmPlatformIsPrimaryCore ( > +// IN UINTN MpId > +// ); > +ASM_PFX(ArmPlatformIsPrimaryCore): > + mov r0, #1 > + bx lr > + > +//UINTN > +//ArmPlatformGetCorePosition ( > +// IN UINTN MpId > +// ); > +// With this function: CorePos = (ClusterId * 4) + CoreId > +ASM_PFX(ArmPlatformGetCorePosition): > + and r1, r0, #ARM_CORE_MASK > + and r0, r0, #ARM_CLUSTER_MASK > + add r0, r1, r0, LSR #6 > + bx lr > + > +//EFI_PHYSICAL_ADDRESS > +//GetPhysAddrTop ( > +// VOID > +// ); > +ASM_PFX(ArmGetPhysAddrTop): > + mov r0, #0x00000000 > + mov r1, #0x10000 > + bx lr > + > +ASM_FUNCTION_REMOVE_IF_UNREFERENCED > diff --git > a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ArmVirtualizationPlatformLib.inf > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ArmVirtualizationPlatformLib.inf > new file mode 100644 > index 000000000000..e7d6ec536dcd > --- /dev/null > +++ > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/ArmVirtualizationPlatformLib.inf > @@ -0,0 +1,60 @@ > +#/* @file > +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +# Copyright (c) 2014, 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 = 0x00010005 > + BASE_NAME = ArmVirtualizationPlatformLib > + FILE_GUID = 00214cc1-06d1-45fe-9700- > dca5726ad7bf > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = ArmPlatformLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + > +[LibraryClasses] > + IoLib > + ArmLib > + PrintLib > + FdtLib > + > +[Sources.common] > + Virt.c > + VirtMem.c > + > +[Sources.AARCH64] > + AARCH64/VirtHelper.S | GCC > + > +[Sources.ARM] > + ARM/VirtHelper.S | GCC > + > +[FeaturePcd] > + gEmbeddedTokenSpaceGuid.PcdCacheEnable > + gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec > + > +[Pcd] > + gArmTokenSpaceGuid.PcdSystemMemorySize > + gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress > + > +[FixedPcd] > + gArmPlatformTokenSpaceGuid.PcdCoreCount > + gArmTokenSpaceGuid.PcdSystemMemoryBase > + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask > + gArmTokenSpaceGuid.PcdArmPrimaryCore > + gArmTokenSpaceGuid.PcdFdBaseAddress > + gArmTokenSpaceGuid.PcdFdSize > diff --git > a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/Virt.c > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/Virt.c > new file mode 100644 > index 000000000000..a02712274dd3 > --- /dev/null > +++ > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/Virt.c > @@ -0,0 +1,151 @@ > +/** @file > +* > +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. > +* Copyright (c) 2014, 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 <Library/IoLib.h> > +#include <Library/ArmPlatformLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PcdLib.h> > +#include <ArmPlatform.h> > +#include <libfdt.h> > + > +/** > + Return the current Boot Mode > + > + This function returns the boot reason on the platform > + > + @return Return the current Boot Mode of the platform > + > +**/ > +EFI_BOOT_MODE > +ArmPlatformGetBootMode ( > + VOID > + ) > +{ > + return BOOT_WITH_FULL_CONFIGURATION; > +} > + > +/** > + Initialize controllers that must setup in the normal world > + > + This function is called by the ArmPlatformPkg/Pei or > ArmPlatformPkg/Pei/PlatformPeim > + in the PEI phase. > + > +**/ > +RETURN_STATUS > +ArmPlatformInitialize ( > + IN UINTN MpId > + ) > +{ > + // > + // We are relying on ArmPlatformInitializeSystemMemory () being > called from > + // InitializeMemory (), which only occurs if the following feature > is disabled > + // > + ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)); > + return RETURN_SUCCESS; > +} > + > +/** > + Initialize the system (or sometimes called permanent) memory > + > + This memory is generally represented by the DRAM. > + > +**/ > +VOID > +ArmPlatformInitializeSystemMemory ( > + VOID > + ) > +{ > + VOID *DeviceTreeBase; > + INT32 Node, Prev; > + UINT64 NewBase; > + UINT64 NewSize; > + > + NewBase = 0; > + NewSize = 0; > + > + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); > + ASSERT (DeviceTreeBase != NULL); > + > + // > + // Make sure we have a valid device tree blob > + // > + ASSERT (fdt_check_header (DeviceTreeBase) == 0); > + > + // > + // Look for a memory node > + // > + for (Prev = 0;; Prev = Node) { > + CONST CHAR8 *Type; > + INT32 Len; > + > + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); > + if (Node < 0) { > + break; > + } > + > + Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); > + if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { > + CONST UINT64 *RegProp; > + > + // > + // 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))) { > + > + NewBase = fdt64_to_cpu (RegProp[0]); > + NewSize = fdt64_to_cpu (RegProp[1]); > + > + // > + // Make sure the start of DRAM matches our expectation > + // > + ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); > + PcdSet64 (PcdSystemMemorySize, NewSize); > + > + DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", > + __FUNCTION__, NewBase, NewBase + NewSize - 1)); > + } else { > + DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n", > + __FUNCTION__)); > + } > + break; > + } > + } > + // > + // 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)PcdGet32 (PcdFdBaseAddress) + > + (UINT64)PcdGet32 (PcdFdSize) <= NewBase || > + (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize); > +} > + > +VOID > +ArmPlatformGetPlatformPpiList ( > + OUT UINTN *PpiListSize, > + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList > + ) > +{ > + *PpiListSize = 0; > + *PpiList = NULL; > +} > diff --git > a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/VirtMem.c > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/VirtMem.c > new file mode 100644 > index 000000000000..153c1d20e908 > --- /dev/null > +++ > b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform > Lib/VirtMem.c > @@ -0,0 +1,107 @@ > +/** @file > +* > +* Copyright (c) 2014, 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 <Library/ArmPlatformLib.h> > +#include <Library/DebugLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/PcdLib.h> > +#include <Library/IoLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/ArmPlatformGlobalVariableLib.h> > +#include <ArmPlatform.h> > + > +// Number of Virtual Memory Map Descriptors > +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 > + > +// DDR attributes > +#define DDR_ATTRIBUTES_CACHED > ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK > +#define DDR_ATTRIBUTES_UNCACHED > ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED > + > +EFI_PHYSICAL_ADDRESS > +ArmGetPhysAddrTop ( > + VOID > + ); > + > +/** > + 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 > +ArmPlatformGetVirtualMemoryMap ( > + IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap > + ) > +{ > + ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; > + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; > + > + ASSERT (VirtualMemoryMap != NULL); > + > + VirtualMemoryTable = AllocatePages ( > + EFI_SIZE_TO_PAGES ( > + sizeof (ARM_MEMORY_REGION_DESCRIPTOR) > + * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS > + ) > + ); > + > + if (VirtualMemoryTable == NULL) { > + DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", > __FUNCTION__)); > + return; > + } > + > + if (FeaturePcdGet (PcdCacheEnable) == TRUE) { > + CacheAttributes = DDR_ATTRIBUTES_CACHED; > + } else { > + CacheAttributes = DDR_ATTRIBUTES_UNCACHED; > + } > + > + // System DRAM > + VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); > + VirtualMemoryTable[0].VirtualBase = > VirtualMemoryTable[0].PhysicalBase; > + VirtualMemoryTable[0].Length = PcdGet64 (PcdSystemMemorySize); > + VirtualMemoryTable[0].Attributes = CacheAttributes; > + > + DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n" > + "\tPhysicalBase: 0x%lX\n" > + "\tVirtualBase: 0x%lX\n" > + "\tLength: 0x%lX\n", > + __FUNCTION__, > + VirtualMemoryTable[0].PhysicalBase, > + VirtualMemoryTable[0].VirtualBase, > + VirtualMemoryTable[0].Length)); > + > + // Peripheral space before DRAM > + VirtualMemoryTable[1].PhysicalBase = 0x0; > + VirtualMemoryTable[1].VirtualBase = 0x0; > + VirtualMemoryTable[1].Length = > VirtualMemoryTable[0].PhysicalBase; > + VirtualMemoryTable[1].Attributes = > ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > + > + // Peripheral space after DRAM > + VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length + > VirtualMemoryTable[1].Length; > + VirtualMemoryTable[2].VirtualBase = > VirtualMemoryTable[2].PhysicalBase; > + VirtualMemoryTable[2].Length = ArmGetPhysAddrTop () - > VirtualMemoryTable[2].PhysicalBase; > + VirtualMemoryTable[2].Attributes = > ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > + > + // End of Table > + ZeroMem (&VirtualMemoryTable[3], sizeof > (ARM_MEMORY_REGION_DESCRIPTOR)); > + > + *VirtualMemoryMap = VirtualMemoryTable; > +} > -- > 1.8.3.2 > ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S new file mode 100644 index 000000000000..fd0bfe4afa2d --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S @@ -0,0 +1,86 @@ +# +# Copyright (c) 2011-2013, ARM 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 <AsmMacroIoLibV8.h> +#include <Base.h> +#include <Library/ArmLib.h> +#include <Library/PcdLib.h> +#include <AutoGen.h> + +.text +.align 2 + +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) +GCC_ASM_EXPORT(ArmGetPhysAddrTop) + +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) + +ASM_PFX(ArmPlatformPeiBootAction): + ret + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0) + ldrh w0, [x0] + ret + +# IN None +# OUT x0 = number of cores present in the system +ASM_PFX(ArmGetCpuCountPerCluster): + mov x0, #1 + ret + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_PFX(ArmPlatformIsPrimaryCore): + mov x0, #1 + ret + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +// With this function: CorePos = (ClusterId * 4) + CoreId +ASM_PFX(ArmPlatformGetCorePosition): + and x1, x0, #ARM_CORE_MASK + and x0, x0, #ARM_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret + +//EFI_PHYSICAL_ADDRESS +//GetPhysAddrTop ( +// VOID +// ); +ASM_PFX(ArmGetPhysAddrTop): + mrs x0, id_aa64mmfr0_el1 + adr x1, .LPARanges + and x0, x0, #7 + ldrb w1, [x1, x0] + mov x0, #1 + lsl x0, x0, x1 + ret +.LPARanges: + .byte 32, 36, 40, 42, 44, 48, -1, -1 + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S new file mode 100644 index 000000000000..dc79b982b598 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S @@ -0,0 +1,81 @@ +# +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. +# Copyright (c) 2014, 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 <AsmMacroIoLib.h> +#include <Base.h> +#include <Library/ArmLib.h> +#include <Library/PcdLib.h> +#include <AutoGen.h> + +.text +.align 2 + +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) +GCC_ASM_EXPORT(ArmGetPhysAddrTop) + +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount) + +ASM_PFX(ArmPlatformPeiBootAction): + bx lr + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0) + ldr r0, [r0] + bx lr + +# IN None +# OUT r0 = number of cores present in the system +ASM_PFX(ArmGetCpuCountPerCluster): + mov r0, #1 + bx lr + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_PFX(ArmPlatformIsPrimaryCore): + mov r0, #1 + bx lr + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +// With this function: CorePos = (ClusterId * 4) + CoreId +ASM_PFX(ArmPlatformGetCorePosition): + and r1, r0, #ARM_CORE_MASK + and r0, r0, #ARM_CLUSTER_MASK + add r0, r1, r0, LSR #6 + bx lr + +//EFI_PHYSICAL_ADDRESS +//GetPhysAddrTop ( +// VOID +// ); +ASM_PFX(ArmGetPhysAddrTop): + mov r0, #0x00000000 + mov r1, #0x10000 + bx lr + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf new file mode 100644 index 000000000000..e7d6ec536dcd --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf @@ -0,0 +1,60 @@ +#/* @file +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. +# Copyright (c) 2014, 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 = 0x00010005 + BASE_NAME = ArmVirtualizationPlatformLib + FILE_GUID = 00214cc1-06d1-45fe-9700-dca5726ad7bf + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + IoLib + ArmLib + PrintLib + FdtLib + +[Sources.common] + Virt.c + VirtMem.c + +[Sources.AARCH64] + AARCH64/VirtHelper.S | GCC + +[Sources.ARM] + ARM/VirtHelper.S | GCC + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec + +[Pcd] + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdCoreCount + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c new file mode 100644 index 000000000000..a02712274dd3 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c @@ -0,0 +1,151 @@ +/** @file +* +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* Copyright (c) 2014, 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 <Library/IoLib.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <ArmPlatform.h> +#include <libfdt.h> + +/** + Return the current Boot Mode + + This function returns the boot reason on the platform + + @return Return the current Boot Mode of the platform + +**/ +EFI_BOOT_MODE +ArmPlatformGetBootMode ( + VOID + ) +{ + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + Initialize controllers that must setup in the normal world + + This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim + in the PEI phase. + +**/ +RETURN_STATUS +ArmPlatformInitialize ( + IN UINTN MpId + ) +{ + // + // We are relying on ArmPlatformInitializeSystemMemory () being called from + // InitializeMemory (), which only occurs if the following feature is disabled + // + ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)); + return RETURN_SUCCESS; +} + +/** + Initialize the system (or sometimes called permanent) memory + + This memory is generally represented by the DRAM. + +**/ +VOID +ArmPlatformInitializeSystemMemory ( + VOID + ) +{ + VOID *DeviceTreeBase; + INT32 Node, Prev; + UINT64 NewBase; + UINT64 NewSize; + + NewBase = 0; + NewSize = 0; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // + // Make sure we have a valid device tree blob + // + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + // + // Look for a memory node + // + for (Prev = 0;; Prev = Node) { + CONST CHAR8 *Type; + INT32 Len; + + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); + if (Node < 0) { + break; + } + + Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); + if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { + CONST UINT64 *RegProp; + + // + // 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))) { + + NewBase = fdt64_to_cpu (RegProp[0]); + NewSize = fdt64_to_cpu (RegProp[1]); + + // + // Make sure the start of DRAM matches our expectation + // + ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); + PcdSet64 (PcdSystemMemorySize, NewSize); + + DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", + __FUNCTION__, NewBase, NewBase + NewSize - 1)); + } else { + DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n", + __FUNCTION__)); + } + break; + } + } + // + // 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)PcdGet32 (PcdFdBaseAddress) + + (UINT64)PcdGet32 (PcdFdSize) <= NewBase || + (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize); +} + +VOID +ArmPlatformGetPlatformPpiList ( + OUT UINTN *PpiListSize, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList + ) +{ + *PpiListSize = 0; + *PpiList = NULL; +} diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c new file mode 100644 index 000000000000..153c1d20e908 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c @@ -0,0 +1,107 @@ +/** @file +* +* Copyright (c) 2014, 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 <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/PcdLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ArmPlatformGlobalVariableLib.h> +#include <ArmPlatform.h> + +// Number of Virtual Memory Map Descriptors +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 + +// DDR attributes +#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK +#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED + +EFI_PHYSICAL_ADDRESS +ArmGetPhysAddrTop ( + VOID + ); + +/** + 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 +ArmPlatformGetVirtualMemoryMap ( + IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap + ) +{ + ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + + ASSERT (VirtualMemoryMap != NULL); + + VirtualMemoryTable = AllocatePages ( + EFI_SIZE_TO_PAGES ( + sizeof (ARM_MEMORY_REGION_DESCRIPTOR) + * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS + ) + ); + + if (VirtualMemoryTable == NULL) { + DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__)); + return; + } + + if (FeaturePcdGet (PcdCacheEnable) == TRUE) { + CacheAttributes = DDR_ATTRIBUTES_CACHED; + } else { + CacheAttributes = DDR_ATTRIBUTES_UNCACHED; + } + + // System DRAM + VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + VirtualMemoryTable[0].VirtualBase = VirtualMemoryTable[0].PhysicalBase; + VirtualMemoryTable[0].Length = PcdGet64 (PcdSystemMemorySize); + VirtualMemoryTable[0].Attributes = CacheAttributes; + + DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n" + "\tPhysicalBase: 0x%lX\n" + "\tVirtualBase: 0x%lX\n" + "\tLength: 0x%lX\n", + __FUNCTION__, + VirtualMemoryTable[0].PhysicalBase, + VirtualMemoryTable[0].VirtualBase, + VirtualMemoryTable[0].Length)); + + // Peripheral space before DRAM + VirtualMemoryTable[1].PhysicalBase = 0x0; + VirtualMemoryTable[1].VirtualBase = 0x0; + VirtualMemoryTable[1].Length = VirtualMemoryTable[0].PhysicalBase; + VirtualMemoryTable[1].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // Peripheral space after DRAM + VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length + VirtualMemoryTable[1].Length; + VirtualMemoryTable[2].VirtualBase = VirtualMemoryTable[2].PhysicalBase; + VirtualMemoryTable[2].Length = ArmGetPhysAddrTop () - VirtualMemoryTable[2].PhysicalBase; + VirtualMemoryTable[2].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // End of Table + ZeroMem (&VirtualMemoryTable[3], sizeof (ARM_MEMORY_REGION_DESCRIPTOR)); + + *VirtualMemoryMap = VirtualMemoryTable; +}