You've already forked edk2-platforms
mirror of
https://github.com/Dasharo/edk2-platforms.git
synced 2026-03-06 14:51:43 -08:00
RPi4: reserve/map memory above 4GB when present
This makes all 8GB usable on the Pi 4 8GB variant. Like RAM in the 3-4GB range, this is still gated by the option to limit RAM to 3GB. Tested on 4GB and 8GB boards, with and without 3GB limit. Signed-off-by: Andrei Warkentin <andrey.warkentin@gmail.com> Reviewed-by: Pete Batard <pete@akeo.ie>
This commit is contained in:
committed by
Ard Biesheuvel
parent
cf2f013b9d
commit
678f6bff3c
@@ -343,7 +343,6 @@ ApplyVariables (
|
||||
UINT32 CpuClock = PcdGet32 (PcdCpuClock);
|
||||
UINT32 CustomCpuClock = PcdGet32 (PcdCustomCpuClock);
|
||||
UINT32 Rate = 0;
|
||||
UINT64 SystemMemorySize;
|
||||
|
||||
switch (CpuClock) {
|
||||
case CHIPSET_CPU_CLOCK_LOW:
|
||||
@@ -386,27 +385,43 @@ ApplyVariables (
|
||||
|
||||
if (mModelFamily >= 4 && PcdGet32 (PcdRamMoreThan3GB) != 0 &&
|
||||
PcdGet32 (PcdRamLimitTo3GB) == 0) {
|
||||
UINT64 SystemMemorySize;
|
||||
UINT64 SystemMemorySizeBelow4GB;
|
||||
|
||||
ASSERT (BCM2711_SOC_REGISTERS != 0);
|
||||
SystemMemorySize = (UINT64)mModelInstalledMB * SIZE_1MB;
|
||||
/*
|
||||
* Similar to how we compute the > 3 GB RAM segment's size in PlatformLib/
|
||||
* RaspberryPiMem.c, with some overlap protection for the Bcm2xxx register
|
||||
* spaces. This computation should also work for models with more than 4 GB
|
||||
* RAM, if there ever exist ones.
|
||||
* spaces. SystemMemorySizeBelow4GB tracks the maximum memory below 4GB
|
||||
* line, factoring in the limit imposed by the SoC register range.
|
||||
*/
|
||||
SystemMemorySize = (UINT64)mModelInstalledMB * SIZE_1MB;
|
||||
ASSERT (SystemMemorySize > 3UL * SIZE_1GB);
|
||||
SystemMemorySize = MIN(SystemMemorySize, BCM2836_SOC_REGISTERS);
|
||||
if (BCM2711_SOC_REGISTERS > 0) {
|
||||
SystemMemorySize = MIN(SystemMemorySize, BCM2711_SOC_REGISTERS);
|
||||
}
|
||||
SystemMemorySizeBelow4GB = MIN(SystemMemorySize, 4UL * SIZE_1GB);
|
||||
SystemMemorySizeBelow4GB = MIN(SystemMemorySizeBelow4GB, BCM2836_SOC_REGISTERS);
|
||||
SystemMemorySizeBelow4GB = MIN(SystemMemorySizeBelow4GB, BCM2711_SOC_REGISTERS);
|
||||
|
||||
ASSERT (SystemMemorySizeBelow4GB > 3UL * SIZE_1GB);
|
||||
|
||||
Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, 3UL * BASE_1GB,
|
||||
SystemMemorySize - (3UL * SIZE_1GB),
|
||||
SystemMemorySizeBelow4GB - (3UL * SIZE_1GB),
|
||||
EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Status = gDS->SetMemorySpaceAttributes (3UL * BASE_1GB,
|
||||
SystemMemorySize - (3UL * SIZE_1GB),
|
||||
EFI_MEMORY_WB);
|
||||
SystemMemorySizeBelow4GB - (3UL * SIZE_1GB), EFI_MEMORY_WB);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (SystemMemorySize > 4UL * SIZE_1GB) {
|
||||
//
|
||||
// Register any memory above 4GB.
|
||||
//
|
||||
Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, 4UL * BASE_1GB,
|
||||
SystemMemorySize - (4UL * SIZE_1GB),
|
||||
EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Status = gDS->SetMemorySpaceAttributes (4UL * BASE_1GB,
|
||||
SystemMemorySize - (4UL * SIZE_1GB), EFI_MEMORY_WB);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
if (mModelFamily == 3 || mModelFamily == 2) {
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset
|
||||
gArmTokenSpaceGuid.PcdSystemMemoryBase
|
||||
gArmTokenSpaceGuid.PcdSystemMemorySize
|
||||
gRaspberryPiTokenSpaceGuid.PcdExtendedMemoryBase
|
||||
gRaspberryPiTokenSpaceGuid.PcdNvStorageEventLogSize
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
|
||||
|
||||
@@ -58,18 +58,55 @@ ArmPlatformGetVirtualMemoryMap (
|
||||
{
|
||||
UINTN Index = 0;
|
||||
UINTN GpuIndex;
|
||||
INT64 OrigMemorySize;
|
||||
INT64 SystemMemorySize;
|
||||
INT64 TotalMemorySize;
|
||||
INT64 MemorySizeBelow3GB;
|
||||
INT64 MemorySizeBelow4GB;
|
||||
ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
|
||||
|
||||
// Early output of the info we got from VideoCore can prove valuable.
|
||||
DEBUG ((DEBUG_INFO, "Board Rev: 0x%lX\n", mBoardRevision));
|
||||
DEBUG ((DEBUG_INFO, "Base RAM : 0x%ll08X (Size 0x%ll08X)\n", mSystemMemoryBase, mSystemMemoryEnd + 1));
|
||||
DEBUG ((DEBUG_INFO, "RAM < 1GB: 0x%ll08X (Size 0x%ll08X)\n", mSystemMemoryBase, mSystemMemoryEnd + 1));
|
||||
DEBUG ((DEBUG_INFO, "VideoCore: 0x%ll08X (Size 0x%ll08X)\n", mVideoCoreBase, mVideoCoreSize));
|
||||
|
||||
ASSERT (mSystemMemoryBase == 0);
|
||||
ASSERT (VirtualMemoryMap != NULL);
|
||||
|
||||
// Compute the total RAM size available on this platform
|
||||
TotalMemorySize = SIZE_256MB;
|
||||
TotalMemorySize <<= (mBoardRevision >> 20) & 0x07;
|
||||
DEBUG ((DEBUG_INFO, "Total RAM: 0x%ll08X\n", TotalMemorySize));
|
||||
|
||||
//
|
||||
// Ensure that what we declare as System Memory doesn't overlap with the
|
||||
// SoC MMIO registers. This can be achieved through a MIN () with the
|
||||
// base address since SystemMemoryBase is 0 (we assert if it isn't).
|
||||
//
|
||||
ASSERT (BCM2836_SOC_REGISTERS < 4UL * SIZE_1GB);
|
||||
MemorySizeBelow4GB = MIN(TotalMemorySize, 4UL * SIZE_1GB);
|
||||
MemorySizeBelow4GB = MIN(MemorySizeBelow4GB, BCM2836_SOC_REGISTERS);
|
||||
if (BCM2711_SOC_REGISTERS > 0) {
|
||||
ASSERT (BCM2836_SOC_REGISTERS < 4UL * SIZE_1GB);
|
||||
MemorySizeBelow4GB = MIN(MemorySizeBelow4GB, BCM2711_SOC_REGISTERS);
|
||||
}
|
||||
|
||||
//
|
||||
// By default we limit the memory to 3 GB to work around OS support for
|
||||
// DMA bugs in the SoC, for OSes that don't support _DMA range descriptors.
|
||||
// On boards with more RAM (4GB, 8GB), the extra memory is added by ConfigDxe
|
||||
// provided the configuration setting for 3GB limit is off.
|
||||
//
|
||||
MemorySizeBelow3GB = MIN(MemorySizeBelow4GB, 3UL * SIZE_1GB);
|
||||
|
||||
//
|
||||
// On Pi 3 we've seen SoC registers may overlap the reported VideoCore range,
|
||||
// so clamp that down as well.
|
||||
//
|
||||
if (mVideoCoreBase + mVideoCoreSize > BCM2836_SOC_REGISTERS) {
|
||||
mVideoCoreSize = BCM2836_SOC_REGISTERS - mVideoCoreBase;
|
||||
DEBUG ((DEBUG_WARN, "VideoCore range overlapped SoC MMIO, now 0x%ll08X (Size 0x%ll08X)\n",
|
||||
mVideoCoreBase, mVideoCoreSize));
|
||||
}
|
||||
|
||||
VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages
|
||||
(EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) *
|
||||
MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
|
||||
@@ -77,7 +114,6 @@ ArmPlatformGetVirtualMemoryMap (
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Firmware Volume
|
||||
VirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64 (PcdFdBaseAddress);
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
@@ -123,7 +159,7 @@ ArmPlatformGetVirtualMemoryMap (
|
||||
VirtualMemoryTable[Index].Length = mSystemMemoryEnd + 1 - FixedPcdGet64 (PcdSystemMemoryBase);
|
||||
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_BASIC_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"Base System RAM";
|
||||
VirtualMemoryInfo[Index++].Name = L"System RAM < 1GB";
|
||||
|
||||
// GPU Reserved
|
||||
GpuIndex = Index;
|
||||
@@ -134,21 +170,9 @@ ArmPlatformGetVirtualMemoryMap (
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_UNMAPPED_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"GPU Reserved";
|
||||
|
||||
// Compute the total RAM size available on this platform
|
||||
SystemMemorySize = SIZE_256MB;
|
||||
SystemMemorySize <<= (mBoardRevision >> 20) & 0x07;
|
||||
|
||||
//
|
||||
// Ensure that what we declare as System Memory doesn't overlap with the
|
||||
// Bcm2836 SoC registers. This can be achieved through a MIN () with the
|
||||
// base address since SystemMemoryBase is 0 (we assert if it isn't).
|
||||
//
|
||||
SystemMemorySize = MIN(SystemMemorySize, BCM2836_SOC_REGISTERS);
|
||||
|
||||
// Extended SoC registers (PCIe, genet, ...)
|
||||
if (BCM2711_SOC_REGISTERS > 0) {
|
||||
// Same overlap protection as above for the Bcm2711 SoC registers
|
||||
SystemMemorySize = MIN(SystemMemorySize, BCM2711_SOC_REGISTERS);
|
||||
VirtualMemoryTable[Index].PhysicalBase = BCM2711_SOC_REGISTERS;
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = BCM2711_SOC_REGISTER_LENGTH;
|
||||
@@ -159,45 +183,44 @@ ArmPlatformGetVirtualMemoryMap (
|
||||
|
||||
// Base SoC registers
|
||||
VirtualMemoryTable[Index].PhysicalBase = BCM2836_SOC_REGISTERS;
|
||||
// On the Pi 3 the SoC registers may overlap VideoCore => fix this
|
||||
if (VirtualMemoryTable[GpuIndex].PhysicalBase + VirtualMemoryTable[GpuIndex].Length > VirtualMemoryTable[Index].PhysicalBase) {
|
||||
VirtualMemoryTable[GpuIndex].Length = VirtualMemoryTable[Index].PhysicalBase - VirtualMemoryTable[GpuIndex].PhysicalBase;
|
||||
}
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = BCM2836_SOC_REGISTER_LENGTH;
|
||||
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_UNMAPPED_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"SoC Reserved (283x)";
|
||||
|
||||
//
|
||||
// By default we limit the memory to 3 GB to work around the DMA bugs in the SoC,
|
||||
// for OSes that don't support _DMA range descriptors. On 4GB boards, it's runtime
|
||||
// setting to boot with 4 GB, and the additional 1 GB is added by ConfigDxe.
|
||||
//
|
||||
OrigMemorySize = SystemMemorySize;
|
||||
SystemMemorySize = MIN(SystemMemorySize, 3UL * SIZE_1GB);
|
||||
|
||||
// If we have RAM above the 1 GB mark, declare it
|
||||
if (SystemMemorySize - SIZE_1GB > 0) {
|
||||
VirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64 (PcdExtendedMemoryBase);
|
||||
// Memory in the 1GB - 3GB range is always available.
|
||||
if (MemorySizeBelow3GB > SIZE_1GB) {
|
||||
VirtualMemoryTable[Index].PhysicalBase = SIZE_1GB;
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = SystemMemorySize - SIZE_1GB;
|
||||
VirtualMemoryTable[Index].Length = MemorySizeBelow3GB - VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_BASIC_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"Extended System RAM below 3 GB";
|
||||
VirtualMemoryInfo[Index++].Name = L"Extended System RAM < 3GB";
|
||||
}
|
||||
|
||||
//
|
||||
// If we have RAM above 3 GB mark, declare it so it's mapped, but
|
||||
// don't add it to the memory map. This is done later by ConfigDxe if necessary.
|
||||
// If we have RAM in the 3GB - 4GB range, declare it as mapped, but don't
|
||||
// add it to the memory map. This is done later by ConfigDxe if necessary.
|
||||
//
|
||||
if (OrigMemorySize > (3UL * SIZE_1GB)) {
|
||||
if (MemorySizeBelow4GB > 3UL * SIZE_1GB) {
|
||||
VirtualMemoryTable[Index].PhysicalBase = 3UL * SIZE_1GB;
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = OrigMemorySize - VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = MemorySizeBelow4GB - VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_UNMAPPED_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"Extended System RAM above 3 GB";
|
||||
VirtualMemoryInfo[Index++].Name = L"Extended System RAM < 4GB";
|
||||
}
|
||||
|
||||
// Same treatment for the memory above 4GB.
|
||||
if (TotalMemorySize > 4UL * SIZE_1GB) {
|
||||
VirtualMemoryTable[Index].PhysicalBase = 4UL * SIZE_1GB;
|
||||
VirtualMemoryTable[Index].VirtualBase = VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Length = TotalMemorySize - VirtualMemoryTable[Index].PhysicalBase;
|
||||
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
|
||||
VirtualMemoryInfo[Index].Type = RPI_MEM_UNMAPPED_REGION;
|
||||
VirtualMemoryInfo[Index++].Name = L"Extended System RAM >= 4GB";
|
||||
}
|
||||
|
||||
// End of Table
|
||||
|
||||
@@ -403,7 +403,6 @@
|
||||
#
|
||||
# Device specific addresses
|
||||
#
|
||||
gRaspberryPiTokenSpaceGuid.PcdExtendedMemoryBase|0x40000000
|
||||
gBcm27xxTokenSpaceGuid.PcdBcm27xxRegistersAddress|0xfc000000
|
||||
gBcm27xxTokenSpaceGuid.PcdBcmGenetRegistersAddress|0xfd580000
|
||||
gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress|0xfe000000
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
gRaspberryPiTokenSpaceGuid.PcdNvStorageVariableBase|0x0|UINT32|0x00000005
|
||||
gRaspberryPiTokenSpaceGuid.PcdNvStorageFtwSpareBase|0x0|UINT32|0x00000006
|
||||
gRaspberryPiTokenSpaceGuid.PcdNvStorageFtwWorkingBase|0x0|UINT32|0x00000007
|
||||
gRaspberryPiTokenSpaceGuid.PcdExtendedMemoryBase|0x0|UINT32|0x00000008
|
||||
gRaspberryPiTokenSpaceGuid.PcdFdtSize|0x10000|UINT32|0x00000009
|
||||
gRaspberryPiTokenSpaceGuid.PcdCpuLowSpeedMHz|600|UINT32|0x0000000a
|
||||
gRaspberryPiTokenSpaceGuid.PcdCpuDefSpeedMHz|800|UINT32|0x0000000b
|
||||
|
||||
Reference in New Issue
Block a user