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