blob: b4e0e1b8f5dd2e2854c9a7c04952b842dcb17756 [file] [log] [blame]
/** @file
*
* Copyright (c) 2016-2017, Linaro Ltd. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/
#include <Guid/EventGroup.h>
#include <Guid/HiKey960Variable.h>
#include <Hi3660.h>
#include <Hkadc.h>
#include <libfdt.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/NonDiscoverableDeviceRegistrationLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>
#include <Library/SerialPortLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/Abootimg.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/EmbeddedGpio.h>
#include <Protocol/NonDiscoverableDevice.h>
#include <Protocol/PlatformVirtualKeyboard.h>
#define ADC_ADCIN0 0
#define ADC_ADCIN1 1
#define ADC_ADCIN2 2
#define HKADC_DATA_GRADE0 0
#define HKADC_DATA_GRADE1 100
#define HKADC_DATA_GRADE2 300
#define HKADC_DATA_GRADE3 500
#define HKADC_DATA_GRADE4 700
#define HKADC_DATA_GRADE5 900
#define HKADC_DATA_GRADE6 1100
#define HKADC_DATA_GRADE7 1300
#define HKADC_DATA_GRADE8 1500
#define HKADC_DATA_GRADE9 1700
#define HKADC_DATA_GRADE10 1800
#define BOARDID_VALUE0 0
#define BOARDID_VALUE1 1
#define BOARDID_VALUE2 2
#define BOARDID_VALUE3 3
#define BOARDID_VALUE4 4
#define BOARDID_VALUE5 5
#define BOARDID_VALUE6 6
#define BOARDID_VALUE7 7
#define BOARDID_VALUE8 8
#define BOARDID_VALUE9 9
#define BOARDID_UNKNOW 0xF
#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"
#define SERIAL_NUMBER_SIZE 17
#define SERIAL_NUMBER_BLOCK_SIZE EFI_PAGE_SIZE
#define SERIAL_NUMBER_LBA 20
#define RANDOM_MAX 0x7FFFFFFFFFFFFFFF
#define RANDOM_MAGIC 0x9A4DBEAF
#define ADB_REBOOT_ADDRESS 0x32100000
#define ADB_REBOOT_BOOTLOADER 0x77665500
#define ADB_REBOOT_NONE 0x77665501
#define DETECT_SW_FASTBOOT 68 // GPIO8_4
typedef struct {
UINT64 Magic;
UINT64 Data;
CHAR16 UnicodeSN[SERIAL_NUMBER_SIZE];
} RANDOM_SERIAL_NUMBER;
enum {
BOOT_MODE_RECOVERY = 0,
BOOT_MODE_NORMAL,
BOOT_MODE_MASK = 1,
};
STATIC UINTN mBoardId;
STATIC EMBEDDED_GPIO *mGpio;
STATIC
VOID
InitAdc (
VOID
)
{
// reset hkadc
MmioWrite32 (CRG_PERRSTEN2, PERRSTEN2_HKADCSSI);
// wait a few clock cycles
MicroSecondDelay (2);
MmioWrite32 (CRG_PERRSTDIS2, PERRSTEN2_HKADCSSI);
MicroSecondDelay (2);
// enable hkadc clock
MmioWrite32 (CRG_PERDIS2, PEREN2_HKADCSSI);
MicroSecondDelay (2);
MmioWrite32 (CRG_PEREN2, PEREN2_HKADCSSI);
MicroSecondDelay (2);
}
STATIC
EFI_STATUS
AdcGetAdc (
IN UINTN Channel,
OUT UINTN *Value
)
{
UINT32 Data;
UINT16 Value1, Value0;
if (Channel > HKADC_CHANNEL_MAX) {
DEBUG ((DEBUG_ERROR, "invalid channel:%d\n", Channel));
return EFI_OUT_OF_RESOURCES;
}
// configure the read/write operation for external HKADC
MmioWrite32 (HKADC_WR01_DATA, HKADC_WR01_VALUE | Channel);
MmioWrite32 (HKADC_WR23_DATA, HKADC_WR23_VALUE);
MmioWrite32 (HKADC_WR45_DATA, HKADC_WR45_VALUE);
// configure the number of accessing registers
MmioWrite32 (HKADC_WR_NUM, HKADC_WR_NUM_VALUE);
// configure delay of accessing registers
MmioWrite32 (HKADC_DELAY01, HKADC_CHANNEL0_DELAY01_VALUE);
MmioWrite32 (HKADC_DELAY23, HKADC_DELAY23_VALUE);
// start HKADC
MmioWrite32 (HKADC_DSP_START, 1);
do {
Data = MmioRead32 (HKADC_DSP_START);
} while (Data & 1);
// convert AD result
Value1 = (UINT16)MmioRead32 (HKADC_DSP_RD2_DATA);
Value0 = (UINT16)MmioRead32 (HKADC_DSP_RD3_DATA);
Data = ((Value1 << 4) & HKADC_VALUE_HIGH) | ((Value0 >> 4) & HKADC_VALUE_LOW);
*Value = Data;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
AdcGetValue (
IN UINTN Channel,
IN OUT UINTN *Value
)
{
EFI_STATUS Status;
UINTN Result;
Status = AdcGetAdc (Channel, Value);
if (EFI_ERROR (Status)) {
return Status;
}
// convert ADC value to micro-volt
Result = ((*Value & HKADC_VALID_VALUE) * HKADC_VREF_1V8) / HKADC_ACCURACY;
*Value = Result;
return EFI_SUCCESS;
}
STATIC
UINTN
AdcinDataRemap (
IN UINTN AdcinValue
)
{
UINTN Result;
if (AdcinValue < HKADC_DATA_GRADE0) {
Result = BOARDID_UNKNOW;
} else if (AdcinValue < HKADC_DATA_GRADE1) {
Result = BOARDID_VALUE0;
} else if (AdcinValue < HKADC_DATA_GRADE2) {
Result = BOARDID_VALUE1;
} else if (AdcinValue < HKADC_DATA_GRADE3) {
Result = BOARDID_VALUE2;
} else if (AdcinValue < HKADC_DATA_GRADE4) {
Result = BOARDID_VALUE3;
} else if (AdcinValue < HKADC_DATA_GRADE5) {
Result = BOARDID_VALUE4;
} else if (AdcinValue < HKADC_DATA_GRADE6) {
Result = BOARDID_VALUE5;
} else if (AdcinValue < HKADC_DATA_GRADE7) {
Result = BOARDID_VALUE6;
} else if (AdcinValue < HKADC_DATA_GRADE8) {
Result = BOARDID_VALUE7;
} else if (AdcinValue < HKADC_DATA_GRADE9) {
Result = BOARDID_VALUE8;
} else if (AdcinValue < HKADC_DATA_GRADE10) {
Result = BOARDID_VALUE9;
} else {
Result = BOARDID_UNKNOW;
}
return Result;
}
STATIC
EFI_STATUS
InitBoardId (
OUT UINTN *Id
)
{
UINTN Adcin0, Adcin1, Adcin2;
UINTN Adcin0Remap, Adcin1Remap, Adcin2Remap;
InitAdc ();
// read ADC channel0 data
AdcGetValue (ADC_ADCIN0, &Adcin0);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin0:%d\n", Adcin0));
Adcin0Remap = AdcinDataRemap (Adcin0);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin0Remap:%d\n", Adcin0Remap));
if (Adcin0Remap == BOARDID_UNKNOW) {
return EFI_INVALID_PARAMETER;
}
// read ADC channel1 data
AdcGetValue (ADC_ADCIN1, &Adcin1);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin1:%d\n", Adcin1));
Adcin1Remap = AdcinDataRemap (Adcin1);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin1Remap:%d\n", Adcin1Remap));
if (Adcin1Remap == BOARDID_UNKNOW) {
return EFI_INVALID_PARAMETER;
}
// read ADC channel2 data
AdcGetValue (ADC_ADCIN2, &Adcin2);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin2:%d\n", Adcin2));
Adcin2Remap = AdcinDataRemap (Adcin2);
DEBUG ((DEBUG_ERROR, "[BDID]Adcin2Remap:%d\n", Adcin2Remap));
if (Adcin2Remap == BOARDID_UNKNOW) {
return EFI_INVALID_PARAMETER;
}
*Id = BOARDID3_BASE * 1000 + (Adcin2Remap * 100) + (Adcin1Remap * 10) + Adcin0Remap;
DEBUG ((DEBUG_ERROR, "[BDID]boardid: %d\n", *Id));
return EFI_SUCCESS;
}
STATIC
VOID
InitSdCard (
IN VOID
)
{
UINT32 Data;
// LDO16
Data = MmioRead32 (PMU_REG_BASE + (0x79 << 2)) & 7;
Data |= 6;
MmioWrite32 (PMU_REG_BASE + (0x79 << 2), Data);
MmioOr32 (PMU_REG_BASE + (0x78 << 2), 2);
MicroSecondDelay (100);
// LDO9
Data = MmioRead32 (PMU_REG_BASE + (0x6b << 2)) & 7;
Data |= 5;
MmioWrite32 (PMU_REG_BASE + (0x6b << 2), Data);
MmioOr32 (PMU_REG_BASE + (0x6a << 2), 2);
MicroSecondDelay (100);
// GPIO203
MmioWrite32 (0xfff11000 + (24 << 2), 0); // GPIO function
// SD pinmux
MmioWrite32 (0xff37e000 + 0x0, 1); // SD_CLK
MmioWrite32 (0xff37e000 + 0x4, 1); // SD_CMD
MmioWrite32 (0xff37e000 + 0x8, 1); // SD_DATA0
MmioWrite32 (0xff37e000 + 0xc, 1); // SD_DATA1
MmioWrite32 (0xff37e000 + 0x10, 1); // SD_DATA2
MmioWrite32 (0xff37e000 + 0x14, 1); // SD_DATA3
MmioWrite32 (0xff37e800 + 0x0, 15 << 4); // SD_CLK float with 32mA
MmioWrite32 (0xff37e800 + 0x4, (1 << 0) | (8 << 4)); // SD_CMD
MmioWrite32 (0xff37e800 + 0x8, (1 << 0) | (8 << 4)); // SD_DATA0
MmioWrite32 (0xff37e800 + 0xc, (1 << 0) | (8 << 4)); // SD_DATA1
MmioWrite32 (0xff37e800 + 0x10, (1 << 0) | (8 << 4)); // SD_DATA2
MmioWrite32 (0xff37e800 + 0x14, (1 << 0) | (8 << 4)); // SD_DATA3
do {
MmioOr32 (CRG_REG_BASE + 0xb8, (1 << 6) | (1 << 6 << 16) | (0 << 4) | (3 << 4 << 16));
Data = MmioRead32 (CRG_REG_BASE + 0xb8);
} while ((Data & ((1 << 6) | (3 << 4))) != ((1 << 6) | (0 << 4)));
// Unreset SD controller
MmioWrite32 (CRG_PERRSTDIS4, 1 << 18);
do {
Data = MmioRead32 (CRG_PERRSTSTAT4);
} while ((Data & (1 << 18)) == (1 << 18));
// Enable SD controller clock
MmioOr32 (CRG_REG_BASE + 0, 1 << 30);
MmioOr32 (CRG_REG_BASE + 0x40, 1 << 17);
do {
Data = MmioRead32 (CRG_REG_BASE + 0x48);
} while ((Data & (1 << 17)) != (1 << 17));
}
VOID
InitPeripherals (
IN VOID
)
{
// Enable FPLL0
MmioOr32 (SCTRL_SCFPLLCTRL0, SCTRL_SCFPLLCTRL0_FPLL0_EN);
InitSdCard ();
// Enable wifi clock
MmioOr32 (PMIC_HARDWARE_CTRL0, PMIC_HARDWARE_CTRL0_WIFI_CLK);
MmioOr32 (PMIC_OSC32K_ONOFF_CTRL, PMIC_OSC32K_ONOFF_CTRL_EN_32K);
}
/**
Notification function of the event defined as belonging to the
EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
the entry point of the driver.
This function is called when an event belonging to the
EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
event is signalled once at the end of the dispatching of all
drivers (end of the so called DXE phase).
@param[in] Event Event declared in the entry point of the driver whose
notification function is being invoked.
@param[in] Context NULL
**/
STATIC
VOID
OnEndOfDxe (
IN EFI_EVENT Event,
IN VOID *Context
)
{
UINT32 BootMode;
BootMode = MmioRead32 (SCTRL_BAK_DATA0) & BOOT_MODE_MASK;
if (BootMode == BOOT_MODE_RECOVERY) {
SerialPortWrite ((UINT8 *)"WARNING: CAN NOT BOOT KERNEL IN RECOVERY MODE!\r\n", 48);
SerialPortWrite ((UINT8 *)"Switch to normal boot mode, then reboot to boot kernel.\r\n", 57);
}
}
EFI_STATUS
EFIAPI
AbootimgAppendKernelArgs (
IN CHAR16 *Args,
IN UINTN Size
)
{
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIoProtocol;
VOID *DataPtr;
RANDOM_SERIAL_NUMBER *RandomSN;
EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath;
EFI_HANDLE FlashHandle;
if (Args == NULL) {
return EFI_INVALID_PARAMETER;
}
FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePath, &FlashHandle);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
// Failing to locate partitions should not prevent to do other Android FastBoot actions
return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
FlashHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIoProtocol,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Warning: Couldn't open block device (status: %r)\n", Status));
return EFI_DEVICE_ERROR;
}
DataPtr = AllocatePages (1);
if (DataPtr == NULL) {
return EFI_BUFFER_TOO_SMALL;
}
Status = BlockIoProtocol->ReadBlocks (
BlockIoProtocol,
BlockIoProtocol->Media->MediaId,
SERIAL_NUMBER_LBA,
SERIAL_NUMBER_BLOCK_SIZE,
DataPtr
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Warning: Failed on reading blocks\n"));
goto Exit;
}
RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
if (RandomSN->Magic != RANDOM_MAGIC) {
UnicodeSPrint(
RandomSN->UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16),
L"0123456789abcdef"
);
}
if (mBoardId == HIKEY960_BOARDID_V1) {
UnicodeSPrint (
Args + StrLen (Args), Size - StrLen (Args),
L" console=ttyAMA5 androidboot.serialno=%s",
RandomSN->UnicodeSN
);
} else {
UnicodeSPrint (
Args + StrLen (Args), Size - StrLen (Args),
L" console=ttyAMA6 androidboot.serialno=%s",
RandomSN->UnicodeSN
);
}
FreePages (DataPtr, 1);
return EFI_SUCCESS;
Exit:
FreePages (DataPtr, 1);
return Status;
}
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
);
}
// Ignore it if can't find LED compatible
if (offset < 0) {
DEBUG ((DEBUG_WARN, "WARN: Failed to find node with compatible (err:%d)\n", err));
goto Exit;
}
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
);
}
// Ignore it if can't find LED compatible
if (offset < 0) {
DEBUG ((DEBUG_WARN, "WARN: Failed to find node with compatible (err:%d)\n", err));
goto Exit;
}
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;
}
Exit:
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
VirtualKeyboardRegister (
IN VOID
)
{
EFI_STATUS Status;
Status = gBS->LocateProtocol (
&gEmbeddedGpioProtocolGuid,
NULL,
(VOID **) &mGpio
);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VirtualKeyboardReset (
IN VOID
)
{
EFI_STATUS Status;
if (mGpio == NULL) {
return EFI_INVALID_PARAMETER;
}
// Configure GPIO68 as GPIO function
MmioWrite32 (0xe896c108, 0);
Status = mGpio->Set (mGpio, DETECT_SW_FASTBOOT, GPIO_MODE_INPUT);
return Status;
}
BOOLEAN
EFIAPI
VirtualKeyboardQuery (
IN VIRTUAL_KBD_KEY *VirtualKey
)
{
EFI_STATUS Status;
UINTN Value = 0;
if ((VirtualKey == NULL) || (mGpio == NULL)) {
return FALSE;
}
if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
goto Done;
} else {
Status = mGpio->Get (mGpio, DETECT_SW_FASTBOOT, &Value);
if (EFI_ERROR (Status) || (Value != 0)) {
return FALSE;
}
}
Done:
VirtualKey->Signature = VIRTUAL_KEYBOARD_KEY_SIGNATURE;
VirtualKey->Key.ScanCode = SCAN_NULL;
VirtualKey->Key.UnicodeChar = L'f';
return TRUE;
}
EFI_STATUS
EFIAPI
VirtualKeyboardClear (
IN VIRTUAL_KBD_KEY *VirtualKey
)
{
if (VirtualKey == NULL) {
return EFI_INVALID_PARAMETER;
}
if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_NONE);
WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
}
return EFI_SUCCESS;
}
PLATFORM_VIRTUAL_KBD_PROTOCOL mVirtualKeyboard = {
VirtualKeyboardRegister,
VirtualKeyboardReset,
VirtualKeyboardQuery,
VirtualKeyboardClear
};
EFI_STATUS
EFIAPI
HiKey960EntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT EndOfDxeEvent;
Status = InitBoardId (&mBoardId);
if (EFI_ERROR (Status)) {
return Status;
}
InitPeripherals ();
//
// Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
// The "OnEndOfDxe()" function is declared as the call back function.
// It will be called at the end of the DXE phase when an event of the
// same group is signalled to inform about the end of the DXE phase.
// Install the INSTALL_FDT_PROTOCOL protocol.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
OnEndOfDxe,
NULL,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
if (EFI_ERROR (Status)) {
return Status;
}
// RegisterNonDicoverableMmioDevice
Status = RegisterNonDiscoverableMmioDevice (
NonDiscoverableDeviceTypeUfs,
NonDiscoverableDeviceDmaTypeNonCoherent,
NULL,
NULL,
1,
FixedPcdGet32 (PcdDwUfsHcDxeBaseAddress),
SIZE_4KB
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = RegisterNonDiscoverableMmioDevice (
NonDiscoverableDeviceTypeSdhci,
NonDiscoverableDeviceDmaTypeNonCoherent,
NULL,
NULL,
1,
0xFF37F000, // SD
SIZE_4KB
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->InstallProtocolInterface (
&ImageHandle,
&gAbootimgProtocolGuid,
EFI_NATIVE_INTERFACE,
&mAbootimg
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->InstallProtocolInterface (
&ImageHandle,
&gPlatformVirtualKeyboardProtocolGuid,
EFI_NATIVE_INTERFACE,
&mVirtualKeyboard
);
return Status;
}