Skip to content

Commit

Permalink
Platforms/RPi3: Add multiple embedded Device Tree selection
Browse files Browse the repository at this point in the history
The Raspberry Pi 3 platform currently has 2 different models, each with a
different Device Tree. Rather than embedding a single one, and requiring
users to manually provide the other, this patch ensures that we now embed
both and and serve the relevant one at runtime.

This patch also adds support for the Raspberry Pi 4 in FdtDxe.

Signed-off-by: Pete Batard <pete@akeo.ie>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
  • Loading branch information
pbatard authored and Leif Lindholm committed Aug 16, 2019
1 parent ab52a57 commit 7da906b
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
56 changes: 50 additions & 6 deletions Platform/RaspberryPi/RPi3/Drivers/FdtDxe/FdtDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,11 @@ FdtDxeInitialize (
)
{
EFI_STATUS Status;
EFI_GUID *FdtGuid;
VOID *FdtImage;
UINTN FdtSize;
INT32 Retval;
UINT32 BoardRevision;
BOOLEAN Internal;

Status = gBS->LocateProtocol (&gRaspberryPiFirmwareProtocolGuid, NULL,
Expand All @@ -386,16 +388,58 @@ FdtDxeInitialize (
DEBUG ((DEBUG_INFO, "Device Tree passed via config.txt (0x%lx bytes)\n", FdtSize));
Status = EFI_SUCCESS;
} else {
/*
* Use one of the embedded FDT's.
*/
Internal = TRUE;
DEBUG ((DEBUG_INFO, "No/Bad Device Tree found at address 0x%p (%a), "
"trying internal one...\n", FdtImage, fdt_strerror (Retval)));
Status = GetSectionFromAnyFv (&gRaspberryPiFdtFileGuid, EFI_SECTION_RAW, 0,
&FdtImage, &FdtSize);
if (Status == EFI_SUCCESS) {
if (fdt_check_header (FdtImage) != 0) {
Status = EFI_INCOMPATIBLE_VERSION;
"looking up internal one...\n", FdtImage, fdt_strerror (Retval)));
/*
* Query the board revision to differentiate between models.
*/
Status = mFwProtocol->GetModelRevision (&BoardRevision);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to get board type: %r\n", Status));
DEBUG ((DEBUG_INFO, "Using default internal Device Tree\n"));
FdtGuid = &gRaspberryPiDefaultFdtGuid;
} else {
// www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
switch ((BoardRevision >> 4) & 0xFF) {
case 0x08:
DEBUG ((DEBUG_INFO, "Using Raspberry Pi 3 Model B internal Device Tree\n"));
FdtGuid = &gRaspberryPi3ModelBFdtGuid;
break;
case 0x0D:
DEBUG ((DEBUG_INFO, "Using Raspberry Pi 3 Model B+ internal Device Tree\n"));
FdtGuid = &gRaspberryPi3ModelBPlusFdtGuid;
break;
case 0x11:
DEBUG ((DEBUG_INFO, "Using Raspberry Pi 4 Model B internal Device Tree\n"));
FdtGuid = &gRaspberryPi4ModelBFdtGuid;
break;
default:
DEBUG ((DEBUG_INFO, "Using default internal Device Tree\n"));
FdtGuid = &gRaspberryPiDefaultFdtGuid;
break;
}
}
do {
Status = GetSectionFromAnyFv (FdtGuid, EFI_SECTION_RAW, 0, &FdtImage, &FdtSize);
if (Status == EFI_SUCCESS) {
if (fdt_check_header (FdtImage) != 0) {
Status = EFI_INCOMPATIBLE_VERSION;
}
}
// No retry needed if we are successful or are dealing with the default Fdt.
if ( (Status == EFI_SUCCESS) ||
(CompareGuid (FdtGuid, &gRaspberryPiDefaultFdtGuid)) )
break;
// Otherwise, try one more time with the default Fdt. An example of this
// is if we detected a non-default Fdt, that isn't included in the FDF.
DEBUG ((DEBUG_INFO, "Internal Device Tree was not found for this platform, "
"falling back to default...\n"));
FdtGuid = &gRaspberryPiDefaultFdtGuid;
} while (1);
}

if (EFI_ERROR (Status)) {
Expand Down
5 changes: 4 additions & 1 deletion Platform/RaspberryPi/RPi3/Drivers/FdtDxe/FdtDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@

[Guids]
gFdtTableGuid
gRaspberryPiFdtFileGuid
gRaspberryPi3ModelBFdtGuid
gRaspberryPi3ModelBPlusFdtGuid
gRaspberryPi4ModelBFdtGuid
gRaspberryPiDefaultFdtGuid

[Protocols]
gRaspberryPiFirmwareProtocolGuid ## CONSUMES
Expand Down
8 changes: 7 additions & 1 deletion Platform/RaspberryPi/RPi3/RPi3.dec
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@

[Guids]
gRaspberryPiTokenSpaceGuid = {0xCD7CC258, 0x31DB, 0x11E6, {0x9F, 0xD3, 0x63, 0xB0, 0xB8, 0xEE, 0xD6, 0xB5}}
gRaspberryPiFdtFileGuid = {0xDF5DA223, 0x1D27, 0x47C3, { 0x8D, 0x1B, 0x9A, 0x41, 0xB5, 0x5A, 0x18, 0xBC}}
gRaspberryPiEventResetGuid = {0xCD7CC258, 0x31DB, 0x11E6, {0x9F, 0xD3, 0x63, 0xB4, 0xB4, 0xE4, 0xD4, 0xB4}}
gConfigDxeFormSetGuid = {0xCD7CC258, 0x31DB, 0x22E6, {0x9F, 0x22, 0x63, 0xB0, 0xB8, 0xEE, 0xD6, 0xB5}}
# GUIDs used by FdtDxe to serve a Device Tree at runtime. Not all of these need to apply
# to the current platform or match an actual FDF binary, but they need to be defined.
gRaspberryPi3ModelBFdtGuid = { 0xDF5DA223, 0x1D27, 0x47C3, { 0x8D, 0x1B, 0x9A, 0x41, 0xB5, 0x5A, 0x18, 0xBC } }
gRaspberryPi3ModelBPlusFdtGuid = { 0x3D523012, 0x73FE, 0x40E5, { 0x89, 0x2E, 0x1A, 0x4D, 0xF6, 0x0F, 0x3C, 0x0C } }
gRaspberryPi4ModelBFdtGuid = { 0x80AB6833, 0xCAE4, 0x4CEE, { 0xB5, 0x9D, 0xEB, 0x20, 0x39, 0xB0, 0x55, 0x51 } }
# Default Fdt to serve if the hardware model can't be detected. Should match one of the above.
gRaspberryPiDefaultFdtGuid = {0xDF5DA223, 0x1D27, 0x47C3, { 0x8D, 0x1B, 0x9A, 0x41, 0xB5, 0x5A, 0x18, 0xBC}}

[PcdsFixedAtBuild.common]
gRaspberryPiTokenSpaceGuid.PcdFdtBaseAddress|0x10000|UINT32|0x00000001
Expand Down
6 changes: 5 additions & 1 deletion Platform/RaspberryPi/RPi3/RPi3.fdf
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,15 @@ READ_LOCK_STATUS = TRUE
INF Platform/RaspberryPi/$(PLATFORM_NAME)/Drivers/LogoDxe/LogoDxe.inf

#
# FDT (GUID matches gRaspberryPiFdtFileGuid in FdtDxe)
# Device Tree support (used by FdtDxe)
# GUIDs should match gRaspberryPi#####FdtGuid's from the .dec
#
FILE FREEFORM = DF5DA223-1D27-47C3-8D1B-9A41B55A18BC {
SECTION RAW = Platform/RaspberryPi/$(PLATFORM_NAME)/DeviceTree/bcm2710-rpi-3-b.dtb
}
FILE FREEFORM = 3D523012-73FE-40E5-892E-1A4DF60F3C0C {
SECTION RAW = Platform/RaspberryPi/$(PLATFORM_NAME)/DeviceTree/bcm2710-rpi-3-b-plus.dtb
}

[FV.FVMAIN_COMPACT]
FvAlignment = 16
Expand Down

0 comments on commit 7da906b

Please sign in to comment.