Files
nix-config/packages/edk2/patches/platforms/0002-Platform-RaspberryPi-Read-board-revision-and-serial-.patch
2026-01-07 21:28:20 -06:00

1081 lines
33 KiB
Diff

From ca35cfb913171881685b8dddd1f61512c1a2b053 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?=
<mariobalanica02@gmail.com>
Date: Tue, 12 Dec 2023 00:49:37 +0200
Subject: [PATCH 02/16] Platform/RaspberryPi: Read board revision and serial
from FDT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The mailbox "get revision code" property no longer works on RPi 5. "Get
serial" still does, but only returns the low part of the number.
It is now recommended to read these fields from the FDT passed by the
VPU firmware, which also conveniently fills in other useful info under
the /chosen node.
This works on all supported boards, provided there's a valid DTB in the
boot partition.
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
---
.../RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c | 26 +--
.../Drivers/ConfigDxe/ConfigDxe.inf | 2 +
.../PlatformSmbiosDxe/PlatformSmbiosDxe.c | 80 +++----
.../PlatformSmbiosDxe/PlatformSmbiosDxe.inf | 2 +
.../Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c | 207 ------------------
.../Include/Library/BoardInfoLib.h | 24 ++
.../Include/Library/BoardRevisionHelperLib.h | 42 ++++
.../Include/Library/FdtPlatformLib.h | 18 ++
.../Include/Protocol/RpiFirmware.h | 35 ---
.../Library/BoardInfoLib/BoardInfoLib.c | 78 +++++++
.../Library/BoardInfoLib/BoardInfoLib.inf | 27 +++
.../BoardRevisionHelperLib.c | 153 +++++++++++++
.../BoardRevisionHelperLib.inf | 22 ++
.../Library/FdtPlatformLib/FdtPlatformLib.c | 32 +++
.../Library/FdtPlatformLib/FdtPlatformLib.inf | 30 +++
Platform/RaspberryPi/RPi3/RPi3.dsc | 4 +
Platform/RaspberryPi/RPi4/RPi4.dsc | 4 +
17 files changed, 480 insertions(+), 306 deletions(-)
create mode 100644 Platform/RaspberryPi/Include/Library/BoardInfoLib.h
create mode 100644 Platform/RaspberryPi/Include/Library/BoardRevisionHelperLib.h
create mode 100644 Platform/RaspberryPi/Include/Library/FdtPlatformLib.h
create mode 100644 Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.c
create mode 100644 Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
create mode 100644 Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.c
create mode 100644 Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf
create mode 100644 Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.c
create mode 100644 Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
index 24847879..2a688fab 100644
--- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
+++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
@@ -28,6 +28,8 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PcdLib.h>
+#include <Library/BoardInfoLib.h>
+#include <Library/BoardRevisionHelperLib.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/BcmGenetPlatformDevice.h>
#include <Protocol/RpiFirmware.h>
@@ -935,26 +937,22 @@ ConfigInitialize (
return Status;
}
- Status = mFwProtocol->GetModelFamily (&mModelFamily);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Couldn't get the Raspberry Pi model family: %r\n", Status));
+ Status = BoardInfoGetRevisionCode (&mModelRevision);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Couldn't get the Raspberry Pi revision: %r\n", Status));
} else {
- DEBUG ((DEBUG_INFO, "Current Raspberry Pi model family is %d\n", mModelFamily));
+ DEBUG ((DEBUG_INFO, "Current Raspberry Pi revision %x\n", mModelRevision));
}
- Status = mFwProtocol->GetModelInstalledMB (&mModelInstalledMB);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Couldn't get the Raspberry Pi installed RAM size: %r\n", Status));
+ mModelFamily = BoardRevisionGetModelFamily (mModelRevision);
+ if (mModelFamily == 0) {
+ DEBUG ((DEBUG_ERROR, "Couldn't get the Raspberry Pi model family\n"));
} else {
- DEBUG ((DEBUG_INFO, "Current Raspberry Pi installed RAM size is %d MB\n", mModelInstalledMB));
+ DEBUG ((DEBUG_INFO, "Current Raspberry Pi model family is %d\n", mModelFamily));
}
- Status = mFwProtocol->GetModelRevision (&mModelRevision);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Couldn't get the Raspberry Pi revision: %r\n", Status));
- } else {
- DEBUG ((DEBUG_INFO, "Current Raspberry Pi revision %x\n", mModelRevision));
- }
+ mModelInstalledMB = BoardRevisionGetMemorySize (mModelRevision) / 1024 / 1024;
+ DEBUG ((DEBUG_INFO, "Current Raspberry Pi installed RAM size is %d MB\n", mModelInstalledMB));
Status = mFwProtocol->GetClockRate (RPI_MBOX_CLOCK_RATE_CORE, &mCoreClockRate);
if (Status != EFI_SUCCESS) {
diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf
index 475e6455..412b21e4 100644
--- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf
+++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf
@@ -56,6 +56,8 @@
UefiDriverEntryPoint
UefiLib
UefiRuntimeServicesTableLib
+ BoardInfoLib
+ BoardRevisionHelperLib
[Guids]
gConfigDxeFormSetGuid
diff --git a/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c b/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c
index 0d013224..8f0eeeec 100644
--- a/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c
+++ b/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c
@@ -51,11 +51,14 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PrintLib.h>
+#include <Library/BoardInfoLib.h>
+#include <Library/BoardRevisionHelperLib.h>
#include <ConfigVars.h>
#define SMB_IS_DIGIT(c) (((c) >= '0') && ((c) <= '9'))
STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
+STATIC UINT32 mBoardRevisionCode;
/***********************************************************************
SMBIOS data definition TYPE0 BIOS Information
@@ -860,30 +863,19 @@ SysInfoUpdateSmbiosType1 (
VOID
)
{
- UINT32 BoardRevision = 0;
EFI_STATUS Status = EFI_SUCCESS;
UINT64 BoardSerial = 0;
- INTN Prod = -1;
- INTN Manu = -1;
-
- Status = mFwProtocol->GetModelRevision (&BoardRevision);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed to get board model: %r\n", Status));
- } else {
- Prod = (BoardRevision >> 4) & 0xFF;
- Manu = (BoardRevision >> 16) & 0x0F;
- }
AsciiStrCpyS (mSysInfoProductName, sizeof (mSysInfoProductName),
- mFwProtocol->GetModelName (Prod));
+ BoardRevisionGetModelName (mBoardRevisionCode));
AsciiStrCpyS (mSysInfoManufName, sizeof (mSysInfoManufName),
- mFwProtocol->GetManufacturerName (Manu));
+ BoardRevisionGetManufacturerName (mBoardRevisionCode));
AsciiSPrint (mSysInfoVersionName, sizeof (mSysInfoVersionName),
- "%X", BoardRevision);
+ "%X", mBoardRevisionCode);
- I64ToHexString (mSysInfoSKU, sizeof (mSysInfoSKU), BoardRevision);
+ I64ToHexString (mSysInfoSKU, sizeof (mSysInfoSKU), mBoardRevisionCode);
- Status = mFwProtocol->GetSerial (&BoardSerial);
+ Status = BoardInfoGetSerialNumber (&BoardSerial);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to get board serial: %r\n", Status));
}
@@ -892,7 +884,7 @@ SysInfoUpdateSmbiosType1 (
DEBUG ((DEBUG_ERROR, "Board Serial Number: %a\n", mSysInfoSerial));
- mSysInfoType1.Uuid.Data1 = BoardRevision;
+ mSysInfoType1.Uuid.Data1 = mBoardRevisionCode;
mSysInfoType1.Uuid.Data2 = 0x0;
mSysInfoType1.Uuid.Data3 = 0x0;
// Swap endianness, so that the serial is more user-friendly as a UUID
@@ -984,7 +976,7 @@ ProcessorInfoUpdateSmbiosType4 (
DEBUG ((DEBUG_INFO, "Current CPU speed: %uHz\n", Rate));
}
- AsciiStrCpyS (mCpuName, sizeof (mCpuName), mFwProtocol->GetCpuName (-1));
+ AsciiStrCpyS (mCpuName, sizeof (mCpuName), BoardRevisionGetProcessorName (mBoardRevisionCode));
ProcessorId = (UINT64 *)&(mProcessorInfoType4.ProcessorId);
*ProcessorId = ArmReadMidr();
@@ -1044,25 +1036,15 @@ PhyMemArrayInfoUpdateSmbiosType16 (
)
{
EFI_SMBIOS_HANDLE MemArraySmbiosHandle;
- EFI_STATUS Status;
- UINT32 InstalledMB = 0;
-
- //
- // Update memory size fields:
- // - Type 16 MaximumCapacity in KB
- // - Type 17 size in MB (since bit 15 = 0)
- // - Type 17 VolatileSize in Bytes
- //
- // The minimum RAM size used on any Raspberry Pi model is 256 MB
- mMemDevInfoType17.Size = 256;
+ //
+ // Update memory size fields:
+ // - Type 16 MaximumCapacity in KB
+ // - Type 17 size in MB (since bit 15 = 0)
+ // - Type 17 VolatileSize in Bytes
+ //
- Status = mFwProtocol->GetModelInstalledMB (&InstalledMB);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_WARN, "Couldn't get the board memory size - defaulting to 256 MB: %r\n", Status));
- } else {
- mMemDevInfoType17.Size = InstalledMB; // Size in MB
- }
+ mMemDevInfoType17.Size = BoardRevisionGetMemorySize (mBoardRevisionCode) / 1024 / 1024;
mPhyMemArrayInfoType16.MaximumCapacity = mMemDevInfoType17.Size * 1024; // Size in KB
mMemDevInfoType17.VolatileSize = MultU64x32 (mMemDevInfoType17.Size, 1024 * 1024); // Size in Bytes
@@ -1095,26 +1077,17 @@ MemArrMapInfoUpdateSmbiosType19 (
VOID
)
{
- EFI_STATUS Status;
- UINT32 InstalledMB = 0;
-
// Note: Type 19 addresses are expressed in KB, not bytes
// The memory layout used in all known Pi SoC's starts at 0
mMemArrMapInfoType19.StartingAddress = 0;
- // The minimum RAM size used on any Raspberry Pi model is 256 MB
- mMemArrMapInfoType19.EndingAddress = 256 * 1024;
- Status = mFwProtocol->GetModelInstalledMB (&InstalledMB);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_WARN, "Couldn't get the board memory size - defaulting to 256 MB: %r\n", Status));
- } else {
- if (PcdGet32 (PcdRamMoreThan3GB) && PcdGet32 (PcdRamLimitTo3GB)) {
- ASSERT (InstalledMB > 3 * 1024);
- mMemArrMapInfoType19.EndingAddress = 3 * 1024 * 1024;
- } else {
- mMemArrMapInfoType19.EndingAddress = InstalledMB * 1024;
- }
+ mMemArrMapInfoType19.EndingAddress = BoardRevisionGetMemorySize (mBoardRevisionCode) / 1024;
+
+ if (PcdGet32 (PcdRamMoreThan3GB) && PcdGet32 (PcdRamLimitTo3GB)) {
+ ASSERT (mMemArrMapInfoType19.EndingAddress > 3 * 1024 * 1024);
+ mMemArrMapInfoType19.EndingAddress = 3 * 1024 * 1024;
}
+
mMemArrMapInfoType19.EndingAddress -= 1;
LogSmbiosData ((EFI_SMBIOS_TABLE_HEADER*)&mMemArrMapInfoType19, mMemArrMapInfoType19Strings, NULL);
@@ -1151,6 +1124,13 @@ PlatformSmbiosDriverEntryPoint (
return Status;
}
+ Status = BoardInfoGetRevisionCode (&mBoardRevisionCode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Failed to get board revision code - some fields will be inaccurate! Status=%r\n",
+ __func__, Status));
+ }
+
BIOSInfoUpdateSmbiosType0 ();
SysInfoUpdateSmbiosType1 ();
diff --git a/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf b/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
index 2b24b22c..74865d79 100644
--- a/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+++ b/Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
@@ -41,6 +41,8 @@
DebugLib
PrintLib
TimeBaseLib
+ BoardInfoLib
+ BoardRevisionHelperLib
[Protocols]
gEfiSmbiosProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
diff --git a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c b/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
index 6fe76e1d..91f581ef 100644
--- a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
+++ b/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
@@ -560,208 +560,6 @@ RpiFirmwareGetFirmwareRevision (
return EFI_SUCCESS;
}
-STATIC
-CHAR8*
-EFIAPI
-RpiFirmwareGetModelName (
- IN INTN ModelId
- )
-{
- UINT32 Revision;
-
- // If a negative ModelId is passed, detect it.
- if ((ModelId < 0) && (RpiFirmwareGetModelRevision (&Revision) == EFI_SUCCESS)) {
- ModelId = (Revision >> 4) & 0xFF;
- }
-
- switch (ModelId) {
- // www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- case 0x00:
- return "Raspberry Pi Model A";
- case 0x01:
- return "Raspberry Pi Model B";
- case 0x02:
- return "Raspberry Pi Model A+";
- case 0x03:
- return "Raspberry Pi Model B+";
- case 0x04:
- return "Raspberry Pi 2 Model B";
- case 0x06:
- return "Raspberry Pi Compute Module 1";
- case 0x08:
- return "Raspberry Pi 3 Model B";
- case 0x09:
- return "Raspberry Pi Zero";
- case 0x0A:
- return "Raspberry Pi Compute Module 3";
- case 0x0C:
- return "Raspberry Pi Zero W";
- case 0x0D:
- return "Raspberry Pi 3 Model B+";
- case 0x0E:
- return "Raspberry Pi 3 Model A+";
- case 0x10:
- return "Raspberry Pi Compute Module 3+";
- case 0x11:
- return "Raspberry Pi 4 Model B";
- case 0x13:
- return "Raspberry Pi 400";
- case 0x14:
- return "Raspberry Pi Compute Module 4";
- default:
- return "Unknown Raspberry Pi Model";
- }
-}
-
-STATIC
-EFI_STATUS
-EFIAPI
-RPiFirmwareGetModelInstalledMB (
- OUT UINT32 *InstalledMB
- )
-{
- EFI_STATUS Status;
- UINT32 Revision;
-
- Status = RpiFirmwareGetModelRevision(&Revision);
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Could not get the board revision: Status == %r\n",
- __FUNCTION__, Status));
- return EFI_DEVICE_ERROR;
- }
-
- //
- // www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- // Bits [20-22] indicate the amount of memory starting with 256MB (000b)
- // and doubling in size for each value (001b = 512 MB, 010b = 1GB, etc.)
- //
- *InstalledMB = 256 << ((Revision >> 20) & 0x07);
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-EFIAPI
-RPiFirmwareGetModelFamily (
- OUT UINT32 *ModelFamily
- )
-{
- EFI_STATUS Status;
- UINT32 Revision;
- UINT32 ModelId;
-
- Status = RpiFirmwareGetModelRevision(&Revision);
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_ERROR,
- "%a: Could not get the board revision: Status == %r\n",
- __FUNCTION__, Status));
- return EFI_DEVICE_ERROR;
- } else {
- ModelId = (Revision >> 4) & 0xFF;
- }
-
- switch (ModelId) {
- // www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- case 0x00: // Raspberry Pi Model A
- case 0x01: // Raspberry Pi Model B
- case 0x02: // Raspberry Pi Model A+
- case 0x03: // Raspberry Pi Model B+
- case 0x06: // Raspberry Pi Compute Module 1
- case 0x09: // Raspberry Pi Zero
- case 0x0C: // Raspberry Pi Zero W
- *ModelFamily = 1;
- break;
- case 0x04: // Raspberry Pi 2 Model B
- *ModelFamily = 2;
- break;
- case 0x08: // Raspberry Pi 3 Model B
- case 0x0A: // Raspberry Pi Compute Module 3
- case 0x0D: // Raspberry Pi 3 Model B+
- case 0x0E: // Raspberry Pi 3 Model A+
- case 0x10: // Raspberry Pi Compute Module 3+
- *ModelFamily = 3;
- break;
- case 0x11: // Raspberry Pi 4 Model B
- case 0x13: // Raspberry Pi 400
- case 0x14: // Raspberry Pi Computer Module 4
- *ModelFamily = 4;
- break;
- default:
- *ModelFamily = 0;
- break;
- }
-
- if (*ModelFamily == 0) {
- DEBUG ((DEBUG_ERROR,
- "%a: Unknown Raspberry Pi model family : ModelId == 0x%x\n",
- __FUNCTION__, ModelId));
- return EFI_UNSUPPORTED;
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-CHAR8*
-EFIAPI
-RpiFirmwareGetManufacturerName (
- IN INTN ManufacturerId
- )
-{
- UINT32 Revision;
-
- // If a negative ModelId is passed, detect it.
- if ((ManufacturerId < 0) && (RpiFirmwareGetModelRevision (&Revision) == EFI_SUCCESS)) {
- ManufacturerId = (Revision >> 16) & 0x0F;
- }
-
- switch (ManufacturerId) {
- // www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- case 0x00:
- return "Sony UK";
- case 0x01:
- return "Egoman";
- case 0x02:
- case 0x04:
- return "Embest";
- case 0x03:
- return "Sony Japan";
- case 0x05:
- return "Stadium";
- default:
- return "Unknown Manufacturer";
- }
-}
-
-STATIC
-CHAR8*
-EFIAPI
-RpiFirmwareGetCpuName (
- IN INTN CpuId
- )
-{
- UINT32 Revision;
-
- // If a negative CpuId is passed, detect it.
- if ((CpuId < 0) && (RpiFirmwareGetModelRevision (&Revision) == EFI_SUCCESS)) {
- CpuId = (Revision >> 12) & 0x0F;
- }
-
- switch (CpuId) {
- // www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- case 0x00:
- return "BCM2835 (ARM11)";
- case 0x01:
- return "BCM2836 (ARM Cortex-A7)";
- case 0x02:
- return "BCM2837 (ARM Cortex-A53)";
- case 0x03:
- return "BCM2711 (ARM Cortex-A72)";
- default:
- return "Unknown CPU Model";
- }
-}
-
#pragma pack()
typedef struct {
UINT32 Width;
@@ -1549,13 +1347,8 @@ STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = {
RpiFirmwareGetSerial,
RpiFirmwareGetModel,
RpiFirmwareGetModelRevision,
- RpiFirmwareGetModelName,
- RPiFirmwareGetModelFamily,
RpiFirmwareGetFirmwareRevision,
- RpiFirmwareGetManufacturerName,
- RpiFirmwareGetCpuName,
RpiFirmwareGetArmMemory,
- RPiFirmwareGetModelInstalledMB,
RpiFirmwareNotifyXhciReset,
RpiFirmwareGetCurrentClockState,
RpiFirmwareSetClockState,
diff --git a/Platform/RaspberryPi/Include/Library/BoardInfoLib.h b/Platform/RaspberryPi/Include/Library/BoardInfoLib.h
new file mode 100644
index 00000000..acdfd17a
--- /dev/null
+++ b/Platform/RaspberryPi/Include/Library/BoardInfoLib.h
@@ -0,0 +1,24 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __BOARD_INFO_LIB_H__
+#define __BOARD_INFO_LIB_H__
+
+EFI_STATUS
+EFIAPI
+BoardInfoGetRevisionCode (
+ OUT UINT32 *RevisionCode
+ );
+
+EFI_STATUS
+EFIAPI
+BoardInfoGetSerialNumber (
+ OUT UINT64 *SerialNumber
+ );
+
+#endif /* __BOARD_INFO_LIB_H__ */
diff --git a/Platform/RaspberryPi/Include/Library/BoardRevisionHelperLib.h b/Platform/RaspberryPi/Include/Library/BoardRevisionHelperLib.h
new file mode 100644
index 00000000..3e3183fe
--- /dev/null
+++ b/Platform/RaspberryPi/Include/Library/BoardRevisionHelperLib.h
@@ -0,0 +1,42 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __BOARD_REVISION_HELPER_LIB_H__
+#define __BOARD_REVISION_HELPER_LIB_H__
+
+UINT64
+EFIAPI
+BoardRevisionGetMemorySize (
+ IN UINT32 RevisionCode
+ );
+
+UINT32
+EFIAPI
+BoardRevisionGetModelFamily (
+ IN UINT32 RevisionCode
+ );
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetModelName (
+ IN UINT32 RevisionCode
+ );
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetManufacturerName (
+ IN UINT32 RevisionCode
+ );
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetProcessorName (
+ IN UINT32 RevisionCode
+ );
+
+#endif /* __BOARD_REVISION_HELPER_LIB_H__ */
diff --git a/Platform/RaspberryPi/Include/Library/FdtPlatformLib.h b/Platform/RaspberryPi/Include/Library/FdtPlatformLib.h
new file mode 100644
index 00000000..f8354c8d
--- /dev/null
+++ b/Platform/RaspberryPi/Include/Library/FdtPlatformLib.h
@@ -0,0 +1,18 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __FDT_PLATFORM_LIB_H__
+#define __FDT_PLATFORM_LIB_H__
+
+VOID *
+EFIAPI
+FdtPlatformGetBase (
+ VOID
+ );
+
+#endif /* __FDT_PLATFORM_LIB_H__ */
diff --git a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h b/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
index c48bb6e4..86bf1687 100644
--- a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
+++ b/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
@@ -112,42 +112,12 @@ EFI_STATUS
UINT32 *Revision
);
-typedef
-CHAR8*
-(EFIAPI *GET_MODEL_NAME) (
- INTN ModelId
- );
-
-typedef
-EFI_STATUS
-(EFIAPI *GET_MODEL_FAMILY) (
- UINT32 *ModelFamily
- );
-
typedef
EFI_STATUS
(EFIAPI *GET_FIRMWARE_REVISION) (
UINT32 *Revision
);
-typedef
-EFI_STATUS
-(EFIAPI *GET_MODEL_INSTALLED_MB) (
- UINT32 *InstalledMB
- );
-
-typedef
-CHAR8*
-(EFIAPI *GET_MANUFACTURER_NAME) (
- INTN ManufacturerId
- );
-
-typedef
-CHAR8*
-(EFIAPI *GET_CPU_NAME) (
- INTN CpuId
- );
-
typedef
EFI_STATUS
(EFIAPI *GET_ARM_MEM) (
@@ -186,13 +156,8 @@ typedef struct {
GET_SERIAL GetSerial;
GET_MODEL GetModel;
GET_MODEL_REVISION GetModelRevision;
- GET_MODEL_NAME GetModelName;
- GET_MODEL_FAMILY GetModelFamily;
GET_FIRMWARE_REVISION GetFirmwareRevision;
- GET_MANUFACTURER_NAME GetManufacturerName;
- GET_CPU_NAME GetCpuName;
GET_ARM_MEM GetArmMem;
- GET_MODEL_INSTALLED_MB GetModelInstalledMB;
NOTIFY_XHCI_RESET NotifyXhciReset;
GET_CLOCK_STATE GetClockState;
SET_CLOCK_STATE SetClockState;
diff --git a/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.c b/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.c
new file mode 100644
index 00000000..514ad7fe
--- /dev/null
+++ b/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.c
@@ -0,0 +1,78 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Uefi.h>
+#include <Library/BoardInfoLib.h>
+#include <Library/FdtPlatformLib.h>
+#include <libfdt.h>
+
+EFI_STATUS
+EFIAPI
+BoardInfoGetRevisionCode (
+ OUT UINT32 *RevisionCode
+ )
+{
+ VOID *Fdt;
+ INT32 Node;
+ CONST VOID *Property;
+ INT32 Length;
+
+ Fdt = FdtPlatformGetBase ();
+ if (Fdt == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Node = fdt_path_offset (Fdt, "/system");
+ if (Node < 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ Property = fdt_getprop (Fdt, Node, "linux,revision", &Length);
+ if (Property == NULL) {
+ return EFI_NOT_FOUND;
+ } else if (Length != sizeof (UINT32)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ *RevisionCode = fdt32_to_cpu (*(UINT32 *) Property);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInfoGetSerialNumber (
+ OUT UINT64 *SerialNumber
+ )
+{
+ VOID *Fdt;
+ INT32 Node;
+ CONST VOID *Property;
+ INT32 Length;
+
+ Fdt = FdtPlatformGetBase ();
+ if (Fdt == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Node = fdt_path_offset (Fdt, "/system");
+ if (Node < 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ Property = fdt_getprop (Fdt, Node, "linux,serial", &Length);
+ if (Property == NULL) {
+ return EFI_NOT_FOUND;
+ } else if (Length != sizeof (UINT64)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ *SerialNumber = fdt64_to_cpu (*(UINT64 *) Property);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf b/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
new file mode 100644
index 00000000..13623fb7
--- /dev/null
+++ b/Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
@@ -0,0 +1,27 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = BoardInfoLib
+ FILE_GUID = 88b5ad3d-d7a0-4525-932b-af97f0fe1310
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInfoLib
+
+[Sources]
+ BoardInfoLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Platform/RaspberryPi/RaspberryPi.dec
+
+[LibraryClasses]
+ FdtPlatformLib
+ FdtLib
diff --git a/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.c b/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.c
new file mode 100644
index 00000000..d120bb6d
--- /dev/null
+++ b/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.c
@@ -0,0 +1,153 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Uefi.h>
+#include <Library/BoardRevisionHelperLib.h>
+
+//
+// https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#new-style-revision-codes
+//
+#define RPI_MEMORY_SIZE(Rev) ((Rev >> 20) & 0x07)
+#define RPI_MANUFACTURER(Rev) ((Rev >> 16) & 0x0F)
+#define RPI_PROCESSOR(Rev) ((Rev >> 12) & 0x0F)
+#define RPI_TYPE(Rev) ((Rev >> 4) & 0xFF)
+
+UINT64
+EFIAPI
+BoardRevisionGetMemorySize (
+ IN UINT32 RevisionCode
+ )
+{
+ if (RevisionCode != 0) {
+ return SIZE_256MB * 1ULL << RPI_MEMORY_SIZE (RevisionCode);
+ }
+ return SIZE_256MB; // Smallest possible size
+}
+
+UINT32
+EFIAPI
+BoardRevisionGetModelFamily (
+ IN UINT32 RevisionCode
+ )
+{
+ if (RevisionCode != 0) {
+ switch (RPI_TYPE (RevisionCode)) {
+ case 0x00: // Raspberry Pi Model A
+ case 0x01: // Raspberry Pi Model B
+ case 0x02: // Raspberry Pi Model A+
+ case 0x03: // Raspberry Pi Model B+
+ case 0x06: // Raspberry Pi Compute Module 1
+ case 0x09: // Raspberry Pi Zero
+ case 0x0C: // Raspberry Pi Zero W
+ return 1;
+ case 0x04: // Raspberry Pi 2 Model B
+ return 2;
+ case 0x08: // Raspberry Pi 3 Model B
+ case 0x0A: // Raspberry Pi Compute Module 3
+ case 0x0D: // Raspberry Pi 3 Model B+
+ case 0x0E: // Raspberry Pi 3 Model A+
+ case 0x10: // Raspberry Pi Compute Module 3+
+ return 3;
+ case 0x11: // Raspberry Pi 4 Model B
+ case 0x13: // Raspberry Pi 400
+ case 0x14: // Raspberry Pi Computer Module 4
+ return 4;
+ }
+ }
+ return 0;
+}
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetModelName (
+ IN UINT32 RevisionCode
+ )
+{
+ if (RevisionCode != 0) {
+ switch (RPI_TYPE (RevisionCode)) {
+ case 0x00:
+ return "Raspberry Pi Model A";
+ case 0x01:
+ return "Raspberry Pi Model B";
+ case 0x02:
+ return "Raspberry Pi Model A+";
+ case 0x03:
+ return "Raspberry Pi Model B+";
+ case 0x04:
+ return "Raspberry Pi 2 Model B";
+ case 0x06:
+ return "Raspberry Pi Compute Module 1";
+ case 0x08:
+ return "Raspberry Pi 3 Model B";
+ case 0x09:
+ return "Raspberry Pi Zero";
+ case 0x0A:
+ return "Raspberry Pi Compute Module 3";
+ case 0x0C:
+ return "Raspberry Pi Zero W";
+ case 0x0D:
+ return "Raspberry Pi 3 Model B+";
+ case 0x0E:
+ return "Raspberry Pi 3 Model A+";
+ case 0x10:
+ return "Raspberry Pi Compute Module 3+";
+ case 0x11:
+ return "Raspberry Pi 4 Model B";
+ case 0x13:
+ return "Raspberry Pi 400";
+ case 0x14:
+ return "Raspberry Pi Compute Module 4";
+ }
+ }
+ return "Unknown Raspberry Pi Model";
+}
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetManufacturerName (
+ IN UINT32 RevisionCode
+ )
+{
+ if (RevisionCode != 0) {
+ switch (RPI_MANUFACTURER (RevisionCode)) {
+ case 0x00:
+ return "Sony UK";
+ case 0x01:
+ return "Egoman";
+ case 0x02:
+ case 0x04:
+ return "Embest";
+ case 0x03:
+ return "Sony Japan";
+ case 0x05:
+ return "Stadium";
+ }
+ }
+ return "Unknown Manufacturer";
+}
+
+CHAR8 *
+EFIAPI
+BoardRevisionGetProcessorName (
+ IN UINT32 RevisionCode
+ )
+{
+ if (RevisionCode != 0) {
+ switch (RPI_PROCESSOR (RevisionCode)) {
+ case 0x00:
+ return "BCM2835 (ARM11)";
+ case 0x01:
+ return "BCM2836 (Arm Cortex-A7)";
+ case 0x02:
+ return "BCM2837 (Arm Cortex-A53)";
+ case 0x03:
+ return "BCM2711 (Arm Cortex-A72)";
+ }
+ }
+ return "Unknown CPU Model";
+}
diff --git a/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf b/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf
new file mode 100644
index 00000000..d00f9236
--- /dev/null
+++ b/Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf
@@ -0,0 +1,22 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = BoardRevisionHelperLib
+ FILE_GUID = 6c0bda11-145b-4dc1-a923-5595135e597c
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardRevisionHelperLib
+
+[Sources]
+ BoardRevisionHelperLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Platform/RaspberryPi/RaspberryPi.dec
diff --git a/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.c b/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.c
new file mode 100644
index 00000000..7d148c01
--- /dev/null
+++ b/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.c
@@ -0,0 +1,32 @@
+/** @file
+ *
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Library/DebugLib.h>
+#include <Library/FdtPlatformLib.h>
+#include <libfdt.h>
+
+VOID *
+EFIAPI
+FdtPlatformGetBase (
+ VOID
+ )
+{
+ VOID *Fdt;
+ INT32 FdtError;
+
+ Fdt = (VOID *)(UINTN) PcdGet32 (PcdFdtBaseAddress);
+
+ FdtError = fdt_check_header (Fdt);
+ if (FdtError != 0) {
+ DEBUG ((DEBUG_ERROR, "%a: Bad/missing FDT at 0x%p! Ret=%a\n",
+ __func__, Fdt, fdt_strerror (FdtError)));
+ ASSERT (FALSE);
+ return NULL;
+ }
+ return Fdt;
+}
diff --git a/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf b/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
new file mode 100644
index 00000000..b35106c6
--- /dev/null
+++ b/Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = FdtPlatformLib
+ FILE_GUID = 473305de-3504-4efb-b223-65b845e08ac0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FdtPlatformLib
+
+[Sources]
+ FdtPlatformLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Platform/RaspberryPi/RaspberryPi.dec
+
+[LibraryClasses]
+ DebugLib
+ FdtLib
+
+[Pcd]
+ gRaspberryPiTokenSpaceGuid.PcdFdtBaseAddress
diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3/RPi3.dsc
index 5e90f421..9c549ac7 100644
--- a/Platform/RaspberryPi/RPi3/RPi3.dsc
+++ b/Platform/RaspberryPi/RPi3/RPi3.dsc
@@ -181,6 +181,10 @@
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
GpioLib|Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf
+ FdtPlatformLib|Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
+ BoardInfoLib|Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
+ BoardRevisionHelperLib|Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
diff --git a/Platform/RaspberryPi/RPi4/RPi4.dsc b/Platform/RaspberryPi/RPi4/RPi4.dsc
index 4ab6a819..ba839fd1 100644
--- a/Platform/RaspberryPi/RPi4/RPi4.dsc
+++ b/Platform/RaspberryPi/RPi4/RPi4.dsc
@@ -189,6 +189,10 @@
# The "segment lib" provides the CAM accessors/etc when they aren't ECAM standard
PciSegmentLib|Silicon/Broadcom/Bcm27xx/Library/Bcm2711PciSegmentLib/PciSegmentLib.inf
+ FdtPlatformLib|Platform/RaspberryPi/Library/FdtPlatformLib/FdtPlatformLib.inf
+ BoardInfoLib|Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf
+ BoardRevisionHelperLib|Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
--
2.51.2