Home | History | Annotate | Download | only in HiKey960Dxe
      1 /** @file
      2 *
      3 *  Copyright (c) 2016-2017, Linaro Ltd. All rights reserved.
      4 *
      5 *  This program and the accompanying materials
      6 *  are licensed and made available under the terms and conditions of the BSD License
      7 *  which accompanies this distribution.  The full text of the license may be found at
      8 *  http://opensource.org/licenses/bsd-license.php
      9 *
     10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 *
     13 **/
     14 
     15 #include <Guid/EventGroup.h>
     16 #include <Guid/HiKey960Variable.h>
     17 
     18 #include <Hi3660.h>
     19 #include <Hkadc.h>
     20 #include <libfdt.h>
     21 
     22 #include <Library/BaseLib.h>
     23 #include <Library/BaseMemoryLib.h>
     24 #include <Library/CacheMaintenanceLib.h>
     25 #include <Library/DebugLib.h>
     26 #include <Library/DevicePathLib.h>
     27 #include <Library/MemoryAllocationLib.h>
     28 #include <Library/NonDiscoverableDeviceRegistrationLib.h>
     29 #include <Library/IoLib.h>
     30 #include <Library/PcdLib.h>
     31 #include <Library/PrintLib.h>
     32 #include <Library/SerialPortLib.h>
     33 #include <Library/TimerLib.h>
     34 #include <Library/UefiBootServicesTableLib.h>
     35 #include <Library/UefiRuntimeServicesTableLib.h>
     36 
     37 #include <Protocol/Abootimg.h>
     38 #include <Protocol/BlockIo.h>
     39 #include <Protocol/DevicePathToText.h>
     40 #include <Protocol/EmbeddedGpio.h>
     41 #include <Protocol/NonDiscoverableDevice.h>
     42 #include <Protocol/PlatformVirtualKeyboard.h>
     43 
     44 #define ADC_ADCIN0                       0
     45 #define ADC_ADCIN1                       1
     46 #define ADC_ADCIN2                       2
     47 
     48 #define HKADC_DATA_GRADE0                0
     49 #define HKADC_DATA_GRADE1                100
     50 #define HKADC_DATA_GRADE2                300
     51 #define HKADC_DATA_GRADE3                500
     52 #define HKADC_DATA_GRADE4                700
     53 #define HKADC_DATA_GRADE5                900
     54 #define HKADC_DATA_GRADE6                1100
     55 #define HKADC_DATA_GRADE7                1300
     56 #define HKADC_DATA_GRADE8                1500
     57 #define HKADC_DATA_GRADE9                1700
     58 #define HKADC_DATA_GRADE10               1800
     59 
     60 #define BOARDID_VALUE0                   0
     61 #define BOARDID_VALUE1                   1
     62 #define BOARDID_VALUE2                   2
     63 #define BOARDID_VALUE3                   3
     64 #define BOARDID_VALUE4                   4
     65 #define BOARDID_VALUE5                   5
     66 #define BOARDID_VALUE6                   6
     67 #define BOARDID_VALUE7                   7
     68 #define BOARDID_VALUE8                   8
     69 #define BOARDID_VALUE9                   9
     70 #define BOARDID_UNKNOW                   0xF
     71 
     72 #define BOARDID3_BASE                    5
     73 
     74 #define HIKEY960_BOARDID_V1              5300
     75 #define HIKEY960_BOARDID_V2              5301
     76 
     77 #define HIKEY960_COMPATIBLE_LEDS_V1      "gpio-leds_v1"
     78 #define HIKEY960_COMPATIBLE_LEDS_V2      "gpio-leds_v2"
     79 #define HIKEY960_COMPATIBLE_HUB_V1       "hisilicon,gpio_hubv1"
     80 #define HIKEY960_COMPATIBLE_HUB_V2       "hisilicon,gpio_hubv2"
     81 
     82 #define SERIAL_NUMBER_SIZE               17
     83 #define SERIAL_NUMBER_BLOCK_SIZE         EFI_PAGE_SIZE
     84 #define SERIAL_NUMBER_LBA                20
     85 #define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
     86 #define RANDOM_MAGIC                     0x9A4DBEAF
     87 
     88 #define ADB_REBOOT_ADDRESS               0x32100000
     89 #define ADB_REBOOT_BOOTLOADER            0x77665500
     90 #define ADB_REBOOT_NONE                  0x77665501
     91 
     92 #define DETECT_SW_FASTBOOT               68        // GPIO8_4
     93 
     94 typedef struct {
     95   UINT64        Magic;
     96   UINT64        Data;
     97   CHAR16        UnicodeSN[SERIAL_NUMBER_SIZE];
     98 } RANDOM_SERIAL_NUMBER;
     99 
    100 enum {
    101   BOOT_MODE_RECOVERY  = 0,
    102   BOOT_MODE_NORMAL,
    103   BOOT_MODE_MASK = 1,
    104 };
    105 
    106 STATIC UINTN    mBoardId;
    107 STATIC UINTN    mRebootUpdated;
    108 STATIC UINTN    mRebootReason;
    109 
    110 STATIC EMBEDDED_GPIO   *mGpio;
    111 
    112 STATIC
    113 VOID
    114 InitAdc (
    115   VOID
    116   )
    117 {
    118   // reset hkadc
    119   MmioWrite32 (CRG_PERRSTEN2, PERRSTEN2_HKADCSSI);
    120   // wait a few clock cycles
    121   MicroSecondDelay (2);
    122   MmioWrite32 (CRG_PERRSTDIS2, PERRSTEN2_HKADCSSI);
    123   MicroSecondDelay (2);
    124   // enable hkadc clock
    125   MmioWrite32 (CRG_PERDIS2, PEREN2_HKADCSSI);
    126   MicroSecondDelay (2);
    127   MmioWrite32 (CRG_PEREN2, PEREN2_HKADCSSI);
    128   MicroSecondDelay (2);
    129 }
    130 
    131 STATIC
    132 EFI_STATUS
    133 AdcGetAdc (
    134   IN  UINTN         Channel,
    135   OUT UINTN         *Value
    136   )
    137 {
    138   UINT32            Data;
    139   UINT16            Value1, Value0;
    140 
    141   if (Channel > HKADC_CHANNEL_MAX) {
    142     DEBUG ((DEBUG_ERROR, "invalid channel:%d\n", Channel));
    143     return EFI_OUT_OF_RESOURCES;
    144   }
    145   // configure the read/write operation for external HKADC
    146   MmioWrite32 (HKADC_WR01_DATA, HKADC_WR01_VALUE | Channel);
    147   MmioWrite32 (HKADC_WR23_DATA, HKADC_WR23_VALUE);
    148   MmioWrite32 (HKADC_WR45_DATA, HKADC_WR45_VALUE);
    149   // configure the number of accessing registers
    150   MmioWrite32 (HKADC_WR_NUM, HKADC_WR_NUM_VALUE);
    151   // configure delay of accessing registers
    152   MmioWrite32 (HKADC_DELAY01, HKADC_CHANNEL0_DELAY01_VALUE);
    153   MmioWrite32 (HKADC_DELAY23, HKADC_DELAY23_VALUE);
    154 
    155   // start HKADC
    156   MmioWrite32 (HKADC_DSP_START, 1);
    157   do {
    158     Data = MmioRead32 (HKADC_DSP_START);
    159   } while (Data & 1);
    160 
    161   // convert AD result
    162   Value1 = (UINT16)MmioRead32 (HKADC_DSP_RD2_DATA);
    163   Value0 = (UINT16)MmioRead32 (HKADC_DSP_RD3_DATA);
    164 
    165   Data = ((Value1 << 4) & HKADC_VALUE_HIGH) | ((Value0 >> 4) & HKADC_VALUE_LOW);
    166   *Value = Data;
    167   return EFI_SUCCESS;
    168 }
    169 
    170 STATIC
    171 EFI_STATUS
    172 AdcGetValue (
    173   IN UINTN         Channel,
    174   IN OUT UINTN     *Value
    175   )
    176 {
    177   EFI_STATUS       Status;
    178   UINTN            Result;
    179 
    180   Status = AdcGetAdc (Channel, Value);
    181   if (EFI_ERROR (Status)) {
    182     return Status;
    183   }
    184 
    185   // convert ADC value to micro-volt
    186   Result = ((*Value & HKADC_VALID_VALUE) * HKADC_VREF_1V8) / HKADC_ACCURACY;
    187   *Value = Result;
    188   return EFI_SUCCESS;
    189 }
    190 
    191 STATIC
    192 UINTN
    193 AdcinDataRemap (
    194   IN UINTN           AdcinValue
    195   )
    196 {
    197   UINTN              Result;
    198 
    199   if (AdcinValue < HKADC_DATA_GRADE0) {
    200     Result = BOARDID_UNKNOW;
    201   } else if (AdcinValue < HKADC_DATA_GRADE1) {
    202     Result = BOARDID_VALUE0;
    203   } else if (AdcinValue < HKADC_DATA_GRADE2) {
    204     Result = BOARDID_VALUE1;
    205   } else if (AdcinValue < HKADC_DATA_GRADE3) {
    206     Result = BOARDID_VALUE2;
    207   } else if (AdcinValue < HKADC_DATA_GRADE4) {
    208     Result = BOARDID_VALUE3;
    209   } else if (AdcinValue < HKADC_DATA_GRADE5) {
    210     Result = BOARDID_VALUE4;
    211   } else if (AdcinValue < HKADC_DATA_GRADE6) {
    212     Result = BOARDID_VALUE5;
    213   } else if (AdcinValue < HKADC_DATA_GRADE7) {
    214     Result = BOARDID_VALUE6;
    215   } else if (AdcinValue < HKADC_DATA_GRADE8) {
    216     Result = BOARDID_VALUE7;
    217   } else if (AdcinValue < HKADC_DATA_GRADE9) {
    218     Result = BOARDID_VALUE8;
    219   } else if (AdcinValue < HKADC_DATA_GRADE10) {
    220     Result = BOARDID_VALUE9;
    221   } else {
    222     Result = BOARDID_UNKNOW;
    223   }
    224   return Result;
    225 }
    226 
    227 STATIC
    228 EFI_STATUS
    229 InitBoardId (
    230   OUT UINTN          *Id
    231   )
    232 {
    233   UINTN              Adcin0, Adcin1, Adcin2;
    234   UINTN              Adcin0Remap, Adcin1Remap, Adcin2Remap;
    235 
    236   InitAdc ();
    237 
    238   // read ADC channel0 data
    239   AdcGetValue (ADC_ADCIN0, &Adcin0);
    240   DEBUG ((DEBUG_ERROR, "[BDID]Adcin0:%d\n", Adcin0));
    241   Adcin0Remap = AdcinDataRemap (Adcin0);
    242   DEBUG ((DEBUG_ERROR, "[BDID]Adcin0Remap:%d\n", Adcin0Remap));
    243   if (Adcin0Remap == BOARDID_UNKNOW) {
    244     return EFI_INVALID_PARAMETER;
    245   }
    246   // read ADC channel1 data
    247   AdcGetValue (ADC_ADCIN1, &Adcin1);
    248   DEBUG ((DEBUG_ERROR, "[BDID]Adcin1:%d\n", Adcin1));
    249   Adcin1Remap = AdcinDataRemap (Adcin1);
    250   DEBUG ((DEBUG_ERROR, "[BDID]Adcin1Remap:%d\n", Adcin1Remap));
    251   if (Adcin1Remap == BOARDID_UNKNOW) {
    252     return EFI_INVALID_PARAMETER;
    253   }
    254   // read ADC channel2 data
    255   AdcGetValue (ADC_ADCIN2, &Adcin2);
    256   DEBUG ((DEBUG_ERROR, "[BDID]Adcin2:%d\n", Adcin2));
    257   Adcin2Remap = AdcinDataRemap (Adcin2);
    258   DEBUG ((DEBUG_ERROR, "[BDID]Adcin2Remap:%d\n", Adcin2Remap));
    259   if (Adcin2Remap == BOARDID_UNKNOW) {
    260     return EFI_INVALID_PARAMETER;
    261   }
    262   *Id = BOARDID3_BASE * 1000 + (Adcin2Remap * 100) + (Adcin1Remap * 10) + Adcin0Remap;
    263   DEBUG ((DEBUG_ERROR, "[BDID]boardid: %d\n", *Id));
    264   return EFI_SUCCESS;
    265 }
    266 
    267 STATIC
    268 VOID
    269 InitSdCard (
    270   IN VOID
    271   )
    272 {
    273   UINT32        Data;
    274 
    275   // LDO16
    276   Data = MmioRead32 (PMU_REG_BASE + (0x79 << 2)) & 7;
    277   Data |= 6;
    278   MmioWrite32 (PMU_REG_BASE + (0x79 << 2), Data);
    279   MmioOr32 (PMU_REG_BASE + (0x78 << 2), 2);
    280   MicroSecondDelay (100);
    281 
    282   // LDO9
    283   Data = MmioRead32 (PMU_REG_BASE + (0x6b << 2)) & 7;
    284   Data |= 5;
    285   MmioWrite32 (PMU_REG_BASE + (0x6b << 2), Data);
    286   MmioOr32 (PMU_REG_BASE + (0x6a << 2), 2);
    287   MicroSecondDelay (100);
    288 
    289   // GPIO203
    290   MmioWrite32 (0xfff11000 + (24 << 2), 0); // GPIO function
    291 
    292   // SD pinmux
    293   MmioWrite32 (0xff37e000 + 0x0, 1); // SD_CLK
    294   MmioWrite32 (0xff37e000 + 0x4, 1); // SD_CMD
    295   MmioWrite32 (0xff37e000 + 0x8, 1); // SD_DATA0
    296   MmioWrite32 (0xff37e000 + 0xc, 1); // SD_DATA1
    297   MmioWrite32 (0xff37e000 + 0x10, 1); // SD_DATA2
    298   MmioWrite32 (0xff37e000 + 0x14, 1); // SD_DATA3
    299   MmioWrite32 (0xff37e800 + 0x0, 15 << 4); // SD_CLK float with 32mA
    300   MmioWrite32 (0xff37e800 + 0x4, (1 << 0) | (8 << 4)); // SD_CMD
    301   MmioWrite32 (0xff37e800 + 0x8, (1 << 0) | (8 << 4)); // SD_DATA0
    302   MmioWrite32 (0xff37e800 + 0xc, (1 << 0) | (8 << 4)); // SD_DATA1
    303   MmioWrite32 (0xff37e800 + 0x10, (1 << 0) | (8 << 4)); // SD_DATA2
    304   MmioWrite32 (0xff37e800 + 0x14, (1 << 0) | (8 << 4)); // SD_DATA3
    305 
    306   do {
    307     MmioOr32 (CRG_REG_BASE + 0xb8, (1 << 6) | (1 << 6 << 16) | (0 << 4) | (3 << 4 << 16));
    308     Data = MmioRead32 (CRG_REG_BASE + 0xb8);
    309   } while ((Data & ((1 << 6) | (3 << 4))) != ((1 << 6) | (0 << 4)));
    310 
    311   // Unreset SD controller
    312   MmioWrite32 (CRG_PERRSTDIS4, 1 << 18);
    313   do {
    314     Data = MmioRead32 (CRG_PERRSTSTAT4);
    315   } while ((Data & (1 << 18)) == (1 << 18));
    316   // Enable SD controller clock
    317   MmioOr32 (CRG_REG_BASE + 0, 1 << 30);
    318   MmioOr32 (CRG_REG_BASE + 0x40, 1 << 17);
    319   do {
    320     Data = MmioRead32 (CRG_REG_BASE + 0x48);
    321   } while ((Data & (1 << 17)) != (1 << 17));
    322 }
    323 
    324 VOID
    325 InitPeripherals (
    326   IN VOID
    327   )
    328 {
    329   // Enable FPLL0
    330   MmioOr32 (SCTRL_SCFPLLCTRL0, SCTRL_SCFPLLCTRL0_FPLL0_EN);
    331 
    332   InitSdCard ();
    333 
    334   // Enable wifi clock
    335   MmioOr32 (PMIC_HARDWARE_CTRL0, PMIC_HARDWARE_CTRL0_WIFI_CLK);
    336   MmioOr32 (PMIC_OSC32K_ONOFF_CTRL, PMIC_OSC32K_ONOFF_CTRL_EN_32K);
    337 }
    338 
    339 /**
    340   Notification function of the event defined as belonging to the
    341   EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
    342   the entry point of the driver.
    343 
    344   This function is called when an event belonging to the
    345   EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
    346   event is signalled once at the end of the dispatching of all
    347   drivers (end of the so called DXE phase).
    348 
    349   @param[in]  Event    Event declared in the entry point of the driver whose
    350                        notification function is being invoked.
    351   @param[in]  Context  NULL
    352 **/
    353 STATIC
    354 VOID
    355 OnEndOfDxe (
    356   IN EFI_EVENT  Event,
    357   IN VOID       *Context
    358   )
    359 {
    360   UINT32        BootMode;
    361 
    362   BootMode = MmioRead32 (SCTRL_BAK_DATA0) & BOOT_MODE_MASK;
    363   if (BootMode == BOOT_MODE_RECOVERY) {
    364     SerialPortWrite ((UINT8 *)"WARNING: CAN NOT BOOT KERNEL IN RECOVERY MODE!\r\n", 48);
    365     SerialPortWrite ((UINT8 *)"Switch to normal boot mode, then reboot to boot kernel.\r\n", 57);
    366   }
    367 }
    368 
    369 EFI_STATUS
    370 EFIAPI
    371 AbootimgAppendKernelArgs (
    372   IN CHAR16            *Args,
    373   IN UINTN              Size
    374   )
    375 {
    376   EFI_STATUS                  Status;
    377   EFI_BLOCK_IO_PROTOCOL      *BlockIoProtocol;
    378   VOID                       *DataPtr;
    379   RANDOM_SERIAL_NUMBER       *RandomSN;
    380   EFI_DEVICE_PATH_PROTOCOL   *FlashDevicePath;
    381   EFI_HANDLE                  FlashHandle;
    382 
    383   if (Args == NULL) {
    384     return EFI_INVALID_PARAMETER;
    385   }
    386   FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
    387   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePath, &FlashHandle);
    388   if (EFI_ERROR (Status)) {
    389     DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
    390     // Failing to locate partitions should not prevent to do other Android FastBoot actions
    391     return EFI_SUCCESS;
    392   }
    393   Status = gBS->OpenProtocol (
    394                   FlashHandle,
    395                   &gEfiBlockIoProtocolGuid,
    396                   (VOID **) &BlockIoProtocol,
    397                   gImageHandle,
    398                   NULL,
    399                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    400                   );
    401   if (EFI_ERROR (Status)) {
    402     DEBUG ((DEBUG_WARN, "Warning: Couldn't open block device (status: %r)\n", Status));
    403     return EFI_DEVICE_ERROR;
    404   }
    405 
    406   DataPtr = AllocatePages (1);
    407   if (DataPtr == NULL) {
    408     return EFI_BUFFER_TOO_SMALL;
    409   }
    410   Status = BlockIoProtocol->ReadBlocks (
    411                               BlockIoProtocol,
    412                               BlockIoProtocol->Media->MediaId,
    413                               SERIAL_NUMBER_LBA,
    414                               SERIAL_NUMBER_BLOCK_SIZE,
    415                               DataPtr
    416                               );
    417   if (EFI_ERROR (Status)) {
    418     DEBUG ((DEBUG_WARN, "Warning: Failed on reading blocks\n"));
    419     goto Exit;
    420   }
    421   RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
    422   if (RandomSN->Magic != RANDOM_MAGIC) {
    423     UnicodeSPrint(
    424       RandomSN->UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16),
    425       L"0123456789abcdef"
    426       );
    427   }
    428   if (mBoardId == HIKEY960_BOARDID_V1) {
    429     UnicodeSPrint (
    430       Args + StrLen (Args), Size - StrLen (Args),
    431       L" console=ttyAMA5 androidboot.serialno=%s",
    432       RandomSN->UnicodeSN
    433       );
    434   } else {
    435     UnicodeSPrint (
    436       Args + StrLen (Args), Size - StrLen (Args),
    437       L" console=ttyAMA6 androidboot.serialno=%s",
    438       RandomSN->UnicodeSN
    439       );
    440   }
    441   FreePages (DataPtr, 1);
    442   return EFI_SUCCESS;
    443 Exit:
    444   FreePages (DataPtr, 1);
    445   return Status;
    446 }
    447 
    448 EFI_STATUS
    449 EFIAPI
    450 AbootimgUpdateDtb (
    451   IN  EFI_PHYSICAL_ADDRESS        OrigFdtBase,
    452   OUT EFI_PHYSICAL_ADDRESS       *NewFdtBase
    453   )
    454 {
    455   //UINT8            *FdtPtr;
    456   UINTN             FdtSize, NumPages;
    457   INTN              err, offset;
    458   EFI_STATUS        Status;
    459 
    460   //
    461   // Sanity checks on the original FDT blob.
    462   //
    463   err = fdt_check_header ((VOID*)(UINTN)OrigFdtBase);
    464   if (err != 0) {
    465     DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (err:%d)\n", err));
    466     return EFI_INVALID_PARAMETER;
    467   }
    468 
    469   //
    470   // Store the FDT as Runtime Service Data to prevent the Kernel from
    471   // overwritting its data.
    472   //
    473   FdtSize = fdt_totalsize ((VOID *)(UINTN)OrigFdtBase);
    474   NumPages = EFI_SIZE_TO_PAGES (FdtSize) + 20;
    475   Status = gBS->AllocatePages (
    476                   AllocateAnyPages, EfiRuntimeServicesData,
    477                   NumPages, NewFdtBase);
    478   if (EFI_ERROR (Status)) {
    479     return EFI_BUFFER_TOO_SMALL;
    480   }
    481 
    482   CopyMem (
    483     (VOID*)(UINTN)*NewFdtBase,
    484     (VOID*)(UINTN)OrigFdtBase,
    485     FdtSize
    486     );
    487 
    488   if (mBoardId == HIKEY960_BOARDID_V1) {
    489     offset = fdt_node_offset_by_compatible (
    490                (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_LEDS_V1
    491                );
    492   } else {
    493     offset = fdt_node_offset_by_compatible (
    494                (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_LEDS_V2
    495                );
    496   }
    497   // Ignore it if can't find LED compatible
    498   if (offset < 0) {
    499     DEBUG ((DEBUG_WARN, "WARN: Failed to find node with compatible (err:%d)\n", err));
    500     goto Exit;
    501   }
    502   err = fdt_setprop_string ((VOID*)(UINTN)*NewFdtBase, offset, "status", "ok");
    503   if (err) {
    504     DEBUG ((DEBUG_ERROR, "ERROR: Failed to update status property\n"));
    505     return EFI_INVALID_PARAMETER;
    506   }
    507   err = fdt_set_name ((VOID*)(UINTN)*NewFdtBase, offset, "gpio-leds");
    508   if (err) {
    509     DEBUG ((DEBUG_ERROR, "ERROR: Failed to update compatible name\n"));
    510     return EFI_INVALID_PARAMETER;
    511   }
    512 
    513   if (mBoardId == HIKEY960_BOARDID_V1) {
    514     offset = fdt_node_offset_by_compatible (
    515                (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_HUB_V1
    516                );
    517   } else {
    518     offset = fdt_node_offset_by_compatible (
    519                (VOID*)(UINTN)*NewFdtBase, -1, HIKEY960_COMPATIBLE_HUB_V2
    520                );
    521   }
    522   // Ignore it if can't find LED compatible
    523   if (offset < 0) {
    524     DEBUG ((DEBUG_WARN, "WARN: Failed to find node with compatible (err:%d)\n", err));
    525     goto Exit;
    526   }
    527   err = fdt_setprop_string ((VOID*)(UINTN)*NewFdtBase, offset, "status", "ok");
    528   if (err) {
    529     DEBUG ((DEBUG_ERROR, "ERROR: Failed to update status property\n"));
    530     return EFI_INVALID_PARAMETER;
    531   }
    532 
    533 Exit:
    534   fdt_pack ((VOID*)(UINTN)*NewFdtBase);
    535   err = fdt_check_header ((VOID*)(UINTN)*NewFdtBase);
    536   if (err != 0) {
    537     DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (err:%d)\n", err));
    538     gBS->FreePages (*NewFdtBase, NumPages);
    539     return EFI_INVALID_PARAMETER;
    540   }
    541 
    542   return EFI_SUCCESS;
    543 }
    544 
    545 ABOOTIMG_PROTOCOL mAbootimg = {
    546   AbootimgAppendKernelArgs,
    547   AbootimgUpdateDtb
    548 };
    549 
    550 EFI_STATUS
    551 EFIAPI
    552 VirtualKeyboardRegister (
    553   IN VOID
    554   )
    555 {
    556   EFI_STATUS           Status;
    557 
    558   Status = gBS->LocateProtocol (
    559                   &gEmbeddedGpioProtocolGuid,
    560                   NULL,
    561                   (VOID **) &mGpio
    562                   );
    563   if (EFI_ERROR (Status)) {
    564     return Status;
    565   }
    566   return EFI_SUCCESS;
    567 }
    568 
    569 EFI_STATUS
    570 EFIAPI
    571 VirtualKeyboardReset (
    572   IN VOID
    573   )
    574 {
    575   EFI_STATUS           Status;
    576 
    577   if (mGpio == NULL) {
    578     return EFI_INVALID_PARAMETER;
    579   }
    580   // Configure GPIO68 as GPIO function
    581   MmioWrite32 (0xe896c108, 0);
    582   Status = mGpio->Set (mGpio, DETECT_SW_FASTBOOT, GPIO_MODE_INPUT);
    583   return Status;
    584 }
    585 
    586 BOOLEAN
    587 EFIAPI
    588 VirtualKeyboardQuery (
    589   IN VIRTUAL_KBD_KEY             *VirtualKey
    590   )
    591 {
    592   EFI_STATUS           Status;
    593   UINTN                Value = 0;
    594 
    595   if ((VirtualKey == NULL) || (mGpio == NULL)) {
    596     return FALSE;
    597   }
    598   // If current reason doesn't match the initial one, it's updated by fastboot.
    599   if (MmioRead32 (ADB_REBOOT_ADDRESS) != mRebootReason) {
    600     mRebootUpdated = 1;
    601   }
    602   if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
    603     goto Done;
    604   } else {
    605     Status = mGpio->Get (mGpio, DETECT_SW_FASTBOOT, &Value);
    606     if (EFI_ERROR (Status) || (Value != 0)) {
    607       return FALSE;
    608     }
    609   }
    610 Done:
    611   VirtualKey->Signature = VIRTUAL_KEYBOARD_KEY_SIGNATURE;
    612   VirtualKey->Key.ScanCode = SCAN_NULL;
    613   VirtualKey->Key.UnicodeChar = L'f';
    614   return TRUE;
    615 }
    616 
    617 EFI_STATUS
    618 EFIAPI
    619 VirtualKeyboardClear (
    620   IN VIRTUAL_KBD_KEY            *VirtualKey
    621   )
    622 {
    623   if (VirtualKey == NULL) {
    624     return EFI_INVALID_PARAMETER;
    625   }
    626   // Only clear the reboot flag that is set before reboot.
    627   if ((MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) &&
    628       (mRebootUpdated == 0)) {
    629     MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_NONE);
    630     WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
    631   }
    632   return EFI_SUCCESS;
    633 }
    634 
    635 PLATFORM_VIRTUAL_KBD_PROTOCOL mVirtualKeyboard = {
    636   VirtualKeyboardRegister,
    637   VirtualKeyboardReset,
    638   VirtualKeyboardQuery,
    639   VirtualKeyboardClear
    640 };
    641 
    642 EFI_STATUS
    643 EFIAPI
    644 HiKey960EntryPoint (
    645   IN EFI_HANDLE         ImageHandle,
    646   IN EFI_SYSTEM_TABLE   *SystemTable
    647   )
    648 {
    649   EFI_STATUS            Status;
    650   EFI_EVENT             EndOfDxeEvent;
    651 
    652   Status = InitBoardId (&mBoardId);
    653   if (EFI_ERROR (Status)) {
    654     return Status;
    655   }
    656 
    657   InitPeripherals ();
    658 
    659   // Record the reboot reason if it exists
    660   mRebootReason = MmioRead32 (ADB_REBOOT_ADDRESS);
    661 
    662   //
    663   // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
    664   // The "OnEndOfDxe()" function is declared as the call back function.
    665   // It will be called at the end of the DXE phase when an event of the
    666   // same group is signalled to inform about the end of the DXE phase.
    667   // Install the INSTALL_FDT_PROTOCOL protocol.
    668   //
    669   Status = gBS->CreateEventEx (
    670                   EVT_NOTIFY_SIGNAL,
    671                   TPL_CALLBACK,
    672                   OnEndOfDxe,
    673                   NULL,
    674                   &gEfiEndOfDxeEventGroupGuid,
    675                   &EndOfDxeEvent
    676                   );
    677   if (EFI_ERROR (Status)) {
    678     return Status;
    679   }
    680 
    681   // RegisterNonDicoverableMmioDevice
    682   Status = RegisterNonDiscoverableMmioDevice (
    683              NonDiscoverableDeviceTypeUfs,
    684              NonDiscoverableDeviceDmaTypeNonCoherent,
    685              NULL,
    686              NULL,
    687              1,
    688              FixedPcdGet32 (PcdDwUfsHcDxeBaseAddress),
    689              SIZE_4KB
    690              );
    691   if (EFI_ERROR (Status)) {
    692     return Status;
    693   }
    694   Status = RegisterNonDiscoverableMmioDevice (
    695              NonDiscoverableDeviceTypeSdhci,
    696              NonDiscoverableDeviceDmaTypeNonCoherent,
    697              NULL,
    698              NULL,
    699              1,
    700              0xFF37F000, // SD
    701              SIZE_4KB
    702              );
    703   if (EFI_ERROR (Status)) {
    704     return Status;
    705   }
    706 
    707   Status = gBS->InstallProtocolInterface (
    708                   &ImageHandle,
    709                   &gAbootimgProtocolGuid,
    710                   EFI_NATIVE_INTERFACE,
    711                   &mAbootimg
    712                   );
    713   if (EFI_ERROR (Status)) {
    714     return Status;
    715   }
    716 
    717   Status = gBS->InstallProtocolInterface (
    718                   &ImageHandle,
    719                   &gPlatformVirtualKeyboardProtocolGuid,
    720                   EFI_NATIVE_INTERFACE,
    721                   &mVirtualKeyboard
    722                   );
    723   return Status;
    724 }
    725