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