From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-io1-f66.google.com (mail-io1-f66.google.com [209.85.166.66]) by mx.groups.io with SMTP id smtpd.web10.3457.1591514431646253393 for ; Sun, 07 Jun 2020 00:20:31 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20161025 header.b=HxHdhGdo; spf=pass (domain: gmail.com, ip: 209.85.166.66, mailfrom: andrey.warkentin@gmail.com) Received: by mail-io1-f66.google.com with SMTP id p20so15053196iop.11 for ; Sun, 07 Jun 2020 00:20:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=AJhbYKwR38PYeqSkVsrZT39dVo2dLOfJ8VHU8x76Cns=; b=HxHdhGdovPKDR2VSoTu0v6jKyr2GLucwXGdBb9hNtbDX12QTLa+MKCQLOV8kvE4YJW NH57sIgvyETHrD170etawRNcL0vp5xT2R1zfU2pm+SFuBcG/N54bfv0bRcq6UlM7kzx5 iVKXUAF4rQ8IISVlLJ/vHGBYKAH3AtxWMolb/Q1ffFJqubb2hW9gFyWBA3A3K6ELTQKE WFQFgbVe+uymMxaePROuYrMXH+9uoHJLj6vgJCyz88e1iln0qq6ew/S7bd7DuoS8ox8X mXMYbF1XGN/aTBjgZeD4iyMLKqrAM23uEnv0ES9l7bT6AMknctfsbuxEL+GlKF7ABx6E CeCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=AJhbYKwR38PYeqSkVsrZT39dVo2dLOfJ8VHU8x76Cns=; b=LbyYkIBA0t150RaCjUftKht/dtEl4zVBSzFa/FGnUfKX71F8OEFVvia9v8eNJqxUOs jUfu9wlZV8cvqcZJ6aV0wEVGkzET9G241XQq4HXWIKfE1UbAmShmFBICRoqEWtZhsRSM Y8BOPvxLu0si4bqt+UpGlKc4P8XT/7id1ceKG4KWN5IqfiuLIUFMkWRX+oVisAgvKYDT 18aCRL5hD63+mI7lUkm9s6kHr0veu7fMjdT31qAiOuLTeWHJtGWdh07U+OP2Y3/y2BnG 0NeLO9N1Yci8DrvPha+weVOk5l+aY631L8XMfvKb/AAKdzrMmQXwVT6K7eFBChKaLMNm DkHA== X-Gm-Message-State: AOAM533oJrzDrHNVy32z/3D9Tbo3VePnthq5lzIoy9wJHjuE/ZtASpPU ng0xfvye41Sx5imn1K3U3pxY9SSL X-Google-Smtp-Source: ABdhPJxsEaBUNkTChJpsYHKD/grPbEQLDIVTP8N6cGmKpzbAOq5knZluADiFkEyMpy/D4Uy3ToKkVQ== X-Received: by 2002:a05:6638:12d2:: with SMTP id v18mr16196084jas.4.1591514430518; Sun, 07 Jun 2020 00:20:30 -0700 (PDT) Return-Path: Received: from localhost.localdomain (c-98-214-99-181.hsd1.il.comcast.net. [98.214.99.181]) by smtp.gmail.com with ESMTPSA id j80sm6091730ili.65.2020.06.07.00.20.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 Jun 2020 00:20:29 -0700 (PDT) From: "Andrei Warkentin" To: devel@edk2.groups.io Cc: ard.biesheuvel@arm.com, leif@nuviainc.com, pete@akeo.ie, philmd@redhat.com Subject: [edk2-platforms][PATCH 1/1] RPi4: reserve/map memory above 4GB when present Date: Sun, 7 Jun 2020 00:20:23 -0700 Message-Id: <20200607072023.127337-1-andrey.warkentin@gmail.com> X-Mailer: git-send-email 2.17.1 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 --- This is the v2 with Pete's feedback. Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c | 39 +++++--- Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf | 1 - Platform/RaspberryPi/Library/PlatformLib/RaspberryPiMem.c | 99 ++++++++++++-------- Platform/RaspberryPi/RPi4/RPi4.dsc | 1 - Platform/RaspberryPi/RaspberryPi.dec | 1 - 5 files changed, 88 insertions(+), 53 deletions(-) diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c index 583f07c9..2ce3af89 100644 --- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c +++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c @@ -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) { diff --git a/Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf b/Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf index f48016cc..54c3f303 100644 --- a/Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf +++ b/Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf @@ -55,7 +55,6 @@ gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset gArmTokenSpaceGuid.PcdSystemMemoryBase gArmTokenSpaceGuid.PcdSystemMemorySize - gRaspberryPiTokenSpaceGuid.PcdExtendedMemoryBase gRaspberryPiTokenSpaceGuid.PcdNvStorageEventLogSize gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize diff --git a/Platform/RaspberryPi/Library/PlatformLib/RaspberryPiMem.c b/Platform/RaspberryPi/Library/PlatformLib/RaspberryPiMem.c index aae189ec..60a7b43a 100644 --- a/Platform/RaspberryPi/Library/PlatformLib/RaspberryPiMem.c +++ b/Platform/RaspberryPi/Library/PlatformLib/RaspberryPiMem.c @@ -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 < 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 above 3 GB"; + VirtualMemoryInfo[Index++].Name = L"Extended System RAM >= 4GB"; } // End of Table diff --git a/Platform/RaspberryPi/RPi4/RPi4.dsc b/Platform/RaspberryPi/RPi4/RPi4.dsc index cbff9d99..e055f13c 100644 --- a/Platform/RaspberryPi/RPi4/RPi4.dsc +++ b/Platform/RaspberryPi/RPi4/RPi4.dsc @@ -403,7 +403,6 @@ # # Device specific addresses # - gRaspberryPiTokenSpaceGuid.PcdExtendedMemoryBase|0x40000000 gBcm27xxTokenSpaceGuid.PcdBcm27xxRegistersAddress|0xfc000000 gBcm27xxTokenSpaceGuid.PcdBcmGenetRegistersAddress|0xfd580000 gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress|0xfe000000 diff --git a/Platform/RaspberryPi/RaspberryPi.dec b/Platform/RaspberryPi/RaspberryPi.dec index 1a3c44e0..5b402123 100644 --- a/Platform/RaspberryPi/RaspberryPi.dec +++ b/Platform/RaspberryPi/RaspberryPi.dec @@ -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 -- 2.17.1