From e1cd7431e1d903f04086406f0ea4041430f94ea7 Mon Sep 17 00:00:00 2001 From: Gustave Monce Date: Mon, 22 Jun 2020 18:11:12 +0200 Subject: [PATCH 1/3] Update preloader struct to contain boot options --- include/PreloaderEnvironment.h | 14 ++++++++++++-- src/EFIApp.c | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/PreloaderEnvironment.h b/include/PreloaderEnvironment.h index bf6354f..73069fe 100644 --- a/include/PreloaderEnvironment.h +++ b/include/PreloaderEnvironment.h @@ -12,7 +12,14 @@ #define __PRELOADER_ENV_H__ #define PRELOADER_ENV_ADDR 0xb0000000 -#define PRELOADER_HEADER SIGNATURE_32('B', 'S', 'E', 'N') +#define PRELOADER_HEADER SIGNATURE_32('B', 'S', 'E', '2') + +typedef enum _PRELOADER_ENVIRONMENT_BOOT_MODE { + BOOT_MODE_PSCI = 0, + BOOT_MODE_MPPARK, + BOOT_MODE_MPPARK_EL2, + BOOT_MODE_MAX +} PRELOADER_ENVIRONMENT_BOOT_MODE; typedef struct _PRELOADER_ENVIRONMENT { UINT32 Header; @@ -20,10 +27,13 @@ typedef struct _PRELOADER_ENVIRONMENT { CHAR8 PreloaderRelease[64]; EFI_TIME BootTimeEpoch; UINT32 UefiDisplayInfo[30]; + UINT32 BootMode; + UINT32 EnablePlatformSdCardBoot; + UINT32 UseQuadCoreConfiguration; UINT32 Crc32; } PRELOADER_ENVIRONMENT, *PPRELOADER_ENVIRONMENT; #endif -#define PRELOADER_VERSION 0x1000 +#define PRELOADER_VERSION 0x1001 #define PRELOADER_RELEASE "PreLoader Unknown Release" diff --git a/src/EFIApp.c b/src/EFIApp.c index 97589af..ac7f78d 100644 --- a/src/EFIApp.c +++ b/src/EFIApp.c @@ -528,6 +528,10 @@ EFI_STATUS efi_main( goto exit; } + PreloaderEnv.BootMode = BOOT_MODE_PSCI; + PreloaderEnv.EnablePlatformSdCardBoot = 1; + PreloaderEnv.UseQuadCoreConfiguration = 0; + PreloaderEnv.Crc32 = 0x0; Status = gBS->CalculateCrc32( &PreloaderEnv, From bfbd409e2ce5f3d7023c7040381a6b294574b855 Mon Sep 17 00:00:00 2001 From: Gustave Monce Date: Thu, 25 Jun 2020 14:21:34 +0200 Subject: [PATCH 2/3] Implement a better updated struct backwards compatible with older uefis --- include/PreloaderEnvironment.h | 20 +++++++++++++++----- src/EFIApp.c | 18 ++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/PreloaderEnvironment.h b/include/PreloaderEnvironment.h index 73069fe..341d2c9 100644 --- a/include/PreloaderEnvironment.h +++ b/include/PreloaderEnvironment.h @@ -12,7 +12,7 @@ #define __PRELOADER_ENV_H__ #define PRELOADER_ENV_ADDR 0xb0000000 -#define PRELOADER_HEADER SIGNATURE_32('B', 'S', 'E', '2') +#define PRELOADER_HEADER SIGNATURE_32('B', 'S', 'E', 'N') typedef enum _PRELOADER_ENVIRONMENT_BOOT_MODE { BOOT_MODE_PSCI = 0, @@ -21,19 +21,29 @@ typedef enum _PRELOADER_ENVIRONMENT_BOOT_MODE { BOOT_MODE_MAX } PRELOADER_ENVIRONMENT_BOOT_MODE; -typedef struct _PRELOADER_ENVIRONMENT { +typedef struct _PRELOADER_ENVIRONMENT_VERSION_1 { UINT32 Header; UINT32 PreloaderVersion; CHAR8 PreloaderRelease[64]; EFI_TIME BootTimeEpoch; UINT32 UefiDisplayInfo[30]; + UINT32 Crc32; +} PRELOADER_ENVIRONMENT_VERSION_1, * PPRELOADER_ENVIRONMENT_VERSION_1; + +typedef struct _PRELOADER_ENVIRONMENT_VERSION_2 { + UINT32 Header; + UINT32 PreloaderVersion; + CHAR8 PreloaderRelease[64]; + EFI_TIME BootTimeEpoch; + UINT32 UefiDisplayInfo[30]; + UINT32 Crc32; UINT32 BootMode; UINT32 EnablePlatformSdCardBoot; UINT32 UseQuadCoreConfiguration; - UINT32 Crc32; -} PRELOADER_ENVIRONMENT, *PPRELOADER_ENVIRONMENT; + UINT32 Crc32v2; +} PRELOADER_ENVIRONMENT_VERSION_2, *PPRELOADER_ENVIRONMENT_VERSION_2; #endif -#define PRELOADER_VERSION 0x1001 +#define PRELOADER_VERSION 0x2000 #define PRELOADER_RELEASE "PreLoader Unknown Release" diff --git a/src/EFIApp.c b/src/EFIApp.c index ac7f78d..675e330 100644 --- a/src/EFIApp.c +++ b/src/EFIApp.c @@ -256,7 +256,7 @@ EFI_STATUS efi_main( QCOM_PCIE_PROTOCOL *PCIExpressProtocol; - PRELOADER_ENVIRONMENT PreloaderEnv; + PRELOADER_ENVIRONMENT_VERSION_2 PreloaderEnv; UINT32 PreloaderEnvCrc32; UINTN VarSize; VOID* PreloaderEnvFinalDest; @@ -533,9 +533,11 @@ EFI_STATUS efi_main( PreloaderEnv.UseQuadCoreConfiguration = 0; PreloaderEnv.Crc32 = 0x0; + PreloaderEnv.Crc32v2 = 0x0; + Status = gBS->CalculateCrc32( &PreloaderEnv, - sizeof(PreloaderEnv), + sizeof(PRELOADER_ENVIRONMENT_VERSION_1), &PreloaderEnvCrc32 ); if (EFI_ERROR(Status)) @@ -545,6 +547,18 @@ EFI_STATUS efi_main( } PreloaderEnv.Crc32 = PreloaderEnvCrc32; + Status = gBS->CalculateCrc32( + &PreloaderEnv, + sizeof(PreloaderEnv), + &PreloaderEnvCrc32 + ); + if (EFI_ERROR(Status)) + { + Print(L"CRC32v2 calc failed \n"); + goto exit; + } + PreloaderEnv.Crc32v2 = PreloaderEnvCrc32; + // Relocate HOB Status = gBS->AllocatePages( AllocateAddress, From a1a346ae620c5639d59c91f3b57d081cdfbc5b06 Mon Sep 17 00:00:00 2001 From: Gustave Monce Date: Thu, 25 Jun 2020 17:10:23 +0200 Subject: [PATCH 3/3] Implement BCD option reading --- contrib/msvc/uefi-simple.vcxproj | 2 + contrib/msvc/uefi-simple.vcxproj.filters | 6 + include/BlBootConfiguration.h | 42 +++++++ include/application.h | 4 + src/BlApplicationEntry.c | 7 +- src/BlBootConfiguration.c | 139 +++++++++++++++++++++++ src/EFIApp.c | 50 ++++++++ 7 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 include/BlBootConfiguration.h create mode 100644 src/BlBootConfiguration.c diff --git a/contrib/msvc/uefi-simple.vcxproj b/contrib/msvc/uefi-simple.vcxproj index 053c8e2..9a23d30 100644 --- a/contrib/msvc/uefi-simple.vcxproj +++ b/contrib/msvc/uefi-simple.vcxproj @@ -157,10 +157,12 @@ + + diff --git a/contrib/msvc/uefi-simple.vcxproj.filters b/contrib/msvc/uefi-simple.vcxproj.filters index 5f3cb88..e07b01b 100644 --- a/contrib/msvc/uefi-simple.vcxproj.filters +++ b/contrib/msvc/uefi-simple.vcxproj.filters @@ -77,6 +77,9 @@ Header Files\Application + + Header Files\Application + @@ -88,6 +91,9 @@ Source Files\BootApp + + Source Files\BootApp + diff --git a/include/BlBootConfiguration.h b/include/BlBootConfiguration.h new file mode 100644 index 0000000..be6086b --- /dev/null +++ b/include/BlBootConfiguration.h @@ -0,0 +1,42 @@ +#pragma once +#ifndef _BOOTCONFIG_H_ + +#include +#include + +// Sup types +#include "suptypes.h" + +// Bootloader +#include "bl.h" +#include "context.h" + +typedef struct _BcdElementType +{ + union { + ULONG PackedValue; + struct { + ULONG SubType : 24; + ULONG Format : 4; + ULONG Class : 4; + }; + }; +} BcdElementType, * PBcdElementType; + +EFI_STATUS BlGetBootOptionBoolean( + PBL_BCD_OPTION List, + ULONG Type, + BOOLEAN* Value +); + +EFI_STATUS BlGetBootOptionInteger( + PBL_BCD_OPTION List, + ULONG Type, + UINT64* Value +); + +EFI_STATUS BlGetLoadedApplicationEntry( + PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, + PBL_LOADED_APPLICATION_ENTRY BlpApplicationEntry +); +#endif \ No newline at end of file diff --git a/include/application.h b/include/application.h index c06cfd1..32924ba 100644 --- a/include/application.h +++ b/include/application.h @@ -10,5 +10,9 @@ // Status enum #include "ntstatus.h" +// BCD +#include "BlBootConfiguration.h" + // Exports EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable); +EFI_STATUS EFIApp_Main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable, PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters); \ No newline at end of file diff --git a/src/BlApplicationEntry.c b/src/BlApplicationEntry.c index 1160d18..1d834a9 100644 --- a/src/BlApplicationEntry.c +++ b/src/BlApplicationEntry.c @@ -32,9 +32,10 @@ NTSTATUS BlApplicationEntry( // Do what ever you want now if (FirmwareDescriptor->SystemTable) { - efi_main( - FirmwareDescriptor->ImageHandle, - FirmwareDescriptor->SystemTable + EFIApp_Main( + FirmwareDescriptor->ImageHandle, + FirmwareDescriptor->SystemTable, + BootAppParameters ); } diff --git a/src/BlBootConfiguration.c b/src/BlBootConfiguration.c new file mode 100644 index 0000000..88fb266 --- /dev/null +++ b/src/BlBootConfiguration.c @@ -0,0 +1,139 @@ +#include +#include + +#include "application.h" + +EFI_STATUS MiscGetBootOption( + _In_ PBL_BCD_OPTION List, + _In_ ULONG Type) +{ + uint32_t NextOption = 0, ListOption; + PBL_BCD_OPTION Option, FoundOption; + + /* No options, bail out */ + if (!List) + { + return EFI_SUCCESS; + } + + /* Loop while we find an option */ + FoundOption = NULL; + do + { + /* Get the next option and see if it matches the type */ + Option = (PBL_BCD_OPTION)((uint32_t)List + NextOption); + if ((Option->Type == Type) && !(Option->Empty)) + { + FoundOption = Option; + break; + } + + /* Store the offset of the next option */ + NextOption = Option->NextEntryOffset; + + /* Failed to match. Check for list options */ + ListOption = Option->ListOffset; + if (ListOption) + { + /* Try to get a match in the associated option */ + Option = MiscGetBootOption((PBL_BCD_OPTION)((uint32_t)Option + + ListOption), + Type); + if (Option) + { + /* Return it */ + FoundOption = Option; + break; + } + } + } while (NextOption); + + /* Return the option that was found, if any */ + return FoundOption; +} + +EFI_STATUS BlGetLoadedApplicationEntry( + _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, + _Out_ PBL_LOADED_APPLICATION_ENTRY BlpApplicationEntry) +{ + PBL_APPLICATION_ENTRY AppEntry; + uint32_t ParamPointer; + + ParamPointer = (uint32_t)BootAppParameters; + AppEntry = (PBL_APPLICATION_ENTRY)(ParamPointer + BootAppParameters->AppEntryOffset); + + /* Check if the caller sent us their internal BCD options */ + if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL) + { + /* These are external to us now, as far as we are concerned */ + AppEntry->Flags &= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL; + AppEntry->Flags |= BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL; + } + + /* Save the application entry flags */ + BlpApplicationEntry->Flags = AppEntry->Flags; + + /* Copy the GUID and point to the options */ + BlpApplicationEntry->EFI_GUID = AppEntry->EFI_GUID; + BlpApplicationEntry->BcdData = &AppEntry->BcdData; + + return EFI_SUCCESS; +} + +EFI_STATUS BlGetBootOptionInteger( + _In_ PBL_BCD_OPTION List, + _In_ ULONG Type, + _Out_ UINT64* Value) +{ + NTSTATUS Status; + PBL_BCD_OPTION Option; + BcdElementType ElementType; + + /* Make sure this is a BCD_TYPE_INTEGER */ + ElementType.PackedValue = Type; + if (ElementType.Format != 0x05) + { + return STATUS_INVALID_PARAMETER; + } + + /* Return the data */ + Option = MiscGetBootOption(List, Type); + if (Option) + { + *Value = *(UINT64*)((uint32_t)Option + Option->DataOffset); + } + + /* Option found */ + Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND; + + return Status; +} + +EFI_STATUS BlGetBootOptionBoolean( + _In_ PBL_BCD_OPTION List, + _In_ ULONG Type, + _Out_ BOOLEAN* Value) +{ + NTSTATUS Status; + PBL_BCD_OPTION Option; + BcdElementType ElementType; + + /* Make sure this is a BCD_TYPE_BOOLEAN */ + ElementType.PackedValue = Type; + if (ElementType.Format != 0x06) + { + return STATUS_INVALID_PARAMETER; + } + + /* Return the data */ + Option = MiscGetBootOption(List, Type); + if (Option) + { + *Value = *(BOOLEAN*)((uint32_t)Option + Option->DataOffset); + } + + /* Option found */ + Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND; + + return Status; +} \ No newline at end of file diff --git a/src/EFIApp.c b/src/EFIApp.c index 675e330..cf82539 100644 --- a/src/EFIApp.c +++ b/src/EFIApp.c @@ -2,6 +2,8 @@ #include "scm.h" #include "PCIe.h" #include "PreloaderEnvironment.h" +#include "BlBootConfiguration.h" +#include "application.h" VOID JumpToAddressAArch64( EFI_HANDLE ImageHandle, @@ -230,7 +232,15 @@ EFI_STATUS efi_main( EFI_SYSTEM_TABLE *SystemTable ) { + return EFIApp_Main(ImageHandle, SystemTable, NULL); +} +EFI_STATUS EFIApp_Main( + EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE* SystemTable, + PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters +) +{ EFI_STATUS Status = EFI_SUCCESS; UINTN NumHandles = 0; @@ -262,6 +272,10 @@ EFI_STATUS efi_main( VOID* PreloaderEnvFinalDest; EFI_PHYSICAL_ADDRESS PreloaderEnvAddr = PRELOADER_ENV_ADDR; + BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry; + UINT64 BcdIntegerValue = 0; + BOOLEAN BcdBoolValue = FALSE; + #if defined(_GNU_EFI) InitializeLib( ImageHandle, @@ -532,6 +546,42 @@ EFI_STATUS efi_main( PreloaderEnv.EnablePlatformSdCardBoot = 1; PreloaderEnv.UseQuadCoreConfiguration = 0; + if (BootAppParameters != NULL) + { + BlGetLoadedApplicationEntry(BootAppParameters, + &BlpApplicationEntry); + + // Boot mode + Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData, + 0x25133701, + (UINT64*)&BcdIntegerValue); + if (!EFI_ERROR(Status)) + { + if (BcdIntegerValue >= 0 && BcdIntegerValue < BOOT_MODE_MAX) + { + PreloaderEnv.BootMode = (UINT32)BcdIntegerValue; + } + } + + // Sd card support + Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData, + 0x26133701, + (BOOLEAN*)&BcdBoolValue); + if (!EFI_ERROR(Status)) + { + PreloaderEnv.EnablePlatformSdCardBoot = BcdBoolValue; + } + + // Force Quad Core for MPPARK EL2 + Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData, + 0x26133702, + (BOOLEAN*)&BcdBoolValue); + if (!EFI_ERROR(Status)) + { + PreloaderEnv.UseQuadCoreConfiguration = BcdBoolValue; + } + } + PreloaderEnv.Crc32 = 0x0; PreloaderEnv.Crc32v2 = 0x0;