Platforms/HiKey960Dxe: support abootimg protocol interface
Support to append kernel args and update DTB.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960.dsc b/Platforms/Hisilicon/HiKey960/HiKey960.dsc
index c77a682..ebba558 100644
--- a/Platforms/Hisilicon/HiKey960/HiKey960.dsc
+++ b/Platforms/Hisilicon/HiKey960/HiKey960.dsc
@@ -165,7 +165,7 @@
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
[BuildOptions]
- GCC:*_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/MdeModulePkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Include
+ GCC:*_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/MdeModulePkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Include -I$(WORKSPACE)/EmbeddedPkg/Include
[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c
index 44fd744..bf917be 100644
--- a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c
+++ b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c
@@ -16,7 +16,9 @@
#include <Hi3660.h>
#include <Hkadc.h>
+#include <libfdt.h>
+#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
@@ -28,6 +30,7 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/Abootimg.h>
#include <Protocol/NonDiscoverableDevice.h>
#define ADC_ADCIN0 0
@@ -60,6 +63,16 @@
#define BOARDID3_BASE 5
+#define HIKEY960_BOARDID_V1 5300
+#define HIKEY960_BOARDID_V2 5301
+
+#define HIKEY960_COMPATIBLE_LEDS_V1 "gpio-leds_v1"
+#define HIKEY960_COMPATIBLE_LEDS_V2 "gpio-leds_v2"
+#define HIKEY960_COMPATIBLE_HUB_V1 "hisilicon,gpio_hubv1"
+#define HIKEY960_COMPATIBLE_HUB_V2 "hisilicon,gpio_hubv2"
+
+STATIC UINTN mBoardId;
+
STATIC
VOID
InitAdc (
@@ -241,6 +254,125 @@
EFI_STATUS
EFIAPI
+AbootimgAppendKernelArgs (
+ IN CHAR16 *Args,
+ IN UINTN Size
+ )
+{
+ if (Args == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (mBoardId == HIKEY960_BOARDID_V1) {
+ StrCatS (Args, Size, L" earlycon=pl011,0xfdf05000,115200 console=ttyAMA5");
+ } else {
+ StrCatS (Args, Size, L" earlycon=pl011,0xfff32000,115200 console=ttyAMA6");
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AbootimgUpdateDtb (
+ IN EFI_PHYSICAL_ADDRESS OrigFdtBase,
+ OUT EFI_PHYSICAL_ADDRESS *NewFdtBase
+ )
+{
+ //UINT8 *FdtPtr;
+ UINTN FdtSize, NumPages;
+ INTN err, offset;
+ EFI_STATUS Status;
+
+ //
+ // Sanity checks on the original FDT blob.
+ //
+ err = fdt_check_header ((VOID*)(UINTN)OrigFdtBase);
+ if (err != 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (err:%d)\n", err));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Store the FDT as Runtime Service Data to prevent the Kernel from
+ // overwritting its data.
+ //
+ FdtSize = fdt_totalsize ((VOID *)(UINTN)OrigFdtBase);
+ NumPages = EFI_SIZE_TO_PAGES (FdtSize) + 20;
+ Status = gBS->AllocatePages (
+ AllocateAnyPages, EfiRuntimeServicesData,
+ NumPages, NewFdtBase);
+ if (EFI_ERROR (Status)) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CopyMem (
+ (VOID*)(UINTN)*NewFdtBase,
+ (VOID*)(UINTN)OrigFdtBase,
+ FdtSize
+ );
+
+ if (mBoardId == HIKEY960_BOARDID_V1) {
+ offset = fdt_node_offset_by_compatible (
+ (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_LEDS_V1
+ );
+ } else {
+ offset = fdt_node_offset_by_compatible (
+ (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_LEDS_V2
+ );
+ }
+ if (offset < 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Failed to find node with compatible (err:%d)\n", err));
+ gBS->FreePages (*NewFdtBase, NumPages);
+ return EFI_INVALID_PARAMETER;
+ }
+ err = fdt_setprop_string ((VOID*)(UINTN)*NewFdtBase, offset, "status", "ok");
+ if (err) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Failed to update status property\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ err = fdt_set_name ((VOID*)(UINTN)*NewFdtBase, offset, "gpio-leds");
+ if (err) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Failed to update compatible name\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mBoardId == HIKEY960_BOARDID_V1) {
+ offset = fdt_node_offset_by_compatible (
+ (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_HUB_V1
+ );
+ } else {
+ offset = fdt_node_offset_by_compatible (
+ (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_HUB_V2
+ );
+ }
+ if (offset < 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Failed to find node with compatible (err:%d)\n", err));
+ gBS->FreePages (*NewFdtBase, NumPages);
+ return EFI_INVALID_PARAMETER;
+ }
+ err = fdt_setprop_string ((VOID*)(UINTN)*NewFdtBase, offset, "status", "ok");
+ if (err) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Failed to update status property\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ fdt_pack ((VOID*)(UINTN)*NewFdtBase);
+ err = fdt_check_header ((VOID*)(UINTN)*NewFdtBase);
+ if (err != 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (err:%d)\n", err));
+ gBS->FreePages (*NewFdtBase, NumPages);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+ABOOTIMG_PROTOCOL mAbootimg = {
+ AbootimgAppendKernelArgs,
+ AbootimgUpdateDtb
+};
+
+EFI_STATUS
+EFIAPI
HiKey960EntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
@@ -248,9 +380,8 @@
{
EFI_STATUS Status;
EFI_EVENT EndOfDxeEvent;
- UINTN BoardId;
- Status = InitBoardId (&BoardId);
+ Status = InitBoardId (&mBoardId);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -270,6 +401,9 @@
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
// RegisterNonDicoverableMmioDevice
Status = RegisterNonDiscoverableMmioDevice (
@@ -281,6 +415,16 @@
FixedPcdGet32 (PcdDwUfsHcDxeBaseAddress),
SIZE_4KB
);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gAbootimgProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mAbootimg
+ );
return Status;
}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
index bffd70c..87fd435 100644
--- a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
+++ b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
@@ -22,6 +22,7 @@
HiKey960Dxe.c
[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OpenPlatformPkg/Drivers/Block/DwUfsHcDxe/DwUfsHcDxe.dec
@@ -30,6 +31,7 @@
BaseMemoryLib
DebugLib
DxeServicesTableLib
+ FdtLib
IoLib
NonDiscoverableDeviceRegistrationLib
PcdLib
@@ -40,6 +42,9 @@
UefiLib
UefiRuntimeServicesTableLib
+[Protocols]
+ gAbootimgProtocolGuid
+
[Guids]
gEfiEndOfDxeEventGroupGuid
gEfiFileInfoGuid