aboutsummaryrefslogtreecommitdiffstats
path: root/Platforms/Hisilicon/HiKey960
diff options
context:
space:
mode:
Diffstat (limited to 'Platforms/Hisilicon/HiKey960')
-rw-r--r--Platforms/Hisilicon/HiKey960/Binary/lpm3.imgbin0 -> 217344 bytes
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960.dec39
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960.dsc546
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960.fdf377
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c699
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf64
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c732
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf62
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.c77
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf37
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.c125
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf45
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c363
-rw-r--r--Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf50
-rw-r--r--Platforms/Hisilicon/HiKey960/Include/ArmPlatform.h26
-rw-r--r--Platforms/Hisilicon/HiKey960/Include/Guid/HiKey960Variable.h24
-rw-r--r--Platforms/Hisilicon/HiKey960/Include/Hi3660.h145
-rw-r--r--Platforms/Hisilicon/HiKey960/Include/Hkadc.h66
-rw-r--r--Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/AArch64/HiKey960Helper.S52
-rw-r--r--Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960.c189
-rw-r--r--Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Lib.inf63
-rw-r--r--Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Mem.c173
22 files changed, 3954 insertions, 0 deletions
diff --git a/Platforms/Hisilicon/HiKey960/Binary/lpm3.img b/Platforms/Hisilicon/HiKey960/Binary/lpm3.img
new file mode 100644
index 0000000..bd0243b
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Binary/lpm3.img
Binary files differ
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960.dec b/Platforms/Hisilicon/HiKey960/HiKey960.dec
new file mode 100644
index 0000000..6dea5b8
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960.dec
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2014-2017, Linaro Limited. 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.
+#
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010019
+ PACKAGE_NAME = HiKey960
+ PACKAGE_GUID = a71a681b-3c46-4c92-9fc2-986919026362
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+ Include # Root include for the package
+
+[Guids.common]
+ gDwUsbDeviceGuid = { 0x72d78ea6, 0x4dee, 0x11e3, { 0x81, 0x00, 0xf3, 0x84, 0x2a, 0x48, 0xd0, 0xa0 } }
+ gHiKey960TokenSpaceGuid = { 0x73efcd58, 0x3320, 0x4043, { 0xa8, 0x87, 0xd1, 0xf9, 0xb4, 0x49, 0x48, 0x87 } }
+ gHiKey960VariableGuid = { 0x29727c8d, 0x3531, 0x7a41, { 0x81, 0x9c, 0x7e, 0x50, 0x4e, 0xdd, 0x24, 0x3f } }
+
+[PcdsFixedAtBuild.common]
+ gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L""|VOID*|0x00000001
+ gHiKey960TokenSpaceGuid.PcdArmFastbootFlashLimit|L""|VOID*|0x00000002
+ gHiKey960TokenSpaceGuid.PcdXloaderDevicePath|L""|VOID*|0x00000003
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960.dsc b/Platforms/Hisilicon/HiKey960/HiKey960.dsc
new file mode 100644
index 0000000..ae979d5
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960.dsc
@@ -0,0 +1,546 @@
+#
+# Copyright (c) 2016-2017, Linaro Limited. 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.
+#
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = HiKey960
+ PLATFORM_GUID = ce90122d-5e18-4016-9030-5376535c81b6
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/HiKey960
+ SUPPORTED_ARCHITECTURES = AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.fdf
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+ ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
+ ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
+ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+
+ ArmPlatformLib|OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Lib.inf
+ ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+ ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
+
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+ DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+ PlatformBdsLib|OpenPlatformPkg/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+ AbootimgLib|EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf
+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ UsbSerialNumberLib|OpenPlatformPkg/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
+
+ PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+ SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+ RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+
+ #
+ # Allow dynamic PCDs
+ #
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
+ # BDS Libraries
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+ PlatformBootManagerLib|OpenPlatformPkg/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+ # UiApp dependencies
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+ # USB Requirements
+ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+ DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+
+ UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+
+ # Network Libraries
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+ IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+ UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+
+[LibraryClasses.AARCH64]
+ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+ ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+ ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.SEC]
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+ PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+ MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+ ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
+ DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
+
+[LibraryClasses.common.DXE_CORE]
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[BuildOptions]
+ GCC:*_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/MdeModulePkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Include -I$(WORKSPACE)/OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Include -I$(WORKSPACE)/EmbeddedPkg/Include
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+ GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000
+ GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+ #
+ # Control what commands are supported from the UI
+ # Turn these on and off to add features or save size
+ #
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE
+
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE
+
+ # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+ gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
+
+ ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+ # It could be set FALSE to save size.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+ gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+ # DEBUG_ASSERT_ENABLED 0x01
+ # DEBUG_PRINT_ENABLED 0x02
+ # DEBUG_CODE_ENABLED 0x04
+ # CLEAR_MEMORY_ENABLED 0x08
+ # ASSERT_BREAKPOINT_ENABLED 0x10
+ # ASSERT_DEADLOOP_ENABLED 0x20
+!if $(TARGET) == RELEASE
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+ # DEBUG_INIT 0x00000001 // Initialization
+ # DEBUG_WARN 0x00000002 // Warnings
+ # DEBUG_LOAD 0x00000004 // Load events
+ # DEBUG_FS 0x00000008 // EFI File system
+ # DEBUG_POOL 0x00000010 // Alloc & Free's
+ # DEBUG_PAGE 0x00000020 // Alloc & Free's
+ # DEBUG_INFO 0x00000040 // Verbose
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers
+ # DEBUG_VARIABLE 0x00000100 // Variable
+ # DEBUG_BM 0x00000400 // Boot Manager
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver
+ # DEBUG_NET 0x00004000 // SNI Driver
+ # DEBUG_UNDI 0x00010000 // UNDI Driver
+ # DEBUG_LOADFILE 0x00020000 // UNDI Driver
+ # DEBUG_EVENT 0x00080000 // Event messages
+ # DEBUG_GCD 0x00100000 // Global Coherency Database changes
+ # DEBUG_CACHE 0x00200000 // Memory range cachability changes
+ # DEBUG_ERROR 0x80000000 // Error
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8008000F
+
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+ #
+ # Optional feature to help prevent EFI memory map fragments
+ # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+ # Values are in EFI Pages (4K). DXE Core will make sure that
+ # at least this much of each type of memory can be allocated
+ # from a single memory range. This way you only end up with
+ # maximum of two fragements for each type in the memory map
+ # (the memory used, and the free memory that was prereserved
+ # but not used).
+ #
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|""
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
+
+ gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"Linaro"
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Alpha"
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"HiKey960"
+
+ # TimerPeriod
+ gEmbeddedTokenSpaceGuid.PcdTimerPeriod|1000
+
+ # System Memory (3GB)
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0xC0000000
+
+ # HiKey960 Dual-Cluster profile
+ gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+ gArmPlatformTokenSpaceGuid.PcdClusterCount|2
+
+ gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+ #
+ # ARM Pcds
+ #
+ gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000000000000
+
+ #
+ # ARM PrimeCell
+ #
+
+ ## PL011 - Serial Terminal
+ DEFINE SERIAL_BASE = 0xFFF32000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|$(SERIAL_BASE)
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+ gArmPlatformTokenSpaceGuid.PL011UartInteger|10
+ gArmPlatformTokenSpaceGuid.PL011UartFractional|26
+
+ ## PL011 - Serial Debug UART
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|$(SERIAL_BASE)
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz|19200000
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|115200
+
+ ## PL031 RealTimeClock
+ gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0xFFF05000
+
+ #
+ # ARM General Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0xE82B1000
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE82B2000
+
+ # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
+ gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(CE660500-824D-11E0-AC72-0002A5D5C51B)"
+ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+ # GUID of the UEFI Shell
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+ # GUID of the UI app
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+
+ gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+
+ #
+ # Ufs
+ #
+ gDwUfsHcDxeTokenSpaceGuid.PcdDwUfsHcDxeBaseAddress|0xFF3B0000
+
+ #
+ # DW USB3 controller
+ #
+ gDwUsb3DxeTokenSpaceGuid.PcdDwUsb3DxeBaseAddress|0xFF100000
+
+ #
+ #
+ # Fastboot
+ #
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId|0x18d1
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xd00d
+ gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L"VenHw(0D51905B-B77E-452A-A2C0-ECA0CC8D514A,00003BFF0000000000)/UFS(0x0,0x3)"
+ # Flash limit 128M/time, for memory concern
+ gHiKey960TokenSpaceGuid.PcdArmFastbootFlashLimit|"134217728"
+ gHiKey960TokenSpaceGuid.PcdXloaderDevicePath|L"VenHw(0D51905B-B77E-452A-A2C0-ECA0CC8D514A,00003BFF0000000000)/UFS(0x0,0x0)"
+
+ #
+ # Android Loader
+ #
+ gEmbeddedTokenSpaceGuid.PcdAndroidBootDevicePath|L"VenHw(0D51905B-B77E-452A-A2C0-ECA0CC8D514A,00003BFF0000000000)/UFS(0x0,0x3)/HD(7,GPT,D3340696-9B95-4C64-8DF6-E6D4548FBA41,0x12100,0x4000)"
+ gEmbeddedTokenSpaceGuid.PcdSdBootDevicePath|L"VenHw(0D51905B-B77E-452A-A2C0-ECA0CC8D514A,00F037FF0000000000)/SD(0x0)/HD(1,MBR,0x00000000,0x3F,0x21FC0)"
+
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|1
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+ #
+ # PEI Phase modules
+ #
+ ArmPlatformPkg/PrePi/PeiUniCore.inf
+
+ #
+ # DXE
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ }
+
+ #
+ # Architectural Protocols
+ #
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+ EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+ #
+ # GPIO
+ #
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf
+ ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+
+ #
+ # Virtual Keyboard
+ #
+ OpenPlatformPkg/Drivers/Keyboard/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
+
+ #
+ # MMC/SD
+ #
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf
+ MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+ OpenPlatformPkg/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.inf
+ MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
+
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
+
+ #
+ # USB Host Support
+ #
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+
+ #
+ # USB Mass Storage Support
+ #
+ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ #
+ # UEFI Network Stack
+ #
+ MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+ MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+ MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+ MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+ MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+ MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+ MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+ MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+ MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+
+ #
+ # AX88772 Ethernet Driver
+ #
+ OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+
+ #
+ # Ufs
+ #
+ OpenPlatformPkg/Drivers/Block/DwUfsHcDxe/DwUfsHcDxe.inf
+ MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # USB Peripheral Support
+ #
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
+ OpenPlatformPkg/Drivers/Usb/DwUsb3Dxe/DwUsb3Dxe.inf
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
+ EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+ #
+ # Fastboot
+ #
+ EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf {
+ <LibraryClasses>
+ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+ }
+
+ #
+ # Android Loader
+ #
+ EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf {
+ <LibraryClasses>
+ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+ }
+
+ #
+ # Bds
+ #
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+ }
+ ShellPkg/Application/Shell/Shell.inf {
+ <LibraryClasses>
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ <PcdsFixedAtBuild>
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+ }
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960.fdf b/Platforms/Hisilicon/HiKey960/HiKey960.fdf
new file mode 100644
index 0000000..ec94e60
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960.fdf
@@ -0,0 +1,377 @@
+#
+# Copyright (c) 2016-2017, Linaro Limited. 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.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL33_AP_UEFI]
+BaseAddress = 0x1AC98000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in NOR Flash.
+Size = 0x000F0000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize = 0x00001000
+NumBlocks = 0xF0
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x000F0000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 8 # FV alignment and FV attributes setting.
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+ INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+ #
+ # Multiple Console IO support
+ #
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+ INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+ #
+ # GPIO
+ #
+ INF OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf
+ INF ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+
+ #
+ # Virtual Keyboard
+ #
+ INF OpenPlatformPkg/Drivers/Keyboard/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
+
+ #
+ # MMC/SD
+ #
+ INF OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf
+ INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+ INF OpenPlatformPkg/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.inf
+ INF MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
+
+ INF OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
+
+ #
+ # UEFI Network Stack
+ #
+ INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+ INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+ INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+ INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+
+ #
+ # AX88772 Ethernet Driver for Apple Ethernet Adapter
+ #
+ INF OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # Ufs
+ #
+ INF OpenPlatformPkg/Drivers/Block/DwUfsHcDxe/DwUfsHcDxe.inf
+ INF MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatBinPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # USB Host Support
+ #
+ INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+
+ #
+ # USB Mass Storage Support
+ #
+ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ #
+ # USB Peripheral Support
+ #
+ INF OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
+ INF OpenPlatformPkg/Drivers/Usb/DwUsb3Dxe/DwUsb3Dxe.inf
+ INF OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
+ INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+ #
+ # Fastboot
+ #
+ INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+
+ #
+ # Android Loader
+ #
+ INF EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf
+
+ #
+ # UEFI applications
+ #
+ INF ShellPkg/Application/Shell/Shell.inf
+
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ INF MdeModulePkg/Application/UiApp/UiApp.inf
+
+
+[FV.FVMAIN_COMPACT]
+FvAlignment = 8
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF ArmPlatformPkg/PrePi/PeiUniCore.inf
+
+ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FVMAIN
+ }
+ }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+#
+# These SEC rules are used for ArmPlatformPkg/PrePi module.
+# ArmPlatformPkg/PrePi is declared as a SEC module to make GenFv patch the
+# UEFI Firmware to jump to ArmPlatformPkg/PrePi entrypoint
+#
+[Rule.ARM.SEC]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.AARCH64.SEC]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 4K $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+# A shim specific rule is required to ensure the alignment is 4K.
+# Otherwise BaseTools pick up the AArch32 alignment (ie: 32)
+[Rule.ARM.SEC.SHIM]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 4K $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+ FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ UI STRING ="$(MODULE_NAME)" Optional
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ }
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c
new file mode 100644
index 0000000..6e4db11
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.c
@@ -0,0 +1,699 @@
+/** @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/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;
+
+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
+ )
+{
+}
+
+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" earlycon=pl011,0xfdf05000,115200 console=ttyAMA5 androidboot.serialno=%s",
+ RandomSN->UnicodeSN
+ );
+ } else {
+ UnicodeSPrint (
+ Args + StrLen (Args), Size - StrLen (Args),
+ L" earlycon=pl011,0xfff32000,115200 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;
+}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
new file mode 100644
index 0000000..df668a8
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960Dxe/HiKey960Dxe.inf
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2016-2017, Linaro Limited. 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.
+#
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = HiKey960Dxe
+ FILE_GUID = 6d824b2c-640e-4643-b9f2-9c09e8bff429
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HiKey960EntryPoint
+
+[Sources.common]
+ HiKey960Dxe.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OpenPlatformPkg/Drivers/Block/DwUfsHcDxe/DwUfsHcDxe.dec
+ OpenPlatformPkg/Drivers/Keyboard/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ CacheMaintenanceLib
+ DebugLib
+ DxeServicesTableLib
+ FdtLib
+ IoLib
+ NonDiscoverableDeviceRegistrationLib
+ PcdLib
+ PrintLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gAbootimgProtocolGuid
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+ gEmbeddedGpioProtocolGuid
+ gPlatformVirtualKeyboardProtocolGuid
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gEfiFileInfoGuid
+
+[Pcd]
+ gDwUfsHcDxeTokenSpaceGuid.PcdDwUfsHcDxeBaseAddress
+ gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+
+[Depex]
+ TRUE
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c b/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c
new file mode 100644
index 0000000..c87040d
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c
@@ -0,0 +1,732 @@
+/** @file
+
+ Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2015-2017, Linaro. 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.
+
+**/
+
+/*
+ Implementation of the Android Fastboot Platform protocol, to be used by the
+ Fastboot UEFI application, for Hisilicon HiKey platform.
+*/
+
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/EraseBlock.h>
+#include <Protocol/SimpleTextOut.h>
+
+#include <Protocol/DevicePathToText.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+
+#define PARTITION_NAME_MAX_LENGTH (72/2)
+
+#define SERIAL_NUMBER_LBA 20
+#define RANDOM_MAX 0x7FFFFFFFFFFFFFFF
+#define RANDOM_MAGIC 0x9A4DBEAF
+
+#define ADB_REBOOT_ADDRESS 0x32100000
+#define ADB_REBOOT_BOOTLOADER 0x77665500
+
+#define UFS_BLOCK_SIZE 4096
+
+typedef struct _FASTBOOT_PARTITION_LIST {
+ LIST_ENTRY Link;
+ CHAR16 PartitionName[PARTITION_NAME_MAX_LENGTH];
+ EFI_LBA StartingLBA;
+ EFI_LBA EndingLBA;
+} FASTBOOT_PARTITION_LIST;
+
+STATIC LIST_ENTRY mPartitionListHead;
+STATIC EFI_HANDLE mFlashHandle;
+STATIC EFI_BLOCK_IO_PROTOCOL *mFlashBlockIo;
+STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;
+
+/*
+ Helper to free the partition list
+*/
+STATIC
+VOID
+FreePartitionList (
+ VOID
+ )
+{
+ FASTBOOT_PARTITION_LIST *Entry;
+ FASTBOOT_PARTITION_LIST *NextEntry;
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+
+ RemoveEntryList (&Entry->Link);
+ FreePool (Entry);
+
+ Entry = NextEntry;
+ }
+}
+
+/*
+ Read the PartitionName fields from the GPT partition entries, putting them
+ into an allocated array that should later be freed.
+*/
+STATIC
+EFI_STATUS
+ReadPartitionEntries (
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ OUT EFI_PARTITION_ENTRY **PartitionEntries,
+ OUT UINTN *PartitionNumbers
+ )
+{
+ UINT32 MediaId;
+ EFI_PARTITION_TABLE_HEADER *GptHeader;
+ EFI_PARTITION_ENTRY *Entry;
+ EFI_STATUS Status;
+ VOID *Buffer;
+ UINTN PageCount;
+ UINTN BlockSize;
+ UINTN Count, EndLBA;
+
+ if ((PartitionEntries == NULL) || (PartitionNumbers == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MediaId = BlockIo->Media->MediaId;
+ BlockSize = BlockIo->Media->BlockSize;
+
+ //
+ // Read size of Partition entry and number of entries from GPT header
+ //
+
+ PageCount = EFI_SIZE_TO_PAGES (6 * BlockSize);
+ Buffer = AllocatePages (PageCount);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = BlockIo->ReadBlocks (BlockIo, MediaId, 0, PageCount * EFI_PAGE_SIZE, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ GptHeader = (EFI_PARTITION_TABLE_HEADER *)(Buffer + BlockSize);
+
+ // Check there is a GPT on the media
+ if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
+ GptHeader->MyLBA != 1) {
+ DEBUG ((DEBUG_ERROR,
+ "Fastboot platform: No GPT on flash. "
+ "Fastboot on Versatile Express does not support MBR.\n"
+ ));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Entry = (EFI_PARTITION_ENTRY *)(Buffer + (2 * BlockSize));
+ EndLBA = GptHeader->FirstUsableLBA - 1;
+ Count = 0;
+ while (1) {
+ if ((Entry->StartingLBA > EndLBA) && (Entry->EndingLBA <= GptHeader->LastUsableLBA)) {
+ Count++;
+ EndLBA = Entry->EndingLBA;
+ Entry++;
+ } else {
+ break;
+ }
+ }
+ if (Count == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Count > GptHeader->NumberOfPartitionEntries) {
+ Count = GptHeader->NumberOfPartitionEntries;
+ }
+
+ *PartitionEntries = (EFI_PARTITION_ENTRY *)((UINTN)Buffer + (2 * BlockSize));
+ *PartitionNumbers = Count;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadPtable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup;
+ UINTN PartitionNumbers = 0;
+ UINTN LoopIndex;
+ EFI_PARTITION_ENTRY *PartitionEntries = NULL;
+ FASTBOOT_PARTITION_LIST *Entry;
+
+ InitializeListHead (&mPartitionListHead);
+
+ Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Status
+ ));
+ return Status;
+ }
+
+ //
+ // Get EFI_HANDLES for all the partitions on the block devices pointed to by
+ // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
+ // There's no way to find all of a device's children, so we get every handle
+ // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
+ // that don't represent partitions on the flash device.
+ //
+ FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+
+ // Create another device path pointer because LocateDevicePath will modify it.
+ FlashDevicePathDup = FlashDevicePath;
+ Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &mFlashHandle);
+ 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 (
+ mFlashHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &mFlashBlockIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Read the GPT partition entry array into memory so we can get the partition names
+ Status = ReadPartitionEntries (mFlashBlockIo, &PartitionEntries, &PartitionNumbers);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
+ // Failing to locate partitions should not prevent to do other Android FastBoot actions
+ return EFI_SUCCESS;
+ }
+ for (LoopIndex = 0; LoopIndex < PartitionNumbers; LoopIndex++) {
+ // Create entry
+ Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
+ if (Entry == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePartitionList ();
+ goto Exit;
+ }
+ StrnCpy (
+ Entry->PartitionName,
+ PartitionEntries[LoopIndex].PartitionName,
+ PARTITION_NAME_MAX_LENGTH
+ );
+ Entry->StartingLBA = PartitionEntries[LoopIndex].StartingLBA;
+ Entry->EndingLBA = PartitionEntries[LoopIndex].EndingLBA;
+ InsertTailList (&mPartitionListHead, &Entry->Link);
+ }
+Exit:
+ FreePages (
+ (VOID *)((UINTN)PartitionEntries - (2 * mFlashBlockIo->Media->BlockSize)),
+ EFI_SIZE_TO_PAGES (6 * mFlashBlockIo->Media->BlockSize)
+ );
+ return Status;
+}
+
+/*
+ Initialise: Open the Android NVM device and find the partitions on it. Save them in
+ a list along with the "PartitionName" fields for their GPT entries.
+ We will use these partition names as the key in
+ HiKey960FastbootPlatformFlashPartition.
+*/
+EFI_STATUS
+HiKey960FastbootPlatformInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = LoadPtable ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return Status;
+}
+
+VOID
+HiKey960FastbootPlatformUnInit (
+ VOID
+ )
+{
+ FreePartitionList ();
+}
+
+EFI_STATUS
+HiKey960FlashPtable (
+ IN UINTN Size,
+ IN VOID *Image
+ )
+{
+ EFI_STATUS Status;
+ Status = mFlashBlockIo->WriteBlocks (
+ mFlashBlockIo,
+ mFlashBlockIo->Media->MediaId,
+ 0,
+ Size,
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
+ return Status;
+ }
+ FreePartitionList ();
+ Status = LoadPtable ();
+ return Status;
+}
+
+EFI_STATUS
+HiKey960ErasePtable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+#if 0
+ EFI_ERASE_BLOCK_PROTOCOL *EraseBlockProtocol;
+#endif
+
+#if 0
+ Status = gBS->OpenProtocol (
+ mFlashHandle,
+ &gEfiEraseBlockProtocolGuid,
+ (VOID **) &EraseBlockProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fastboot platform: could not open Erase Block IO: %r\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+ Status = EraseBlockProtocol->EraseBlocks (
+ EraseBlockProtocol,
+ mFlashBlockIo->Media->MediaId,
+ 0,
+ NULL,
+ 6 * mFlashBlockIo->Media->BlockSize
+ );
+#else
+ {
+ VOID *DataPtr;
+ UINTN Lba;
+
+ DataPtr = AllocatePages (1);
+ ZeroMem (DataPtr, EFI_PAGE_SIZE);
+ for (Lba = 0; Lba < 6; Lba++) {
+ Status = mFlashBlockIo->WriteBlocks (
+ mFlashBlockIo,
+ mFlashBlockIo->Media->MediaId,
+ Lba,
+ EFI_PAGE_SIZE,
+ DataPtr
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+Exit:
+ FreePages (DataPtr, 1);
+ }
+#endif
+ FreePartitionList ();
+ return Status;
+}
+
+EFI_STATUS
+HiKey960FlashXloader (
+ IN UINTN Size,
+ IN VOID *Image
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_HANDLE Handle;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ DevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdXloaderDevicePath));
+
+ Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePath, &Handle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate xloader device (status: %r)\n", Status));
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlockIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open xloader device (status: %r)\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **) &DiskIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = DiskIo->WriteDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ 0,
+ Size,
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
+ return Status;
+ }
+ return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformFlashPartition (
+ IN CHAR8 *PartitionName,
+ IN UINTN Size,
+ IN VOID *Image
+ )
+{
+ EFI_STATUS Status;
+ UINTN PartitionSize;
+ FASTBOOT_PARTITION_LIST *Entry;
+ CHAR16 PartitionNameUnicode[60];
+ BOOLEAN PartitionFound;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINTN BlockSize;
+
+ // Support the pseudo partition name, such as "ptable".
+ if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+ return HiKey960FlashPtable (Size, Image);
+ } else if (AsciiStrCmp (PartitionName, "xloader") == 0) {
+ return HiKey960FlashXloader (Size, Image);
+ }
+
+ AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+ PartitionFound = FALSE;
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ // Search the partition list for the partition named by PartitionName
+ if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+ PartitionFound = TRUE;
+ break;
+ }
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+ }
+ if (!PartitionFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Check image will fit on device
+ BlockSize = mFlashBlockIo->Media->BlockSize;
+ PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * BlockSize;
+ if (PartitionSize < Size) {
+ DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
+ DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));
+
+ return EFI_VOLUME_FULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ mFlashHandle,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **) &DiskIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = DiskIo->WriteDisk (
+ DiskIo,
+ mFlashBlockIo->Media->MediaId,
+ Entry->StartingLBA * BlockSize,
+ Size,
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize, Status));
+ return Status;
+ }
+
+ mFlashBlockIo->FlushBlocks(mFlashBlockIo);
+ MicroSecondDelay (50000);
+
+ return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformErasePartition (
+ IN CHAR8 *PartitionName
+ )
+{
+ EFI_STATUS Status;
+ EFI_ERASE_BLOCK_PROTOCOL *EraseBlockProtocol;
+ UINTN Size;
+ BOOLEAN PartitionFound;
+ CHAR16 PartitionNameUnicode[60];
+ FASTBOOT_PARTITION_LIST *Entry;
+
+ AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+
+ // Support the pseudo partition name, such as "ptable".
+ if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+ return HiKey960ErasePtable ();
+ }
+
+ PartitionFound = FALSE;
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ // Search the partition list for the partition named by PartitionName
+ if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+ PartitionFound = TRUE;
+ break;
+ }
+ Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+ }
+ if (!PartitionFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->OpenProtocol (
+ mFlashHandle,
+ &gEfiEraseBlockProtocolGuid,
+ (VOID **) &EraseBlockProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Size = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+ Status = EraseBlockProtocol->EraseBlocks (
+ EraseBlockProtocol,
+ mFlashBlockIo->Media->MediaId,
+ Entry->StartingLBA,
+ NULL,
+ Size
+ );
+ return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformGetVar (
+ IN CHAR8 *Name,
+ OUT CHAR8 *Value
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 PartitionSize;
+ FASTBOOT_PARTITION_LIST *Entry;
+ CHAR16 PartitionNameUnicode[60];
+ BOOLEAN PartitionFound;
+ CHAR16 UnicodeSN[SERIAL_NUMBER_SIZE];
+
+ if (!AsciiStrCmp (Name, "max-download-size")) {
+ AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit));
+ } else if (!AsciiStrCmp (Name, "product")) {
+ AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
+ } else if (!AsciiStrCmp (Name, "serialno")) {
+ Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+ UnicodeStrToAsciiStr (UnicodeSN, Value);
+ } else if ( !AsciiStrnCmp (Name, "partition-size", 14)) {
+ AsciiStrToUnicodeStr ((Name + 15), PartitionNameUnicode);
+ PartitionFound = FALSE;
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ // Search the partition list for the partition named by PartitionName
+ if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+ PartitionFound = TRUE;
+ break;
+ }
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+ }
+ if (!PartitionFound) {
+ *Value = '\0';
+ return EFI_NOT_FOUND;
+ }
+
+ PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+ DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-size:%a 0X%llx\n", Name, PartitionSize ));
+ AsciiSPrint (Value, 12, "0x%llx", PartitionSize);
+ } else if ( !AsciiStrnCmp (Name, "partition-type", 14)) {
+ DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-type:%a\n", (Name + 15) ));
+ if ( !AsciiStrnCmp ( (Name + 15) , "system", 6) || !AsciiStrnCmp ( (Name + 15) , "userdata", 8)
+ || !AsciiStrnCmp ( (Name + 15) , "cache", 5)) {
+ AsciiStrCpy (Value, "ext4");
+ } else {
+ AsciiStrCpy (Value, "raw");
+ }
+ } else if ( !AsciiStrCmp (Name, "erase-block-size")) {
+ AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE);
+ } else if ( !AsciiStrCmp (Name, "logical-block-size")) {
+ AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE);
+ } else {
+ *Value = '\0';
+ }
+ return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformOemCommand (
+ IN CHAR8 *Command
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 UnicodeSN[SERIAL_NUMBER_SIZE];
+
+ if (AsciiStrCmp (Command, "Demonstrate") == 0) {
+ DEBUG ((DEBUG_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
+ return EFI_SUCCESS;
+ } else if (AsciiStrCmp (Command, "serialno") == 0) {
+ Status = GenerateUsbSN (UnicodeSN);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to generate USB Serial Number.\n"));
+ return Status;
+ }
+ Status = StoreSNToBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+ return Status;
+ } else if (AsciiStrCmp (Command, "reboot-bootloader") == 0) {
+ MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_BOOTLOADER);
+ WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_ERROR,
+ "HiKey960: Unrecognised Fastboot OEM command: %a\n",
+ Command
+ ));
+ return EFI_NOT_FOUND;
+ }
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformFlashPartitionEx (
+ IN CHAR8 *PartitionName,
+ IN UINTN Offset,
+ IN UINTN Size,
+ IN VOID *Image
+ )
+{
+ EFI_STATUS Status;
+ UINTN PartitionSize;
+ FASTBOOT_PARTITION_LIST *Entry;
+ CHAR16 PartitionNameUnicode[60];
+ BOOLEAN PartitionFound;
+ UINTN BlockSize;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+ PartitionFound = FALSE;
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ // Search the partition list for the partition named by PartitionName
+ if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+ PartitionFound = TRUE;
+ break;
+ }
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+ }
+ if (!PartitionFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Check image will fit on device
+ PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+ if (PartitionSize < Size) {
+ DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
+ DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));
+
+ return EFI_VOLUME_FULL;
+ }
+
+ BlockSize = mFlashBlockIo->Media->BlockSize;
+
+ Status = gBS->OpenProtocol (
+ mFlashHandle,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **) &DiskIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = DiskIo->WriteDisk (
+ DiskIo,
+ mFlashBlockIo->Media->MediaId,
+ Entry->StartingLBA * BlockSize + Offset,
+ Size,
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize + Offset, Status));
+ return Status;
+ }
+ return Status;
+}
+
+FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
+ HiKey960FastbootPlatformInit,
+ HiKey960FastbootPlatformUnInit,
+ HiKey960FastbootPlatformFlashPartition,
+ HiKey960FastbootPlatformErasePartition,
+ HiKey960FastbootPlatformGetVar,
+ HiKey960FastbootPlatformOemCommand,
+ HiKey960FastbootPlatformFlashPartitionEx
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960FastbootPlatformEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gAndroidFastbootPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPlatformProtocol
+ );
+}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
new file mode 100644
index 0000000..180b624
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
@@ -0,0 +1,62 @@
+#/** @file
+#
+# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2015-2017, Linaro. 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = HiKey960FastbootDxe
+ FILE_GUID = 80f046c6-d5ba-4916-a656-2e2b28d32304
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HiKey960FastbootPlatformEntryPoint
+
+[Sources.common]
+ HiKey960FastbootDxe.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+ DebugLib
+ DevicePathLib
+ IoLib
+ MemoryAllocationLib
+ PcdLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ UsbSerialNumberLib
+ TimerLib
+
+[Protocols]
+ gAndroidFastbootPlatformProtocolGuid
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+ gEfiDiskIoProtocolGuid
+ gEfiEraseBlockProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
+
+[Packages]
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dec
+
+[Pcd]
+ gArmPlatformTokenSpaceGuid.PcdFirmwareVendor
+ gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+ gHiKey960TokenSpaceGuid.PcdArmFastbootFlashLimit
+ gHiKey960TokenSpaceGuid.PcdXloaderDevicePath
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.c b/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.c
new file mode 100644
index 0000000..7c61ff7
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.c
@@ -0,0 +1,77 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro. 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 <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+
+GPIO_CONTROLLER gGpioDevice[]= {
+ { 0xe8a0b000, 0, 8 }, // GPIO0
+ { 0xe8a0c000, 8, 8 }, // GPIO1
+ { 0xe8a0d000, 16, 8 }, // GPIO2
+ { 0xe8a0e000, 24, 8 }, // GPIO3
+ { 0xe8a0f000, 32, 8 }, // GPIO4
+ { 0xe8a10000, 40, 8 }, // GPIO5
+ { 0xe8a11000, 48, 8 }, // GPIO6
+ { 0xe8a12000, 56, 8 }, // GPIO7
+ { 0xe8a13000, 64, 8 }, // GPIO8
+ { 0xe8a14000, 72, 8 }, // GPIO9
+ { 0xe8a15000, 80, 8 }, // GPIO10
+ { 0xe8a16000, 88, 8 }, // GPIO11
+ { 0xe8a17000, 96, 8 }, // GPIO12
+ { 0xe8a18000, 104, 8 }, // GPIO13
+ { 0xe8a19000, 112, 8 }, // GPIO14
+ { 0xe8a1a000, 120, 8 }, // GPIO15
+ { 0xe8a1b000, 128, 8 }, // GPIO16
+ { 0xe8a1c000, 136, 8 }, // GPIO17
+ { 0xff3b4000, 144, 8 }, // GPIO18
+ { 0xff3b5000, 152, 8 }, // GPIO19
+ { 0xe8a1f000, 160, 8 }, // GPIO20
+ { 0xe8a20000, 168, 8 }, // GPIO21
+ { 0xfff0b000, 176, 8 }, // GPIO22
+ { 0xfff0c000, 184, 8 }, // GPIO23
+ { 0xfff0d000, 192, 8 }, // GPIO24
+ { 0xfff0e000, 200, 8 }, // GPIO25
+ { 0xfff0f000, 208, 8 }, // GPIO26
+ { 0xfff10000, 216, 8 }, // GPIO27
+ { 0xfff1d000, 224, 8 }, // GPIO28
+};
+
+PLATFORM_GPIO_CONTROLLER gPlatformGpioDevice = {
+ 232, 29, gGpioDevice
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960GpioEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ // Install the Embedded Platform GPIO Protocol onto a new handle
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gPlatformGpioProtocolGuid, &gPlatformGpioDevice,
+ NULL
+ );
+ if (EFI_ERROR(Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ return Status;
+}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf
new file mode 100644
index 0000000..9160afe
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960GpioDxe/HiKey960GpioDxe.inf
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2017, Linaro. 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.
+#
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = HiKey960Gpio
+ FILE_GUID = 6aa12592-7e36-4aec-acf8-2ac2fd13815c
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HiKey960GpioEntryPoint
+
+[Sources.common]
+ HiKey960GpioDxe.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dec
+
+[LibraryClasses]
+ DebugLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gPlatformGpioProtocolGuid
+
+[Depex]
+ TRUE
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.c b/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.c
new file mode 100644
index 0000000..3e52270
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.c
@@ -0,0 +1,125 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro. 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 <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+#include <Protocol/PlatformDwMmc.h>
+
+#include <Hi3660.h>
+
+#define DETECT_SD_CARD 203 // GPIO 25_3
+
+DW_MMC_HC_SLOT_CAP
+DwMmcCapability[1] = {
+ {
+ .HighSpeed = 1,
+ .BusWidth = 4,
+ .SlotType = RemovableSlot,
+ .CardType = SdCardType,
+ .Voltage30 = 1,
+ .BaseClkFreq = 3200
+ }
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960GetCapability (
+ IN EFI_HANDLE Controller,
+ IN UINT8 Slot,
+ OUT DW_MMC_HC_SLOT_CAP *Capability
+ )
+{
+ if (Capability == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DwMmcCapability[0].Controller == 0) {
+ DwMmcCapability[0].Controller = Controller;
+ CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
+ } else if (DwMmcCapability[0].Controller == Controller) {
+ CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+EFIAPI
+HiKey960CardDetect (
+ IN UINT8 Slot
+ )
+{
+ EFI_STATUS Status;
+ EMBEDDED_GPIO *Gpio;
+ UINTN Value;
+
+ if (Slot == 0) {
+ Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to get GPIO protocol: %r\n", Status));
+ goto Exit;
+ }
+ Status = Gpio->Set (Gpio, DETECT_SD_CARD, GPIO_MODE_INPUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to sed GPIO as input mode: %r\n", Status));
+ goto Exit;
+ }
+ Status = Gpio->Get (Gpio, DETECT_SD_CARD, &Value);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to get GPIO value: %r\n", Status));
+ goto Exit;
+ }
+ if (Value == 0) {
+ return TRUE;
+ }
+ }
+Exit:
+ return FALSE;
+}
+
+PLATFORM_DW_MMC_PROTOCOL mDwMmcDevice = {
+ HiKey960GetCapability,
+ HiKey960CardDetect
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960MmcEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gPlatformDwMmcProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mDwMmcDevice
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return Status;
+}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf
new file mode 100644
index 0000000..2d843f9
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960MmcDxe/HiKey960MmcDxe.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+# Copyright (c) 2017, Linaro. 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = HiKey960MmcDxe
+ FILE_GUID = e10d1dea-2f00-4eea-ac5d-9d6cfa7831a0
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HiKey960MmcEntryPoint
+
+[Sources.common]
+ HiKey960MmcDxe.c
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiDriverBindingProtocolGuid
+ gEmbeddedGpioProtocolGuid
+ gPlatformDwMmcProtocolGuid
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OpenPlatformPkg/Drivers/SdMmc/DwMmcHcDxe/DwMmcHcDxe.dec
+
+[Depex]
+ TRUE
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c b/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c
new file mode 100644
index 0000000..8a771b6
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c
@@ -0,0 +1,363 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro. 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 <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DwUsb.h>
+
+#include <Hi3660.h>
+
+#define USB_EYE_PARAM 0x01c466e3
+#define USB_PHY_TX_VBOOST_LVL 5
+
+#define DWC3_PHY_RX_OVRD_IN_HI 0x1006
+#define DWC3_PHY_RX_SCOPE_VDCC 0x1026
+
+#define RX_SCOPE_LFPS_EN (1 << 0)
+
+#define TX_VBOOST_LVL_MASK 7
+#define TX_VBOOST_LVL(x) ((x) & TX_VBOOST_LVL_MASK)
+
+#define SERIAL_NUMBER_LBA 20
+
+STATIC EFI_HANDLE mFlashHandle;
+
+UINTN
+HiKey960GetUsbMode (
+ IN VOID
+ )
+{
+ return USB_DEVICE_MODE;
+}
+
+VOID
+HiKey960UsbPhyCrWaitAck (
+ VOID
+ )
+{
+ INT32 Timeout = 1000;
+ UINT32 Data;
+
+ while (TRUE) {
+ Data = MmioRead32 (USB3OTG_PHY_CR_STS);
+ if ((Data & USB3OTG_PHY_CR_ACK) == USB3OTG_PHY_CR_ACK) {
+ return;
+ }
+ MicroSecondDelay (50);
+ if (Timeout-- <= 0) {
+ DEBUG ((DEBUG_ERROR, "Wait PHY_CR_ACK timeout!\n"));
+ return;
+ }
+ }
+}
+
+VOID
+HiKey960UsbPhyCrSetAddr (
+ IN UINT32 Addr
+ )
+{
+ // set addr
+ MmioWrite32 (
+ USB3OTG_PHY_CR_CTRL,
+ USB3OTG_PHY_CR_DATA_IN (Addr)
+ );
+ MicroSecondDelay (100);
+ // cap addr
+ MmioOr32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_CAP_ADDR);
+ HiKey960UsbPhyCrWaitAck ();
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+}
+
+UINT16
+HiKey960UsbPhyCrRead (
+ IN UINT32 Addr
+ )
+{
+ INT32 Timeout = 1000;
+ UINT32 Data;
+
+ HiKey960UsbPhyCrSetAddr (Addr);
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_READ);
+ MicroSecondDelay (100);
+
+ while (TRUE) {
+ Data = MmioRead32 (USB3OTG_PHY_CR_STS);
+ if ((Data & USB3OTG_PHY_CR_ACK) == USB3OTG_PHY_CR_ACK) {
+ DEBUG ((
+ DEBUG_INFO,
+ "Addr 0x%x, Data Out:0x%x\n",
+ Addr,
+ USB3OTG_PHY_CR_DATA_OUT(Data)
+ ));
+ break;
+ }
+ MicroSecondDelay (50);
+ if (Timeout-- <= 0) {
+ DEBUG ((DEBUG_ERROR, "Wait PHY_CR_ACK timeout!\n"));
+ break;
+ }
+ }
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+ return (UINT16)USB3OTG_PHY_CR_DATA_OUT(Data);
+}
+
+VOID
+HiKey960UsbPhyCrWrite (
+ IN UINT32 Addr,
+ IN UINT32 Value
+ )
+{
+ UINT32 Data;
+
+ HiKey960UsbPhyCrSetAddr (Addr);
+ Data = USB3OTG_PHY_CR_DATA_IN(Value);
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, Data);
+
+ Data = MmioRead32 (USB3OTG_PHY_CR_CTRL);
+ Data |= USB3OTG_PHY_CR_CAP_DATA;
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, Data);
+ HiKey960UsbPhyCrWaitAck ();
+
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+ MmioWrite32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_WRITE);
+ HiKey960UsbPhyCrWaitAck ();
+}
+
+VOID
+HiKey960UsbSetEyeDiagramParam (
+ VOID
+ )
+{
+ UINT32 Data;
+
+ /* set eye diagram for usb 2.0 */
+ MmioWrite32 (USB3OTG_CTRL4, USB_EYE_PARAM);
+ /* set eye diagram for usb 3.0 */
+ HiKey960UsbPhyCrRead (DWC3_PHY_RX_OVRD_IN_HI);
+ HiKey960UsbPhyCrWrite (DWC3_PHY_RX_OVRD_IN_HI, BIT11 | BIT9 | BIT8 |BIT7);
+ HiKey960UsbPhyCrRead (DWC3_PHY_RX_OVRD_IN_HI);
+
+ /* enable RX_SCOPE_LFPS_EN for usb 3.0 */
+ Data = HiKey960UsbPhyCrRead (DWC3_PHY_RX_SCOPE_VDCC);
+ Data |= RX_SCOPE_LFPS_EN;
+ HiKey960UsbPhyCrWrite (DWC3_PHY_RX_SCOPE_VDCC, Data);
+ HiKey960UsbPhyCrRead (DWC3_PHY_RX_SCOPE_VDCC);
+
+ Data = MmioRead32 (USB3OTG_CTRL6);
+ Data &= ~TX_VBOOST_LVL_MASK;
+ Data = TX_VBOOST_LVL (USB_PHY_TX_VBOOST_LVL);
+ MmioWrite32 (USB3OTG_CTRL6, Data);
+ DEBUG ((
+ DEBUG_INFO,
+ "set ss phy tx vboost lvl 0x%x\n",
+ MmioRead32 (USB3OTG_CTRL6)
+ ));
+}
+
+STATIC
+VOID
+HiKey960UsbReset (
+ VOID
+ )
+{
+ MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTG);
+ MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTGPHY_POR);
+ MmioWrite32 (
+ CRG_PERRSTEN4,
+ PERRSTEN4_USB3OTG_MUX | PERRSTEN4_USB3OTG_AHBIF | PERRSTEN4_USB3OTG_32K
+ );
+ MmioWrite32 (
+ CRG_PERDIS4,
+ PEREN4_GT_ACLK_USB3OTG | PEREN4_GT_CLK_USB3OTG_REF
+ );
+
+ MmioAnd32 (PCTRL_CTRL24, ~PCTRL_CTRL24_USB3PHY_3MUX1_SEL);
+ // disable
+ MmioWrite32 (PCTRL_CTRL3, (PCTRL_CTRL3_USB_TXCO_EN << 16) | 0);
+ MicroSecondDelay (10000);
+}
+
+STATIC
+VOID
+HiKey960UsbRelease (
+ VOID
+ )
+{
+ /* enable USB REFCLK ISO */
+ MmioWrite32 (CRG_ISODIS, PERISOEN_USB_REFCLK_ISO_EN);
+ /* enable USB_TXCO_EN */
+ MmioWrite32 (PCTRL_CTRL3, (PCTRL_CTRL3_USB_TXCO_EN << 16) | PCTRL_CTRL3_USB_TXCO_EN);
+
+ MmioAnd32 (PCTRL_CTRL24, ~PCTRL_CTRL24_USB3PHY_3MUX1_SEL);
+
+ MmioWrite32 (
+ CRG_PEREN4,
+ PEREN4_GT_ACLK_USB3OTG | PEREN4_GT_CLK_USB3OTG_REF
+ );
+ MmioWrite32 (
+ CRG_PERRSTDIS4,
+ PERRSTEN4_USB3OTG_MUX | PERRSTEN4_USB3OTG_AHBIF | PERRSTEN4_USB3OTG_32K
+ );
+
+ MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTG | PERRSTEN4_USB3OTGPHY_POR);
+
+ /* enable PHY REF CLK */
+ MmioOr32 (USB3OTG_CTRL0, USB3OTG_CTRL0_SC_USB3PHY_ABB_GT_EN);
+
+ MmioOr32 (USB3OTG_CTRL7, USB3OTG_CTRL7_REF_SSP_EN);
+
+ /* exit from IDDQ mode */
+ MmioAnd32 (
+ USB3OTG_CTRL2,
+ ~(USB3OTG_CTRL2_TEST_POWERDOWN_SSP | USB3OTG_CTRL2_TEST_POWERDOWN_HSP)
+ );
+ MicroSecondDelay (100000);
+
+ MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_USB3OTGPHY_POR);
+ MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_USB3OTG);
+ MicroSecondDelay (10000);
+ MmioOr32 (USB3OTG_CTRL3, USB3OTG_CTRL3_VBUSVLDEXT | USB3OTG_CTRL3_VBUSVLDEXTSEL);
+ MicroSecondDelay (100000);
+
+ HiKey960UsbSetEyeDiagramParam ();
+}
+
+EFI_STATUS
+HiKey960UsbPhyInit (
+ IN UINT8 Mode
+ )
+{
+ HiKey960UsbReset ();
+ MicroSecondDelay (10000);
+ HiKey960UsbRelease ();
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetLang (
+ OUT CHAR16 *Lang,
+ OUT UINT8 *Length
+ )
+{
+ if ((Lang == NULL) || (Length == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Lang[0] = 0x409;
+ *Length = sizeof (CHAR16);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetManuFacturer (
+ OUT CHAR16 *ManuFacturer,
+ OUT UINT8 *Length
+ )
+{
+ UINTN VariableSize;
+ CHAR16 DataUnicode[MANU_FACTURER_STRING_LENGTH];
+
+ if ((ManuFacturer == NULL) || (Length == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ VariableSize = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
+ ZeroMem (DataUnicode, MANU_FACTURER_STRING_LENGTH * sizeof(CHAR16));
+ StrCpy (DataUnicode, L"96Boards");
+ CopyMem (ManuFacturer, DataUnicode, VariableSize);
+ *Length = VariableSize;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetProduct (
+ OUT CHAR16 *Product,
+ OUT UINT8 *Length
+ )
+{
+ UINTN VariableSize;
+ CHAR16 DataUnicode[PRODUCT_STRING_LENGTH];
+
+ if ((Product == NULL) || (Length == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ VariableSize = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
+ ZeroMem (DataUnicode, PRODUCT_STRING_LENGTH * sizeof(CHAR16));
+ StrCpy (DataUnicode, L"HiKey960");
+ CopyMem (Product, DataUnicode, VariableSize);
+ *Length = VariableSize;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetSerialNo (
+ OUT CHAR16 *SerialNo,
+ OUT UINT8 *Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath;
+
+ if (mFlashHandle == 0) {
+ FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+ Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePath, &mFlashHandle);
+ 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;
+ }
+ }
+
+ if ((SerialNo == NULL) || (Length == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, SerialNo);
+ *Length = StrSize (SerialNo);
+ return Status;
+}
+
+DW_USB_PROTOCOL mDwUsbDevice = {
+ HiKey960UsbGetLang,
+ HiKey960UsbGetManuFacturer,
+ HiKey960UsbGetProduct,
+ HiKey960UsbGetSerialNo,
+ HiKey960UsbPhyInit
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gDwUsbProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mDwUsbDevice
+ );
+}
diff --git a/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf b/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
new file mode 100644
index 0000000..8f42b75
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
@@ -0,0 +1,50 @@
+#/** @file
+#
+# Copyright (c) 2015-2017, Linaro. 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = HiKey960UsbDxe
+ FILE_GUID = 9998be97-6fb6-40f6-a98d-d797dc7b9d32
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HiKey960UsbEntryPoint
+
+[Sources.common]
+ HiKey960UsbDxe.c
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UsbSerialNumberLib
+
+[Protocols]
+ gDwUsbProtocolGuid
+ gEfiBlockIoProtocolGuid
+ gEfiDriverBindingProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ OpenPlatformPkg/Drivers/Usb/DwUsb3Dxe/DwUsb3Dxe.dec
+ OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dec
+
+[Pcd]
+ gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+
+[Depex]
+ TRUE
diff --git a/Platforms/Hisilicon/HiKey960/Include/ArmPlatform.h b/Platforms/Hisilicon/HiKey960/Include/ArmPlatform.h
new file mode 100644
index 0000000..e7772f7
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Include/ArmPlatform.h
@@ -0,0 +1,26 @@
+/** @file
+*
+* Copyright (c) 2016-2017, Linaro Limited. 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.
+*
+**/
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+//
+// We don't care about this value, but the PL031 driver depends on the macro
+// to exist: it will pass it on to our ArmPlatformSysConfigLib:ConfigGet()
+// function, which just returns EFI_UNSUPPORTED.
+//
+//
+#define SYS_CFG_RTC 0
+
+#endif /* __PLATFORM_H__ */
diff --git a/Platforms/Hisilicon/HiKey960/Include/Guid/HiKey960Variable.h b/Platforms/Hisilicon/HiKey960/Include/Guid/HiKey960Variable.h
new file mode 100644
index 0000000..b9909c2
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Include/Guid/HiKey960Variable.h
@@ -0,0 +1,24 @@
+/** @file
+*
+* Copyright (c) 2013-2014, ARM Limited. All rights reserved.
+* Copyright (c) 2015-2016, Linaro. 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.
+*
+**/
+
+#ifndef __HIKEY960_VARIABLE_H__
+#define __HIKEY960_VARIABLE_H__
+
+#define HIKEY960_VARIABLE_GUID \
+ { 0x29727c8d, 0x3531, 0x7a41, { 0x81, 0x9c, 0x7e, 0x50, 0x4e, 0xdd, 0x24, 0x3f } }
+
+extern EFI_GUID gHiKey960VariableGuid;
+
+#endif /* __HIKEY960_VARIABLE_H__ */
diff --git a/Platforms/Hisilicon/HiKey960/Include/Hi3660.h b/Platforms/Hisilicon/HiKey960/Include/Hi3660.h
new file mode 100644
index 0000000..939f7f0
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Include/Hi3660.h
@@ -0,0 +1,145 @@
+/** @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.
+*
+**/
+
+#ifndef __HI3660_H__
+#define __HI3660_H__
+
+#define HKADC_SSI_REG_BASE 0xE82B8000
+
+#define PCTRL_REG_BASE 0xE8A09000
+
+#define PCTRL_CTRL3 (PCTRL_REG_BASE + 0x010)
+#define PCTRL_CTRL24 (PCTRL_REG_BASE + 0x064)
+
+#define PCTRL_CTRL3_USB_TXCO_EN (1 << 1)
+#define PCTRL_CTRL24_USB3PHY_3MUX1_SEL (1 << 25)
+
+#define SCTRL_REG_BASE 0xFFF0A000
+
+#define SCTRL_SCFPLLCTRL0 (SCTRL_REG_BASE + 0x120)
+#define SCTRL_SCFPLLCTRL0_FPLL0_EN (1 << 0)
+
+#define USB3OTG_BC_REG_BASE 0xFF200000
+
+#define USB3OTG_CTRL0 (USB3OTG_BC_REG_BASE + 0x000)
+#define USB3OTG_CTRL2 (USB3OTG_BC_REG_BASE + 0x008)
+#define USB3OTG_CTRL3 (USB3OTG_BC_REG_BASE + 0x00C)
+#define USB3OTG_CTRL4 (USB3OTG_BC_REG_BASE + 0x010)
+#define USB3OTG_CTRL6 (USB3OTG_BC_REG_BASE + 0x018)
+#define USB3OTG_CTRL7 (USB3OTG_BC_REG_BASE + 0x01C)
+#define USB3OTG_PHY_CR_STS (USB3OTG_BC_REG_BASE + 0x050)
+#define USB3OTG_PHY_CR_CTRL (USB3OTG_BC_REG_BASE + 0x054)
+
+#define USB3OTG_CTRL0_SC_USB3PHY_ABB_GT_EN (1 << 15)
+#define USB3OTG_CTRL2_TEST_POWERDOWN_SSP (1 << 1)
+#define USB3OTG_CTRL2_TEST_POWERDOWN_HSP (1 << 0)
+#define USB3OTG_CTRL3_VBUSVLDEXT (1 << 6)
+#define USB3OTG_CTRL3_VBUSVLDEXTSEL (1 << 5)
+#define USB3OTG_CTRL7_REF_SSP_EN (1 << 16)
+#define USB3OTG_PHY_CR_DATA_OUT(x) (((x) & 0xFFFF) << 1)
+#define USB3OTG_PHY_CR_ACK (1 << 0)
+#define USB3OTG_PHY_CR_DATA_IN(x) (((x) & 0xFFFF) << 4)
+#define USB3OTG_PHY_CR_WRITE (1 << 3)
+#define USB3OTG_PHY_CR_READ (1 << 2)
+#define USB3OTG_PHY_CR_CAP_DATA (1 << 1)
+#define USB3OTG_PHY_CR_CAP_ADDR (1 << 0)
+
+#define PMU_REG_BASE 0xFFF34000
+#define PMIC_HARDWARE_CTRL0 (PMU_REG_BASE + (0x0C5 << 2))
+#define PMIC_OSC32K_ONOFF_CTRL (PMU_REG_BASE + (0x0CC << 2))
+
+#define PMIC_HARDWARE_CTRL0_WIFI_CLK (1 << 5)
+#define PMIC_OSC32K_ONOFF_CTRL_EN_32K (1 << 1)
+
+
+#define CRG_REG_BASE 0xFFF35000
+
+#define CRG_PEREN2 (CRG_REG_BASE + 0x020)
+#define CRG_PERDIS2 (CRG_REG_BASE + 0x024)
+#define CRG_PERCLKEN2 (CRG_REG_BASE + 0x028)
+#define CRG_PERSTAT2 (CRG_REG_BASE + 0x02C)
+#define CRG_PEREN4 (CRG_REG_BASE + 0x040)
+#define CRG_PERDIS4 (CRG_REG_BASE + 0x044)
+#define CRG_PERCLKEN4 (CRG_REG_BASE + 0x048)
+#define CRG_PERSTAT4 (CRG_REG_BASE + 0x04C)
+#define CRG_PERRSTEN2 (CRG_REG_BASE + 0x078)
+#define CRG_PERRSTDIS2 (CRG_REG_BASE + 0x07C)
+#define CRG_PERRSTSTAT2 (CRG_REG_BASE + 0x080)
+#define CRG_PERRSTEN3 (CRG_REG_BASE + 0x084)
+#define CRG_PERRSTDIS3 (CRG_REG_BASE + 0x088)
+#define CRG_PERRSTSTAT3 (CRG_REG_BASE + 0x08C)
+#define CRG_PERRSTEN4 (CRG_REG_BASE + 0x090)
+#define CRG_PERRSTDIS4 (CRG_REG_BASE + 0x094)
+#define CRG_PERRSTSTAT4 (CRG_REG_BASE + 0x098)
+#define CRG_ISOEN (CRG_REG_BASE + 0x144)
+#define CRG_ISODIS (CRG_REG_BASE + 0x148)
+#define CRG_ISOSTAT (CRG_REG_BASE + 0x14C)
+
+#define PERI_UFS_BIT (1 << 12)
+#define PERI_ARST_UFS_BIT (1 << 7)
+
+#define PEREN2_HKADCSSI BIT24
+
+#define PEREN4_GT_ACLK_USB3OTG (1 << 1)
+#define PEREN4_GT_CLK_USB3OTG_REF (1 << 0)
+
+#define PERRSTEN2_HKADCSSI BIT24
+
+#define PERRSTEN4_USB3OTG_MUX (1 << 8)
+#define PERRSTEN4_USB3OTG_AHBIF (1 << 7)
+#define PERRSTEN4_USB3OTG_32K (1 << 6)
+#define PERRSTEN4_USB3OTG (1 << 5)
+#define PERRSTEN4_USB3OTGPHY_POR (1 << 3)
+
+#define PERISOEN_USB_REFCLK_ISO_EN (1 << 25)
+
+#define CRG_CLKDIV16_OFFSET 0x0E8
+#define SC_DIV_UFSPHY_CFG_MASK (0x3 << 9)
+#define SC_DIV_UFSPHY_CFG(x) (((x) & 0x3) << 9)
+
+#define CRG_CLKDIV17_OFFSET 0x0EC
+#define SC_DIV_UFS_PERIBUS (1 << 14)
+
+#define UFS_SYS_REG_BASE 0xFF3B1000
+
+#define UFS_SYS_PSW_POWER_CTRL_OFFSET 0x004
+#define UFS_SYS_PHY_ISO_EN_OFFSET 0x008
+#define UFS_SYS_HC_LP_CTRL_OFFSET 0x00C
+#define UFS_SYS_PHY_CLK_CTRL_OFFSET 0x010
+#define UFS_SYS_PSW_CLK_CTRL_OFFSET 0x014
+#define UFS_SYS_CLOCK_GATE_BYPASS_OFFSET 0x018
+#define UFS_SYS_RESET_CTRL_EN_OFFSET 0x01C
+#define UFS_SYS_MONITOR_HH_OFFSET 0x03C
+#define UFS_SYS_UFS_SYSCTRL_OFFSET 0x05C
+#define UFS_SYS_UFS_DEVICE_RESET_CTRL_OFFSET 0x060
+#define UFS_SYS_UFS_APB_ADDR_MASK_OFFSET 0x064
+
+#define BIT_UFS_PSW_ISO_CTRL (1 << 16)
+#define BIT_UFS_PSW_MTCMOS_EN (1 << 0)
+#define BIT_UFS_REFCLK_ISO_EN (1 << 16)
+#define BIT_UFS_PHY_ISO_CTRL (1 << 0)
+#define BIT_SYSCTRL_LP_ISOL_EN (1 << 16)
+#define BIT_SYSCTRL_PWR_READY (1 << 8)
+#define BIT_SYSCTRL_REF_CLOCK_EN (1 << 24)
+#define MASK_SYSCTRL_REF_CLOCK_SEL (3 << 8)
+#define MASK_SYSCTRL_CFG_CLOCK_FREQ (0xFF)
+#define BIT_SYSCTRL_PSW_CLK_EN (1 << 4)
+#define MASK_UFS_CLK_GATE_BYPASS (0x3F)
+#define BIT_SYSCTRL_LP_RESET_N (1 << 0)
+#define BIT_UFS_REFCLK_SRC_SE1 (1 << 0)
+#define MASK_UFS_SYSCTRL_BYPASS (0x3F << 16)
+#define MASK_UFS_DEVICE_RESET (1 << 16)
+#define BIT_UFS_DEVICE_RESET (1 << 0)
+
+#endif /* __HI3660_H__ */
diff --git a/Platforms/Hisilicon/HiKey960/Include/Hkadc.h b/Platforms/Hisilicon/HiKey960/Include/Hkadc.h
new file mode 100644
index 0000000..93ab5db
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Include/Hkadc.h
@@ -0,0 +1,66 @@
+/** @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.
+*
+**/
+
+#ifndef __HKADC_H__
+#define __HKADC_H__
+
+#include <Hi3660.h>
+
+#define HKADC_DSP_START (HKADC_SSI_REG_BASE + 0x000)
+#define HKADC_WR_NUM (HKADC_SSI_REG_BASE + 0x008)
+#define HKADC_DSP_START_CLR (HKADC_SSI_REG_BASE + 0x01C)
+#define HKADC_WR01_DATA (HKADC_SSI_REG_BASE + 0x020)
+
+#define WR1_WRITE_MODE BIT31
+#define WR1_READ_MODE (0 << 31)
+#define WR1_ADDR(x) (((x) & 0x7F) << 24)
+#define WR1_DATA(x) (((x) & 0xFF) << 16)
+#define WR0_WRITE_MODE BIT15
+#define WR0_READ_MODE (0 << 15)
+#define WR0_ADDR(x) (((x) & 0x7F) << 8)
+#define WR0_DATA(x) ((x) & 0xFF)
+
+#define HKADC_WR23_DATA (HKADC_SSI_REG_BASE + 0x024)
+#define HKADC_WR45_DATA (HKADC_SSI_REG_BASE + 0x028)
+#define HKADC_DELAY01 (HKADC_SSI_REG_BASE + 0x030)
+#define HKADC_DELAY23 (HKADC_SSI_REG_BASE + 0x034)
+#define HKADC_DELAY45 (HKADC_SSI_REG_BASE + 0x038)
+#define HKADC_DSP_RD2_DATA (HKADC_SSI_REG_BASE + 0x048)
+#define HKADC_DSP_RD3_DATA (HKADC_SSI_REG_BASE + 0x04C)
+
+// HKADC Internal Registers
+#define HKADC_CTRL_ADDR 0x00
+#define HKADC_START_ADDR 0x01
+#define HKADC_DATA1_ADDR 0x03 // high 8 bits
+#define HKADC_DATA0_ADDR 0x04 // low 8 bits
+#define HKADC_MODE_CFG 0x0A
+
+#define HKADC_VALUE_HIGH 0x0FF0
+#define HKADC_VALUE_LOW 0x000F
+#define HKADC_VALID_VALUE 0x0FFF
+
+#define HKADC_CHANNEL_MAX 15
+#define HKADC_VREF_1V8 1800
+#define HKADC_ACCURACY 0x0FFF
+
+#define HKADC_WR01_VALUE ((HKADC_START_ADDR << 24) | (0x1 << 16))
+#define HKADC_WR23_VALUE ((0x1 << 31) | (HKADC_DATA0_ADDR << 24) | (1 << 15) | (HKADC_DATA1_ADDR << 8))
+#define HKADC_WR45_VALUE (0x80)
+#define HKADC_CHANNEL0_DELAY01_VALUE ((0x0700 << 16) | 0xFFFF)
+#define HKADC_DELAY01_VALUE ((0x0700 << 16) | 0x0200)
+#define HKADC_DELAY23_VALUE ((0x00C8 << 16) | 0x00C8)
+#define START_DELAY_TIMEOUT 2000
+#define HKADC_WR_NUM_VALUE 4
+
+#endif /* __HKADC_H__ */
diff --git a/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/AArch64/HiKey960Helper.S b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/AArch64/HiKey960Helper.S
new file mode 100644
index 0000000..0589c53
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/AArch64/HiKey960Helper.S
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2016-2017, Linaro Limited. 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 <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+.text
+.align 3
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+ ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+ MOV32 (w1, FixedPcdGet32(PcdArmPrimaryCoreMask))
+ and x0, x0, x1
+ MOV32 (w1, FixedPcdGet32(PcdArmPrimaryCore))
+ cmp w0, w1
+ cset x0, eq
+ ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+ MOV32 (w0, FixedPcdGet32(PcdArmPrimaryCore))
+ ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+ and x1, x0, #ARM_CORE_MASK
+ and x0, x0, #ARM_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
diff --git a/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960.c b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960.c
new file mode 100644
index 0000000..efbfb5f
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960.c
@@ -0,0 +1,189 @@
+/** @file
+*
+* Copyright (c) 2016-2017, Linaro Limited. 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 <Drivers/PL011Uart.h>
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+ARM_CORE_INFO mHiKey960InfoTable[] = {
+ {
+ // Cluster 0, Core 0
+ 0x0, 0x0,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 1
+ 0x0, 0x1,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 2
+ 0x0, 0x2,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 3
+ 0x0, 0x3,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 0
+ 0x1, 0x0,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 1
+ 0x1, 0x1,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 2
+ 0x1, 0x2,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 3
+ 0x1, 0x3,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (UINT64)0xFFFFFFFF
+ }
+};
+
+/**
+ Return the current Boot Mode
+
+ This function returns the boot reason on the platform
+
+ @return Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+ VOID
+ )
+{
+ return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+ Initialize controllers that must setup in the normal world
+
+ This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+ in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+ IN UINTN MpId
+ )
+{
+ RETURN_STATUS Status;
+ UINT64 BaudRate;
+ UINT32 ReceiveFifoDepth;
+ EFI_PARITY_TYPE Parity;
+ UINT8 DataBits;
+ EFI_STOP_BITS_TYPE StopBits;
+
+ Status = RETURN_SUCCESS;
+
+ //
+ // Initialize the Serial Debug UART
+ //
+ if (FixedPcdGet64 (PcdSerialDbgRegisterBase)) {
+ ReceiveFifoDepth = 0; // Use the default value for FIFO depth
+ Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
+ DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
+ StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
+
+ BaudRate = (UINTN)FixedPcdGet64 (PcdSerialDbgUartBaudRate);
+ Status = PL011UartInitializePort (
+ (UINTN)FixedPcdGet64 (PcdSerialDbgRegisterBase),
+ FixedPcdGet32 (PcdSerialDbgUartClkInHz),
+ &BaudRate,
+ &ReceiveFifoDepth,
+ &Parity,
+ &DataBits,
+ &StopBits
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Initialize the system (or sometimes called permanent) memory
+
+ This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+ VOID
+ )
+{
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+ OUT UINTN *CoreCount,
+ OUT ARM_CORE_INFO **ArmCoreTable
+ )
+{
+ // Only support one cluster
+ *CoreCount = sizeof(mHiKey960InfoTable) / sizeof(ARM_CORE_INFO);
+ *ArmCoreTable = mHiKey960InfoTable;
+ return EFI_SUCCESS;
+}
+
+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &mArmMpCoreInfoPpiGuid,
+ &mMpCoreInfoPpi
+ }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+ OUT UINTN *PpiListSize,
+ OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+ )
+{
+ *PpiListSize = sizeof(gPlatformPpiTable);
+ *PpiList = gPlatformPpiTable;
+}
diff --git a/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Lib.inf b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Lib.inf
new file mode 100644
index 0000000..c85956b
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Lib.inf
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2016-2017, Linaro Limited. 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.
+#
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HiKey960Lib
+ FILE_GUID = 977ad020-e78c-4349-bda8-a3dedfd3aa47
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ ArmLib
+ HobLib
+ MemoryAllocationLib
+ SerialPortLib
+
+[Sources.common]
+ HiKey960.c
+ HiKey960Mem.c
+
+[Sources.AARCH64]
+ AArch64/HiKey960Helper.S
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+ #
+ # PL011 Serial Debug UART
+ #
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
+
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
diff --git a/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Mem.c b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Mem.c
new file mode 100644
index 0000000..174bac2
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey960/Library/HiKey960Lib/HiKey960Mem.c
@@ -0,0 +1,173 @@
+/** @file
+*
+* Copyright (c) 2016-2017, Linaro Limited. 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 <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 12
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+#define HI3660_PERIPH_BASE 0xE0000000
+#define HI3660_PERIPH_SZ 0x20000000
+
+#define HIKEY960_EXTRA_SYSTEM_MEMORY_BASE 0x0000000100000000
+#define HIKEY960_EXTRA_SYSTEM_MEMORY_SIZE 0x0000000020000000
+
+#define HIKEY960_MEMORY_SIZE 0x0000000100000000
+
+#define HIKEY960_RESERVED_MEMORY
+
+STATIC struct HiKey960ReservedMemory {
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_PHYSICAL_ADDRESS Size;
+} HiKey960ReservedMemoryBuffer [] = {
+ { 0x1AC00000, 0x00098000 }, // ARM-TF reserved
+ { 0x32000000, 0x00100000 }, // PSTORE/RAMOOPS
+ { 0x32100000, 0x00001000 }, // ADB REBOOT "REASON"
+ { 0x3E000000, 0x02000000 }, // TEE OS
+ { 0x89B80000, 0x00100000 }, // MCU Code reserved
+ { 0x89C80000, 0x00040000 } // MCU reserved
+};
+
+/**
+ Return the Virtual Memory Map of your platform
+
+ This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+ @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+ Virtual Memory mapping. This array must be ended by a zero-filled
+ entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+ IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+ )
+{
+ ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes;
+ ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
+#ifdef HIKEY960_RESERVED_MEMORY
+ UINTN Index = 0, Count, ReservedTop;
+ EFI_PEI_HOB_POINTERS NextHob;
+ UINT64 ResourceLength;
+ EFI_PHYSICAL_ADDRESS ResourceTop;
+#endif
+
+ ResourceAttributes = (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED
+ );
+
+ // Create initial Base Hob for system memory.
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ PcdGet64 (PcdSystemMemoryBase),
+ PcdGet64 (PcdSystemMemorySize)
+ );
+
+#ifdef HIKEY960_RESERVED_MEMORY
+ NextHob.Raw = GetHobList ();
+ Count = sizeof (HiKey960ReservedMemoryBuffer) / sizeof (struct HiKey960ReservedMemory);
+ while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL)
+ {
+ if (Index >= Count)
+ break;
+ if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+ (HiKey960ReservedMemoryBuffer[Index].Offset >= NextHob.ResourceDescriptor->PhysicalStart) &&
+ ((HiKey960ReservedMemoryBuffer[Index].Offset + HiKey960ReservedMemoryBuffer[Index].Size) <=
+ NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
+ {
+ ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+ ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+ ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+ ReservedTop = HiKey960ReservedMemoryBuffer[Index].Offset + HiKey960ReservedMemoryBuffer[Index].Size;
+
+ // Create the System Memory HOB for the reserved buffer
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_RESERVED,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT,
+ HiKey960ReservedMemoryBuffer[Index].Offset,
+ HiKey960ReservedMemoryBuffer[Index].Size
+ );
+ // Update the HOB
+ NextHob.ResourceDescriptor->ResourceLength = HiKey960ReservedMemoryBuffer[Index].Offset -
+ NextHob.ResourceDescriptor->PhysicalStart;
+
+ // If there is some memory available on the top of the reserved memory then create a HOB
+ if (ReservedTop < ResourceTop)
+ {
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ ReservedTop,
+ ResourceTop - ReservedTop);
+ }
+ Index++;
+ }
+ NextHob.Raw = GET_NEXT_HOB (NextHob);
+ }
+#endif
+
+ ASSERT (VirtualMemoryMap != NULL);
+
+ VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages (
+ EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)
+ );
+ if (VirtualMemoryTable == NULL) {
+ return;
+ }
+
+ if (FeaturePcdGet (PcdCacheEnable) == TRUE) {
+ CacheAttributes = DDR_ATTRIBUTES_CACHED;
+ } else {
+ CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+ }
+
+ Index = 0;
+
+ // DDR - 3.0GB section
+ VirtualMemoryTable[Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize);
+ VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+ // Hi3660 SOC peripherals
+ VirtualMemoryTable[++Index].PhysicalBase = HI3660_PERIPH_BASE;
+ VirtualMemoryTable[Index].VirtualBase = HI3660_PERIPH_BASE;
+ VirtualMemoryTable[Index].Length = HI3660_PERIPH_SZ;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // End of Table
+ VirtualMemoryTable[++Index].PhysicalBase = 0;
+ VirtualMemoryTable[Index].VirtualBase = 0;
+ VirtualMemoryTable[Index].Length = 0;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+ ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+ *VirtualMemoryMap = VirtualMemoryTable;
+}