/** @file * * Copyright (c) 2018, Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "HiKeyDxe.h" STATIC VOID UartInit ( IN VOID ) { UINT32 Val; /* make UART1 out of reset */ MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART1); MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART1); /* make UART2 out of reset */ MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART2); MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART2); /* make UART3 out of reset */ MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART3); MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART3); /* make UART4 out of reset */ MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART4); MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART4); /* make DW_MMC2 out of reset */ MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, PERIPH_RST0_MMC2); /* enable clock for BT/WIFI */ Val = MmioRead32 (PMUSSI_ONOFF8_REG) | PMUSSI_ONOFF8_EN_32KB; MmioWrite32 (PMUSSI_ONOFF8_REG, Val); } STATIC EMBEDDED_GPIO *mGpio; STATIC VOID MtcmosInit ( IN VOID ) { UINT32 Data; /* enable MTCMOS for GPU */ MmioWrite32 (AO_CTRL_BASE + SC_PW_MTCMOS_EN0, PW_EN0_G3D); do { Data = MmioRead32 (AO_CTRL_BASE + SC_PW_MTCMOS_ACK_STAT0); } while ((Data & PW_EN0_G3D) == 0); } EFI_STATUS HiKeyInitPeripherals ( IN VOID ) { UINT32 Data, Bits; /* make I2C0/I2C1/I2C2/SPI0 out of reset */ Bits = PERIPH_RST3_I2C0 | PERIPH_RST3_I2C1 | PERIPH_RST3_I2C2 | \ PERIPH_RST3_SSP; MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, Bits); do { Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT3); } while (Data & Bits); UartInit (); /* MTCMOS -- Multi-threshold CMOS */ MtcmosInit (); /* Set DETECT_J15_FASTBOOT (GPIO24) pin as GPIO function */ MmioWrite32 (IOCG_084_REG, 0); /* configure GPIO24 as nopull */ MmioWrite32 (IOMG_080_REG, 0); /* configure GPIO24 as GPIO */ return EFI_SUCCESS; } STATIC EFI_STATUS CreatePlatformBootOptionFromPath ( IN CHAR16 *PathStr, IN CHAR16 *Description, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH *DevicePath; DevicePath = (EFI_DEVICE_PATH *)ConvertTextToDevicePath (PathStr); ASSERT (DevicePath != NULL); Status = EfiBootManagerInitializeLoadOption ( BootOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, Description, DevicePath, NULL, 0 ); FreePool (DevicePath); return Status; } STATIC EFI_STATUS CreatePlatformBootOptionFromGuid ( IN EFI_GUID *FileGuid, IN CHAR16 *Description, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *TempDevicePath; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; Status = gBS->HandleProtocol ( gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage ); ASSERT_EFI_ERROR (Status); EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle); ASSERT (TempDevicePath != NULL); DevicePath = AppendDevicePathNode ( TempDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); ASSERT (DevicePath != NULL); Status = EfiBootManagerInitializeLoadOption ( BootOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, Description, DevicePath, NULL, 0 ); FreePool (DevicePath); return Status; } STATIC EFI_STATUS GetPlatformBootOptionsAndKeys ( OUT UINTN *BootCount, OUT EFI_BOOT_MANAGER_LOAD_OPTION **BootOptions, OUT EFI_INPUT_KEY **BootKeys ) { EFI_GUID *FileGuid; CHAR16 *PathStr; EFI_STATUS Status; UINTN Size; Size = sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * HIKEY_BOOT_OPTION_NUM; *BootOptions = (EFI_BOOT_MANAGER_LOAD_OPTION *)AllocateZeroPool (Size); if (*BootOptions == NULL) { DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootOptions\n")); return EFI_OUT_OF_RESOURCES; } Size = sizeof (EFI_INPUT_KEY) * HIKEY_BOOT_OPTION_NUM; *BootKeys = (EFI_INPUT_KEY *)AllocateZeroPool (Size); if (*BootKeys == NULL) { DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootKeys\n")); Status = EFI_OUT_OF_RESOURCES; goto Error; } PathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath); ASSERT (PathStr != NULL); Status = CreatePlatformBootOptionFromPath ( PathStr, L"Boot from SD", &(*BootOptions)[0] ); ASSERT_EFI_ERROR (Status); PathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath); ASSERT (PathStr != NULL); Status = CreatePlatformBootOptionFromPath ( PathStr, L"Grub", &(*BootOptions)[1] ); ASSERT_EFI_ERROR (Status); FileGuid = PcdGetPtr (PcdAndroidBootFile); ASSERT (FileGuid != NULL); Status = CreatePlatformBootOptionFromGuid ( FileGuid, L"Android Boot", &(*BootOptions)[2] ); ASSERT_EFI_ERROR (Status); FileGuid = PcdGetPtr (PcdAndroidFastbootFile); ASSERT (FileGuid != NULL); Status = CreatePlatformBootOptionFromGuid ( FileGuid, L"Android Fastboot", &(*BootOptions)[3] ); ASSERT_EFI_ERROR (Status); (*BootKeys)[3].ScanCode = SCAN_NULL; (*BootKeys)[3].UnicodeChar = 'f'; *BootCount = 4; return EFI_SUCCESS; Error: FreePool (*BootOptions); return Status; } PLATFORM_BOOT_MANAGER_PROTOCOL mPlatformBootManager = { GetPlatformBootOptionsAndKeys }; 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; } Status = mGpio->Set (mGpio, DETECT_J15_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_J15_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 HiKeyEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; Status = HiKeyInitPeripherals (); if (EFI_ERROR (Status)) { return Status; } Status = gBS->InstallProtocolInterface ( &ImageHandle, &gPlatformVirtualKeyboardProtocolGuid, EFI_NATIVE_INTERFACE, &mVirtualKeyboard ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->InstallProtocolInterface ( &ImageHandle, &gPlatformBootManagerProtocolGuid, EFI_NATIVE_INTERFACE, &mPlatformBootManager ); return Status; }