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