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/PreloaderEnvironment.h b/include/PreloaderEnvironment.h
index bf6354f..341d2c9 100644
--- a/include/PreloaderEnvironment.h
+++ b/include/PreloaderEnvironment.h
@@ -14,16 +14,36 @@
#define PRELOADER_ENV_ADDR 0xb0000000
#define PRELOADER_HEADER SIGNATURE_32('B', 'S', 'E', 'N')
-typedef struct _PRELOADER_ENVIRONMENT {
+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_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;
-} PRELOADER_ENVIRONMENT, *PPRELOADER_ENVIRONMENT;
+ UINT32 BootMode;
+ UINT32 EnablePlatformSdCardBoot;
+ UINT32 UseQuadCoreConfiguration;
+ UINT32 Crc32v2;
+} PRELOADER_ENVIRONMENT_VERSION_2, *PPRELOADER_ENVIRONMENT_VERSION_2;
#endif
-#define PRELOADER_VERSION 0x1000
+#define PRELOADER_VERSION 0x2000
#define PRELOADER_RELEASE "PreLoader Unknown Release"
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 97589af..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;
@@ -256,12 +266,16 @@ EFI_STATUS efi_main(
QCOM_PCIE_PROTOCOL *PCIExpressProtocol;
- PRELOADER_ENVIRONMENT PreloaderEnv;
+ PRELOADER_ENVIRONMENT_VERSION_2 PreloaderEnv;
UINT32 PreloaderEnvCrc32;
UINTN VarSize;
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,
@@ -528,10 +542,52 @@ EFI_STATUS efi_main(
goto exit;
}
+ PreloaderEnv.BootMode = BOOT_MODE_PSCI;
+ 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;
+
Status = gBS->CalculateCrc32(
&PreloaderEnv,
- sizeof(PreloaderEnv),
+ sizeof(PRELOADER_ENVIRONMENT_VERSION_1),
&PreloaderEnvCrc32
);
if (EFI_ERROR(Status))
@@ -541,6 +597,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,