ArmPlatformPkg/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>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-By: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16138 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Casadevall 2014-09-18 18:05:03 +00:00 committed by oliviermartin
parent ad10693231
commit a36d531f5d
6 changed files with 609 additions and 0 deletions

View File

@ -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(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
//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
//
// Bits 0..2 of the AA64MFR0_EL1 system register encode the size of the
// physical address space support on this CPU:
// 0 == 32 bits, 1 == 36 bits, etc etc
// 6 and 7 are reserved
//
.LPARanges:
.byte 32, 36, 40, 42, 44, 48, -1, -1
ASM_FUNCTION_REMOVE_IF_UNREFERENCED

View File

@ -0,0 +1,74 @@
#
# 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(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
//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

View File

@ -0,0 +1,78 @@
#
# Copyright (c) 2011-2014, 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>
INCLUDE AsmMacroIoLib.inc
EXPORT ArmPlatformPeiBootAction
EXPORT ArmPlatformIsPrimaryCore
EXPORT ArmPlatformGetPrimaryCoreMpId
EXPORT ArmPlatformGetCorePosition
EXPORT ArmGetPhysAddrTop
IMPORT _gPcd_FixedAtBuild_PcdArmPrimaryCore
IMPORT _gPcd_FixedAtBuild_PcdArmPrimaryCoreMask
IMPORT _gPcd_FixedAtBuild_PcdCoreCount
ArmPlatformPeiBootAction FUNCTION
bx lr
ENDFUNC
//UINTN
//ArmPlatformGetPrimaryCoreMpId (
// VOID
// );
ArmPlatformGetPrimaryCoreMpId FUNCTION
LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
ldr r0, [r0]
bx lr
ENDFUNC
//UINTN
//ArmPlatformIsPrimaryCore (
// IN UINTN MpId
// );
ArmPlatformIsPrimaryCore FUNCTION
mov r0, #1
bx lr
ENDFUNC
//UINTN
//ArmPlatformGetCorePosition (
// IN UINTN MpId
// );
// With this function: CorePos = (ClusterId * 4) + CoreId
ArmPlatformGetCorePosition FUNCTION
and r1, r0, #ARM_CORE_MASK
and r0, r0, #ARM_CLUSTER_MASK
add r0, r1, r0, LSR #6
bx lr
ENDFUNC
//EFI_PHYSICAL_ADDRESS
//GetPhysAddrTop (
// VOID
// );
ArmGetPhysAddrTop FUNCTION
mov r0, #0x00000000
mov r1, #0x10000
bx lr
ENDFUNC
END

View File

@ -0,0 +1,67 @@
#/* @file
# Copyright (c) 2011-2014, 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|SEC PEIM
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
[LibraryClasses]
IoLib
ArmLib
PrintLib
FdtLib
SerialPortLib
HobLib
[Sources.common]
Virt.c
VirtMem.c
[Sources.AARCH64]
AARCH64/VirtHelper.S | GCC
[Sources.ARM]
ARM/VirtHelper.S | GCC
ARM/VirtHelper.asm | RVCT
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemorySize
[FixedPcd]
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
gArmTokenSpaceGuid.PcdArmPrimaryCore
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize
[Guids]
gEarlyPL011BaseAddressGuid

View File

@ -0,0 +1,197 @@
/** @file
*
* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
* Copyright (c) 2014, Linaro Limited. All rights reserved.
* Copyright (c) 2014, Red Hat, Inc.
*
*
* 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>
#include <Pi/PiBootMode.h>
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiMultiPhase.h>
#include <Pi/PiHob.h>
#include <Library/HobLib.h>
#include <Guid/EarlyPL011BaseAddress.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;
}
/**
This function is called by PrePeiCore, in the SEC 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.
This function is called from InitializeMemory() in MemoryInitPeim, in the PEI
phase.
**/
VOID
ArmPlatformInitializeSystemMemory (
VOID
)
{
VOID *DeviceTreeBase;
INT32 Node, Prev;
UINT64 NewBase;
UINT64 NewSize;
BOOLEAN HaveMemory, HaveUART;
UINT64 *HobData;
CONST CHAR8 *Type;
CONST CHAR8 *Compatible;
CONST CHAR8 *CompItem;
INT32 Len;
CONST UINT64 *RegProp;
UINT64 UartBase;
NewBase = 0;
NewSize = 0;
HaveMemory = FALSE;
HaveUART = FALSE;
HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *HobData);
ASSERT (HobData != NULL);
*HobData = 0;
DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
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; !(HaveMemory && HaveUART); 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))) {
NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
NewSize = fdt64_to_cpu (ReadUnaligned64 (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__));
}
HaveMemory = TRUE;
continue;
}
//
// Check for UART node
//
Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
//
// Iterate over the NULL-separated items in the compatible string
//
for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
CompItem += 1 + AsciiStrLen (CompItem)) {
if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
ASSERT (Len == 16);
UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
*HobData = UartBase;
HaveUART = TRUE;
continue;
}
}
}
//
// 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;
}

View File

@ -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;
}