浏览代码

Platform,Silicon: Import Hisilicon D02,D03,D05 and HiKey

Imported from commit efd798c1eb of
https://git.linaro.org/uefi/OpenPlatformPkg.git

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Leif Lindholm 6 年之前
父节点
当前提交
600081b52d
共有 100 个文件被更改,包括 22701 次插入0 次删除
  1. 94 0
      Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.c
  2. 53 0
      Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.inf
  3. 341 0
      Platform/Hisilicon/D02/FdtUpdateLibD02/FdtUpdateLib.c
  4. 43 0
      Platform/Hisilicon/D02/FdtUpdateLibD02/FdtUpdateLib.inf
  5. 34 0
      Platform/Hisilicon/D02/Include/Library/CpldD02.h
  6. 105 0
      Platform/Hisilicon/D02/Library/OemMiscLibD02/BoardFeatureD02.c
  7. 二进制
      Platform/Hisilicon/D02/Library/OemMiscLibD02/BoardFeatureD02Strings.uni
  8. 77 0
      Platform/Hisilicon/D02/Library/OemMiscLibD02/OemMiscLibD02.c
  9. 45 0
      Platform/Hisilicon/D02/Library/OemMiscLibD02/OemMiscLibD02.inf
  10. 147 0
      Platform/Hisilicon/D02/Library/PlatformPciLib/PlatformPciLib.c
  11. 182 0
      Platform/Hisilicon/D02/Library/PlatformPciLib/PlatformPciLib.inf
  12. 31 0
      Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfig.h
  13. 173 0
      Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.c
  14. 50 0
      Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.inf
  15. 44 0
      Platform/Hisilicon/D02/Pv660D02.dec
  16. 453 0
      Platform/Hisilicon/D02/Pv660D02.dsc
  17. 317 0
      Platform/Hisilicon/D02/Pv660D02.fdf
  18. 44 0
      Platform/Hisilicon/D03/D03.dec
  19. 525 0
      Platform/Hisilicon/D03/D03.dsc
  20. 334 0
      Platform/Hisilicon/D03/D03.fdf
  21. 40 0
      Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig.h
  22. 362 0
      Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.c
  23. 52 0
      Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
  24. 437 0
      Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.c
  25. 180 0
      Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.h
  26. 53 0
      Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
  27. 180 0
      Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.c
  28. 55 0
      Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.inf
  29. 25 0
      Platform/Hisilicon/D03/Include/Library/CpldD03.h
  30. 178 0
      Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClock.h
  31. 504 0
      Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c
  32. 48 0
      Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf
  33. 487 0
      Platform/Hisilicon/D03/Library/FdtUpdateLib/FdtUpdateLib.c
  34. 50 0
      Platform/Hisilicon/D03/Library/FdtUpdateLib/FdtUpdateLib.inf
  35. 197 0
      Platform/Hisilicon/D03/Library/OemMiscLib2P/BoardFeature2PHi1610.c
  36. 二进制
      Platform/Hisilicon/D03/Library/OemMiscLib2P/BoardFeature2PHi1610Strings.uni
  37. 141 0
      Platform/Hisilicon/D03/Library/OemMiscLib2P/OemMiscLib2PHi1610.c
  38. 54 0
      Platform/Hisilicon/D03/Library/OemMiscLib2P/OemMiscLib2PHi1610.inf
  39. 156 0
      Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c
  40. 182 0
      Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
  41. 663 0
      Platform/Hisilicon/D05/D05.dsc
  42. 358 0
      Platform/Hisilicon/D05/D05.fdf
  43. 64 0
      Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.c
  44. 53 0
      Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.inf
  45. 225 0
      Platform/Hisilicon/D05/Library/OemMiscLibD05/BoardFeatureD05.c
  46. 56 0
      Platform/Hisilicon/D05/Library/OemMiscLibD05/BoardFeatureD05Strings.uni
  47. 107 0
      Platform/Hisilicon/D05/Library/OemMiscLibD05/OemMiscLibD05.c
  48. 55 0
      Platform/Hisilicon/D05/Library/OemMiscLibD05/OemMiscLibD05.inf
  49. 279 0
      Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c
  50. 183 0
      Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
  51. 36 0
      Platform/Hisilicon/HiKey/HiKey.dec
  52. 482 0
      Platform/Hisilicon/HiKey/HiKey.dsc
  53. 351 0
      Platform/Hisilicon/HiKey/HiKey.fdf
  54. 26 0
      Platform/Hisilicon/HiKey/Include/ArmPlatform.h
  55. 159 0
      Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKey.c
  56. 49 0
      Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyHelper.S
  57. 51 0
      Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyLib.inf
  58. 204 0
      Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyMem.c
  59. 40 0
      Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatform.c
  60. 72 0
      Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
  61. 508 0
      Silicon/Hisilicon/Drivers/AcpiPlatformDxe/EthMac.c
  62. 22 0
      Silicon/Hisilicon/Drivers/AcpiPlatformDxe/EthMac.h
  63. 109 0
      Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashBlockIoDxe.c
  64. 1243 0
      Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.c
  65. 228 0
      Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.h
  66. 69 0
      Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
  67. 269 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
  68. 22 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni
  69. 62 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
  70. 20 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni
  71. 137 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
  72. 16 0
      Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h
  73. 162 0
      Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashConfig.c
  74. 594 0
      Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.c
  75. 64 0
      Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.inf
  76. 628 0
      Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashHw.c
  77. 116 0
      Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashHw.h
  78. 1651 0
      Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c
  79. 521 0
      Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h
  80. 74 0
      Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
  81. 2313 0
      Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
  82. 1049 0
      Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.c
  83. 46 0
      Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.inf
  84. 205 0
      Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c
  85. 36 0
      Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.h
  86. 50 0
      Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf
  87. 762 0
      Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.c
  88. 79 0
      Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.h
  89. 59 0
      Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
  90. 30 0
      Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassStrings.uni
  91. 728 0
      Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
  92. 108 0
      Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
  93. 64 0
      Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
  94. 32 0
      Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
  95. 226 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMisc.h
  96. 58 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
  97. 108 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
  98. 194 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
  99. 28 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
  100. 25 0
      Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni

+ 94 - 0
Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.c

@@ -0,0 +1,94 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/ArmLib.h>
+
+#include <PlatformArch.h>
+#include <Library/PlatformSysCtrlLib.h>
+
+#include <Library/OemMiscLib.h>
+
+#define TIMER_SUBCTRL_BASE                              PcdGet64(PcdPeriSubctrlAddress)
+#define ALG_BASE                                        (0xA0000000)
+#define PERI_SUB_CTRL_BASE                              (0x80000000)
+#define SC_TM_CLKEN0_REG                                (0x2050)
+#define SYS_APB_IF_BASE                                 (0x10000)
+#define TSENSOR_REG                                     (0x5000)
+#define SC_ITS_M3_INT_MUX_SEL_REG                       (0x21F0)
+#define SC_HLLC_RESET_DREQ_REG                          (0xA8C)
+#define SC_ITS_M3_INT_MUX_SEL_VALUE                     (0xF)
+#define SC_HLLC_RESET_DREQ_VALUE                        (0x1f)
+#define TSENSOR_CONFIG_VALUE                            (0x1)
+
+VOID PlatformTimerStart (VOID)
+{
+    // Timer0 clock enable
+    MmioWrite32 (TIMER_SUBCTRL_BASE + SC_TM_CLKEN0_REG, 0x3);
+}
+
+EFI_STATUS
+EFIAPI
+EarlyConfigEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+    DEBUG((EFI_D_INFO,"SMMU CONFIG........."));
+    SmmuConfigForOS();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"ITS CONFIG........."));
+    ITSCONFIG();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"AP CONFIG........."));
+    MmioWrite64(FixedPcdGet64(PcdMailBoxAddress), 0x0);
+    (void)WriteBackInvalidateDataCacheRange((VOID *) FixedPcdGet64(PcdMailBoxAddress), 8);
+    ArmDataSynchronizationBarrier ();
+    ArmInstructionSynchronizationBarrier ();
+
+    CoreSelectBoot();
+
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"MN CONFIG........."));
+    MN_CONFIG ();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"RTC CONFIG........."));
+
+    MmioWrite32(ALG_BASE + SC_ITS_M3_INT_MUX_SEL_REG, SC_ITS_M3_INT_MUX_SEL_VALUE);
+
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"Tsensor CONFIG........."));
+
+    MmioWrite32(PERI_SUB_CTRL_BASE + SYS_APB_IF_BASE + TSENSOR_REG, TSENSOR_CONFIG_VALUE);
+    MmioWrite32(ALG_BASE + SC_HLLC_RESET_DREQ_REG, SC_HLLC_RESET_DREQ_VALUE);
+
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"Timer CONFIG........."));
+    PlatformTimerStart ();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    return EFI_SUCCESS;
+}

+ 53 - 0
Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.inf

@@ -0,0 +1,53 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = EarlyConfigPeim
+  FILE_GUID                      = A181AD33-E64A-4084-A54A-A69DF1FB0ABF
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = EarlyConfigEntry
+
+[Sources.common]
+  EarlyConfigPeim.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PcdLib
+  DebugLib
+  IoLib
+  CacheMaintenanceLib
+  ArmLib
+
+  PlatformSysCtrlLib
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdMailBoxAddress
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress
+
+[Depex]
+## As we will clean mailbox in this module, need to wait memory init complete
+  gEfiPeiMemoryDiscoveredPpiGuid
+
+[BuildOptions]
+

+ 341 - 0
Platform/Hisilicon/D02/FdtUpdateLibD02/FdtUpdateLib.c

@@ -0,0 +1,341 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <libfdt.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/FdtUpdateLib.h>
+#include <Protocol/HisiBoardNicProtocol.h>
+#include <Library/MemoryAllocationLib.h>
+
+MAC_ADDRESS gMacAddress[1];
+
+CHAR8  *EthName[8]=
+{
+ "ethernet@0","ethernet@1",
+ "ethernet@2","ethernet@3",
+ "ethernet@4","ethernet@5",
+ "ethernet@6","ethernet@7"
+};
+
+CHAR8  *MacName[4]=
+{
+ "ethernet-mac@c7040000",
+ "ethernet-mac@c7044000",
+ "ethernet-mac@c7048000",
+ "ethernet-mac@c704c000"
+};
+
+STATIC
+BOOLEAN
+IsMemMapRegion (
+  IN EFI_MEMORY_TYPE MemoryType
+  )
+{
+  switch(MemoryType)
+    {
+        case EfiRuntimeServicesCode:
+        case EfiRuntimeServicesData:
+        case EfiConventionalMemory:
+        case EfiACPIReclaimMemory:
+        case EfiACPIMemoryNVS:
+        case EfiLoaderCode:
+        case EfiLoaderData:
+        case EfiBootServicesCode:
+        case EfiBootServicesData:
+        case EfiPalCode:
+                return TRUE;
+        default:
+                return FALSE;
+  }
+}
+
+EFI_STATUS
+GetMacAddress (UINT32 Port)
+{
+    EFI_MAC_ADDRESS Mac;
+    EFI_STATUS Status;
+    HISI_BOARD_NIC_PROTOCOL *OemNic = NULL;
+
+    Status = gBS->LocateProtocol(&gHisiBoardNicProtocolGuid, NULL, (VOID **)&OemNic);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol failed %r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    Status = OemNic->GetMac(&Mac, Port);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] GetMac failed %r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    gMacAddress[0].data0=Mac.Addr[0];
+    gMacAddress[0].data1=Mac.Addr[1];
+    gMacAddress[0].data2=Mac.Addr[2];
+    gMacAddress[0].data3=Mac.Addr[3];
+    gMacAddress[0].data4=Mac.Addr[4];
+    gMacAddress[0].data5=Mac.Addr[5];
+    DEBUG((EFI_D_ERROR, "Port%d:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+        Port,gMacAddress[0].data0,gMacAddress[0].data1,gMacAddress[0].data2,
+        gMacAddress[0].data3,gMacAddress[0].data4,gMacAddress[0].data5));
+
+    return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+DelPhyhandleUpdateMacAddress(IN VOID* Fdt)
+{
+    UINT8               port;
+    INTN                ethernetnode;
+    INTN                node;
+    INTN                Error;
+    struct              fdt_property *m_prop;
+    int                 m_oldlen;
+    EFI_STATUS          Status = EFI_SUCCESS;
+
+    node = fdt_subnode_offset(Fdt, 0, "soc");
+    if (node < 0)
+    {
+        DEBUG ((EFI_D_ERROR, "can not find soc root node\n"));
+        return EFI_INVALID_PARAMETER;
+    }
+    else
+    {
+        for( port=0; port<8; port++ )
+        {
+            (VOID) GetMacAddress(port);
+            ethernetnode=fdt_subnode_offset(Fdt, node,EthName[port]);
+            if (ethernetnode < 0)
+            {
+                DEBUG ((EFI_D_ERROR, "can not find ethernet@ %d node\n",port));
+            }
+            m_prop = fdt_get_property_w(Fdt, ethernetnode, "local-mac-address", &m_oldlen);
+            if(m_prop)
+            {
+                Error = fdt_delprop(Fdt, ethernetnode, "local-mac-address");
+                if (Error)
+                {
+                    DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop() Local-mac-address: %a\n", fdt_strerror (Error)));
+                    Status = EFI_INVALID_PARAMETER;
+                }
+                Error = fdt_setprop(Fdt, ethernetnode, "local-mac-address",gMacAddress,sizeof(MAC_ADDRESS));
+                if (Error)
+                {
+                    DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop():local-mac-address %a\n", fdt_strerror (Error)));
+                    Status = EFI_INVALID_PARAMETER;
+                }
+            }
+        }
+    }
+    return Status;
+}
+
+EFI_STATUS UpdateMemoryNode(VOID* Fdt)
+{
+    INTN                Error = 0;
+    EFI_STATUS          Status = EFI_SUCCESS;
+    UINT32              Index = 0;
+    UINT32              MemIndex;
+    INTN                node;
+    struct              fdt_property *m_prop;
+    int                 m_oldlen;
+    EFI_MEMORY_DESCRIPTOR *MemoryMap;
+    EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+    EFI_MEMORY_DESCRIPTOR *MemoryMapPtrCurrent;
+    UINTN                 MemoryMapSize;
+    UINTN                 Pages0 = 0;
+    UINTN                 Pages1 = 0;
+    UINTN                 MapKey;
+    UINTN                 DescriptorSize;
+    UINT32                DescriptorVersion;
+    PHY_MEM_REGION        *mRegion;
+    UINTN                 MemoryMapLastEndAddress ;
+    UINTN                 MemoryMapcontinuousStartAddress ;
+    UINTN                 MemoryMapCurrentStartAddress;
+    BOOLEAN               FindMemoryRegionFlag = FALSE;
+    node = fdt_subnode_offset(Fdt, 0, "memory");
+    if (node < 0)
+    {
+        // Create the memory node
+        node = fdt_add_subnode(Fdt, 0, "memory");
+        if(node < 0)
+        {
+          DEBUG((EFI_D_INFO, "[%a]:[%dL] fdt add subnode error\n", __FUNCTION__, __LINE__));
+        }
+    }
+    //find the memory node property
+    m_prop = fdt_get_property_w(Fdt, node, "memory", &m_oldlen);
+    if(m_prop)
+        Error=fdt_delprop(Fdt, node, "reg");
+    if (Error)
+    {
+        DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop(): %a\n", fdt_strerror (Error)));
+        Status = EFI_INVALID_PARAMETER;
+        return Status;
+    }
+
+    MemoryMap = NULL;
+    MemoryMapSize = 0;
+    MemIndex = 0;
+
+    Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+    if (Status == EFI_BUFFER_TOO_SMALL)
+    {
+        // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive
+        // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.
+        //DEBUG ((EFI_D_ERROR, "MemoryMapsize: 0x%lx\n",MemoryMapSize));
+        Pages0 = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+        MemoryMap = AllocatePages (Pages0);
+        if (MemoryMap == NULL)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            return Status;
+        }
+        Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+    }
+
+    if(MemoryMap == NULL)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        //goto EXIT;
+        return Status;
+    }
+
+    mRegion = NULL;
+    Pages1 = EFI_SIZE_TO_PAGES (sizeof(PHY_MEM_REGION) *( MemoryMapSize / DescriptorSize));
+    mRegion = (PHY_MEM_REGION*)AllocatePages(Pages1);
+    if (mRegion == NULL)
+    {
+      Status = EFI_OUT_OF_RESOURCES;
+      return Status;
+    }
+
+    if (!EFI_ERROR(Status))
+    {
+        MemoryMapPtr = MemoryMap;
+        MemoryMapPtrCurrent = MemoryMapPtr;
+        MemoryMapLastEndAddress = 0;
+        MemoryMapcontinuousStartAddress = 0;
+        MemoryMapCurrentStartAddress = 0;
+        for ( Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++)
+        {
+            MemoryMapPtrCurrent = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + Index*DescriptorSize);
+            MemoryMapCurrentStartAddress = (UINTN)MemoryMapPtrCurrent->PhysicalStart;
+
+            if (!IsMemMapRegion ((EFI_MEMORY_TYPE)MemoryMapPtrCurrent->Type))
+            {
+                continue;
+            }
+            else
+            {
+                FindMemoryRegionFlag = TRUE;
+                if(MemoryMapCurrentStartAddress != MemoryMapLastEndAddress)
+                {
+                    mRegion[MemIndex].BaseHigh= cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
+                    mRegion[MemIndex].BaseLow=cpu_to_fdt32(MemoryMapcontinuousStartAddress);
+                    mRegion[MemIndex].LengthHigh= cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
+                    mRegion[MemIndex].LengthLow=cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
+                    MemIndex+=1;
+                    MemoryMapcontinuousStartAddress=MemoryMapCurrentStartAddress;
+                }
+            }
+            MemoryMapLastEndAddress = (UINTN)(MemoryMapPtrCurrent->PhysicalStart + MemoryMapPtrCurrent->NumberOfPages * EFI_PAGE_SIZE);
+        }
+        if (FindMemoryRegionFlag)
+        {
+            mRegion[MemIndex].BaseHigh = cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
+            mRegion[MemIndex].BaseLow = cpu_to_fdt32(MemoryMapcontinuousStartAddress);
+            mRegion[MemIndex].LengthHigh = cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
+            mRegion[MemIndex].LengthLow = cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
+        }
+    }
+    Error = fdt_setprop(Fdt, node, "reg",mRegion,sizeof(PHY_MEM_REGION) *(MemIndex+1));
+    FreePages (mRegion, Pages1);
+    FreePages (MemoryMap, Pages0);
+    if (Error)
+    {
+        DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop(): %a\n", fdt_strerror (Error)));
+        Status = EFI_INVALID_PARAMETER;
+        return Status;
+    }
+  return Status;
+}
+
+/*
+ * Entry point for fdtupdate lib.
+ */
+
+EFI_STATUS EFIFdtUpdate(UINTN FdtFileAddr)
+{
+    INTN                Error;
+    VOID*               Fdt;
+    UINT32              Size;
+    UINTN               NewFdtBlobSize;
+    UINTN               NewFdtBlobBase;
+    EFI_STATUS          Status = EFI_SUCCESS;
+
+    Error = fdt_check_header ((VOID*)(UINTN)(FdtFileAddr));
+    if (Error != 0)
+    {
+        DEBUG ((EFI_D_ERROR,"ERROR: Device Tree header not valid (%a)\n", fdt_strerror(Error)));
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Size = (UINTN)fdt_totalsize ((VOID*)(UINTN)(FdtFileAddr));
+    NewFdtBlobSize = Size + ADD_FILE_LENGTH;
+    Fdt = (VOID*)(UINTN)FdtFileAddr;
+
+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
+    if (EFI_ERROR (Status))
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+
+    Error = fdt_open_into(Fdt,(VOID*)(UINTN)(NewFdtBlobBase), (NewFdtBlobSize));
+    if (Error) {
+        DEBUG ((EFI_D_ERROR, "ERROR:fdt_open_into(): %a\n", fdt_strerror (Error)));
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+    }
+
+    Fdt = (VOID*)(UINTN)NewFdtBlobBase;
+
+    Status = DelPhyhandleUpdateMacAddress(Fdt);
+    if (EFI_ERROR (Status))
+    {
+        DEBUG ((EFI_D_ERROR, "DelPhyhandleUpdateMacAddress fail:\n"));
+        Status = EFI_SUCCESS;
+    }
+
+    Status = UpdateMemoryNode(Fdt);
+    if (EFI_ERROR (Status))
+    {
+        goto EXIT;
+    }
+
+    gBS->CopyMem(((VOID*)(UINTN)(FdtFileAddr)),((VOID*)(UINTN)(NewFdtBlobBase)),NewFdtBlobSize);
+
+EXIT:
+    gBS->FreePages(NewFdtBlobBase,EFI_SIZE_TO_PAGES(NewFdtBlobSize));
+
+    return Status;
+}

+ 43 - 0
Platform/Hisilicon/D02/FdtUpdateLibD02/FdtUpdateLib.inf

@@ -0,0 +1,43 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = FdtUpdateLib
+  FILE_GUID                      = 02CF1727-E697-47fc-8CC2-5DCB81B26DD9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FdtUpdateLib
+
+
+[Sources.common]
+  FdtUpdateLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  FdtLib
+  OemAddressMapLib
+
+[Protocols]
+  gHisiBoardNicProtocolGuid
+
+[Pcd]
+

+ 34 - 0
Platform/Hisilicon/D02/Include/Library/CpldD02.h

@@ -0,0 +1,34 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 __CPLDD02_H__
+#define __CPLDD02_H__
+#define CPLD_LOGIC_VERSION                (0x52)
+#define PRODUCT_VERSION                   (0x53)
+#define CPLD_LOGIC_COMPLIER_YEAR          (0x54)
+#define CPLD_LOGIC_COMPLIER_MONTH         (0x55)
+#define CPLD_LOGIC_COMPLIER_DAY           (0x56)
+#define CPLD_LOGIC_COMPLIER_HOUR          (0x57)
+#define CPLD_LOGIC_COMPLIER_MINUTE        (0x58)
+#define BOARD_ID                          (0x59)
+#define BOM_VERSION                       (0x5A)
+#define CPLD_BIOS_CURRENT_CHANNEL_REG_D02 (0x5B)
+
+#define CPU0_PCIE1_RESET_REG                (0x12)
+#define CPU0_PCIE2_RESET_REG                (0x13)
+#define CPU1_PCIE1_RESET_REG                (0x14)
+#define CPU1_PCIE2_RESET_REG                (0x15)
+
+#endif /* __CPLDD02_H__ */

+ 105 - 0
Platform/Hisilicon/D02/Library/OemMiscLibD02/BoardFeatureD02.c

@@ -0,0 +1,105 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <PlatformArch.h>
+#include <Library/OemMiscLib.h>
+#include <Library/SerdesLib.h>
+#include <Library/CpldIoLib.h>
+#include <Library/CpldD02.h>
+#include <Library/TimerLib.h>
+#include <Library/I2CLib.h>
+#include <Library/HiiLib.h>
+
+I2C_DEVICE gDS3231RtcDevice = {
+    .Socket = 0,
+    .Port = 7,
+    .DeviceType = DEVICE_TYPE_SPD,
+    .SlaveDeviceAddress = 0x68
+};
+
+// Set Tx output polarity. Not inverting data is default. For Phosphor660 D02 Board
+//if((1 == ulMacroId) && ((7 == ulDsNum)||(0 == ulDsNum)))
+SERDES_POLARITY_INVERT gSerdesPolarityTxDesc[] =
+{
+    {1, 7},
+    {1, 0},
+    {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+// Set Rx data polarity. Not inverting data is default. For Phosphor660 D02 Board
+//if((1 == ulMacroId) && ((0 == ulDsNum) || (1 == ulDsNum)))
+SERDES_POLARITY_INVERT gSerdesPolarityRxDesc[] =
+{
+    {1, 0},
+    {1, 1},
+    {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+SERDES_PARAM gSerdesParam = {
+  .Hilink0Mode = EmHilink0Pcie1X8,
+  .Hilink1Mode = EmHilink1Pcie0X8,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = EmHilink3GeX4,
+  .Hilink4Mode = EmHilink4XgeX4,
+  .Hilink5Mode = EmHilink5Sas1X4,
+};
+
+EFI_STATUS OemGetSerdesParam (SERDES_PARAM *ParamA, SERDES_PARAM *ParamB, UINT32 SocketId)
+{
+  if (ParamA == NULL) {
+    DEBUG((DEBUG_ERROR, "[%a]:[%dL] ParamA == NULL!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  (VOID) CopyMem(ParamA, &gSerdesParam, sizeof(*ParamA));
+  return EFI_SUCCESS;
+}
+
+
+VOID OemPcieResetAndOffReset(void)
+  {
+    WriteCpldReg(CPU0_PCIE1_RESET_REG,0x0);
+    WriteCpldReg(CPU0_PCIE2_RESET_REG,0x0);
+    WriteCpldReg(CPU1_PCIE1_RESET_REG,0x0);
+    WriteCpldReg(CPU1_PCIE2_RESET_REG,0x0);
+    MicroSecondDelay(100000);
+    WriteCpldReg(CPU0_PCIE1_RESET_REG,0x55);
+    WriteCpldReg(CPU0_PCIE2_RESET_REG,0x55);
+    WriteCpldReg(CPU1_PCIE1_RESET_REG,0x55);
+    WriteCpldReg(CPU1_PCIE2_RESET_REG,0x55);
+    return;
+  }
+
+EFI_STRING_ID gDimmToDevLocator[MAX_SOCKET][MAX_CHANNEL][MAX_DIMM] = {
+  {{STRING_TOKEN(STR_D02_DIMM_000), STRING_TOKEN(STR_D02_DIMM_001), 0xFFFF},
+   {STRING_TOKEN(STR_D02_DIMM_010), STRING_TOKEN(STR_D02_DIMM_011), 0xFFFF}}
+};
+
+EFI_HII_HANDLE
+EFIAPI
+OemGetPackages (
+  )
+{
+    return HiiAddPackages (
+                            &gEfiCallerIdGuid,
+                            NULL,
+                            OemMiscLibD02Strings,
+                            NULL,
+                            NULL
+                            );
+}

二进制
Platform/Hisilicon/D02/Library/OemMiscLibD02/BoardFeatureD02Strings.uni


+ 77 - 0
Platform/Hisilicon/D02/Library/OemMiscLibD02/OemMiscLibD02.c

@@ -0,0 +1,77 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/CpldIoLib.h>
+#include <Library/OemMiscLib.h>
+#include <PlatformArch.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/OemAddressMapLib.h>
+#include <Library/SerialPortLib.h>
+
+// Right now we only support 1P
+BOOLEAN OemIsSocketPresent (UINTN Socket)
+{
+  if (0 == Socket)
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+UINTN OemGetSocketNumber (VOID)
+{
+    return 1;
+}
+
+UINTN OemGetDimmSlot(UINTN Socket, UINTN Channel)
+{
+    return 2;
+}
+
+UINTN OemGetDdrChannel (VOID)
+{
+    return 2;
+}
+
+VOID CoreSelectBoot(VOID)
+{
+    if (!PcdGet64 (PcdTrustedFirmwareEnable))
+    {
+        StartupAp ();
+    }
+
+    return;
+}
+
+BOOLEAN OemIsMpBoot()
+{
+    return FALSE;
+}
+
+VOID OemBiosSwitch(UINT32 Master)
+{
+    return;
+}
+
+UINT32 OemIsWarmBoot(VOID)
+{
+    return 0;
+}

+ 45 - 0
Platform/Hisilicon/D02/Library/OemMiscLibD02/OemMiscLibD02.inf

@@ -0,0 +1,45 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = OemMiscLibD02
+  FILE_GUID                      = 1DCE7EC8-3DB6-47cf-A2B5-717FD9AB2570
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OemMiscLib
+
+[Sources.common]
+  BoardFeatureD02.c
+  OemMiscLibD02.c
+  BoardFeatureD02Strings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+
+  Platform/Hisilicon/D02/Pv660D02.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  SerialPortLib
+  CpldIoLib
+
+[BuildOptions]
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable
+

+ 147 - 0
Platform/Hisilicon/D02/Library/PlatformPciLib/PlatformPciLib.c

@@ -0,0 +1,147 @@
+/** @file
+
+  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+
+  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/PcdLib.h>
+#include <Library/PlatformPciLib.h>
+
+PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
+ {// HostBridge 0
+  /* Port 0 */
+  {
+      PCI_HB0RB0_ECAM_BASE,
+      0,  //BusBase
+      63, //BusLimit
+      (PCI_HB0RB0_ECAM_BASE + SIZE_64MB),  //MemBase
+      (PCI_HB0RB0_ECAM_BASE + PCI_HB0RB0_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB0RB0_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+  /* Port 1 */
+  {
+      PCI_HB0RB1_ECAM_BASE,
+      64,  //BusBase
+      127, //BusLimit
+      PCI_HB0RB1_PCIREGION_BASE,
+      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1,
+      PCI_HB0RB1_IO_BASE, //IoBase
+      PCI_HB0RB1_IO_BASE + PCI_HB0RB1_IO_SIZE - 1,  //IoLimit
+      PCI_HB0RB1_CPUMEMREGIONBASE,
+      PCI_HB0RB2_CPUIOREGIONBASE,
+      (PCI_HB0RB1_PCI_BASE),  //RbPciBar
+      PCI_HB0RB1_PCIREGION_BASE,
+      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1
+  },
+  /* Port 2 */
+  {
+      PCI_HB0RB2_ECAM_BASE,
+      128,  //BusBase
+      191, //BusLimit
+      PCI_HB0RB2_PCIREGION_BASE ,
+      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1,
+      PCI_HB0RB2_IO_BASE, //IoBase
+      PCI_HB0RB2_IO_BASE + PCI_HB0RB2_IO_SIZE - 1,  //IoLimit
+      PCI_HB0RB2_CPUMEMREGIONBASE,
+      PCI_HB0RB2_CPUIOREGIONBASE,
+      (PCI_HB0RB2_PCI_BASE),  //RbPciBar
+      PCI_HB0RB2_PCIREGION_BASE ,
+      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB0RB3_ECAM_BASE,
+      192,  //BusBase
+      255, //BusLimit
+      (PCI_HB0RB3_ECAM_BASE),  //MemBase
+      (PCI_HB0RB3_ECAM_BASE + PCI_HB0RB3_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB0RB3_PCI_BASE),  //RbPciBar
+      0,
+      0
+  }
+ },
+{// HostBridge 1
+  /* Port 0 */
+  {
+      PCI_HB1RB0_ECAM_BASE,
+      0,  //BusBase
+      0x1, //BusLimit
+      (PCI_HB1RB0_ECAM_BASE),  //MemBase
+      (PCI_HB1RB0_ECAM_BASE + PCI_HB1RB0_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB0_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+  /* Port 1 */
+  {
+       PCI_HB1RB1_ECAM_BASE,
+      0x2,  //BusBase
+      0x3, //BusLimit
+      (PCI_HB1RB1_ECAM_BASE),  //MemBase
+      (PCI_HB1RB1_ECAM_BASE + PCI_HB1RB1_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB1_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+  /* Port 2 */
+  {
+      PCI_HB1RB2_ECAM_BASE,
+      0x4,  //BusBase
+      0x5, //BusLimit
+      (PCI_HB1RB2_ECAM_BASE),  //MemBase
+      (PCI_HB1RB2_ECAM_BASE + PCI_HB1RB2_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB2_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB1RB3_ECAM_BASE,
+      0x6,  //BusBase
+      0x7, //BusLimit
+      (PCI_HB1RB3_ECAM_BASE),  //MemBase
+      (PCI_HB1RB3_ECAM_BASE + PCI_HB1RB3_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB3_PCI_BASE),  //RbPciBar
+      0,
+      0
+  }
+ }
+};
+

+ 182 - 0
Platform/Hisilicon/D02/Library/PlatformPciLib/PlatformPciLib.inf

@@ -0,0 +1,182 @@
+## @file
+#
+#  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+#  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+#
+#  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                      = PlatformPciLib
+  FILE_GUID                      = 61b7276a-fc67-11e5-82fd-47ea9896dd5d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PlatformPciLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+
+[FixedPcd]
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PciHb0Rb0Base
+  gHisiTokenSpaceGuid.PciHb0Rb1Base
+  gHisiTokenSpaceGuid.PciHb0Rb2Base
+  gHisiTokenSpaceGuid.PciHb0Rb3Base
+  gHisiTokenSpaceGuid.PciHb0Rb4Base
+  gHisiTokenSpaceGuid.PciHb0Rb5Base
+  gHisiTokenSpaceGuid.PciHb0Rb6Base
+  gHisiTokenSpaceGuid.PciHb0Rb7Base
+  gHisiTokenSpaceGuid.PciHb1Rb0Base
+  gHisiTokenSpaceGuid.PciHb1Rb1Base
+  gHisiTokenSpaceGuid.PciHb1Rb2Base
+  gHisiTokenSpaceGuid.PciHb1Rb3Base
+  gHisiTokenSpaceGuid.PciHb1Rb4Base
+  gHisiTokenSpaceGuid.PciHb1Rb5Base
+  gHisiTokenSpaceGuid.PciHb1Rb6Base
+  gHisiTokenSpaceGuid.PciHb1Rb7Base
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionBaseAddress
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionSize
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuMemRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuIoRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoSize

+ 31 - 0
Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfig.h

@@ -0,0 +1,31 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 __OEM_NIC_CONFIG_H__
+#define __OEM_NIC_CONFIG_H__
+
+#define I2C_SLAVEADDR_EEPROM     (0x52)
+
+#define I2C_OFFSET_EEPROM_ETH0   (0xc00)
+#define I2C_OFFSET_EEPROM_ETH1   (I2C_OFFSET_EEPROM_ETH0 + 6)
+#define I2C_OFFSET_EEPROM_ETH2   (I2C_OFFSET_EEPROM_ETH1 + 6)
+#define I2C_OFFSET_EEPROM_ETH3   (I2C_OFFSET_EEPROM_ETH2 + 6)
+#define I2C_OFFSET_EEPROM_ETH4   (I2C_OFFSET_EEPROM_ETH3 + 6)
+#define I2C_OFFSET_EEPROM_ETH5   (I2C_OFFSET_EEPROM_ETH4 + 6)
+#define I2C_OFFSET_EEPROM_ETH6   (I2C_OFFSET_EEPROM_ETH5 + 6)
+#define I2C_OFFSET_EEPROM_ETH7   (I2C_OFFSET_EEPROM_ETH6 + 6)
+
+
+#endif

+ 173 - 0
Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.c

@@ -0,0 +1,173 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/HisiBoardNicProtocol.h>
+#include <Library/I2CLib.h>
+#include <OemNicConfig.h>
+
+#define EEPROM_I2C_PORT 7
+
+EFI_STATUS
+EFIAPI OemGetMac (IN OUT EFI_MAC_ADDRESS *Mac, IN UINTN Port);
+
+EFI_STATUS
+EFIAPI OemSetMac (IN EFI_MAC_ADDRESS *Mac, IN UINTN Port);
+
+HISI_BOARD_NIC_PROTOCOL mOemNicProtocol = {
+  .GetMac = OemGetMac,
+  .SetMac = OemSetMac,
+};
+
+
+EFI_STATUS OemGetMacE2prom(IN UINT32 Port, OUT UINT8 *pucAddr)
+{
+    I2C_DEVICE stI2cDev = {0};
+    EFI_STATUS Status;
+    UINT16     I2cOffset;
+
+    Status = I2CInit(0, EEPROM_I2C_PORT, Normal);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2CInit failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    I2cOffset = I2C_OFFSET_EEPROM_ETH0 + (Port * 6);
+
+    stI2cDev.DeviceType = DEVICE_TYPE_E2PROM;
+    stI2cDev.Port = EEPROM_I2C_PORT;
+    stI2cDev.SlaveDeviceAddress = I2C_SLAVEADDR_EEPROM;
+    stI2cDev.Socket = 0;
+    Status = I2CRead(&stI2cDev, I2cOffset, 6, pucAddr);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2cRead failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS OemSetMacE2prom(IN UINT32 Port, IN UINT8 *pucAddr)
+{
+    I2C_DEVICE stI2cDev = {0};
+    EFI_STATUS Status;
+    UINT16     I2cOffset;
+
+    Status = I2CInit(0, EEPROM_I2C_PORT, Normal);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2CInit failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    I2cOffset = I2C_OFFSET_EEPROM_ETH0 + (Port * 6);
+
+    stI2cDev.DeviceType = DEVICE_TYPE_E2PROM;
+    stI2cDev.Port = EEPROM_I2C_PORT;
+    stI2cDev.SlaveDeviceAddress = I2C_SLAVEADDR_EEPROM;
+    stI2cDev.Socket = 0;
+    Status = I2CWrite(&stI2cDev, I2cOffset, 6, pucAddr);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2cWrite failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI OemGetMac (
+  IN OUT EFI_MAC_ADDRESS *Mac,
+  IN UINTN Port
+  )
+{
+  EFI_STATUS Status;
+
+  if (NULL == Mac)
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Mac buffer is null!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //TODO: discard port number, only support one port
+  // Only 6 bytes are used
+  Status = OemGetMacE2prom(Port, Mac->Addr);
+  if ((EFI_ERROR(Status)))
+  {
+      DEBUG((EFI_D_ERROR, "[%a]:[%dL] Get mac failed!\n", __FUNCTION__, __LINE__));
+      return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI OemSetMac (
+  IN EFI_MAC_ADDRESS *Mac,
+  IN UINTN Port
+  )
+{
+  EFI_STATUS Status;
+
+  if (NULL == Mac)
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Mac buffer is null!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = OemSetMacE2prom(Port, Mac->Addr);
+  if ((EFI_ERROR(Status)))
+  {
+      DEBUG((EFI_D_ERROR, "[%a]:[%dL] Set mac failed!\n", __FUNCTION__, __LINE__));
+      return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+OemNicConfigEntry (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gBS->InstallProtocolInterface(
+    &ImageHandle,
+    &gHisiBoardNicProtocolGuid,
+    EFI_NATIVE_INTERFACE,
+    &mOemNicProtocol
+    );
+
+  if(EFI_ERROR(Status))
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Install Protocol failed %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+

+ 50 - 0
Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.inf

@@ -0,0 +1,50 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = OemNicConfig
+  FILE_GUID                      = 3A23A929-1F38-4d04-8A01-38AD993EB2CE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = OemNicConfigEntry
+
+[Sources.common]
+  OemNicConfigD02.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[Protocols]
+  gHisiBoardNicProtocolGuid       ##Produce
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DebugLib
+  IoLib
+  TimerLib
+  I2CLib
+
+[FixedPcd]
+
+[Depex]
+  TRUE
+
+[BuildOptions]
+

+ 44 - 0
Platform/Hisilicon/D02/Pv660D02.dec

@@ -0,0 +1,44 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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.
+#
+#**/
+
+#
+# PV660 D02 Package
+#
+#
+#
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = Pv660D02Pkg
+  PACKAGE_GUID                   = 54392E0D-972B-459D-8CBE-DB381E7D1B98
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include
+
+[Ppis]
+
+[Protocols]
+
+[Guids]
+
+
+[LibraryClasses]
+
+[PcdsFixedAtBuild]
+
+[PcdsFeatureFlag]
+
+

+ 453 - 0
Platform/Hisilicon/D02/Pv660D02.dsc

@@ -0,0 +1,453 @@
+#
+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015, 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                  = Pv660D02
+  PLATFORM_GUID                  = E1AB8AC3-3EF1-4c6f-8D9F-ABE3EC67188E
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Hisilicon/D02/$(PLATFORM_NAME).fdf
+  DEFINE INCLUDE_TFTP_COMMAND=1
+
+!include Silicon/Hisilicon/Hisilicon.dsc.inc
+
+[LibraryClasses.common]
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
+
+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+  IpmiCmdLib|Silicon/Hisilicon/Hi1610/Library/IpmiCmdLib/IpmiCmdLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+
+!ifdef $(FDT_ENABLE)
+  #FDTUpdateLib
+  FdtUpdateLib|Platform/Hisilicon/D02/FdtUpdateLibD02/FdtUpdateLib.inf
+!endif #$(FDT_ENABLE)
+
+  CpldIoLib|Silicon/Hisilicon/Library/CpldIoLib/CpldIoLib.inf
+
+  SerdesLib|Silicon/Hisilicon/Pv660/Library/Pv660Serdes/Pv660SerdesLib.inf
+
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  RealTimeClockLib|Silicon/Hisilicon/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf
+  OemMiscLib|Platform/Hisilicon/D02/Library/OemMiscLibD02/OemMiscLibD02.inf
+  OemAddressMapLib|Platform/Hisilicon/D02/Library/AddressMapPv660D02/OemAddressMapPv660D02.inf
+  PlatformSysCtrlLib|Silicon/Hisilicon/Pv660/Library/PlatformSysCtrlLibPv660/PlatformSysCtrlLibPv660.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  PlatformBdsLib|Silicon/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+## GIC on D02/D03 is not fully ARM GIC compatible: IRQ cannot be cancelled when
+## input signal is de-asserted, except for virtual timer interrupt IRQ #27.
+## So we choose to use virtual timer instead of physical one as a workaround.
+## This library instance is to override the original define in LibraryClasses.AARCH64 in Hisilicon.dsc.inc.
+[LibraryClasses.AARCH64]
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
+
+[LibraryClasses.common.SEC]
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLibSec.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLibRuntime.inf
+
+[BuildOptions]
+  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/Silicon/Hisilicon/Pv660/Include
+
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+
+  ## 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
+
+[PcdsFixedAtBuild.common]
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D02"
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+
+  # Stacks for MPCores in Secure World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0xE1000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000
+
+  # Stacks for MPCores in Monitor Mode
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0xE100FF00
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x100
+
+  # Stacks for MPCores in Normal World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0xE1000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0xFF00
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3FC00000
+
+  # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x10000000
+
+  ## SP805 Watchdog - Motherboard Watchdog
+  gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x801e0000
+
+  ## Serial Terminal
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x80300000
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+  gHisiTokenSpaceGuid.PcdUartClkInHz|200000000
+
+  gHisiTokenSpaceGuid.PcdSerialPortSendDelay|10000000
+
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+
+  gHisiTokenSpaceGuid.PcdM3SmmuBaseAddress|0xa0040000
+  gHisiTokenSpaceGuid.PcdPcieSmmuBaseAddress|0xb0040000
+  gHisiTokenSpaceGuid.PcdDsaSmmuBaseAddress|0xc0040000
+  gHisiTokenSpaceGuid.PcdAlgSmmuBaseAddress|0xd0040000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Hisilicon D02 UEFI 16.08 RC1"
+
+  gHisiTokenSpaceGuid.PcdSystemProductName|L"D02"
+  gHisiTokenSpaceGuid.PcdSystemVersion|L"Estuary"
+  gHisiTokenSpaceGuid.PcdBaseBoardProductName|L"D02"
+  gHisiTokenSpaceGuid.PcdBaseBoardVersion|L"Estuary"
+
+  gHisiTokenSpaceGuid.PcdSlotPerChannelNum|0x2
+
+  #
+  # ARM PL390 General Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x8D000000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xFE000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x8D100000
+
+  ## DTB address at spi flash
+  gHisiTokenSpaceGuid.FdtFileAddress|0xA4B00000
+
+  gHisiTokenSpaceGuid.PcdNORFlashBase|0x90000000
+  gHisiTokenSpaceGuid.PcdNORFlashCachableSize|0x8000000
+
+  #
+  # ARM OS Loader
+  #
+  # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux:
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from SATA"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"EFI\GRUB2\grubaa64.efi"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|""
+
+  # 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(407B4008-BF5B-11DF-9547-CF16E0D72085)"
+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+  #
+  # ARM Architectual Timer Frequency
+  #
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000
+
+  gHisiTokenSpaceGuid.PcdSysControlBaseAddress|0x80010000
+  gHisiTokenSpaceGuid.PcdMailBoxAddress|0x0000FFF8
+  gHisiTokenSpaceGuid.PcdCpldBaseAddress|0x98000000
+  gHisiTokenSpaceGuid.PcdSFCCFGBaseAddress|0xA6000000
+  gHisiTokenSpaceGuid.PcdSFCMEM0BaseAddress|0xA4000000
+
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress|0x80000000
+
+  gHisiTokenSpaceGuid.PcdMdioSubctrlAddress|0x80000000
+
+  ## 1 SCCL + 1 SICL
+  gHisiTokenSpaceGuid.PcdPlatformDefaultPackageType|0x0
+  gHisiTokenSpaceGuid.PcdArmPrimaryCoreTemp|0x80020000
+  gHisiTokenSpaceGuid.PcdTopOfLowMemory|0x80000000
+  gHisiTokenSpaceGuid.PcdBottomOfHighMemory|0x1000000000
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable|0x1
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+  ## SP804 DualTimer
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz|200
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum|304
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase|0x80060000
+  ## TODO: need to confirm the base for Performance and Metronome base for PV660
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase|0x80060000
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase|0x80060000
+
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask|0x6 # bit0:HB0RB0,bit1:HB0RB1,bit2:HB0RB2,bit3:HB0RB3,bit4:HB1RB0,bit5:HB1RB1,bit6:HB1RB2,bit7:HB1RB3
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress|0x400000000000 # 4T
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress|0x30000000000
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize|0x10000000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress|0x22000000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress|0x24000000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress|0x26000000000
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PciHb0Rb0Base|0xb0070000
+  gHisiTokenSpaceGuid.PciHb0Rb1Base|0xb0080000
+  gHisiTokenSpaceGuid.PciHb0Rb2Base|0xb0090000
+  gHisiTokenSpaceGuid.PciHb0Rb3Base|0xb00a0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress|0xb0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize|0x7feffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress|0xc0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize|0x3feffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase|0x22008000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase|0x2400c000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase|0x2200fff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase|0x2400fff0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize|0xffff #64K
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  Platform/Hisilicon/D02/MemoryInitPei/MemoryInitPeim.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.inf
+  Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  Silicon/Hisilicon/Pv660/Drivers/IoInitDxe/IoInitDxe.inf
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+  Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.inf
+
+
+  Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.inf
+
+  Platform/Hisilicon/D02/Drivers/SFC/SfcDxeDriver.inf
+
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+  Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
+
+  IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+  #
+  #ACPI
+  #
+  MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+  Silicon/Hisilicon/Pv660/Pv660AcpiTables/AcpiTables.inf
+  Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  Silicon/Hisilicon/Pv660/Drivers/UnInstallAcpiTableDxe/UnInstallAcpiTable.inf
+
+  #Pci Express
+  Silicon/Hisilicon/Pv660/Drivers/PcieInitDxe/PcieInitDxe.inf
+  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+     <LibraryClasses>
+       NULL|Platform/Hisilicon/D02/Library/PlatformPciLib/PlatformPciLib.inf
+  }
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  #
+  #network
+  #
+  Platform/Hisilicon/D02/Drivers/Net/SnpPV600Dxe/SnpPV600Dxe.inf
+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.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
+
+  Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+  Silicon/Hisilicon/Pv660/Drivers/SasInitDxe/SasV1Init.inf
+
+  MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  Platform/Hisilicon/D02/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+  #
+  # USB Support
+  #
+  Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+!ifdef $(FDT_ENABLE)
+  Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf {
+    <LibraryClasses>
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+!endif #$(FDT_ENABLE)
+
+  #
+  # Memory test
+  #
+  MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf
+
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  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
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+!ifdef $(INCLUDE_DP)
+      NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf
+!endif #$(INCLUDE_DP)
+!ifdef $(INCLUDE_TFTP_COMMAND)
+      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
+!endif #$(INCLUDE_TFTP_COMMAND)
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }

+ 317 - 0
Platform/Hisilicon/D02/Pv660D02.fdf

@@ -0,0 +1,317 @@
+#
+#  Copyright (c) 2011, 2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015, 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]
+
+################################################################################
+#
+# 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.PV660D02]
+BaseAddress   = 0xA4800000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+
+Size          = 0x00300000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00010000
+NumBlocks     = 0x30
+
+################################################################################
+#
+# 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|0x00040000
+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
+FILE = Platform/Hisilicon/D02/Sec/FVMAIN_SEC.Fv
+
+0x00040000|0x00240000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+## Place for Trusted Firmware
+0x00280000|0x00020000
+gHisiTokenSpaceGuid.PcdTrustedFirmwareBL1Base
+FILE = Platform/Hisilicon/D02/bl1.bin
+0x002a0000|0x00020000
+FILE = Platform/Hisilicon/D02/fip.bin
+
+0x002e0000|0x0000e000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x20000
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER gEfiVariableGuid
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+  #Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdFB8
+  0xB8, 0xdF, 0x00, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002ee000|0x00002000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid          =
+  0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49,
+  0xA0, 0xCE, 0x65, 0x0 , 0xFD, 0x9F, 0x1B, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002f0000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+################################################################################
+#
+# 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        = 16        # 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
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  INF Silicon/Hisilicon/Pv660/Drivers/IoInitDxe/IoInitDxe.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 Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.inf
+  INF Platform/Hisilicon/D02/Drivers/SFC/SfcDxeDriver.inf
+
+  INF Platform/Hisilicon/D02/OemNicConfigD02/OemNicConfigD02.inf
+
+  # PCI Express
+  INF Silicon/Hisilicon/Pv660/Drivers/PcieInitDxe/PcieInitDxe.inf
+  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  ## Sometimes we need to switch to emulated variable store for debug reason
+  #INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+
+  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+  # This is simpler than generic serial console and may be used for debug
+  #INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.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
+  INF IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.inf
+  INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+  INF Silicon/Hisilicon/Pv660/Drivers/SasInitDxe/SasV1Init.inf
+
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+  INF Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+  INF Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+  #
+  #ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  INF RuleOverride=ACPITABLE Silicon/Hisilicon/Pv660/Pv660AcpiTables/AcpiTables.inf
+  INF Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  #
+  #Network
+  #
+  INF Platform/Hisilicon/D02/Drivers/Net/SnpPV600Dxe/SnpPV600Dxe.inf
+
+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+
+!ifdef $(FDT_ENABLE)
+  INF Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf
+!endif #$(FDT_ENABLE)
+
+  INF Silicon/Hisilicon/Pv660/Drivers/UnInstallAcpiTableDxe/UnInstallAcpiTable.inf
+
+  #
+  #Sata
+  #
+  INF Platform/Hisilicon/D02/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+  #
+  # USB Support
+  #
+  INF Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # Build Shell from latest source code instead of prebuilt binary
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  INF MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+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/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  INF Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+  INF Platform/Hisilicon/D02/MemoryInitPei/MemoryInitPeim.inf
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+
+  INF Platform/Hisilicon/D02/EarlyConfigPeim/EarlyConfigPeim.inf
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+!include Silicon/Hisilicon/Hisilicon.fdf.inc
+

+ 44 - 0
Platform/Hisilicon/D03/D03.dec

@@ -0,0 +1,44 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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.
+#
+#**/
+
+#
+# D03 Package
+#
+#
+#
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = D03Pkg
+  PACKAGE_GUID                   = D42C5D53-63FA-4FBA-9FD4-E8EA684FD3BE
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include
+
+[Ppis]
+
+[Protocols]
+
+[Guids]
+
+
+[LibraryClasses]
+
+[PcdsFixedAtBuild]
+
+[PcdsFeatureFlag]
+
+

+ 525 - 0
Platform/Hisilicon/D03/D03.dsc

@@ -0,0 +1,525 @@
+#
+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015, 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                  = D03
+  PLATFORM_GUID                  = e5003abd-8809-6194-ac3d-a6a99ff52478
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Hisilicon/$(PLATFORM_NAME)/$(PLATFORM_NAME).fdf
+  DEFINE INCLUDE_TFTP_COMMAND=1
+
+!include Silicon/Hisilicon/Hisilicon.dsc.inc
+
+[LibraryClasses.common]
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
+
+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+
+
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+  IpmiCmdLib|Silicon/Hisilicon/Hi1610/Library/IpmiCmdLib/IpmiCmdLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+
+
+
+!ifdef $(FDT_ENABLE)
+  #FDTUpdateLib
+  FdtUpdateLib|Platform/Hisilicon/D03/Library/FdtUpdateLib/FdtUpdateLib.inf
+!endif #$(FDT_ENABLE)
+
+  CpldIoLib|Silicon/Hisilicon/Library/CpldIoLib/CpldIoLib.inf
+
+  SerdesLib|Silicon/Hisilicon/Hi1610/Library/Hi1610Serdes/Hi1610SerdesLib.inf
+
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  RealTimeClockLib|Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf
+
+  OemMiscLib|Platform/Hisilicon/D03/Library/OemMiscLib2P/OemMiscLib2PHi1610.inf
+  OemAddressMapLib|Platform/Hisilicon/D03/Library/OemAddressMap2P/OemAddressMap2PHi1610.inf
+  PlatformSysCtrlLib|Silicon/Hisilicon/Hi1610/Library/PlatformSysCtrlLibHi1610/PlatformSysCtrlLibHi1610.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  PlatformBdsLib|Silicon/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  # USB Requirements
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
+  SerialPortLib|Silicon/Hisilicon/Hi1610/Library/Uart/LpcSerialPortLib/LpcSerialPortLib.inf
+
+## GIC on D02/D03 is not fully ARM GIC compatible: IRQ cannot be cancelled when
+## input signal is de-asserted, except for virtual timer interrupt IRQ #27.
+## So we choose to use virtual timer instead of physical one as a workaround.
+## This library instance is to override the original define in LibraryClasses.AARCH64 in Hisilicon.dsc.inc.
+[LibraryClasses.AARCH64]
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
+
+[LibraryClasses.common.SEC]
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLibSec.inf
+
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLibRuntime.inf
+  SerialPortLib|Silicon/Hisilicon/Hi1610/Library/Uart/LpcSerialPortLib/LpcSerialPortLib.inf
+
+[BuildOptions]
+  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/Silicon/Hisilicon/Hi1610/Include
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gHisiTokenSpaceGuid.PcdIsItsSupported|TRUE
+  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D03"
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+
+  # Stacks for MPCores in Secure World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x81000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000
+
+  # Stacks for MPCores in Monitor Mode
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x8100FF00
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x100
+
+  # Stacks for MPCores in Normal World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x81000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0xFF00
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+
+
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3FC00000
+
+
+  # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|1
+  gHisiTokenSpaceGuid.PcdSlotPerChannelNum|0x2
+
+
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask|0x7 # bit0:HB0RB0,bit1:HB0RB1,bit2:HB0RB2,bit3:HB0RB3,bit4:HB1RB0,bit5:HB1RB1,bit6:HB1RB2,bit7:HB1RB3
+
+  ## SP805 Watchdog - Motherboard Watchdog
+  gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x601e0000
+
+  ## Serial Terminal
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x2F8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+  gHisiTokenSpaceGuid.PcdUartClkInHz|1846100
+
+  gHisiTokenSpaceGuid.PcdSerialPortSendDelay|10000000
+
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+
+
+  gHisiTokenSpaceGuid.PcdM3SmmuBaseAddress|0xa0040000
+  gHisiTokenSpaceGuid.PcdPcieSmmuBaseAddress|0xb0040000
+  gHisiTokenSpaceGuid.PcdDsaSmmuBaseAddress|0xc0040000
+  gHisiTokenSpaceGuid.PcdAlgSmmuBaseAddress|0xd0040000
+
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Hisilicon D03 UEFI 16.12 Release"
+
+  gHisiTokenSpaceGuid.PcdBiosVersionString|L"10.01.01T18"
+
+  gHisiTokenSpaceGuid.PcdBiosVersionForBmc|L"1.12"
+
+  gHisiTokenSpaceGuid.PcdSystemProductName|L"D03"
+  gHisiTokenSpaceGuid.PcdSystemVersion|L"Estuary"
+  gHisiTokenSpaceGuid.PcdBaseBoardProductName|L"D03"
+  gHisiTokenSpaceGuid.PcdBaseBoardVersion|L"Estuary"
+
+  gHisiTokenSpaceGuid.PcdCPUInfo|L"Hi1612"
+
+  #
+  # ARM PL390 General Interrupt Controller
+  #
+
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x4D000000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xFE000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x4D100000
+
+  #
+  # ARM OS Loader
+  #
+  # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux:
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from SATA"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"EFI\GRUB2\grubaa64.efi"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|""
+
+  # 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(407B4008-BF5B-11DF-9547-CF16E0D72085)"
+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+  #
+  # ARM Architectual Timer Frequency
+  #
+  # Set it to 0 so that the code will read frequence from register and be
+  # adapted to 66M and 50M boards
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
+
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+  gHisiTokenSpaceGuid.PcdSysControlBaseAddress|0x40010000
+  gHisiTokenSpaceGuid.PcdMailBoxAddress|0x0000FFF8
+
+  gHisiTokenSpaceGuid.PcdCpldBaseAddress|0x78000000
+
+  gHisiTokenSpaceGuid.PcdSFCCFGBaseAddress|0xA6000000
+  gHisiTokenSpaceGuid.PcdSFCMEM0BaseAddress|0xA4000000
+
+
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress|0x40000000
+
+
+  gHisiTokenSpaceGuid.PcdMdioSubctrlAddress|0x60000000
+
+  gHisiTokenSpaceGuid.FdtFileAddress|0xA47C0000
+
+  gHisiTokenSpaceGuid.PcdPlatformDefaultPackageType|0x1
+
+  gHisiTokenSpaceGuid.PcdArmPrimaryCoreTemp|0x80010000
+
+  gHisiTokenSpaceGuid.PcdTopOfLowMemory|0x40000000
+
+  gHisiTokenSpaceGuid.PcdBottomOfHighMemory|0x2000000000
+
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable|0x1
+  gHisiTokenSpaceGuid.PcdNumaEnable|0
+
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress|0x40000000000
+
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress|0xB0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize|0x8000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress|0xB0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress|0xA0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress|0xAC000000
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize|0x4000000
+
+  gHisiTokenSpaceGuid.PciHb0Rb0Base|0xa0090000
+  gHisiTokenSpaceGuid.PciHb0Rb1Base|0xa0200000
+  gHisiTokenSpaceGuid.PciHb0Rb2Base|0xa00a0000
+  gHisiTokenSpaceGuid.PciHb0Rb3Base|0xa00b0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionBaseAddress|0xb2000000
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionSize|0x5feffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress|0xb8000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize|0x5feffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress|0xaa000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize|0x5feffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuMemRegionBase|0xB2000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase|0xB8000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase|0xAA000000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuIoRegionBase|0xb7ff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase|0xbdff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase|0xAfff0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.Pcdsoctype|0x1610
+  ## SP804 DualTimer
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz|200
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum|0xb0
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase|0x40060000
+  ## TODO: need to confirm the base for Performance and Metronome base for PV660
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase|0x40060000
+  gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase|0x40060000
+
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+
+  #
+  # SEC
+  #
+
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  Platform/Hisilicon/D03/Drivers/Ipmi/IpmiInterfacePei/IpmiInterfacePei.inf
+
+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+
+  Platform/Hisilicon/D03/MemoryInitPei/MemoryInitPeim.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.inf
+  Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  Silicon/Hisilicon/Hi1610/Drivers/IoInitDxe/IoInitDxe.inf
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
+
+  Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
+
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+  Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
+    <LibraryClasses>
+      CpldIoLib|Silicon/Hisilicon/Library/CpldIoLib/CpldIoLibRuntime.inf
+  }
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
+  IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+  #
+  #ACPI
+  #
+  MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+  Silicon/Hisilicon/Hi1610/Hi1610AcpiTables/AcpiTablesHi1610.inf
+  Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  #
+  # Usb Support
+  #
+  Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  Platform/Hisilicon/D03/Drivers/OhciDxe/OhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/Ipmi/ipmiInterfaceDxe/IpmiInterfaceDxe.inf
+
+  #
+  #network
+  #
+  Platform/Hisilicon/D03/Drivers/Net/SnpPV660Dxe/SnpPV600Dxe.inf
+
+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/Sas/SasDxeDriver.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
+
+  MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/GetInfoFromBmc/GetInfoFromBmc.inf
+  Platform/Hisilicon/D03/Drivers/TransferSmbiosInfo/TransSmbiosInfo.inf
+  Platform/Hisilicon/D03/Drivers/IpmiMiscOpDxe/IpmiMiscOpDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/IpmiWatchdogDxe/IpmiWatchdogDxe.inf
+
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+
+!ifdef $(FDT_ENABLE)
+  Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf {
+    <LibraryClasses>
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+!endif #$(FDT_ENABLE)
+
+  #PCIe Support
+  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf {
+    <LibraryClasses>
+      NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
+  }
+  Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
+  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+    <LibraryClasses>
+      NULL|Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf
+  }
+
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
+  Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf
+  Platform/Hisilicon/D03/Drivers/Sm750Dxe/UefiSmi.inf
+
+  Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+
+
+  Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+  #
+  # Memory test
+  #
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  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
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+!ifdef $(INCLUDE_DP)
+      NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf
+!endif #$(INCLUDE_DP)
+!ifdef $(INCLUDE_TFTP_COMMAND)
+      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
+!endif #$(INCLUDE_TFTP_COMMAND)
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }

+ 334 - 0
Platform/Hisilicon/D03/D03.fdf

@@ -0,0 +1,334 @@
+#
+#  Copyright (c) 2011, 2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015, 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]
+
+################################################################################
+#
+# 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.D03]
+BaseAddress   = 0xA4800000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+
+Size          = 0x00300000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00010000
+NumBlocks     = 0x30
+
+################################################################################
+#
+# 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|0x00040000
+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
+FILE = Platform/Hisilicon/D03/Sec/FVMAIN_SEC.Fv
+
+0x00040000|0x00240000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+0x00280000|0x00020000
+gHisiTokenSpaceGuid.PcdTrustedFirmwareBL1Base
+FILE = Platform/Hisilicon/D03/bl1.bin
+0x002A0000|0x00020000
+FILE = Platform/Hisilicon/D03/fip.bin
+
+0x002D0000|0x0000E000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x20000
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER gEfiVariableGuid
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+  #Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdFB8
+  0xB8, 0xdF, 0x00, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002DE000|0x00002000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid          =
+  0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49,
+  0xA0, 0xCE, 0x65, 0x0 , 0xFD, 0x9F, 0x1B, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002E0000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+0x002F0000|0x00010000
+FILE = Platform/Hisilicon/D03/CustomData.Fv
+
+################################################################################
+#
+# 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        = 16        # 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
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  INF Silicon/Hisilicon/Hi1610/Drivers/IoInitDxe/IoInitDxe.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 Platform/Hisilicon/D03/Drivers/SFC/SfcDxeDriver.inf
+
+  INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
+
+
+  INF Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.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
+  INF IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+
+  #
+  # Usb Support
+  #
+
+  INF Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  INF Platform/Hisilicon/D03/Drivers/OhciDxe/OhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  INF Platform/Hisilicon/D03/Drivers/Ipmi/ipmiInterfaceDxe/IpmiInterfaceDxe.inf
+  INF Platform/Hisilicon/D03/Drivers/GetInfoFromBmc/GetInfoFromBmc.inf
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf
+  INF Platform/Hisilicon/D03/Drivers/TransferSmbiosInfo/TransSmbiosInfo.inf
+  INF Platform/Hisilicon/D03/Drivers/IpmiMiscOpDxe/IpmiMiscOpDxe.inf
+
+  INF Platform/Hisilicon/D03/Drivers/IpmiWatchdogDxe/IpmiWatchdogDxe.inf
+
+
+  INF Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+  #
+  #ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  INF RuleOverride=ACPITABLE Silicon/Hisilicon/Hi1610/Hi1610AcpiTables/AcpiTablesHi1610.inf
+  INF Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  #
+  #Network
+  #
+
+  INF Platform/Hisilicon/D03/Drivers/Net/SnpPV660Dxe/SnpPV600Dxe.inf
+
+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+
+!ifdef $(FDT_ENABLE)
+  INF Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf
+!endif #$(FDT_ENABLE)
+
+  #
+  # PCI Support
+  #
+  INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+  INF Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
+  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  INF Platform/Hisilicon/D03/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
+  # VGA Driver
+  #
+  INF Platform/Hisilicon/D03/Drivers/Sm750Dxe/UefiSmi.inf
+
+  INF Platform/Hisilicon/D03/Drivers/Sas/SasDxeDriver.inf
+
+  #
+  # Build Shell from latest source code instead of prebuilt binary
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+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/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+
+  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  INF Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+
+  INF Platform/Hisilicon/D03/Drivers/Ipmi/IpmiInterfacePei/IpmiInterfacePei.inf
+  INF Platform/Hisilicon/D03/MemoryInitPei/MemoryInitPeim.inf
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  INF Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.inf
+
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+!include Silicon/Hisilicon/Hisilicon.fdf.inc
+

+ 40 - 0
Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig.h

@@ -0,0 +1,40 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 __OEM_NIC_CONFIG_H__
+#define __OEM_NIC_CONFIG_H__
+
+#define I2C_SLAVEADDR_EEPROM     (0x52)
+
+#define I2C_OFFSET_EEPROM_ETH0   (0xc00)
+#define I2C_OFFSET_EEPROM_ETH1   (I2C_OFFSET_EEPROM_ETH0 + 6)
+#define I2C_OFFSET_EEPROM_ETH2   (I2C_OFFSET_EEPROM_ETH1 + 6)
+#define I2C_OFFSET_EEPROM_ETH3   (I2C_OFFSET_EEPROM_ETH2 + 6)
+#define I2C_OFFSET_EEPROM_ETH4   (I2C_OFFSET_EEPROM_ETH3 + 6)
+#define I2C_OFFSET_EEPROM_ETH5   (I2C_OFFSET_EEPROM_ETH4 + 6)
+#define I2C_OFFSET_EEPROM_ETH6   (I2C_OFFSET_EEPROM_ETH5 + 6)
+#define I2C_OFFSET_EEPROM_ETH7   (I2C_OFFSET_EEPROM_ETH6 + 6)
+
+#define MAC_ADDR_LEN  6
+
+#pragma pack(1)
+typedef struct {
+  UINT16 Crc16;
+  UINT16 MacLen;
+  UINT8  Mac[MAC_ADDR_LEN];
+} NIC_MAC_ADDRESS;
+#pragma pack()
+
+#endif

+ 362 - 0
Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.c

@@ -0,0 +1,362 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/HisiBoardNicProtocol.h>
+#include <OemNicConfig.h>
+#include <Library/CpldIoLib.h>
+
+#include <Library/I2CLib.h>
+
+#define EEPROM_I2C_PORT 6
+#define EEPROM_PAGE_SIZE 0x40
+
+EFI_STATUS
+EFIAPI OemGetMac2P (IN OUT EFI_MAC_ADDRESS *Mac, IN UINTN Port);
+
+EFI_STATUS
+EFIAPI OemSetMac2P (IN EFI_MAC_ADDRESS *Mac, IN UINTN Port);
+
+EFI_STATUS OemGetMacE2prom(IN UINT32 Port, OUT UINT8 *pucAddr);
+EFI_STATUS OemSetMacE2prom(IN UINT32 Port, IN UINT8 *pucAddr);
+
+volatile unsigned char g_2pserveraddr[4][6] =
+{
+    {0x00, 0x18, 0x16, 0x29, 0x11, 0x00},
+    {0x00, 0x18, 0x16, 0x29, 0x11, 0x01},
+    {0x00, 0x18, 0x16, 0x29, 0x11, 0x02},
+    {0x00, 0x18, 0x16, 0x29, 0x11, 0x03}
+};
+
+UINT16 crc_tab[256] = {
+    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+    0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+    0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+    0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+    0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+    0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+    0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+    0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+    0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+    0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+    0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+    0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+    0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+    0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+    0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+    0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+    0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+    0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+    0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+    0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+    0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+    0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+    0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+    0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+    0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+    0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+    0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+    0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+    0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+    0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+    0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
+};
+
+UINT16 make_crc_checksum(UINT8 *buf, UINT32 len)
+{
+    UINT16 StartCRC = 0;
+
+    if (len > (512 * 1024))
+    {
+        return 0;
+    }
+
+    if (NULL == buf)
+    {
+        return 0;
+    }
+
+    while (len)
+    {
+        StartCRC = crc_tab[((UINT8)((StartCRC >> 8) & 0xff)) ^ *(buf++)] ^ ((UINT16)(StartCRC << 8));
+        len--;
+    }
+
+    return StartCRC;
+}
+
+
+EFI_STATUS OemGetMacE2prom(IN UINT32 Port, OUT UINT8 *pucAddr)
+{
+    I2C_DEVICE stI2cDev = {0};
+    EFI_STATUS Status;
+    UINT16     I2cOffset;
+    UINT16     crc16;
+    NIC_MAC_ADDRESS stMacDesc = {0};
+    UINT16     RemainderMacOffset;
+    UINT16     LessSizeOfPage;
+
+    Status = I2CInit(0, EEPROM_I2C_PORT, Normal);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2CInit failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    I2cOffset = I2C_OFFSET_EEPROM_ETH0 + (Port * sizeof(NIC_MAC_ADDRESS));
+
+    stI2cDev.DeviceType = DEVICE_TYPE_E2PROM;
+    stI2cDev.Port = EEPROM_I2C_PORT;
+    stI2cDev.SlaveDeviceAddress = I2C_SLAVEADDR_EEPROM;
+    stI2cDev.Socket = 0;
+    RemainderMacOffset = I2cOffset % EEPROM_PAGE_SIZE;
+    LessSizeOfPage = EEPROM_PAGE_SIZE - RemainderMacOffset;
+    //The length of NIC_MAC_ADDRESS is 10 bytes long,
+    //It surly less than EEPROM page size, so we could
+    //code as bellow, check the address whether across the page boundary,
+    //and split the data when across page boundary.
+    if (sizeof(NIC_MAC_ADDRESS) <= LessSizeOfPage) {
+      Status = I2CRead(&stI2cDev, I2cOffset, sizeof(NIC_MAC_ADDRESS), (UINT8 *)&stMacDesc);
+    } else {
+      Status = I2CRead(&stI2cDev, I2cOffset, LessSizeOfPage, (UINT8 *)&stMacDesc);
+      if (!(EFI_ERROR(Status))) {
+        Status |= I2CRead(
+                          &stI2cDev,
+                          I2cOffset + LessSizeOfPage,
+                          sizeof(NIC_MAC_ADDRESS) - LessSizeOfPage,
+                          (UINT8 *)&stMacDesc + LessSizeOfPage
+                         );
+      }
+    }
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2cRead failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    crc16 = make_crc_checksum((UINT8 *)&(stMacDesc.MacLen), sizeof(stMacDesc.MacLen) + sizeof(stMacDesc.Mac));
+    if ((crc16 != stMacDesc.Crc16) || (0 == crc16))
+    {
+        return EFI_NOT_FOUND;
+    }
+
+    gBS->CopyMem((VOID *)(pucAddr), (VOID *)(stMacDesc.Mac), MAC_ADDR_LEN);
+
+
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS OemSetMacE2prom(IN UINT32 Port, IN UINT8 *pucAddr)
+{
+    I2C_DEVICE stI2cDev = {0};
+    EFI_STATUS Status;
+    UINT16     I2cOffset;
+    NIC_MAC_ADDRESS stMacDesc = {0};
+
+
+    stMacDesc.MacLen = MAC_ADDR_LEN;
+    UINT16     RemainderMacOffset;
+    UINT16     LessSizeOfPage;
+    gBS->CopyMem((VOID *)(stMacDesc.Mac), (VOID *)pucAddr, MAC_ADDR_LEN);
+
+    stMacDesc.Crc16  = make_crc_checksum((UINT8 *)&(stMacDesc.MacLen), sizeof(stMacDesc.MacLen) + MAC_ADDR_LEN);
+
+    Status = I2CInit(0, EEPROM_I2C_PORT, Normal);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2CInit failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    I2cOffset = I2C_OFFSET_EEPROM_ETH0 + (Port * sizeof(NIC_MAC_ADDRESS));
+
+    stI2cDev.DeviceType = DEVICE_TYPE_E2PROM;
+    stI2cDev.Port = EEPROM_I2C_PORT;
+    stI2cDev.SlaveDeviceAddress = I2C_SLAVEADDR_EEPROM;
+    stI2cDev.Socket = 0;
+    RemainderMacOffset = I2cOffset % EEPROM_PAGE_SIZE;
+    LessSizeOfPage = EEPROM_PAGE_SIZE - RemainderMacOffset;
+    //The length of NIC_MAC_ADDRESS is 10 bytes long,
+    //It surly less than EEPROM page size, so we could
+    //code as bellow, check the address whether across the page boundary,
+    //and split the data when across page boundary.
+    if (sizeof(NIC_MAC_ADDRESS) <= LessSizeOfPage) {
+      Status = I2CWrite(&stI2cDev, I2cOffset, sizeof(NIC_MAC_ADDRESS), (UINT8 *)&stMacDesc);
+    } else {
+      Status = I2CWrite(&stI2cDev, I2cOffset, LessSizeOfPage, (UINT8 *)&stMacDesc);
+      if (!(EFI_ERROR(Status))) {
+        Status |= I2CWrite(
+                           &stI2cDev,
+                           I2cOffset + LessSizeOfPage,
+                           sizeof(NIC_MAC_ADDRESS) - LessSizeOfPage,
+                           (UINT8 *)&stMacDesc + LessSizeOfPage
+                          );
+      }
+    }
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Call I2cWrite failed! p1=0x%x.\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI OemGetMac2P (
+  IN OUT EFI_MAC_ADDRESS *Mac,
+  IN UINTN Port
+  )
+{
+    EFI_STATUS Status;
+
+    if (NULL == Mac)
+    {
+      DEBUG((EFI_D_ERROR, "[%a]:[%dL] Mac buffer is null!\n", __FUNCTION__, __LINE__));
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Status = OemGetMacE2prom(Port, Mac->Addr);
+    if ((EFI_ERROR(Status)))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Get mac failed!\n", __FUNCTION__, __LINE__));
+
+        Mac->Addr[0] = 0x00;
+        Mac->Addr[1] = 0x18;
+        Mac->Addr[2] = 0x82;
+        Mac->Addr[3] = 0x2F;
+        Mac->Addr[4] = 0x02;
+        Mac->Addr[5] = Port;
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI OemSetMac2P (
+  IN EFI_MAC_ADDRESS *Mac,
+  IN UINTN Port
+  )
+{
+  EFI_STATUS Status;
+
+  if (NULL == Mac)
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Mac buffer is null!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = OemSetMacE2prom(Port, Mac->Addr);
+  if ((EFI_ERROR(Status)))
+  {
+      DEBUG((EFI_D_ERROR, "[%a]:[%dL] Set mac failed!\n", __FUNCTION__, __LINE__));
+      return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+HISI_BOARD_NIC_PROTOCOL mHisiBoardNicProtocol2P = {
+  .GetMac = OemGetMac2P,
+  .SetMac = OemSetMac2P,
+};
+
+VOID OemFeedbackXGeStatus(BOOLEAN IsLinkup, BOOLEAN IsActOK, UINT32 port)
+{
+    UINT8 CpldValue = 0;
+    UINTN RegOffset = 0x10 + (UINTN)port * 4;
+
+    if (port > 2)
+    {
+        return;
+    }
+
+    if (IsLinkup)
+    {
+        CpldValue = ReadCpldReg(RegOffset);
+        CpldValue |= BIT2;
+        WriteCpldReg(RegOffset, CpldValue);
+    }
+    else
+    {
+        CpldValue = ReadCpldReg(RegOffset);
+        CpldValue &= ~((UINT8)BIT2);
+        WriteCpldReg(RegOffset, CpldValue);
+    }
+
+    if (IsActOK)
+    {
+        CpldValue = ReadCpldReg(RegOffset);
+        CpldValue |= BIT4;
+        WriteCpldReg(RegOffset, CpldValue);
+    }
+    else
+    {
+        CpldValue = ReadCpldReg(RegOffset);
+        CpldValue &= ~((UINT8)BIT4);
+        WriteCpldReg(RegOffset, CpldValue);
+    }
+}
+
+HISI_BOARD_XGE_STATUS_PROTOCOL mHisiBoardXgeStatusProtocol2p = {
+  .FeedbackXgeStatus = OemFeedbackXGeStatus,
+};
+
+
+EFI_STATUS
+EFIAPI
+OemNicConfigEntry (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gBS->InstallProtocolInterface(
+    &ImageHandle,
+    &gHisiBoardNicProtocolGuid,
+    EFI_NATIVE_INTERFACE,
+    &mHisiBoardNicProtocol2P
+    );
+
+  if(EFI_ERROR(Status))
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Install Protocol failed %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  Status = gBS->InstallProtocolInterface(
+    &ImageHandle,
+    &gHisiBoardXgeStatusProtocolGuid,
+    EFI_NATIVE_INTERFACE,
+    &mHisiBoardXgeStatusProtocol2p
+    );
+
+  if(EFI_ERROR(Status))
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Install Protocol failed %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+

+ 52 - 0
Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf

@@ -0,0 +1,52 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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                      = OemNicConfigPangea
+  FILE_GUID                      = 3A23A929-1F38-4d04-8A01-38AD993EB2CE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = OemNicConfigEntry
+
+[Sources.common]
+  OemNicConfig2P.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[Protocols]
+  gHisiBoardNicProtocolGuid       ##Produce
+  gHisiBoardXgeStatusProtocolGuid
+
+[LibraryClasses]
+  CpldIoLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DebugLib
+  IoLib
+  TimerLib
+  I2CLib
+  PcdLib
+
+[FixedPcd]
+
+[Depex]
+  TRUE
+
+[BuildOptions]
+

+ 437 - 0
Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.c

@@ -0,0 +1,437 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/MemoryAllocationLib.h>
+
+//
+// Global variables for Option ROMs
+//
+#define NULL_ROM_FILE_GUID \
+  { \
+    0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} \
+  }
+
+#define SAS_OPTION_ROM_FILE_GUID \
+{ 0xb47533c7, 0xcc78, 0x4e5e, {0x94, 0x33, 0xf2, 0x8b, 0x16, 0xcd, 0x66, 0xdb}}
+
+#define SAS3108_OPTION_ROM_FILE_GUID \
+{ 0xb47533c8, 0xcc78, 0x4e5e, {0x94, 0x33, 0xf2, 0x8b, 0x16, 0xcd, 0x66, 0xd8}}
+
+#define INVALID                     0xBD
+
+
+typedef struct {
+  EFI_HANDLE                      PciPlatformHandle;
+  EFI_PCI_PLATFORM_PROTOCOL       PciPlatform;
+} PCI_PLATFORM_PRIVATE_DATA;
+
+
+#define MAX_ROM_NUMBER  2
+
+
+typedef struct {
+  EFI_GUID  FileName;
+  UINTN     Segment;
+  UINTN     Bus;
+  UINTN     Device;
+  UINTN     Function;
+  UINT16    VendorId;
+  UINT16    DeviceId;
+} PCI_OPTION_ROM_TABLE;
+
+typedef struct {
+  UINTN                   RomSize;
+  VOID                    *RomBase;
+} OPTION_ROM_INFO;
+
+PCI_PLATFORM_PRIVATE_DATA *mPciPrivateData = NULL;
+
+PCI_OPTION_ROM_TABLE      mPciOptionRomTable[] = {
+  {
+    SAS_OPTION_ROM_FILE_GUID,
+    0,
+    2,
+    0,
+    0,
+    0x1000,
+    0x0097
+  },
+  {
+    SAS3108_OPTION_ROM_FILE_GUID,
+    0,
+    1,
+    0,
+    0,
+    0x1000,
+    0x005D
+  },
+
+    //
+    // End of OptionROM Entries
+    //
+  {
+    NULL_ROM_FILE_GUID, // Guid
+    0,                  // Segment
+    0,                  // Bus Number
+    0,                  // Device Number
+    0,                  // Function Number
+    0xffff,             // Vendor ID
+    0xffff              // Device ID
+  }
+};
+
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL         *This,
+  OUT EFI_PCI_PLATFORM_POLICY           *PciPolicy
+  )
+/*++
+
+Routine Description:
+
+  Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+Arguments:
+
+  This       -  The pointer to the Protocol itself.
+  PciPolicy  -  the returned Policy.
+
+Returns:
+
+  EFI_UNSUPPORTED        -  Function not supported.
+  EFI_INVALID_PARAMETER  -  Invalid PciPolicy value.
+
+--*/
+{
+  if (PciPolicy == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetRawImage (
+  IN     EFI_GUID                       *NameGuid,
+  IN OUT VOID                           **Buffer,
+  IN OUT UINTN                          *Size
+  )
+/*++
+
+Routine Description:
+
+  Get an indicated image in raw sections.
+
+Arguments:
+
+  NameGuid  -  NameGuid of the image to get.
+  Buffer    -  Buffer to store the image get.
+  Size      -  size of the image get.
+
+Returns:
+
+  EFI_NOT_FOUND   -  Could not find the image.
+  EFI_LOAD_ERROR  -  Error occurred during image loading.
+  EFI_SUCCESS     -  Image has been successfully loaded.
+
+--*/
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         HandleCount;
+  UINTN                         Index;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  UINT32                        AuthenticationStatus;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status) || HandleCount == 0) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Find desired image in all Fvs
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **)&Fv
+                    );
+    if (EFI_ERROR (Status)) {
+      return EFI_LOAD_ERROR;
+    }
+    //
+    // Try a raw file
+    //
+    *Buffer = NULL;
+    *Size   = 0;
+    Status = Fv->ReadSection (
+                  Fv,
+                  NameGuid,
+                  EFI_SECTION_RAW,
+                  0,
+                  Buffer,
+                  Size,
+                  &AuthenticationStatus
+                  );
+
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+  }
+
+  if (Index >= HandleCount) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetPciRom (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL         *This,
+  IN  EFI_HANDLE                        PciHandle,
+  OUT VOID                              **RomImage,
+  OUT UINTN                             *RomSize
+  )
+/*++
+
+Routine Description:
+
+  Return a PCI ROM image for the onboard device represented by PciHandle.
+
+Arguments:
+
+  This       -  Protocol instance pointer.
+  PciHandle  -  PCI device to return the ROM image for.
+  RomImage   -  PCI Rom Image for onboard device.
+  RomSize    -  Size of RomImage in bytes.
+
+Returns:
+
+  EFI_SUCCESS    -  RomImage is valid.
+  EFI_NOT_FOUND  -  No RomImage.
+
+--*/
+{
+  EFI_STATUS                        Status;
+  EFI_PCI_IO_PROTOCOL               *PciIo;
+  UINT16                            VendorId;
+  UINT16                            DeviceId;
+  UINTN                             TableIndex;
+  UINTN                             RomImageNumber;
+  OPTION_ROM_INFO                   OptionRominfo[MAX_ROM_NUMBER];
+
+  Status = gBS->HandleProtocol (
+                  PciHandle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  (VOID)PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &VendorId);
+  (VOID)PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &DeviceId);
+
+  //
+  // Loop through table of video option rom descriptions
+  //
+  RomImageNumber = 0;
+  for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
+    //
+    // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
+    //
+        if ((VendorId != mPciOptionRomTable[TableIndex].VendorId)
+            || (DeviceId != mPciOptionRomTable[TableIndex].DeviceId)
+        )
+        {
+            continue;
+        }
+
+    Status = GetRawImage (
+              &mPciOptionRomTable[TableIndex].FileName,
+              &(OptionRominfo[RomImageNumber].RomBase),
+              &(OptionRominfo[RomImageNumber].RomSize)
+              );
+
+    if (EFI_ERROR (Status)) {
+      continue;
+    } else {
+      RomImageNumber++;
+      if (RomImageNumber == MAX_ROM_NUMBER) {
+        break;
+      }
+    }
+  }
+
+  if (RomImageNumber == 0) {
+
+    return EFI_NOT_FOUND;
+
+  } else {
+    *RomImage = OptionRominfo[RomImageNumber - 1].RomBase;
+    *RomSize  = OptionRominfo[RomImageNumber - 1].RomSize;
+
+    if (RomImageNumber > 1) {
+      //
+      // More than one OPROM have been found!
+      //
+
+    }
+
+    return EFI_SUCCESS;
+  }
+}
+
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+  IN  EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_HANDLE                                     RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+/*++
+
+Routine Description:
+
+  The PlatformPrepController() function can be used to notify the platform driver so that
+  it can perform platform-specific actions. No specific actions are required.
+  Several notification points are defined at this time. More synchronization points may be
+  added as required in the future. The PCI bus driver calls the platform driver twice for
+  every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+  is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+  been notified.
+  This member function may not perform any error checking on the input parameters. It also
+  does not return any error codes. If this member function detects any error condition, it
+  needs to handle those errors on its own because there is no way to surface any errors to
+  the caller.
+
+Arguments:
+
+  This          -  Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+  HostBridge    -  The associated PCI host bridge handle.
+  RootBridge    -  The associated PCI root bridge handle.
+  PciAddress    -  The address of the PCI device on the PCI bus.
+  Phase         -  The phase of the PCI controller enumeration.
+  ChipsetPhase  -  Defines the execution phase of the PCI chipset driver.
+
+Returns:
+
+  EFI_SUCCESS     -  The function completed successfully.
+  EFI_UNSUPPORTED -  Not supported.
+
+--*/
+{
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+  IN EFI_PCI_PLATFORM_PROTOCOL                       *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE  Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+/*++
+
+Routine Description:
+
+  Perform initialization by the phase indicated.
+
+Arguments:
+
+  This          -  Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+  HostBridge    -  The associated PCI host bridge handle.
+  Phase         -  The phase of the PCI controller enumeration.
+  ChipsetPhase  -  Defines the execution phase of the PCI chipset driver.
+
+Returns:
+
+  EFI_SUCCESS  -  Must return with success.
+
+--*/
+{
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciPlatformDriverEntry (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+/*++
+
+Routine Description:
+  Main Entry point of the Pci Platform Driver.
+
+Arguments:
+
+  ImageHandle  -  Handle to the image.
+  SystemTable  -  Handle to System Table.
+
+Returns:
+
+  EFI_STATUS  -  Status of the function calling.
+
+--*/
+{
+  EFI_STATUS  Status;
+  PCI_PLATFORM_PRIVATE_DATA *PciPrivateData;
+
+  PciPrivateData = AllocateZeroPool (sizeof (PCI_PLATFORM_PRIVATE_DATA));
+  mPciPrivateData = PciPrivateData;
+
+  mPciPrivateData->PciPlatform.PlatformNotify             = PhaseNotify;
+  mPciPrivateData->PciPlatform.PlatformPrepController     = PlatformPrepController;
+  mPciPrivateData->PciPlatform.GetPlatformPolicy          = GetPlatformPolicy;
+  mPciPrivateData->PciPlatform.GetPciRom                  = GetPciRom;
+
+  //
+  // Install on a new handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mPciPrivateData->PciPlatformHandle,
+                  &gEfiPciPlatformProtocolGuid,
+                  &mPciPrivateData->PciPlatform,
+                  NULL
+                  );
+
+  return Status;
+}

+ 180 - 0
Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.h

@@ -0,0 +1,180 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 PCI_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/PciPlatform.h>
+
+
+//
+// Global variables for Option ROMs
+//
+#define NULL_ROM_FILE_GUID \
+  { \
+    0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
+  }
+
+
+typedef struct {
+  EFI_GUID  FileName;
+  UINTN     Segment;
+  UINTN     Bus;
+  UINTN     Device;
+  UINTN     Function;
+  UINT16    VendorId;
+  UINT16    DeviceId;
+} PCI_OPTION_ROM_TABLE;
+
+#define INVALID                     0xBD
+
+
+typedef struct {
+  EFI_HANDLE                      PciPlatformHandle;
+  EFI_PCI_PLATFORM_PROTOCOL       PciPlatform;
+} PCI_PLATFORM_PRIVATE_DATA;
+
+
+
+extern PCI_PLATFORM_PRIVATE_DATA  mPciPrivateData;
+
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+  IN EFI_PCI_PLATFORM_PROTOCOL                        *This,
+  IN EFI_HANDLE                                       HostBridge,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase,
+  IN EFI_PCI_CHIPSET_EXECUTION_PHASE                  ChipsetPhase
+  )
+/*++
+
+Routine Description:
+
+  Perform initialization by the phase indicated.
+
+Arguments:
+
+  This          -  Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+  HostBridge    -  The associated PCI host bridge handle.
+  Phase         -  The phase of the PCI controller enumeration.
+  ChipsetPhase  -  Defines the execution phase of the PCI chipset driver.
+
+Returns:
+
+  EFI_SUCCESS  -  Must return with success.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+  IN  EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_HANDLE                                     RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+/*++
+
+Routine Description:
+
+  The PlatformPrepController() function can be used to notify the platform driver so that
+  it can perform platform-specific actions. No specific actions are required.
+  Several notification points are defined at this time. More synchronization points may be
+  added as required in the future. The PCI bus driver calls the platform driver twice for
+  every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+  is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+  been notified.
+  This member function may not perform any error checking on the input parameters. It also
+  does not return any error codes. If this member function detects any error condition, it
+  needs to handle those errors on its own because there is no way to surface any errors to
+  the caller.
+
+Arguments:
+
+  This          -  Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+  HostBridge    -  The associated PCI host bridge handle.
+  RootBridge    -  The associated PCI root bridge handle.
+  PciAddress    -  The address of the PCI device on the PCI bus.
+  Phase         -  The phase of the PCI controller enumeration.
+  ChipsetPhase  -  Defines the execution phase of the PCI chipset driver.
+
+Returns:
+
+  EFI_SUCCESS  -  The function completed successfully.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+  IN  EFI_PCI_PLATFORM_PROTOCOL            *This,
+  OUT EFI_PCI_PLATFORM_POLICY              *PciPolicy
+  )
+/*++
+
+Routine Description:
+
+  Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+Arguments:
+
+  This       -  The pointer to the Protocol itself.
+  PciPolicy  -  the returned Policy.
+
+Returns:
+
+  EFI_UNSUPPORTED        -  Function not supported.
+  EFI_INVALID_PARAMETER  -  Invalid PciPolicy value.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetPciRom (
+  IN   EFI_PCI_PLATFORM_PROTOCOL            *This,
+  IN   EFI_HANDLE                           PciHandle,
+  OUT  VOID                                 **RomImage,
+  OUT  UINTN                                *RomSize
+  )
+/*++
+
+Routine Description:
+
+  Return a PCI ROM image for the onboard device represented by PciHandle.
+
+Arguments:
+
+  This       -  Protocol instance pointer.
+  PciHandle  -  PCI device to return the ROM image for.
+  RomImage   -  PCI Rom Image for onboard device.
+  RomSize    -  Size of RomImage in bytes.
+
+Returns:
+
+  EFI_SUCCESS    -  RomImage is valid.
+  EFI_NOT_FOUND  -  No RomImage.
+
+--*/
+;
+
+#endif

+ 53 - 0
Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf

@@ -0,0 +1,53 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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            = PciPlatform
+  FILE_GUID            = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
+  MODULE_TYPE          = DXE_DRIVER
+  VERSION_STRING       = 1.0
+  ENTRY_POINT          = PciPlatformDriverEntry
+
+[sources.common]
+  PciPlatform.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiLib
+  BaseLib
+  DebugLib
+  ArmLib
+  IoLib
+  MemoryAllocationLib
+
+[Protocols]
+  gEfiPciPlatformProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiPciIoProtocolGuid
+
+[Pcd]
+
+[FixedPcd]
+
+[Depex]
+  TRUE
+

+ 180 - 0
Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.c

@@ -0,0 +1,180 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <Uefi.h>
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/CacheMaintenanceLib.h>
+
+#include <PlatformArch.h>
+#include <Library/PlatformSysCtrlLib.h>
+
+#include <Library/OemMiscLib.h>
+#include <Library/OemAddressMapLib.h>
+#include <Library/ArmLib.h>
+
+#define PERI_SUBCTRL_BASE                               (0x40000000)
+#define MDIO_SUBCTRL_BASE                               (0x60000000)
+#define PCIE2_SUBCTRL_BASE                              (0xA0000000)
+#define PCIE0_SUBCTRL_BASE                              (0xB0000000)
+#define ALG_BASE                                        (0xD0000000)
+
+#define SC_BROADCAST_EN_REG                             (0x16220)
+#define SC_BROADCAST_SCL1_ADDR0_REG                     (0x16230)
+#define SC_BROADCAST_SCL1_ADDR1_REG                     (0x16234)
+#define SC_BROADCAST_SCL2_ADDR0_REG                     (0x16238)
+#define SC_BROADCAST_SCL2_ADDR1_REG                     (0x1623C)
+#define SC_BROADCAST_SCL3_ADDR0_REG                     (0x16240)
+#define SC_BROADCAST_SCL3_ADDR1_REG                     (0x16244)
+#define PCIE_SUBCTRL_SC_DISP_DAW_EN_REG                 (0x1000)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY3_REG         (0x1010)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY4_REG         (0x1014)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG         (0x1018)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY6_REG         (0x101C)
+#define PCIE_SUBCTRL_SC_REMAP_CTRL_REG                  (0x1200)
+#define SC_ITS_M3_INT_MUX_SEL_REG                       (0x21F0)
+#define SC_TM_CLKEN0_REG                                (0x2050)
+
+#define SC_TM_CLKEN0_REG_VALUE                          (0x3)
+#define SC_BROADCAST_EN_REG_VALUE                       (0x7)
+#define SC_BROADCAST_SCLx_ADDRx_REG_VALUE0              (0x0)
+#define SC_BROADCAST_SCLx_ADDRx_REG_VALUE1              (0x40016260)
+#define SC_BROADCAST_SCLx_ADDRx_REG_VALUE2              (0x60016260)
+#define SC_BROADCAST_SCLx_ADDRx_REG_VALUE3              (0x400)
+#define SC_ITS_M3_INT_MUX_SEL_REG_VALUE                 (0x7)
+#define PCIE_SUBCTRL_SC_REMAP_CTRL_REG_VALUE0           (0x0)
+#define PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE0          (0x27)
+#define PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE1          (0x2F)
+#define PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE2          (0x77)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY3_REG_VALUE0  (0x178033)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY4_REG_VALUE0  (0x17003c)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG_VALUE0  (0x15003d)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG_VALUE1  (0x170035)
+#define PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY6_REG_VALUE0  (0x16003e)
+
+VOID PlatformTimerStart (VOID)
+{
+    // Timer0 clock enable
+    MmioWrite32 (PERI_SUBCTRL_BASE + SC_TM_CLKEN0_REG, SC_TM_CLKEN0_REG_VALUE);
+}
+
+void QResetAp(VOID)
+{
+    MmioWrite64(FixedPcdGet64(PcdMailBoxAddress), 0x0);
+    (void)WriteBackInvalidateDataCacheRange((VOID *) FixedPcdGet64(PcdMailBoxAddress), 8);
+    ArmDataSynchronizationBarrier ();
+    ArmInstructionSynchronizationBarrier ();
+
+    //SCCL A
+    if (!PcdGet64 (PcdTrustedFirmwareEnable))
+    {
+        StartupAp();
+    }
+}
+
+
+EFI_STATUS
+EFIAPI
+EarlyConfigEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+    DEBUG((EFI_D_INFO,"SMMU CONFIG........."));
+    (VOID)SmmuConfigForOS();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+
+    DEBUG((EFI_D_INFO,"AP CONFIG........."));
+    (VOID)QResetAp();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    DEBUG((EFI_D_INFO,"MN CONFIG........."));
+    (VOID)MN_CONFIG();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    if(OemIsMpBoot())
+    {
+        DEBUG((EFI_D_INFO,"Event Broadcast CONFIG........."));
+        //EVENT broadcast
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_EN_REG, SC_BROADCAST_EN_REG_VALUE);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_EN_REG, SC_BROADCAST_EN_REG_VALUE);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (PERI_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_EN_REG, SC_BROADCAST_EN_REG_VALUE);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (S1_BASE + MDIO_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_EN_REG, SC_BROADCAST_EN_REG_VALUE);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL1_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE2);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL2_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE3);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR0_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE1);
+        MmioWrite32 (S1_BASE + PERI_SUBCTRL_BASE + SC_BROADCAST_SCL3_ADDR1_REG, SC_BROADCAST_SCLx_ADDRx_REG_VALUE0);
+
+        DEBUG((EFI_D_INFO,"Done\n"));
+    }
+
+    DEBUG((EFI_D_INFO,"PCIE RAM Address CONFIG........."));
+
+    if(OemIsMpBoot())
+    {
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISP_DAW_EN_REG, PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE0);
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG_VALUE0);
+        MmioWrite32 (PCIE0_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISP_DAW_EN_REG, PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE1);
+        MmioWrite32 (PCIE0_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY3_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY3_REG_VALUE0);
+        MmioWrite32 (PCIE0_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG_VALUE1);
+    }
+
+    else
+    {
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_REMAP_CTRL_REG, PCIE_SUBCTRL_SC_REMAP_CTRL_REG_VALUE0);
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISP_DAW_EN_REG, PCIE_SUBCTRL_SC_DISP_DAW_EN_REG_VALUE2);
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY4_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY4_REG_VALUE0);
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY5_REG_VALUE0);
+        MmioWrite32 (PCIE2_SUBCTRL_BASE + PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY6_REG, PCIE_SUBCTRL_SC_DISPATCH_DAW_ARRAY6_REG_VALUE0);
+    }
+
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    MmioWrite32(ALG_BASE + SC_ITS_M3_INT_MUX_SEL_REG, SC_ITS_M3_INT_MUX_SEL_REG_VALUE);
+
+    DEBUG((EFI_D_INFO,"Timer CONFIG........."));
+    PlatformTimerStart ();
+    DEBUG((EFI_D_INFO,"Done\n"));
+
+    return EFI_SUCCESS;
+}
+

+ 55 - 0
Platform/Hisilicon/D03/EarlyConfigPeim/EarlyConfigPeimD03.inf

@@ -0,0 +1,55 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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                      = EarlyConfigPeimD03
+  FILE_GUID                      = A181AD33-E64A-4084-A54A-A69DF1FB0ABF
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = EarlyConfigEntry
+
+[Sources.common]
+  EarlyConfigPeimD03.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+  ArmPkg/ArmPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PcdLib
+  DebugLib
+  IoLib
+  CacheMaintenanceLib
+
+  PlatformSysCtrlLib
+  ArmLib
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdMailBoxAddress
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress
+
+[Depex]
+## As we will clean mailbox in this module, need to wait memory init complete
+  gEfiPeiMemoryDiscoveredPpiGuid
+
+[BuildOptions]
+

+ 25 - 0
Platform/Hisilicon/D03/Include/Library/CpldD03.h

@@ -0,0 +1,25 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 __CPLD_D03_H__
+#define __CPLD_D03_H__
+
+#define CPLD_BIOSINDICATE_FLAG  0x09
+#define CPLD_I2C_SWITCH_FLAG    0x17
+#define CPU_GET_I2C_CONTROL     BIT2
+#define BMC_I2C_STATUS          BIT3
+
+
+#endif

+ 178 - 0
Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClock.h

@@ -0,0 +1,178 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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.
+*
+*  Based on the files under ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+**/
+
+
+#ifndef __DS3231_REAL_TIME_CLOCK_H__
+#define __DS3231_REAL_TIME_CLOCK_H__
+
+#define DS3231_REGADDR_SECONDS      0x00
+#define DS3231_REGADDR_MIUTES       0x01
+#define DS3231_REGADDR_HOURS        0x02
+#define DS3231_REGADDR_DAY          0x03
+#define DS3231_REGADDR_DATE         0x04
+#define DS3231_REGADDR_MONTH        0x05
+#define DS3231_REGADDR_YEAR         0x06
+#define DS3231_REGADDR_ALARM1SEC    0x07
+#define DS3231_REGADDR_ALARM1MIN    0x08
+#define DS3231_REGADDR_ALARM1HOUR   0x09
+#define DS3231_REGADDR_ALARM1DAY    0x0A
+#define DS3231_REGADDR_ALARM2MIN    0x0B
+#define DS3231_REGADDR_ALARM2HOUR   0x0C
+#define DS3231_REGADDR_ALARM2DAY    0x0D
+#define DS3231_REGADDR_CONTROL      0x0E
+#define DS3231_REGADDR_STATUS       0x0F
+#define DS3231_REGADDR_AGOFFSET     0x10
+#define DS3231_REGADDR_TEMPMSB      0x11
+#define DS3231_REGADDR_TEMPLSB      0x12
+
+
+typedef union {
+  struct{
+    UINT8 A1IE:1;
+    UINT8 A2IE:1;
+    UINT8 INTCN:1;
+    UINT8 RSV:2;
+    UINT8 CONV:1;
+    UINT8 BBSQW:1;
+    UINT8 EOSC_N:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_CONTROL;
+
+typedef union {
+  struct{
+    UINT8 A1F:1;
+    UINT8 A2F:1;
+    UINT8 BSY:1;
+    UINT8 EN32KHZ:2;
+    UINT8 Rsv:3;
+    UINT8 OSF:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_STATUS;
+
+
+typedef union {
+  struct{
+    UINT8 Data:7;
+    UINT8 Sign:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_AGOFFSET;
+
+typedef union {
+  struct{
+    UINT8 Data:7;
+    UINT8 Sign:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_TEMPMSB;
+
+
+typedef union {
+  struct{
+    UINT8 Rsv:6;
+    UINT8 Data:2;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_TEMPLSB;
+
+typedef union {
+  struct{
+    UINT8 Seconds:4;
+    UINT8 Seconds10:3;
+    UINT8 Rsv:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_SECONDS;
+
+typedef union {
+  struct{
+    UINT8 Minutes:4;
+    UINT8 Minutes10:3;
+    UINT8 Rsv:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_MINUTES;
+
+typedef union {
+  struct{
+    UINT8 Hour:4;
+    UINT8 Hours10:1;
+    UINT8 PM_20Hours:1;
+    UINT8 Hour24_n:1;
+    UINT8 Rsv:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_HOURS;
+
+typedef union {
+  struct{
+    UINT8 Day:3;
+    UINT8 Rsv:5;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_DAY;
+
+typedef union {
+  struct{
+    UINT8 Month:4;
+    UINT8 Month10:1;
+    UINT8 Rsv:2;
+    UINT8 Century:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_MONTH;
+
+typedef union {
+  struct{
+    UINT8 Year:4;
+    UINT8 Year10:4;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_YEAR;
+
+typedef union {
+  struct{
+    UINT8 Seconds:4;
+    UINT8 Seconds10:3;
+    UINT8 A1M1:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_ALARM1SEC;
+
+typedef union {
+  struct{
+    UINT8 Minutes:4;
+    UINT8 Minutes10:3;
+    UINT8 A1M2:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_ALARM1MIN;
+
+typedef union {
+  struct{
+    UINT8 Hour:4;
+    UINT8 Hours10:1;
+    UINT8 PM_20Hours:1;
+    UINT8 Hours24:1;
+    UINT8 A1M3:1;
+  }bits;
+  UINT8 u8;
+}RTC_DS3231_ALARM1HOUR;
+
+#endif

+ 504 - 0
Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.c

@@ -0,0 +1,504 @@
+/** @file
+  Implement EFI RealTimeClock runtime services via RTC Lib.
+
+  Currently this driver does not support runtime virtual calling.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+  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.
+
+  Based on the files under ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+
+**/
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+// Use EfiAtRuntime to check stage
+#include <Library/UefiRuntimeLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Library/TimeBaseLib.h>
+#include <Protocol/RealTimeClock.h>
+#include <Library/I2CLib.h>
+#include "DS3231RealTimeClock.h"
+#include <Library/CpldD03.h>
+#include <Library/CpldIoLib.h>
+
+extern I2C_DEVICE gDS3231RtcDevice;
+
+STATIC BOOLEAN       mDS3231Initialized = FALSE;
+
+EFI_STATUS
+IdentifyDS3231 (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = EFI_SUCCESS;
+  return Status;
+}
+
+EFI_STATUS
+SwitchRtcI2cChannelAndLock (
+  VOID
+  )
+{
+  UINT8   Temp;
+  UINT8   Count;
+
+  for (Count = 0; Count < 20; Count++) {
+    Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+
+    if ((Temp & BMC_I2C_STATUS) != 0) {
+      //The I2C channel is shared with BMC,
+      //Check if BMC has taken ownership of I2C.
+      //If so, wait 30ms, then try again.
+      //If not, start using I2C.
+      //And the CPLD_I2C_SWITCH_FLAG will be set to CPU_GET_I2C_CONTROL
+      //BMC will check this flag to decide to use I2C or not.
+      MicroSecondDelay (30000);
+      continue;
+    }
+
+    Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+    Temp = Temp | CPU_GET_I2C_CONTROL;
+    WriteCpldReg (CPLD_I2C_SWITCH_FLAG, Temp);
+
+    //This is empirical value,give cpld some time to make sure the
+    //value is wrote in
+    MicroSecondDelay (2);
+    Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+
+    if ((Temp & CPU_GET_I2C_CONTROL) == CPU_GET_I2C_CONTROL) {
+      return EFI_SUCCESS;
+    }
+
+    //There need 30ms to keep consistent with the previous loops if the CPU failed
+    //to get control of I2C
+    MicroSecondDelay (30000);
+  }
+
+  Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+  Temp = Temp & ~CPU_GET_I2C_CONTROL;
+  WriteCpldReg (CPLD_I2C_SWITCH_FLAG, Temp);
+
+  return EFI_NOT_READY;
+}
+
+
+EFI_STATUS
+InitializeDS3231 (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+  I2C_DEVICE    Dev;
+  RTC_DS3231_CONTROL Temp;
+  RTC_DS3231_HOURS   Hours;
+
+  // Prepare the hardware
+  (VOID)IdentifyDS3231();
+
+  (VOID) CopyMem(&Dev, &gDS3231RtcDevice, sizeof(Dev));
+
+  Status = I2CInit(Dev.Socket,Dev.Port,Normal);
+  if (EFI_ERROR (Status)) {
+    goto EXIT;
+  }
+  // Ensure interrupts are masked. We do not want RTC interrupts in UEFI
+  Status = I2CRead(&Dev,DS3231_REGADDR_CONTROL,1,&Temp.u8);
+  if (EFI_ERROR (Status)) {
+    goto EXIT;
+  }
+  Temp.bits.INTCN = 0;
+  Status = I2CWrite(&Dev,DS3231_REGADDR_CONTROL,1,&Temp.u8);
+  if (EFI_ERROR (Status)) {
+    goto EXIT;
+  }
+
+  MicroSecondDelay(2000);
+  Status = I2CRead(&Dev,DS3231_REGADDR_HOURS,1,&Hours.u8);
+  if (EFI_ERROR (Status)) {
+    goto EXIT;
+  }
+  Hours.bits.Hour24_n = 0;
+  Status = I2CWrite(&Dev,DS3231_REGADDR_HOURS,1,&Hours.u8);
+  if (EFI_ERROR (Status)) {
+    goto EXIT;
+  }
+
+
+  mDS3231Initialized = TRUE;
+
+  EXIT:
+  return Status;
+}
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param  Time                   A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities           An optional pointer to a buffer to receive the real time clock
+                                 device's capabilities.
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER  Time is NULL.
+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.
+  @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an authentication failure.
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+  OUT EFI_TIME                *Time,
+  OUT EFI_TIME_CAPABILITIES   *Capabilities
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  UINT8       Temp;
+  UINT8       BaseHour = 0;
+
+  UINT16      BaseYear = 1900;
+
+  I2C_DEVICE    Dev;
+
+  // Ensure Time is a valid pointer
+  if (NULL == Time) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = SwitchRtcI2cChannelAndLock();
+  if(EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Initialize the hardware if not already done
+  if (!mDS3231Initialized) {
+    Status = InitializeDS3231 ();
+    if (EFI_ERROR (Status)) {
+      Status = EFI_NOT_READY;
+      goto GExit;
+    }
+  }
+
+  (VOID) CopyMem(&Dev, &gDS3231RtcDevice, sizeof(Dev));
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_MONTH,1,&Temp);
+
+  Time->Month = ((Temp>>4)&1)*10+(Temp&0x0F);
+
+
+  if(Temp&0x80){
+    BaseYear = 2000;
+  }
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_YEAR,1,&Temp);
+
+  Time->Year  = BaseYear+(Temp>>4) *10 + (Temp&0x0F);
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_DATE,1,&Temp);
+
+  Time->Day   = ((Temp>>4)&3) *10 + (Temp&0x0F);
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_HOURS,1,&Temp);
+
+  BaseHour = 0;
+  if((Temp&0x30) == 0x30){
+    Status = EFI_DEVICE_ERROR;
+    goto GExit;
+  }else if(Temp&0x20){
+    BaseHour = 20;
+  }else if(Temp&0x10){
+    BaseHour = 10;
+  }
+  Time->Hour        = BaseHour + (Temp&0x0F);
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_MIUTES,1,&Temp);
+
+  Time->Minute      = ((Temp>>4)&7) * 10 + (Temp&0x0F);
+
+  Status |= I2CRead(&Dev,DS3231_REGADDR_SECONDS,1,&Temp);
+
+  Time->Second      = (Temp>>4) * 10 + (Temp&0x0F);
+
+  Time->Nanosecond  = 0;
+  Time->Daylight    = 0;
+  Time->TimeZone    = EFI_UNSPECIFIED_TIMEZONE;
+
+  if((EFI_ERROR(Status)) || (!IsTimeValid(Time)) || ((Time->Year - BaseYear) > 99)) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+GExit:
+  Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+  Temp = Temp & ~CPU_GET_I2C_CONTROL;
+  WriteCpldReg (CPLD_I2C_SWITCH_FLAG, Temp);
+
+  return Status;
+
+}
+
+
+/**
+  Sets the current local time and date information.
+
+  @param  Time                  A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+  IN  EFI_TIME                *Time
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  I2C_DEVICE    Dev;
+  UINT8 Temp;
+
+  UINT16 BaseYear = 1900;
+
+
+
+  // Check the input parameters are within the range specified by UEFI
+  if(!IsTimeValid(Time)){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = SwitchRtcI2cChannelAndLock();
+  if(EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Initialize the hardware if not already done
+  if (!mDS3231Initialized) {
+    Status = InitializeDS3231 ();
+    if (EFI_ERROR (Status)) {
+      goto EXIT;
+    }
+  }
+
+  (VOID) CopyMem(&Dev, &gDS3231RtcDevice, sizeof(Dev));
+
+  Temp = ((Time->Second/10)<<4) | (Time->Second%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_SECONDS,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+  Temp = ((Time->Minute/10)<<4) | (Time->Minute%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_MIUTES,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+  Temp = 0;
+  if(Time->Hour > 19){
+    Temp = 2;
+  } else if(Time->Hour > 9){
+    Temp = 1;
+  }
+
+  Temp = (Temp << 4) | (Time->Hour%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_HOURS,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+  Temp = ((Time->Day/10)<<4) | (Time->Day%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_DATE,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+
+  Temp = 0;
+  if(Time->Year >= 2000){
+    Temp = 0x8;
+    BaseYear = 2000;
+  }
+
+  if(Time->Month > 9){
+    Temp |= 0x1;
+  }
+  Temp = (Temp<<4) | (Time->Month%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_MONTH,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+  Temp = (((Time->Year-BaseYear)/10)<<4) | (Time->Year%10);
+  MicroSecondDelay(1000);
+  Status = I2CWrite(&Dev,DS3231_REGADDR_YEAR,1,&Temp);
+  if(EFI_ERROR (Status)){
+    goto EXIT;
+  }
+
+  EXIT:
+
+  Temp = ReadCpldReg (CPLD_I2C_SWITCH_FLAG);
+  Temp = Temp & ~CPU_GET_I2C_CONTROL;
+  WriteCpldReg (CPLD_I2C_SWITCH_FLAG, Temp);
+
+  return Status;
+}
+
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+  OUT BOOLEAN     *Enabled,
+  OUT BOOLEAN     *Pending,
+  OUT EFI_TIME    *Time
+  )
+{
+  // Not a required feature
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+  IN BOOLEAN      Enabled,
+  OUT EFI_TIME    *Time
+  )
+{
+  // Not a required feature
+  return EFI_UNSUPPORTED;
+}
+
+
+
+/**
+  This is the declaration of an EFI image entry point. This can be the entry point to an application
+  written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+  @param  ImageHandle           Handle that identifies the loaded image.
+  @param  SystemTable           System Table for this image.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle;
+
+
+  EFI_TIME      EfiTime;
+
+  // Setup the setters and getters
+  gRT->GetTime       = LibGetTime;
+  gRT->SetTime       = LibSetTime;
+  gRT->GetWakeupTime = LibGetWakeupTime;
+  gRT->SetWakeupTime = LibSetWakeupTime;
+
+
+  (VOID)gRT->GetTime (&EfiTime, NULL);
+  if((EfiTime.Year < 2015) || (EfiTime.Year > 2099)){
+      EfiTime.Year          = 2015;
+      EfiTime.Month         = 1;
+      EfiTime.Day           = 1;
+      EfiTime.Hour          = 0;
+      EfiTime.Minute        = 0;
+      EfiTime.Second        = 0;
+      EfiTime.Nanosecond    = 0;
+      Status = gRT->SetTime(&EfiTime);
+      if (EFI_ERROR(Status))
+      {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Status : %r\n", __FUNCTION__, __LINE__, Status));
+      }
+  }
+
+  // Install the protocol
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiRealTimeClockArchProtocolGuid,  NULL,
+                  NULL
+                 );
+
+  return Status;
+}
+
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  //
+  // Only needed if you are going to support the OS calling RTC functions in virtual mode.
+  // You will need to call EfiConvertPointer (). To convert any stored physical addresses
+  // to virtual address. After the OS transitions to calling in virtual mode, all future
+  // runtime calls will be made in virtual mode.
+  //
+  return;
+}

+ 48 - 0
Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf

@@ -0,0 +1,48 @@
+#/** @file
+#
+# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+#
+#  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                      = DS3231RealTimeClockLib
+  FILE_GUID                      = 470DFB96-E205-4515-A75E-2E60F853E79D
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RealTimeClockLib
+
+[Sources.common]
+  DS3231RealTimeClockLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Platform/Hisilicon/D03/D03.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  UefiLib
+  DebugLib
+  PcdLib
+  I2CLib
+  TimeBaseLib
+  TimerLib
+# Use EFiAtRuntime to check stage
+  UefiRuntimeLib
+  CpldIoLib
+
+[Pcd]
+

+ 487 - 0
Platform/Hisilicon/D03/Library/FdtUpdateLib/FdtUpdateLib.c

@@ -0,0 +1,487 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <Uefi.h>
+#include <Library/ArmArchTimer.h>
+#include <Library/BaseLib.h>
+#include <libfdt.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/FdtUpdateLib.h>
+#include <PlatformArch.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/HisiBoardNicProtocol.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/OemMiscLib.h>
+
+typedef union AA_DAW
+{
+    /* Define the struct bits */
+    struct
+    {
+        unsigned int    sysdaw_id           : 7  ; /* [6:0] */
+        unsigned int    interleave_en       : 1  ; /* [7] */
+        unsigned int    sysdaw_size         : 4  ; /* [11:8] */
+        unsigned int    reserved            : 4  ; /* [15:12] */
+        unsigned int    sysdaw_addr         : 16 ; /* [31:16] */
+    } bits;
+
+    /* Define an unsigned member */
+    unsigned int    u32;
+
+} AA_DAW_U;
+
+
+
+MAC_ADDRESS gMacAddress[1];
+
+
+CHAR8  *EthName[8]=
+{
+ "ethernet@0","ethernet@1",
+ "ethernet@2","ethernet@3",
+ "ethernet@4","ethernet@5",
+ "ethernet@6","ethernet@7"
+};
+
+UINT8 DawNum[4] = {0, 0, 0, 0};
+PHY_MEM_REGION    *NodemRegion[4] = {NULL, NULL, NULL, NULL};
+UINTN  NumaPages[4] = {0, 0, 0, 0};
+
+CHAR8  *NumaNodeName[4]=
+{
+ "p0-ta","p0-tc",
+ "p1-ta","p1-tc",
+};
+
+STATIC
+BOOLEAN
+IsMemMapRegion (
+  IN EFI_MEMORY_TYPE MemoryType
+  )
+{
+  switch(MemoryType)
+    {
+        case EfiRuntimeServicesCode:
+        case EfiRuntimeServicesData:
+        case EfiConventionalMemory:
+        case EfiACPIReclaimMemory:
+        case EfiACPIMemoryNVS:
+        case EfiLoaderCode:
+        case EfiLoaderData:
+        case EfiBootServicesCode:
+        case EfiBootServicesData:
+        case EfiPalCode:
+                return TRUE;
+        default:
+                return FALSE;
+  }
+}
+
+
+EFI_STATUS
+GetMacAddress (UINT32 Port)
+{
+    EFI_MAC_ADDRESS Mac;
+    EFI_STATUS Status;
+    HISI_BOARD_NIC_PROTOCOL *OemNic = NULL;
+
+    Status = gBS->LocateProtocol(&gHisiBoardNicProtocolGuid, NULL, (VOID **)&OemNic);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol failed %r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    Status = OemNic->GetMac(&Mac, Port);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] GetMac failed %r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    gMacAddress[0].data0=Mac.Addr[0];
+    gMacAddress[0].data1=Mac.Addr[1];
+    gMacAddress[0].data2=Mac.Addr[2];
+    gMacAddress[0].data3=Mac.Addr[3];
+    gMacAddress[0].data4=Mac.Addr[4];
+    gMacAddress[0].data5=Mac.Addr[5];
+    DEBUG((EFI_D_INFO, "Port%d:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+        Port,gMacAddress[0].data0,gMacAddress[0].data1,gMacAddress[0].data2,
+        gMacAddress[0].data3,gMacAddress[0].data4,gMacAddress[0].data5));
+
+    return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+DelPhyhandleUpdateMacAddress(IN VOID* Fdt)
+{
+    UINT8               port;
+    INTN                ethernetnode;
+    INTN                node;
+    INTN                Error;
+    struct              fdt_property *m_prop;
+    int                 m_oldlen;
+    EFI_STATUS          Status = EFI_SUCCESS;
+    EFI_STATUS          GetMacStatus = EFI_SUCCESS;
+
+    node = fdt_subnode_offset(Fdt, 0, "soc");
+    if (node < 0)
+    {
+        DEBUG ((EFI_D_ERROR, "can not find soc root node\n"));
+        return EFI_INVALID_PARAMETER;
+    }
+    else
+    {
+        for( port=0; port<8; port++ )
+        {
+            GetMacStatus= GetMacAddress(port);
+            ethernetnode = fdt_subnode_offset(Fdt, node,EthName[port]);
+            if(!EFI_ERROR(GetMacStatus))
+            {
+
+                if (ethernetnode < 0)
+                {
+                    DEBUG ((EFI_D_WARN, "Can not find ethernet@%d node\n",port));
+                    DEBUG ((EFI_D_WARN, "Suppose port %d is not enabled.\n", port));
+                    continue;
+                }
+                m_prop = fdt_get_property_w(Fdt, ethernetnode, "local-mac-address", &m_oldlen);
+                if(m_prop)
+                {
+                    Error = fdt_delprop(Fdt, ethernetnode, "local-mac-address");
+                    if (Error)
+                    {
+                        DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop() Local-mac-address: %a\n", fdt_strerror (Error)));
+                        Status = EFI_INVALID_PARAMETER;
+                    }
+                    Error = fdt_setprop(Fdt, ethernetnode, "local-mac-address",gMacAddress,sizeof(MAC_ADDRESS));
+                    if (Error)
+                    {
+                        DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop():local-mac-address %a\n", fdt_strerror (Error)));
+                        Status = EFI_INVALID_PARAMETER;
+                    }
+                }
+            }
+        }
+    }
+    return Status;
+}
+
+STATIC
+EFI_STATUS
+UpdateRefClk (IN VOID* Fdt)
+{
+  INTN                node;
+  INTN                Error;
+  struct              fdt_property *m_prop;
+  int                 m_oldlen;
+  UINTN               ArchTimerFreq = 0;
+  UINT32              Data;
+  CONST CHAR8         *Property = "clock-frequency";
+
+  ArmArchTimerReadReg (CntFrq, &ArchTimerFreq);
+  if (!ArchTimerFreq) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Get timer frequency failed!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  node = fdt_subnode_offset(Fdt, 0, "soc");
+  if (node < 0) {
+    DEBUG ((DEBUG_ERROR, "can not find soc node\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  node = fdt_subnode_offset(Fdt, node, "refclk");
+  if (node < 0) {
+    DEBUG ((DEBUG_ERROR, "can not find refclk node\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  m_prop = fdt_get_property_w(Fdt, node, Property, &m_oldlen);
+  if(!m_prop) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Can't find property %a\n", __FUNCTION__, __LINE__, Property));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Error = fdt_delprop(Fdt, node, Property);
+  if (Error) {
+    DEBUG ((DEBUG_ERROR, "ERROR: fdt_delprop() %a: %a\n", Property, fdt_strerror (Error)));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // UINT32 is enough for refclk data length
+  Data = (UINT32) ArchTimerFreq;
+  Data = cpu_to_fdt32 (Data);
+  Error = fdt_setprop(Fdt, node, Property, &Data, sizeof(Data));
+  if (Error) {
+    DEBUG ((DEBUG_ERROR, "ERROR:fdt_setprop() %a: %a\n", Property, fdt_strerror (Error)));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "Update refclk successfully.\n"));
+  return EFI_SUCCESS;
+}
+
+INTN
+GetMemoryNode(VOID* Fdt)
+{
+    INTN                node;
+    int                 m_oldlen;
+    struct              fdt_property *m_prop;
+    INTN                Error = 0;
+
+
+    node = fdt_subnode_offset(Fdt, 0, "memory");
+    if (node < 0)
+    {
+        // Create the memory node
+        node = fdt_add_subnode(Fdt, 0, "memory");
+
+        if(node < 0)
+        {
+          DEBUG((EFI_D_ERROR, "[%a]:[%dL] fdt add subnode error\n", __FUNCTION__, __LINE__));
+
+          return node;
+        }
+
+    }
+    //find the memory node property
+    m_prop = fdt_get_property_w(Fdt, node, "memory", &m_oldlen);
+    if(m_prop)
+    {
+        Error = fdt_delprop(Fdt, node, "reg");
+
+        if (Error)
+        {
+            DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop(): %a\n", fdt_strerror (Error)));
+            node = -1;
+            return node;
+        }
+    }
+
+    return node;
+}
+
+
+EFI_STATUS UpdateMemoryNode(VOID* Fdt)
+{
+    INTN                Error = 0;
+    EFI_STATUS          Status = EFI_SUCCESS;
+    UINT32              Index = 0;
+    UINT32              MemIndex;
+    INTN                node;
+    EFI_MEMORY_DESCRIPTOR *MemoryMap;
+    EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+    EFI_MEMORY_DESCRIPTOR *MemoryMapPtrCurrent;
+    UINTN                 MemoryMapSize;
+    UINTN                 Pages0 = 0;
+    UINTN                 Pages1 = 0;
+    UINTN                 MapKey;
+    UINTN                 DescriptorSize;
+    UINT32                DescriptorVersion;
+    PHY_MEM_REGION        *mRegion;
+    UINTN                 MemoryMapLastEndAddress ;
+    UINTN                 MemoryMapcontinuousStartAddress ;
+    UINTN                 MemoryMapCurrentStartAddress;
+    BOOLEAN               FindMemoryRegionFlag = FALSE;
+
+    node = GetMemoryNode(Fdt);
+    if (node < 0)
+    {
+        DEBUG((EFI_D_ERROR, "Can not find memory node\n"));
+        return EFI_NOT_FOUND;
+    }
+    MemoryMap = NULL;
+    MemoryMapSize = 0;
+    MemIndex = 0;
+
+    Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+    if (Status == EFI_BUFFER_TOO_SMALL)
+    {
+        // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive
+        // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.
+        Pages0 = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+        MemoryMap = AllocatePages (Pages0);
+        if (MemoryMap == NULL)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            return Status;
+        }
+        Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+
+        if (EFI_ERROR(Status))
+        {
+            DEBUG ((EFI_D_ERROR, "FdtUpdateLib GetMemoryMap Error\n"));
+            FreePages (MemoryMap, Pages0);
+            return Status;
+        }
+    }
+    else
+    {
+        DEBUG ((EFI_D_ERROR, "FdtUpdateLib GetmemoryMap Status: %r\n",Status));
+        return EFI_ABORTED;
+    }
+
+    mRegion = NULL;
+    Pages1 = EFI_SIZE_TO_PAGES (sizeof(PHY_MEM_REGION) *( MemoryMapSize / DescriptorSize));
+
+    mRegion = (PHY_MEM_REGION*)AllocatePool(Pages1);
+    if (mRegion == NULL)
+    {
+      Status = EFI_OUT_OF_RESOURCES;
+      FreePages (MemoryMap, Pages0);
+      return Status;
+    }
+
+
+    MemoryMapPtr = MemoryMap;
+    MemoryMapPtrCurrent = MemoryMapPtr;
+    MemoryMapLastEndAddress = 0;
+    MemoryMapcontinuousStartAddress = 0;
+    MemoryMapCurrentStartAddress = 0;
+    for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++)
+    {
+        MemoryMapPtrCurrent = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + Index*DescriptorSize);
+        MemoryMapCurrentStartAddress = (UINTN)MemoryMapPtrCurrent->PhysicalStart;
+
+        if (!IsMemMapRegion ((EFI_MEMORY_TYPE)MemoryMapPtrCurrent->Type))
+        {
+            continue;
+        }
+        else
+        {
+            FindMemoryRegionFlag = TRUE;
+            if(MemoryMapCurrentStartAddress != MemoryMapLastEndAddress)
+            {
+                mRegion[MemIndex].BaseHigh= cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
+                mRegion[MemIndex].BaseLow=cpu_to_fdt32(MemoryMapcontinuousStartAddress);
+                mRegion[MemIndex].LengthHigh= cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
+                mRegion[MemIndex].LengthLow=cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
+                MemIndex+=1;
+                MemoryMapcontinuousStartAddress=MemoryMapCurrentStartAddress;
+            }
+        }
+        MemoryMapLastEndAddress = (UINTN)(MemoryMapPtrCurrent->PhysicalStart + MemoryMapPtrCurrent->NumberOfPages * EFI_PAGE_SIZE);
+    }
+    if (FindMemoryRegionFlag)
+    {
+        mRegion[MemIndex].BaseHigh = cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
+        mRegion[MemIndex].BaseLow = cpu_to_fdt32(MemoryMapcontinuousStartAddress);
+        mRegion[MemIndex].LengthHigh = cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
+        mRegion[MemIndex].LengthLow = cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
+    }
+
+    Error = fdt_setprop(Fdt, node, "reg",mRegion,sizeof(PHY_MEM_REGION) *(MemIndex+1));
+
+    FreePool (mRegion);
+    FreePages (MemoryMap, Pages0);
+    if (Error)
+    {
+        DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop(): %a\n", fdt_strerror (Error)));
+        Status = EFI_INVALID_PARAMETER;
+        return Status;
+    }
+
+  return Status;
+}
+
+
+EFI_STATUS
+UpdateNumaNode(VOID* Fdt)
+{
+    //TODO: Need to update numa node
+    return EFI_SUCCESS;
+}
+/*
+ * Entry point for fdtupdate lib.
+ */
+
+EFI_STATUS EFIFdtUpdate(UINTN FdtFileAddr)
+{
+    INTN                Error;
+    VOID*               Fdt;
+    UINT32              Size;
+    UINTN               NewFdtBlobSize;
+    UINTN               NewFdtBlobBase;
+    EFI_STATUS          Status = EFI_SUCCESS;
+    EFI_STATUS          UpdateNumaStatus = EFI_SUCCESS;
+
+
+    Error = fdt_check_header ((VOID*)(FdtFileAddr));
+    if (0 != Error)
+    {
+        DEBUG ((EFI_D_ERROR,"ERROR: Device Tree header not valid (%a)\n", fdt_strerror(Error)));
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Size = (UINTN)fdt_totalsize ((VOID*)(UINTN)(FdtFileAddr));
+    NewFdtBlobSize = Size + ADD_FILE_LENGTH;
+    Fdt = (VOID*)(UINTN)FdtFileAddr;
+
+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
+    if (EFI_ERROR (Status))
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+
+    Error = fdt_open_into(Fdt,(VOID*)(UINTN)(NewFdtBlobBase), (NewFdtBlobSize));
+    if (Error) {
+        DEBUG ((EFI_D_ERROR, "ERROR:fdt_open_into(): %a\n", fdt_strerror (Error)));
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+    }
+
+    Fdt = (VOID*)(UINTN)NewFdtBlobBase;
+    Status = DelPhyhandleUpdateMacAddress(Fdt);
+    if (EFI_ERROR (Status))
+    {
+        DEBUG ((EFI_D_ERROR, "DelPhyhandleUpdateMacAddress fail:\n"));
+        Status = EFI_SUCCESS;
+    }
+
+    Status =  UpdateRefClk (Fdt);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "UpdateiRefClk fail.\n"));
+    }
+
+    Status = UpdateMemoryNode(Fdt);
+    if (EFI_ERROR (Status))
+    {
+        DEBUG ((EFI_D_ERROR, "UpdateMemoryNode Error\n"));
+        goto EXIT;
+    }
+
+    UpdateNumaStatus = UpdateNumaNode(Fdt);
+    if (EFI_ERROR (UpdateNumaStatus))
+    {
+        DEBUG ((EFI_D_ERROR, "Update NumaNode fail\n"));
+    }
+
+    gBS->CopyMem(((VOID*)(UINTN)(FdtFileAddr)),((VOID*)(UINTN)(NewFdtBlobBase)),NewFdtBlobSize);
+
+EXIT:
+    gBS->FreePages(NewFdtBlobBase,EFI_SIZE_TO_PAGES(NewFdtBlobSize));
+
+    return Status;
+
+
+
+}

+ 50 - 0
Platform/Hisilicon/D03/Library/FdtUpdateLib/FdtUpdateLib.inf

@@ -0,0 +1,50 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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                      = FdtUpdateLib
+  FILE_GUID                      = 02CF1727-E697-47fc-8CC2-5DCB81B26DD9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FdtUpdateLib
+
+
+[Sources.common]
+  FdtUpdateLib.c
+
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  ArmLib
+ FdtLib
+ PlatformSysCtrlLib
+ OemMiscLib
+
+[Protocols]
+ gHisiBoardNicProtocolGuid
+
+[Guids]
+
+[Pcd]
+ gHisiTokenSpaceGuid.PcdNumaEnable
+
+

+ 197 - 0
Platform/Hisilicon/D03/Library/OemMiscLib2P/BoardFeature2PHi1610.c

@@ -0,0 +1,197 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+
+#include <PlatformArch.h>
+#include <Library/OemMiscLib.h>
+#include <Library/SerdesLib.h>
+#include <Library/I2CLib.h>
+#include <Library/HiiLib.h>
+
+I2C_DEVICE gDS3231RtcDevice = {
+    .Socket = 0,
+    .Port = 6,
+    .DeviceType = DEVICE_TYPE_SPD,
+    .SlaveDeviceAddress = 0x68
+};
+
+SERDES_POLARITY_INVERT gSerdesPolarityTxDesc[] =
+{
+    {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+SERDES_POLARITY_INVERT gSerdesPolarityRxDesc[] =
+{
+    {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+SERDES_PARAM gSerdesParam = {
+  .Hilink0Mode = EmHilink0Pcie1X8,
+  .Hilink1Mode = EmHilink1Pcie0X8,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Sas1X4,
+  .Hilink6Mode = 0x0,
+  .UseSsc      = 0,
+};
+
+SERDES_PARAM gSerdesParam0 = {
+  .Hilink0Mode = EmHilink0Hccs1X8Width16,
+  .Hilink1Mode = EmHilink1Hccs0X8Width16,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Sas1X4,
+  .Hilink6Mode = 0x0,
+  .UseSsc      = 0,
+};
+
+SERDES_PARAM gSerdesParam1 = {
+  .Hilink0Mode = EmHilink0Hccs1X8Width16,
+  .Hilink1Mode = EmHilink1Hccs0X8Width16,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Pcie3X4,
+  .Hilink6Mode = 0xF,
+  .UseSsc      = 0,
+};
+
+EFI_STATUS OemGetSerdesParam (SERDES_PARAM *ParamA, SERDES_PARAM *ParamB, UINT32 SocketId)
+{
+  if (ParamA == NULL) {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Param == NULL!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  (VOID) CopyMem(ParamA, &gSerdesParam, sizeof(*ParamA));
+  return EFI_SUCCESS;
+}
+
+
+VOID OemPcieResetAndOffReset(void)
+  {
+    return;
+  }
+
+SMBIOS_TABLE_TYPE9 gPcieSlotInfo[] = {
+    // PCIe0 Slot 1
+    {
+        {                                                     // Hdr
+            EFI_SMBIOS_TYPE_SYSTEM_SLOTS,                         // Type,
+            0,                                                    // Length,
+            0                                                     // Handle
+        },
+        1,                                                    // SlotDesignation
+        SlotTypePciExpressX8,     // SlotType
+        SlotDataBusWidth8X,       // SlotDataBusWidth
+        SlotUsageAvailable,       // SlotUsage
+        SlotLengthOther,          // SlotLength
+        0x0001,                   // SlotId
+        {                         // SlotCharacteristics1
+            0,                      // CharacteristicsUnknown  :1;
+            0,                      // Provides50Volts         :1;
+            0,                      // Provides33Volts         :1;
+            0,                      // SharedSlot              :1;
+            0,                      // PcCard16Supported       :1;
+            0,                      // CardBusSupported        :1;
+            0,                      // ZoomVideoSupported      :1;
+            0                       // ModemRingResumeSupported:1;
+        },
+        {                         // SlotCharacteristics2
+            0,                      // PmeSignalSupported      :1;
+            0,                      // HotPlugDevicesSupported  :1;
+            0,                      // SmbusSignalSupported    :1;
+            0                       // Reserved                :5;
+        },
+        0x00,                     // SegmentGroupNum
+        0x00,                     // BusNum
+        0                         // DevFuncNum
+    },
+
+    // PCIe0 Slot 4
+    {
+        {                                                     // Hdr
+            EFI_SMBIOS_TYPE_SYSTEM_SLOTS,                         // Type,
+            0,                                                    // Length,
+            0                                                     // Handle
+        },
+        1,                                                    // SlotDesignation
+        SlotTypePciExpressX8,     // SlotType
+        SlotDataBusWidth8X,       // SlotDataBusWidth
+        SlotUsageAvailable,       // SlotUsage
+        SlotLengthOther,          // SlotLength
+        0x0004,                   // SlotId
+        {                         // SlotCharacteristics1
+            0,                      // CharacteristicsUnknown  :1;
+            0,                      // Provides50Volts         :1;
+            0,                      // Provides33Volts         :1;
+            0,                      // SharedSlot              :1;
+            0,                      // PcCard16Supported       :1;
+            0,                      // CardBusSupported        :1;
+            0,                      // ZoomVideoSupported      :1;
+            0                       // ModemRingResumeSupported:1;
+        },
+        {                         // SlotCharacteristics2
+            0,                      // PmeSignalSupported      :1;
+            0,                      // HotPlugDevicesSupported  :1;
+            0,                      // SmbusSignalSupported    :1;
+            0                       // Reserved                :5;
+        },
+        0x00,                     // SegmentGroupNum
+        0x00,                     // BusNum
+        0                         // DevFuncNum
+    }
+};
+
+
+UINT8 OemGetPcieSlotNumber ()
+{
+    return  sizeof (gPcieSlotInfo) / sizeof (SMBIOS_TABLE_TYPE9);
+}
+
+EFI_STRING_ID gDimmToDevLocator[MAX_SOCKET][MAX_CHANNEL][MAX_DIMM] = {
+  {{STRING_TOKEN(STR_LEMON_C10_DIMM_000), STRING_TOKEN(STR_LEMON_C10_DIMM_001), STRING_TOKEN(STR_LEMON_C10_DIMM_002)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_010), STRING_TOKEN(STR_LEMON_C10_DIMM_011), STRING_TOKEN(STR_LEMON_C10_DIMM_012)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_020), STRING_TOKEN(STR_LEMON_C10_DIMM_021), STRING_TOKEN(STR_LEMON_C10_DIMM_022)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_030), STRING_TOKEN(STR_LEMON_C10_DIMM_031), STRING_TOKEN(STR_LEMON_C10_DIMM_032)}},
+
+  {{STRING_TOKEN(STR_LEMON_C10_DIMM_100), STRING_TOKEN(STR_LEMON_C10_DIMM_101), STRING_TOKEN(STR_LEMON_C10_DIMM_102)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_110), STRING_TOKEN(STR_LEMON_C10_DIMM_111), STRING_TOKEN(STR_LEMON_C10_DIMM_112)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_120), STRING_TOKEN(STR_LEMON_C10_DIMM_121), STRING_TOKEN(STR_LEMON_C10_DIMM_122)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_130), STRING_TOKEN(STR_LEMON_C10_DIMM_131), STRING_TOKEN(STR_LEMON_C10_DIMM_132)}}
+};
+
+EFI_HII_HANDLE
+EFIAPI
+OemGetPackages (
+  )
+{
+    return HiiAddPackages (
+                            &gEfiCallerIdGuid,
+                            NULL,
+                            OemMiscLib2PStrings,
+                            NULL,
+                            NULL
+                            );
+}
+
+

二进制
Platform/Hisilicon/D03/Library/OemMiscLib2P/BoardFeature2PHi1610Strings.uni


+ 141 - 0
Platform/Hisilicon/D03/Library/OemMiscLib2P/OemMiscLib2PHi1610.c

@@ -0,0 +1,141 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/OemMiscLib.h>
+#include <PlatformArch.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/OemAddressMapLib.h>
+#include <Library/LpcLib.h>
+REPORT_PCIEDIDVID2BMC  PcieDeviceToReport[PCIEDEVICE_REPORT_MAX] = {
+      {67,0,0,0},
+      {225,0,0,3},
+      {0xFFFF,0xFFFF,0xFFFF,0xFFFF},
+      {0xFFFF,0xFFFF,0xFFFF,0xFFFF}
+};
+
+// Right now we only support 1P
+BOOLEAN OemIsSocketPresent (UINTN Socket)
+{
+  if (0 == Socket)
+  {
+    return TRUE;
+  }
+
+  if(1 == Socket)
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+UINTN OemGetSocketNumber (VOID)
+{
+
+    if(!OemIsMpBoot())
+    {
+        return 1;
+    }
+
+    return 2;
+
+}
+
+
+UINTN OemGetDdrChannel (VOID)
+{
+    return 4;
+}
+
+
+UINTN OemGetDimmSlot(UINTN Socket, UINTN Channel)
+{
+    return 2;
+}
+
+
+// Nothing to do for EVB
+VOID OemPostEndIndicator (VOID)
+{
+
+     DEBUG((EFI_D_ERROR,"M3 release reset CONFIG........."));
+
+     MmioWrite32(0xd0002180, 0x3);
+     MmioWrite32(0xd0002194, 0xa4);
+     MmioWrite32(0xd0000a54, 0x1);
+
+     MicroSecondDelay(10000);
+
+     MmioWrite32(0xd0002108, 0x1);
+     MmioWrite32(0xd0002114, 0x1);
+     MmioWrite32(0xd0002120, 0x1);
+     MmioWrite32(0xd0003108, 0x1);
+
+     MicroSecondDelay(500000);
+     DEBUG((EFI_D_ERROR,"Done\n"));
+
+}
+
+
+
+VOID CoreSelectBoot(VOID)
+{
+    if (!PcdGet64 (PcdTrustedFirmwareEnable))
+    {
+        StartupAp ();
+    }
+
+    return;
+}
+
+BOOLEAN OemIsMpBoot()
+{
+    UINT32 Tmp;
+
+    Tmp = MmioRead32(0x602E0050);
+    if ( ((Tmp >> 10) & 0xF) == 0x3)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+VOID OemLpcInit(VOID)
+{
+    LpcInit();
+    return;
+}
+
+UINT32 OemIsWarmBoot(VOID)
+{
+    return 0;
+}
+
+VOID OemBiosSwitch(UINT32 Master)
+{
+    (VOID)Master;
+    return;
+}
+
+BOOLEAN OemIsNeedDisableExpanderBuffer(VOID)
+{
+    return TRUE;
+}

+ 54 - 0
Platform/Hisilicon/D03/Library/OemMiscLib2P/OemMiscLib2PHi1610.inf

@@ -0,0 +1,54 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = OemMiscLib2P
+  FILE_GUID                      = B9CE7465-21A2-4ecd-B347-BBDDBD098CEE
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OemMiscLib
+
+[Sources.common]
+  BoardFeature2PHi1610.c
+  OemMiscLib2PHi1610.c
+  BoardFeature2PHi1610Strings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  TimerLib
+
+[BuildOptions]
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid   ## SOMETIMES_CONSUMES
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
+
+[FixedPcd.common]
+
+[Guids]
+
+[Protocols]
+

+ 156 - 0
Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.c

@@ -0,0 +1,156 @@
+/** @file
+
+  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+
+  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/PcdLib.h>
+#include <Library/PlatformPciLib.h>
+UINT64 pcie_subctrl_base_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa0000000, 0xa0000000,0xa0000000,0xa0000000,0xa0000000,0xa0000000,0xa0000000,0xa0000000},
+                                        {0xb0000000,0xb0000000,0xb0000000,0xb0000000, 0xb0000000,0xb0000000,0xb0000000,0xb0000000}};
+UINT64 PCIE_APB_SLAVE_BASE_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa0090000, 0xa0200000, 0xa00a0000, 0xa00b0000},
+                                      {0xb0090000, 0xb0200000, 0xb00a0000, 0xb00b0000}};
+UINT64 PCIE_PHY_BASE_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa00c0000, 0xa00d0000, 0xa00e0000, 0xa00f0000},
+                                  {0xb00c0000,0xb00d0000, 0xb00e0000, 0xb00f0000}};
+UINT64 PCIE_ITS_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xc6010040, 0xc6010040, 0xc6010040, 0xc6010040},
+                                  {0xc6010040, 0xc6010040, 0xc6010040, 0xc6010040}};
+
+PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
+ {// HostBridge 0
+  /* Port 0 */
+  {
+      PCI_HB0RB0_ECAM_BASE, //ecam
+      0,  //BusBase
+      31, //BusLimit
+      PCI_HB0RB0_PCIREGION_BASE, //Membase
+      PCI_HB0RB0_PCIREGION_BASE + PCI_HB0RB0_PCIREGION_SIZE - 1, //Memlimit
+      PCI_HB0RB0_IO_BASE,  //IoBase
+      (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB0_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB0_PCI_BASE),  //RbPciBar
+      PCI_HB0RB0_PCIREGION_BASE, //PciRegionBase
+      PCI_HB0RB0_PCIREGION_BASE + PCI_HB0RB0_PCIREGION_SIZE - 1, //PciRegionLimit
+
+  },
+  /* Port 1 */
+  {
+      PCI_HB0RB1_ECAM_BASE,//ecam
+      224,  //BusBase
+      254, //BusLimit
+      PCI_HB0RB1_PCIREGION_BASE, //Membase
+      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB1_IO_BASE),  //IoBase
+      (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB1_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB1_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB1_PCI_BASE),  //RbPciBar
+      PCI_HB0RB1_PCIREGION_BASE, //PciRegionBase
+      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1, //PciRegionLimit
+  },
+  /* Port 2 */
+  {
+      PCI_HB0RB2_ECAM_BASE,
+      128,  //BusBase
+      159, //BusLimit
+      PCI_HB0RB2_PCIREGION_BASE ,//MemBase
+      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB2_IO_BASE),  //IOBase
+      (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB2_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB2_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB2_PCI_BASE),  //RbPciBar
+      PCI_HB0RB2_PCIREGION_BASE, //PciRegionBase
+      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1, //PciRegionLimit
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB0RB3_ECAM_BASE,
+      96,  //BusBase
+      127, //BusLimit
+      (PCI_HB0RB3_ECAM_BASE),  //MemBase
+      (PCI_HB0RB3_ECAM_BASE + PCI_HB0RB3_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB0RB3_PCI_BASE),  //RbPciBar
+      0,
+      0
+  }
+ },
+{// HostBridge 1
+  /* Port 0 */
+  {
+      PCI_HB1RB0_ECAM_BASE,
+      128,  //BusBase
+      159, //BusLimit
+      (PCI_HB1RB0_ECAM_BASE),  //MemBase
+      (PCI_HB1RB0_ECAM_BASE + PCI_HB1RB0_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB0_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+  /* Port 1 */
+  {
+      PCI_HB1RB1_ECAM_BASE,
+      160,  //BusBase
+      191, //BusLimit
+      (PCI_HB1RB1_ECAM_BASE),  //MemBase
+      (PCI_HB1RB1_ECAM_BASE + PCI_HB1RB1_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB1_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+  /* Port 2 */
+  {
+      PCI_HB1RB2_ECAM_BASE,
+      192,  //BusBase
+      223, //BusLimit
+      (PCI_HB1RB2_ECAM_BASE),  //MemBase
+      (PCI_HB1RB2_ECAM_BASE + PCI_HB1RB2_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB2_PCI_BASE),  //RbPciBar
+      0,
+      0
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB1RB3_ECAM_BASE,
+      224,  //BusBase
+      255, //BusLimit
+      (PCI_HB1RB3_ECAM_BASE),  //MemBase
+      (PCI_HB1RB3_ECAM_BASE + PCI_HB1RB3_ECAM_SIZE - 1), //MemLimit
+      (0), //IoBase
+      (0),  //IoLimit
+      0,
+      0,
+      (PCI_HB1RB3_PCI_BASE),  //RbPciBar
+      0,
+      0
+  }
+ }
+};
+

+ 182 - 0
Platform/Hisilicon/D03/Library/PlatformPciLib/PlatformPciLib.inf

@@ -0,0 +1,182 @@
+## @file
+#
+#  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+#  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+#
+#  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                      = PlatformPciLib
+  FILE_GUID                      = 61b7276a-fc67-11e5-82fd-47ea9896dd5d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PlatformPciLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+
+[FixedPcd]
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PciHb0Rb0Base
+  gHisiTokenSpaceGuid.PciHb0Rb1Base
+  gHisiTokenSpaceGuid.PciHb0Rb2Base
+  gHisiTokenSpaceGuid.PciHb0Rb3Base
+  gHisiTokenSpaceGuid.PciHb0Rb4Base
+  gHisiTokenSpaceGuid.PciHb0Rb5Base
+  gHisiTokenSpaceGuid.PciHb0Rb6Base
+  gHisiTokenSpaceGuid.PciHb0Rb7Base
+  gHisiTokenSpaceGuid.PciHb1Rb0Base
+  gHisiTokenSpaceGuid.PciHb1Rb1Base
+  gHisiTokenSpaceGuid.PciHb1Rb2Base
+  gHisiTokenSpaceGuid.PciHb1Rb3Base
+  gHisiTokenSpaceGuid.PciHb1Rb4Base
+  gHisiTokenSpaceGuid.PciHb1Rb5Base
+  gHisiTokenSpaceGuid.PciHb1Rb6Base
+  gHisiTokenSpaceGuid.PciHb1Rb7Base
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionBaseAddress
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionSize
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuMemRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuIoRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoSize

+ 663 - 0
Platform/Hisilicon/D05/D05.dsc

@@ -0,0 +1,663 @@
+#
+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015-2016, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015-2016, 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                  = D05
+  PLATFORM_GUID                  = D0D445F1-B2CA-4101-9986-1B23525CBEA6
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010019
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Hisilicon/$(PLATFORM_NAME)/$(PLATFORM_NAME).fdf
+  DEFINE EDK2_SKIP_PEICORE=0
+  DEFINE INCLUDE_TFTP_COMMAND=1
+  DEFINE NETWORK_IP6_ENABLE      = FALSE
+  DEFINE HTTP_BOOT_ENABLE        = FALSE
+
+!include Silicon/Hisilicon/Hisilicon.dsc.inc
+
+[LibraryClasses.common]
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+
+
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+  IpmiCmdLib|Silicon/Hisilicon/Hi1610/Library/IpmiCmdLib/IpmiCmdLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+!endif
+
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
+!endif
+
+!ifdef $(FDT_ENABLE)
+  #FDTUpdateLib
+  FdtUpdateLib|Platform/Hisilicon/D05/Library/FdtUpdateLib/FdtUpdateLib.inf
+!endif #$(FDT_ENABLE)
+
+  CpldIoLib|Silicon/Hisilicon/Library/CpldIoLib/CpldIoLib.inf
+
+  SerdesLib|Silicon/Hisilicon/Hi1616/Library/Hi1616Serdes/Hi1616SerdesLib.inf
+
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  #D05 RTC hardware is same as D03
+  RealTimeClockLib|Platform/Hisilicon/D03/Library/DS3231RealTimeClockLib/DS3231RealTimeClockLib.inf
+
+  OemMiscLib|Platform/Hisilicon/D05/Library/OemMiscLibD05/OemMiscLibD05.inf
+  OemAddressMapLib|Platform/Hisilicon/D05/Library/OemAddressMapD05/OemAddressMapD05.inf
+  PlatformSysCtrlLib|Silicon/Hisilicon/Hi1616/Library/PlatformSysCtrlLibHi1616/PlatformSysCtrlLibHi1616.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  PlatformBdsLib|Silicon/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  # USB Requirements
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  LpcLib|Silicon/Hisilicon/Hi1610/Library/LpcLib/LpcLib.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+
+[LibraryClasses.common.SEC]
+  ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLibSec.inf
+
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLibRuntime.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+
+[BuildOptions]
+  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/Silicon/Hisilicon/Hi1616/Include
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+
+!if $(EDK2_SKIP_PEICORE) == 1
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE
+!endif
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gHisiTokenSpaceGuid.PcdIsItsSupported|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D05"
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+
+  # Stacks for MPCores in Secure World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0xE1000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000
+
+  # Stacks for MPCores in Monitor Mode
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0xE100FF00
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x100
+
+  # Stacks for MPCores in Normal World
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0xE1000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0xFF00
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+
+
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3FC00000
+
+
+  # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x10000000
+
+  gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|1
+  gHisiTokenSpaceGuid.PcdSlotPerChannelNum|0x2
+
+
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask|0x94 # bit0:HB0RB0,bit1:HB0RB1,bit2:HB0RB2,bit3:HB0RB3,bit4:HB0RB4,bit5:HB0RB5,bit6:HB0RB6,bit7:HB0RB7
+                                                # bit8:HB1RB0,bit9:HB1RB1,bit10:HB1RB2,bit11:HB1RB3,bit12:HB1RB4,bit13:HB1RB5,bit14:HB1RB6,bit14:HB1RB15
+  ## enable all the pcie device, because it is ok for bios
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask2P|0x34F4 # bit0:HB0RB0,bit1:HB0RB1,bit2:HB0RB2,bit3:HB0RB3,bit4:HB0RB4,bit5:HB0RB5,bit6:HB0RB6,bit7:HB0RB7
+                                                # bit8:HB1RB0,bit9:HB1RB1,bit10:HB1RB2,bit11:HB1RB3,bit12:HB1RB4,bit13:HB1RB5,bit14:HB1RB6,bit14:HB1RB15
+
+  ## SP805 Watchdog - Motherboard Watchdog
+  gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x601e0000
+
+  ## Serial Terminal
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x602B0000
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz|200000000
+
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+  # use the TTY terminal type (which has a working backspace)
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+
+  gHisiTokenSpaceGuid.PcdM3SmmuBaseAddress|0xa0040000
+  gHisiTokenSpaceGuid.PcdPcieSmmuBaseAddress|0xb0040000
+  gHisiTokenSpaceGuid.PcdDsaSmmuBaseAddress|0xc0040000
+  gHisiTokenSpaceGuid.PcdAlgSmmuBaseAddress|0xd0040000
+
+
+  gHisiTokenSpaceGuid.PcdIsMPBoot|1
+  gHisiTokenSpaceGuid.PcdSocketMask|0x3
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Hisilicon D05 UEFI 16.12 Release"
+
+  gHisiTokenSpaceGuid.PcdBiosVersionString|L"10.01.01T18"
+
+  gHisiTokenSpaceGuid.PcdBiosVersionForBmc|L"1.12"
+
+  gHisiTokenSpaceGuid.PcdSystemProductName|L"D05"
+  gHisiTokenSpaceGuid.PcdSystemVersion|L"Estuary"
+  gHisiTokenSpaceGuid.PcdBaseBoardProductName|L"D05"
+  gHisiTokenSpaceGuid.PcdBaseBoardVersion|L"Estuary"
+
+  gHisiTokenSpaceGuid.PcdCPUInfo|L"Hi1616"
+
+
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x4D000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x4D100000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xFE000000
+
+
+  # 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(407B4008-BF5B-11DF-9547-CF16E0D72085)"
+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+  #
+  # ARM Architectual Timer Frequency
+  #
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000
+
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+  gHisiTokenSpaceGuid.PcdSysControlBaseAddress|0x40010000
+  gHisiTokenSpaceGuid.PcdMailBoxAddress|0x0000FFF8
+
+  gHisiTokenSpaceGuid.PcdCpldBaseAddress|0x78000000
+
+  gHisiTokenSpaceGuid.PcdSFCCFGBaseAddress|0xA6000000
+  gHisiTokenSpaceGuid.PcdSFCMEM0BaseAddress|0xA4000000
+
+
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress|0x40000000
+
+
+  gHisiTokenSpaceGuid.PcdMdioSubctrlAddress|0x60000000
+
+  ## DTB address at spi flash
+  gHisiTokenSpaceGuid.FdtFileAddress|0xA47A0000
+
+  gHisiTokenSpaceGuid.PcdPlatformDefaultPackageType|0x1
+
+  gHisiTokenSpaceGuid.PcdArmPrimaryCoreTemp|0x80010000
+
+  gHisiTokenSpaceGuid.PcdTopOfLowMemory|0x40000000
+
+  gHisiTokenSpaceGuid.PcdBottomOfHighMemory|0x1000000000
+
+  gHisiTokenSpaceGuid.PcdNORFlashBase|0x70000000
+  gHisiTokenSpaceGuid.PcdNORFlashCachableSize|0x8000000
+
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable|0x1
+  gHisiTokenSpaceGuid.PcdNumaEnable|1
+  gHisiTokenSpaceGuid.PcdMacAddress|0xA47E0000
+
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress|0x40000000000
+
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress|0xA0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress|0xA0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress|0xA0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress|0xA0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceBaseAddress|0x8A0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceBaseAddress|0x8B0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceSize|0x8000000
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceBaseAddress|0x8A0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceBaseAddress|0x8B0000000
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceBaseAddress|0x400A0000000
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceBaseAddress|0x400A0000000
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceBaseAddress|0x64000000000
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceSize|0x400000000
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceBaseAddress|0x400A0000000
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceBaseAddress|0x74000000000
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceSize|0x400000000
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceBaseAddress|0x78000000000
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceSize|0x400000000
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceBaseAddress|0x408A0000000
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceSize|0x10000000
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceBaseAddress|0x408A0000000
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceSize|0x10000000
+
+  gHisiTokenSpaceGuid.PciHb0Rb0Base|0xa0090000
+  gHisiTokenSpaceGuid.PciHb0Rb1Base|0xa0200000
+  gHisiTokenSpaceGuid.PciHb0Rb2Base|0xa00a0000
+  gHisiTokenSpaceGuid.PciHb0Rb3Base|0xa00b0000
+  gHisiTokenSpaceGuid.PciHb0Rb4Base|0x8a0090000
+  gHisiTokenSpaceGuid.PciHb0Rb5Base|0x8a0200000
+  gHisiTokenSpaceGuid.PciHb0Rb6Base|0x8a00a0000
+  gHisiTokenSpaceGuid.PciHb0Rb7Base|0x8a00b0000
+  gHisiTokenSpaceGuid.PciHb1Rb0Base|0x600a0090000
+  gHisiTokenSpaceGuid.PciHb1Rb1Base|0x600a0200000
+  gHisiTokenSpaceGuid.PciHb1Rb2Base|0x600a00a0000
+  gHisiTokenSpaceGuid.PciHb1Rb3Base|0x600a00b0000
+  gHisiTokenSpaceGuid.PciHb1Rb4Base|0x700a0090000
+  gHisiTokenSpaceGuid.PciHb1Rb5Base|0x700a0200000
+  gHisiTokenSpaceGuid.PciHb1Rb6Base|0x700a00a0000
+  gHisiTokenSpaceGuid.PciHb1Rb7Base|0x700a00b0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionBaseAddress|0xa8400000
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress|0xa9400000
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress|0xa8800000
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize|0x77effff
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionBaseAddress|0xab400000
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionBaseAddress|0xa9000000
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionSize|0x2feffff
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionBaseAddress|0xb0800000
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionSize|0x77effff
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionBaseAddress|0xac900000
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionSize|0x36effff
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionBaseAddress|0xb9800000
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionSize|0x67effff
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionBaseAddress|0x400a8400000
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionBaseAddress|0x400a9400000
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionBaseAddress|0x20000000
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionSize|0xcfffffff
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionBaseAddress|0x400ab400000
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionBaseAddress|0x30000000
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionSize|0xbfffffff
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionBaseAddress|0x40000000
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionSize|0xafffffff
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionBaseAddress|0x408aa400000
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionSize|0xbeffff
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionBaseAddress|0x408ab400000
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionSize|0xbeffff
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuMemRegionBase|0xA8400000
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase|0xA9400000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase|0xA8800000
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuMemRegionBase|0xAB400000
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuMemRegionBase|0x8A9000000
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuMemRegionBase|0x8B0800000
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuMemRegionBase|0x8AC900000
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuMemRegionBase|0x8B9800000
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuMemRegionBase|0x400A8400000
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuMemRegionBase|0x400A9400000
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuMemRegionBase|0x65020000000
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuMemRegionBase|0x400AB400000
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuMemRegionBase|0x75030000000
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuMemRegionBase|0x79040000000
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuMemRegionBase|0x408AA400000
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuMemRegionBase|0x408AB400000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuIoRegionBase|0xa8ff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase|0xa9ff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase|0xafff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuIoRegionBase|0xabff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuIoRegionBase|0x8abff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuIoRegionBase|0x8b7ff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuIoRegionBase|0x8afff0000
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuIoRegionBase|0x8bfff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuIoRegionBase|0x400a8ff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuIoRegionBase|0x400a9ff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuIoRegionBase|0x67fffff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuIoRegionBase|0x400abff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuIoRegionBase|0x77fffff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuIoRegionBase|0x7bfffff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuIoRegionBase|0x408aaff0000
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuIoRegionBase|0x408abff0000
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoBase|0
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoBase|0
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoSize|0xffff #64K
+
+  gHisiTokenSpaceGuid.Pcdsoctype|0x1610
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+
+  #
+  # SEC
+  #
+
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  Platform/Hisilicon/D05/Drivers/Ipmi/IpmiInterfacePei/IpmiInterfacePei.inf
+
+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+
+  Platform/Hisilicon/D05/MemoryInitPei/MemoryInitPeim.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.inf
+  Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  Silicon/Hisilicon/Hi1610/Drivers/IoInitDxe/IoInitDxe.inf
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+  Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
+
+  Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
+
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  # Sometimes we can use EmuVariableRuntimeDxe instead of real flash variable store for debug.
+  #MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+  Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
+    <LibraryClasses>
+      CpldIoLib|Silicon/Hisilicon/Library/CpldIoLib/CpldIoLibRuntime.inf
+  }
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
+  IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+  #
+  #ACPI
+  #
+  Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+  Silicon/Hisilicon/Hi1616/D05AcpiTables/AcpiTablesHi1616.inf
+  Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  #
+  # Usb Support
+  #
+  Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  Platform/Hisilicon/D05/Drivers/Ipmi/IpmiInterfaceDxe/IpmiInterfaceDxe.inf
+
+  #
+  #network
+  #
+  Platform/Hisilicon/D05/Drivers/Net/SnpPV660Dxe/SnpPV600Dxe.inf
+
+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  NetworkPkg/TcpDxe/TcpDxe.inf
+  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!else
+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!endif
+  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  NetworkPkg/DnsDxe/DnsDxe.inf
+  NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+  NetworkPkg/HttpDxe/HttpDxe.inf
+  NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+!endif
+
+
+  Platform/Hisilicon/D05/Drivers/Sas/SasDxeDriver.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
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  Platform/Hisilicon/D05/Drivers/GetInfoFromBmc/GetInfoFromBmc.inf
+  Platform/Hisilicon/D05/Drivers/TransferSmbiosInfo/TransSmbiosInfo.inf
+  Platform/Hisilicon/D05/Drivers/IpmiMiscOpDxe/IpmiMiscOpDxe.inf
+
+  Platform/Hisilicon/D05/Drivers/IpmiWatchdogDxe/IpmiWatchdogDxe.inf
+
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+
+!ifdef $(FDT_ENABLE)
+  Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf {
+    <LibraryClasses>
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+!endif #$(FDT_ENABLE)
+
+  #PCIe Support
+  Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf {
+    <LibraryClasses>
+      NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
+  }
+  Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
+  Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+    <LibraryClasses>
+      NULL|Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf
+  }
+
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  Platform/Hisilicon/D05/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
+  Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf
+  Platform/Hisilicon/D05/Drivers/Sm750Dxe/UefiSmi.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+  Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+
+
+  Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+  #
+  # Memory test
+  #
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  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
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+!endif
+
+!ifdef $(INCLUDE_DP)
+      NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf
+!endif #$(INCLUDE_DP)
+!ifdef $(INCLUDE_TFTP_COMMAND)
+      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
+!endif #$(INCLUDE_TFTP_COMMAND)
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }

+ 358 - 0
Platform/Hisilicon/D05/D05.fdf

@@ -0,0 +1,358 @@
+#
+#  Copyright (c) 2011, 2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2015-2016, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2015-2016, 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]
+
+################################################################################
+#
+# 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.D05]
+
+BaseAddress   = 0xA4800000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+
+Size          = 0x00300000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00010000
+NumBlocks     = 0x30
+
+################################################################################
+#
+# 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|0x00040000
+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
+FILE = Platform/Hisilicon/D05/Sec/FVMAIN_SEC.Fv
+
+0x00040000|0x00240000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+0x00280000|0x00020000
+gHisiTokenSpaceGuid.PcdTrustedFirmwareBL1Base
+FILE = Platform/Hisilicon/D05/bl1.bin
+0x002A0000|0x00020000
+FILE = Platform/Hisilicon/D05/fip.bin
+
+0x002D0000|0x0000E000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x20000
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER gEfiVariableGuid
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+  #Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdFB8
+  0xB8, 0xdF, 0x00, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002DE000|0x00002000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid          =
+  0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49,
+  0xA0, 0xCE, 0x65, 0x0 , 0xFD, 0x9F, 0x1B, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x002E0000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+0x002F0000|0x00010000
+FILE = Platform/Hisilicon/D03/CustomData.Fv
+
+################################################################################
+#
+# 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        = 16        # 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
+
+  APRIORI DXE {
+    INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  }
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  INF Silicon/Hisilicon/Hi1610/Drivers/IoInitDxe/IoInitDxe.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 Platform/Hisilicon/D05/Drivers/SFC/SfcDxeDriver.inf
+
+  INF Platform/Hisilicon/D03/Drivers/OemNicConfig2PHi1610/OemNicConfig2P.inf
+
+
+  INF Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  # Simple TextIn/TextOut for UEFI Terminal
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.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
+  INF IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+
+  #
+  # Usb Support
+  #
+
+  INF Silicon/Hisilicon/Drivers/VirtualEhciPciIo/VirtualEhciPciIo.inf
+  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  INF Platform/Hisilicon/D05/Drivers/OhciDxe/OhciDxe.inf
+  INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  INF Platform/Hisilicon/D05/Drivers/Ipmi/IpmiInterfaceDxe/IpmiInterfaceDxe.inf
+  INF Platform/Hisilicon/D05/Drivers/GetInfoFromBmc/GetInfoFromBmc.inf
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf
+  INF Platform/Hisilicon/D05/Drivers/TransferSmbiosInfo/TransSmbiosInfo.inf
+  INF Platform/Hisilicon/D05/Drivers/IpmiMiscOpDxe/IpmiMiscOpDxe.inf
+
+  INF Platform/Hisilicon/D05/Drivers/IpmiWatchdogDxe/IpmiWatchdogDxe.inf
+
+
+  INF Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf
+
+  INF Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
+
+  #
+  #ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  INF RuleOverride=ACPITABLE Silicon/Hisilicon/Hi1616/D05AcpiTables/AcpiTablesHi1616.inf
+  INF Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+  #
+  #Network
+  #
+
+  INF Platform/Hisilicon/D05/Drivers/Net/SnpPV660Dxe/SnpPV600Dxe.inf
+
+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  INF NetworkPkg/TcpDxe/TcpDxe.inf
+  INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!else
+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!endif
+  INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  INF NetworkPkg/DnsDxe/DnsDxe.inf
+  INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+  INF NetworkPkg/HttpDxe/HttpDxe.inf
+  INF NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+!endif
+
+!ifdef $(FDT_ENABLE)
+  INF Silicon/Hisilicon/Drivers/UpdateFdtDxe/UpdateFdtDxe.inf
+!endif #$(FDT_ENABLE)
+
+  #
+  # PCI Support
+  #
+  INF Silicon/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+  INF Platform/Hisilicon/D03/Drivers/PciPlatform/PciPlatform.inf
+  INF Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+  INF Platform/Hisilicon/D05/Drivers/ReportPciePlugDidVidToBmc/ReportPciePlugDidVidToBmc.inf
+  # VGA Driver
+  #
+  INF Platform/Hisilicon/D05/Drivers/Sm750Dxe/UefiSmi.inf
+  INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+  INF Platform/Hisilicon/D05/Drivers/Sas/SasDxeDriver.inf
+
+  #
+  # Build Shell from latest source code instead of prebuilt binary
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+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
+
+  APRIORI PEI {
+    INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  }
+  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+
+  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  INF Silicon/Hisilicon/Drivers/VersionInfoPeim/VersionInfoPeim.inf
+
+  INF Platform/Hisilicon/D05/Drivers/Ipmi/IpmiInterfacePei/IpmiInterfacePei.inf
+  INF Platform/Hisilicon/D05/MemoryInitPei/MemoryInitPeim.inf
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  INF Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.inf
+
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+!include Silicon/Hisilicon/Hisilicon.fdf.inc
+

+ 64 - 0
Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.c

@@ -0,0 +1,64 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <PiPei.h>
+#include <PlatformArch.h>
+#include <Uefi.h>
+#include <Library/ArmLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/OemAddressMapLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformSysCtrlLib.h>
+
+VOID
+QResetAp (
+  VOID
+  )
+{
+  MmioWrite64(FixedPcdGet64(PcdMailBoxAddress), 0x0);
+  (VOID)WriteBackInvalidateDataCacheRange((VOID *) FixedPcdGet64(PcdMailBoxAddress), 8);
+
+  if (!PcdGet64 (PcdTrustedFirmwareEnable)) {
+    StartupAp();
+  }
+}
+
+
+EFI_STATUS
+EFIAPI
+EarlyConfigEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  DEBUG((DEBUG_INFO,"SMMU CONFIG........."));
+  (VOID)SmmuConfigForBios();
+  DEBUG((DEBUG_INFO,"Done\n"));
+
+  DEBUG((DEBUG_INFO,"AP CONFIG........."));
+  (VOID)QResetAp();
+  DEBUG((DEBUG_INFO,"Done\n"));
+
+  DEBUG((DEBUG_INFO,"MN CONFIG........."));
+  (VOID)MN_CONFIG();
+  DEBUG((DEBUG_INFO,"Done\n"));
+
+  return EFI_SUCCESS;
+}
+

+ 53 - 0
Platform/Hisilicon/D05/EarlyConfigPeim/EarlyConfigPeimD05.inf

@@ -0,0 +1,53 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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                      = EarlyConfigPeimD05
+  FILE_GUID                      = A181AD33-E64A-4084-A54A-A69DF1FB0ABF
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = EarlyConfigEntry
+
+[Sources.common]
+  EarlyConfigPeimD05.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  CacheMaintenanceLib
+  DebugLib
+  IoLib
+  PcdLib
+  PeimEntryPoint
+  PlatformSysCtrlLib
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdMailBoxAddress
+  gHisiTokenSpaceGuid.PcdPeriSubctrlAddress
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable
+
+[Depex]
+## As we will clean mailbox in this module, need to wait memory init complete
+  gEfiPeiMemoryDiscoveredPpiGuid
+
+[BuildOptions]
+

+ 225 - 0
Platform/Hisilicon/D05/Library/OemMiscLibD05/BoardFeatureD05.c

@@ -0,0 +1,225 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <PlatformArch.h>
+#include <Uefi.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/I2CLib.h>
+#include <Library/IoLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/SerdesLib.h>
+#include <Protocol/Smbios.h>
+
+
+I2C_DEVICE gDS3231RtcDevice = {
+  .Socket = 0,
+  .Port = 4,
+  .DeviceType = DEVICE_TYPE_SPD,
+  .SlaveDeviceAddress = 0x68
+};
+
+SERDES_POLARITY_INVERT gSerdesPolarityTxDesc[] = {
+  {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+SERDES_POLARITY_INVERT gSerdesPolarityRxDesc[] = {
+  {SERDES_INVALID_MACRO_ID, SERDES_INVALID_LANE_NUM}
+};
+
+SERDES_PARAM gSerdesParamNA = {
+  .Hilink0Mode = EmHilink0Hccs1X8Width16,
+  .Hilink1Mode = EmHilink1Hccs0X8Width16,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Sas1X4,
+  .Hilink6Mode = 0x0,
+  .UseSsc      = 0,
+};
+
+SERDES_PARAM gSerdesParamNB = {
+  .Hilink0Mode = EmHilink0Pcie1X8,
+  .Hilink1Mode = EmHilink1Pcie0X8,
+  .Hilink2Mode = EmHilink2Sas0X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Pcie2X2Pcie3X2,
+  .Hilink6Mode = 0xF,
+  .UseSsc      = 0,
+};
+
+SERDES_PARAM gSerdesParamS1NA = {
+  .Hilink0Mode = EmHilink0Hccs1X8Width16,
+  .Hilink1Mode = EmHilink1Hccs0X8Width16,
+  .Hilink2Mode = EmHilink2Pcie2X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Sas1X4,
+  .Hilink6Mode = 0x0,
+  .UseSsc      = 0,
+};
+
+SERDES_PARAM gSerdesParamS1NB = {
+  .Hilink0Mode = EmHilink0Pcie1X8,
+  .Hilink1Mode = EmHilink1Pcie0X8,
+  .Hilink2Mode = EmHilink2Sas0X8,
+  .Hilink3Mode = 0x0,
+  .Hilink4Mode = 0xF,
+  .Hilink5Mode = EmHilink5Pcie2X2Pcie3X2,
+  .Hilink6Mode = 0xF,
+  .UseSsc      = 0,
+};
+
+
+EFI_STATUS
+OemGetSerdesParam (
+ OUT SERDES_PARAM *ParamA,
+ OUT SERDES_PARAM *ParamB,
+ IN  UINT32 SocketId
+ )
+{
+  if (ParamA == NULL || ParamB == NULL) {
+    DEBUG((DEBUG_ERROR, "[%a]:[%dL] Param == NULL!\n", __FUNCTION__, __LINE__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SocketId == 0) {
+    (VOID) CopyMem(ParamA, &gSerdesParamNA, sizeof(*ParamA));
+    (VOID) CopyMem(ParamB, &gSerdesParamNB, sizeof(*ParamB));
+  } else {
+    (VOID) CopyMem(ParamA, &gSerdesParamS1NA, sizeof(*ParamA));
+    (VOID) CopyMem(ParamB, &gSerdesParamS1NB, sizeof(*ParamB));
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+OemPcieResetAndOffReset (
+  VOID
+  )
+{
+  return;
+}
+
+SMBIOS_TABLE_TYPE9 gPcieSlotInfo[] = {
+  // PCIe0 Slot 1
+  {
+    {                                                     // Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS,                       // Type,
+      0,                                                  // Length,
+      0                                                   // Handle
+    },
+    1,                                                    // SlotDesignation
+    SlotTypePciExpressX8,     // SlotType
+    SlotDataBusWidth8X,       // SlotDataBusWidth
+    SlotUsageAvailable,       // SlotUsage
+    SlotLengthOther,          // SlotLength
+    0x0001,                   // SlotId
+    {                         // SlotCharacteristics1
+      0,                      // CharacteristicsUnknown  :1;
+      0,                      // Provides50Volts         :1;
+      0,                      // Provides33Volts         :1;
+      0,                      // SharedSlot              :1;
+      0,                      // PcCard16Supported       :1;
+      0,                      // CardBusSupported        :1;
+      0,                      // ZoomVideoSupported      :1;
+      0                       // ModemRingResumeSupported:1;
+    },
+    {                         // SlotCharacteristics2
+      0,                      // PmeSignalSupported      :1;
+      0,                      // HotPlugDevicesSupported  :1;
+      0,                      // SmbusSignalSupported    :1;
+      0                       // Reserved                :5;
+    },
+    0x00,                     // SegmentGroupNum
+    0x00,                     // BusNum
+    0                         // DevFuncNum
+  },
+
+  // PCIe0 Slot 4
+  {
+    {                                                  // Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS,                    // Type,
+      0,                                               // Length,
+      0                                                // Handle
+    },
+    1,                                                 // SlotDesignation
+    SlotTypePciExpressX8,     // SlotType
+    SlotDataBusWidth8X,       // SlotDataBusWidth
+    SlotUsageAvailable,       // SlotUsage
+    SlotLengthOther,          // SlotLength
+    0x0004,                   // SlotId
+    {                         // SlotCharacteristics1
+      0,                      // CharacteristicsUnknown  :1;
+      0,                      // Provides50Volts         :1;
+      0,                      // Provides33Volts         :1;
+      0,                      // SharedSlot              :1;
+      0,                      // PcCard16Supported       :1;
+      0,                      // CardBusSupported        :1;
+      0,                      // ZoomVideoSupported      :1;
+      0                       // ModemRingResumeSupported:1;
+    },
+    {                         // SlotCharacteristics2
+      0,                      // PmeSignalSupported      :1;
+      0,                      // HotPlugDevicesSupported  :1;
+      0,                      // SmbusSignalSupported    :1;
+      0                       // Reserved                :5;
+    },
+    0x00,                     // SegmentGroupNum
+    0x00,                     // BusNum
+    0                         // DevFuncNum
+  }
+};
+
+
+UINT8
+OemGetPcieSlotNumber (
+  VOID
+  )
+{
+  return  sizeof (gPcieSlotInfo) / sizeof (SMBIOS_TABLE_TYPE9);
+}
+
+EFI_STRING_ID gDimmToDevLocator[MAX_SOCKET][MAX_CHANNEL][MAX_DIMM] = {
+  {{STRING_TOKEN(STR_LEMON_C10_DIMM_000), STRING_TOKEN(STR_LEMON_C10_DIMM_001), STRING_TOKEN(STR_LEMON_C10_DIMM_002)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_010), STRING_TOKEN(STR_LEMON_C10_DIMM_011), STRING_TOKEN(STR_LEMON_C10_DIMM_012)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_020), STRING_TOKEN(STR_LEMON_C10_DIMM_021), STRING_TOKEN(STR_LEMON_C10_DIMM_022)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_030), STRING_TOKEN(STR_LEMON_C10_DIMM_031), STRING_TOKEN(STR_LEMON_C10_DIMM_032)}},
+
+  {{STRING_TOKEN(STR_LEMON_C10_DIMM_100), STRING_TOKEN(STR_LEMON_C10_DIMM_101), STRING_TOKEN(STR_LEMON_C10_DIMM_102)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_110), STRING_TOKEN(STR_LEMON_C10_DIMM_111), STRING_TOKEN(STR_LEMON_C10_DIMM_112)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_120), STRING_TOKEN(STR_LEMON_C10_DIMM_121), STRING_TOKEN(STR_LEMON_C10_DIMM_122)},
+   {STRING_TOKEN(STR_LEMON_C10_DIMM_130), STRING_TOKEN(STR_LEMON_C10_DIMM_131), STRING_TOKEN(STR_LEMON_C10_DIMM_132)}}
+};
+
+EFI_HII_HANDLE
+EFIAPI
+OemGetPackages (
+  )
+{
+  return HiiAddPackages (
+                        &gEfiCallerIdGuid,
+                        NULL,
+                        OemMiscLibHi1616EvbStrings,
+                        NULL,
+                        NULL
+                        );
+}
+
+

+ 56 - 0
Platform/Hisilicon/D05/Library/OemMiscLibD05/BoardFeatureD05Strings.uni

@@ -0,0 +1,56 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2016, Hisilicon 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.
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Begin English Language Strings
+//
+#string STR_MEMORY_SUBCLASS_UNKNOWN    #language en-US  "Unknown"
+
+//
+// DIMM Device Locator strings
+
+#string STR_LEMON_C10_DIMM_000     #language en-US "J5"
+#string STR_LEMON_C10_DIMM_001     #language en-US "J6"
+#string STR_LEMON_C10_DIMM_002     #language en-US "J7"
+#string STR_LEMON_C10_DIMM_010     #language en-US "J8"
+#string STR_LEMON_C10_DIMM_011     #language en-US "J9"
+#string STR_LEMON_C10_DIMM_012     #language en-US "J10"
+#string STR_LEMON_C10_DIMM_020     #language en-US "J11"
+#string STR_LEMON_C10_DIMM_021     #language en-US "J12"
+#string STR_LEMON_C10_DIMM_022     #language en-US "J13"
+#string STR_LEMON_C10_DIMM_030     #language en-US "J14"
+#string STR_LEMON_C10_DIMM_031     #language en-US "J15"
+#string STR_LEMON_C10_DIMM_032     #language en-US "J16"
+#string STR_LEMON_C10_DIMM_100     #language en-US "J17"
+#string STR_LEMON_C10_DIMM_101     #language en-US "J18"
+#string STR_LEMON_C10_DIMM_102     #language en-US "J19"
+#string STR_LEMON_C10_DIMM_110     #language en-US "J20"
+#string STR_LEMON_C10_DIMM_111     #language en-US "J21"
+#string STR_LEMON_C10_DIMM_112     #language en-US "J22"
+#string STR_LEMON_C10_DIMM_120     #language en-US "J23"
+#string STR_LEMON_C10_DIMM_121     #language en-US "J24"
+#string STR_LEMON_C10_DIMM_122     #language en-US "J25"
+#string STR_LEMON_C10_DIMM_130     #language en-US "J26"
+#string STR_LEMON_C10_DIMM_131     #language en-US "J27"
+#string STR_LEMON_C10_DIMM_132     #language en-US "J28"
+
+//
+// End English Language Strings
+//
+

+ 107 - 0
Platform/Hisilicon/D05/Library/OemMiscLibD05/OemMiscLibD05.c

@@ -0,0 +1,107 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, 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 <PlatformArch.h>
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/LpcLib.h>
+#include <Library/OemAddressMapLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformPciLib.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/TimerLib.h>
+
+#define OEM_SINGLE_SOCKET 1
+#define OEM_DUAL_SOCKET 2
+
+REPORT_PCIEDIDVID2BMC  PcieDeviceToReport[PCIEDEVICE_REPORT_MAX] = {
+  {67,0,0,0},
+  {225,0,0,3},
+  {0xFFFF,0xFFFF,0xFFFF,0xFFFF},
+  {0xFFFF,0xFFFF,0xFFFF,0xFFFF}
+};
+
+
+BOOLEAN OemIsSocketPresent (UINTN Socket)
+{
+  if (PcdGet32(PcdSocketMask) & (1 << Socket)) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+
+UINTN OemGetSocketNumber (VOID)
+{
+
+  if(!OemIsMpBoot()) {
+    return OEM_SINGLE_SOCKET;
+  }
+
+  return OEM_DUAL_SOCKET;
+}
+
+
+UINTN OemGetDdrChannel (VOID)
+{
+  return 4;
+}
+
+
+UINTN OemGetDimmSlot(UINTN Socket, UINTN Channel)
+{
+  return 2;
+}
+
+VOID CoreSelectBoot(VOID)
+{
+  if (!PcdGet64 (PcdTrustedFirmwareEnable)) {
+      StartupAp ();
+  }
+
+  return;
+}
+
+BOOLEAN OemIsMpBoot()
+{
+  return PcdGet32(PcdIsMPBoot);
+}
+
+VOID OemLpcInit(VOID)
+{
+  LpcInit();
+  return;
+}
+
+UINT32 OemIsWarmBoot(VOID)
+{
+  return 0;
+}
+
+VOID OemBiosSwitch(UINT32 Master)
+{
+  (VOID)Master;
+  return;
+}
+
+BOOLEAN OemIsNeedDisableExpanderBuffer(VOID)
+{
+  return TRUE;
+}

+ 55 - 0
Platform/Hisilicon/D05/Library/OemMiscLibD05/OemMiscLibD05.inf

@@ -0,0 +1,55 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, 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                      = OemMiscLibHi1616Evb
+  FILE_GUID                      = B9CE7465-21A2-4ecd-B347-BBDDBD098CEE
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OemMiscLib
+
+[Sources.common]
+  BoardFeatureD05.c
+  BoardFeatureD05Strings.uni
+  OemMiscLibD05.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  TimerLib
+
+[BuildOptions]
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid   ## SOMETIMES_CONSUMES
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
+  gHisiTokenSpaceGuid.PcdIsMPBoot
+  gHisiTokenSpaceGuid.PcdSocketMask
+  gHisiTokenSpaceGuid.PcdTrustedFirmwareEnable
+
+[FixedPcd.common]
+
+[Guids]
+
+[Protocols]
+

+ 279 - 0
Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.c

@@ -0,0 +1,279 @@
+/** @file
+
+  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+
+  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/PcdLib.h>
+#include <Library/PlatformPciLib.h>
+
+UINT64 pcie_subctrl_base_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa0000000, 0xa0000000,0xa0000000,0xa0000000,0x8a0000000,0x8a0000000,0x8a0000000,0x8a0000000},
+                                        {0x600a0000000,0x600a0000000,0x600a0000000,0x600a0000000, 0x700a0000000,0x700a0000000,0x700a0000000,0x700a0000000}};
+UINT64 PCIE_APB_SLAVE_BASE_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa0090000, 0xa0200000, 0xa00a0000, 0xa00b0000, 0x8a0090000, 0x8a0200000, 0x8a00a0000, 0x8a00b0000},
+                                         {0x600a0090000, 0x600a0200000, 0x600a00a0000, 0x600a00b0000, 0x700a0090000, 0x700a0200000, 0x700a00a0000, 0x700a00b0000}};
+UINT64 PCIE_PHY_BASE_1610 [PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xa00c0000, 0xa00d0000, 0xa00e0000, 0xa00f0000, 0x8a00c0000, 0x8a00d0000, 0x8a00e0000, 0x8a00f0000},
+                                 {0x600a00c0000, 0x600a00d0000, 0x600a00e0000, 0x600a00f0000, 0x700a00c0000, 0x700a00d0000, 0x700a00e0000, 0x700a00f0000}};
+UINT64 PCIE_ITS_1610[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {{0xc6010040, 0xc6010040, 0xc6010040, 0xc6010040, 0x8c6010040, 0x8c6010040, 0x8c6010040, 0x8c6010040},
+                           {0x400C6010040, 0x400C6010040, 0x400C6010040, 0x400C6010040, 0x408C6010040, 0x408C6010040, 0x408C6010040, 0x408C6010040}};
+
+PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
+ {// HostBridge 0
+  /* Port 0 */
+  {
+      PCI_HB0RB0_ECAM_BASE, //ecam
+      0x80,  //BusBase
+      0x87, //BusLimit
+      PCI_HB0RB0_PCIREGION_BASE, //Membase
+      PCI_HB0RB0_CPUMEMREGIONBASE + PCI_HB0RB0_PCIREGION_SIZE - 1, //Memlimit
+      PCI_HB0RB0_IO_BASE,  //IoBase
+      (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB0_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB0_PCI_BASE),//RbPciBar
+      PCI_HB0RB0_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB0_PCIREGION_BASE + PCI_HB0RB0_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 1 */
+  {
+      PCI_HB0RB1_ECAM_BASE,//ecam
+      0x90,  //BusBase
+      0x97, //BusLimit
+      PCI_HB0RB1_PCIREGION_BASE, //Membase
+      PCI_HB0RB1_CPUMEMREGIONBASE + PCI_HB0RB1_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB1_IO_BASE),  //IoBase
+      (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB1_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB1_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB1_PCI_BASE),  //RbPciBar
+      PCI_HB0RB1_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB1_PCIREGION_BASE + PCI_HB0RB1_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 2 */
+  {
+      PCI_HB0RB2_ECAM_BASE,
+      0x80,  //BusBase
+      0x87, //BusLimit
+      PCI_HB0RB2_CPUMEMREGIONBASE ,//MemBase
+      PCI_HB0RB2_CPUMEMREGIONBASE + PCI_HB0RB2_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB2_IO_BASE),  //IOBase
+      (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB2_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB2_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB2_PCI_BASE),  //RbPciBar
+      PCI_HB0RB2_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB2_PCIREGION_BASE + PCI_HB0RB2_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB0RB3_ECAM_BASE,
+      0xb0,  //BusBase
+      0xb7, //BusLimit
+      (PCI_HB0RB3_ECAM_BASE),  //MemBase
+      (PCI_HB0RB3_CPUMEMREGIONBASE + PCI_HB0RB3_PCIREGION_SIZE - 1), //MemLimit
+      (PCI_HB0RB3_IO_BASE), //IoBase
+      (PCI_HB0RB3_CPUIOREGIONBASE + PCI_HB0RB3_IO_SIZE - 1),  //IoLimit
+      PCI_HB0RB3_CPUMEMREGIONBASE,
+      PCI_HB0RB3_CPUIOREGIONBASE,
+      (PCI_HB0RB3_PCI_BASE),  //RbPciBar
+      PCI_HB0RB3_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB3_PCIREGION_BASE + PCI_HB0RB3_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 4 */
+  {
+      PCI_HB0RB4_ECAM_BASE, //ecam
+      0x88,  //BusBase
+      0x8f, //BusLimit
+      PCI_HB0RB4_CPUMEMREGIONBASE, //Membase
+      PCI_HB0RB4_CPUMEMREGIONBASE + PCI_HB0RB4_PCIREGION_SIZE - 1, //Memlimit
+      PCI_HB0RB4_IO_BASE,  //IoBase
+      (PCI_HB0RB4_CPUIOREGIONBASE + PCI_HB0RB4_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB4_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB4_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB4_PCI_BASE),  //RbPciBar
+      PCI_HB0RB4_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB4_PCIREGION_BASE + PCI_HB0RB4_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 5 */
+  {
+      PCI_HB0RB5_ECAM_BASE,//ecam
+      0x0,  //BusBase
+      0x7, //BusLimit
+      PCI_HB0RB5_CPUMEMREGIONBASE, //Membase
+      PCI_HB0RB5_CPUMEMREGIONBASE + PCI_HB0RB5_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB5_IO_BASE),  //IoBase
+      (PCI_HB0RB5_CPUIOREGIONBASE + PCI_HB0RB5_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB5_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB5_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB5_PCI_BASE),  //RbPciBar
+      PCI_HB0RB5_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB5_PCIREGION_BASE + PCI_HB0RB5_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 6 */
+  {
+      PCI_HB0RB6_ECAM_BASE,
+      0xC0,  //BusBase
+      0xC7, //BusLimit
+      PCI_HB0RB6_PCIREGION_BASE ,//MemBase
+      PCI_HB0RB6_CPUMEMREGIONBASE + PCI_HB0RB6_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB6_IO_BASE),  //IOBase
+      (PCI_HB0RB6_CPUIOREGIONBASE + PCI_HB0RB6_IO_SIZE - 1), //IoLimit
+      PCI_HB0RB6_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB0RB6_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB0RB6_PCI_BASE),  //RbPciBar
+      PCI_HB0RB6_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB6_PCIREGION_BASE + PCI_HB0RB6_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+
+  /* Port 7 */
+  {
+      PCI_HB0RB7_ECAM_BASE,
+      0x90,  //BusBase
+      0x97, //BusLimit
+      PCI_HB0RB7_CPUMEMREGIONBASE,  //MemBase
+      PCI_HB0RB7_CPUMEMREGIONBASE + PCI_HB0RB7_PCIREGION_SIZE - 1, //MemLimit
+      (PCI_HB0RB7_IO_BASE), //IoBase
+      (PCI_HB0RB7_CPUIOREGIONBASE + PCI_HB0RB7_IO_SIZE - 1),  //IoLimit
+      PCI_HB0RB7_CPUMEMREGIONBASE,
+      PCI_HB0RB7_CPUIOREGIONBASE,
+      (PCI_HB0RB7_PCI_BASE),  //RbPciBar
+      PCI_HB0RB7_PCIREGION_BASE, //PciRegionbase
+      PCI_HB0RB7_PCIREGION_BASE + PCI_HB0RB7_PCIREGION_SIZE - 1 //PciRegionlimit
+  }
+ },
+{// HostBridge 1
+  /* Port 0 */
+  {
+      PCI_HB1RB0_ECAM_BASE,
+      0x80,  //BusBase
+      0x87, //BusLimit
+      (PCI_HB1RB0_ECAM_BASE),  //MemBase
+      (PCI_HB1RB0_CPUMEMREGIONBASE + PCI_HB1RB0_PCIREGION_SIZE - 1), //MemLimit
+      PCI_HB1RB0_IO_BASE, //IoBase
+      (PCI_HB0RB0_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB0_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB0_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB0_PCI_BASE),  //RbPciBar
+      PCI_HB1RB0_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB0_PCIREGION_BASE + PCI_HB1RB0_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 1 */
+  {
+      PCI_HB1RB1_ECAM_BASE,
+      0x90,  //BusBase
+      0x97, //BusLimit
+      (PCI_HB1RB1_ECAM_BASE),  //MemBase
+      (PCI_HB1RB1_CPUMEMREGIONBASE + PCI_HB1RB1_PCIREGION_SIZE - 1), //MemLimit
+      PCI_HB1RB1_IO_BASE, //IoBase
+      (PCI_HB0RB1_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB1_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB1_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB1_PCI_BASE),  //RbPciBar
+      PCI_HB1RB1_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB1_PCIREGION_BASE + PCI_HB1RB1_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 2 */
+  {
+      PCI_HB1RB2_ECAM_BASE,
+      0x10,  //BusBase
+      0x1f, //BusLimit
+      PCI_HB1RB2_CPUMEMREGIONBASE,  //MemBase
+      PCI_HB1RB2_CPUMEMREGIONBASE + PCI_HB1RB2_PCIREGION_SIZE - 1, //MemLimit
+      PCI_HB1RB2_IO_BASE, //IoBase
+      (PCI_HB0RB2_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB2_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB2_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB2_PCI_BASE),  //RbPciBar
+      PCI_HB1RB2_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB2_PCIREGION_BASE + PCI_HB1RB2_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+
+  /* Port 3 */
+  {
+      PCI_HB1RB3_ECAM_BASE,
+      0xb0,  //BusBase
+      0xb7, //BusLimit
+      (PCI_HB1RB3_ECAM_BASE),  //MemBase
+      (PCI_HB1RB3_CPUMEMREGIONBASE + PCI_HB1RB3_PCIREGION_SIZE - 1), //MemLimit
+      PCI_HB1RB3_IO_BASE, //IoBase
+      (PCI_HB0RB3_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB3_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB3_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB3_PCI_BASE),  //RbPciBar
+      PCI_HB1RB3_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB3_PCIREGION_BASE + PCI_HB1RB3_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 4 */
+  {
+      PCI_HB1RB4_ECAM_BASE,
+      0x20,  //BusBase
+      0x2f, //BusLimit
+      PCI_HB1RB4_CPUMEMREGIONBASE,  //MemBase
+      PCI_HB1RB4_CPUMEMREGIONBASE + PCI_HB1RB4_PCIREGION_SIZE - 1, //MemLimit
+      PCI_HB1RB4_IO_BASE, //IoBase
+      (PCI_HB0RB4_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB4_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB4_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB4_PCI_BASE),  //RbPciBar
+      PCI_HB1RB4_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB4_PCIREGION_BASE + PCI_HB1RB4_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 5 */
+  {
+      PCI_HB1RB5_ECAM_BASE,
+      0x30,  //BusBase
+      0x3f, //BusLimit
+      PCI_HB1RB5_CPUMEMREGIONBASE,  //MemBase
+      PCI_HB1RB5_CPUMEMREGIONBASE + PCI_HB1RB5_PCIREGION_SIZE - 1, //MemLimit
+      PCI_HB1RB5_IO_BASE, //IoBase
+      (PCI_HB0RB5_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB5_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB5_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB5_PCI_BASE),  //RbPciBar
+      PCI_HB1RB5_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB5_PCIREGION_BASE + PCI_HB1RB5_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+  /* Port 6 */
+  {
+      PCI_HB1RB6_ECAM_BASE,
+      0xa8,  //BusBase
+      0xaf, //BusLimit
+      (PCI_HB1RB6_ECAM_BASE),  //MemBase
+      PCI_HB1RB6_CPUMEMREGIONBASE + PCI_HB1RB6_PCIREGION_SIZE - 1, //MemLimit
+      PCI_HB1RB6_IO_BASE, //IoBase
+      (PCI_HB0RB6_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB6_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB6_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB6_PCI_BASE),  //RbPciBar
+      PCI_HB1RB6_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB0_PCIREGION_BASE + PCI_HB1RB0_PCIREGION_SIZE - 1 //PciRegionlimit
+  },
+
+  /* Port 7 */
+  {
+      PCI_HB1RB7_ECAM_BASE,
+      0xb8,  //BusBase
+      0xbf, //BusLimit
+      (PCI_HB1RB7_ECAM_BASE),  //MemBase
+      PCI_HB1RB7_CPUMEMREGIONBASE + PCI_HB1RB7_PCIREGION_SIZE - 1, //MemLimit
+      PCI_HB1RB7_IO_BASE, //IoBase
+      (PCI_HB0RB7_CPUIOREGIONBASE + PCI_HB0RB0_IO_SIZE - 1), //IoLimit
+      PCI_HB1RB7_CPUMEMREGIONBASE, //CpuMemRegionBase
+      PCI_HB1RB7_CPUIOREGIONBASE,  //CpuIoRegionBase
+      (PCI_HB1RB7_PCI_BASE),  //RbPciBar
+      PCI_HB1RB7_PCIREGION_BASE, //PciRegionbase
+      PCI_HB1RB7_PCIREGION_BASE + PCI_HB1RB7_PCIREGION_SIZE - 1 //PciRegionlimit
+  }
+
+ }
+};
+

+ 183 - 0
Platform/Hisilicon/D05/Library/PlatformPciLib/PlatformPciLib.inf

@@ -0,0 +1,183 @@
+## @file
+#
+#  Copyright (c) 2016, Hisilicon Limited. All rights reserved.<BR>
+#  Copyright (c) 2016, Linaro Limited. All rights reserved.<BR>
+#
+#  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                      = PlatformPciLib
+  FILE_GUID                      = 61b7276a-fc67-11e5-82fd-47ea9896dd5d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PlatformPciLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+
+[FixedPcd]
+  gHisiTokenSpaceGuid.PcdHb1BaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciConfigurationSpaceSize
+  gHisiTokenSpaceGuid.PciHb0Rb0Base
+  gHisiTokenSpaceGuid.PciHb0Rb1Base
+  gHisiTokenSpaceGuid.PciHb0Rb2Base
+  gHisiTokenSpaceGuid.PciHb0Rb3Base
+  gHisiTokenSpaceGuid.PciHb0Rb4Base
+  gHisiTokenSpaceGuid.PciHb0Rb5Base
+  gHisiTokenSpaceGuid.PciHb0Rb6Base
+  gHisiTokenSpaceGuid.PciHb0Rb7Base
+  gHisiTokenSpaceGuid.PciHb1Rb0Base
+  gHisiTokenSpaceGuid.PciHb1Rb1Base
+  gHisiTokenSpaceGuid.PciHb1Rb2Base
+  gHisiTokenSpaceGuid.PciHb1Rb3Base
+  gHisiTokenSpaceGuid.PciHb1Rb4Base
+  gHisiTokenSpaceGuid.PciHb1Rb5Base
+  gHisiTokenSpaceGuid.PciHb1Rb6Base
+  gHisiTokenSpaceGuid.PciHb1Rb7Base
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionBaseAddress
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionBaseAddress
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6PciRegionSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7PciRegionSize
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuMemRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuMemRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6CpuIoRegionBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7CpuIoRegionBase
+
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb0Rb7IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb0IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb1IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb2IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb3IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb4IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb5IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb6IoSize
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoBase
+  gHisiTokenSpaceGuid.PcdHb1Rb7IoSize
+

+ 36 - 0
Platform/Hisilicon/HiKey/HiKey.dec

@@ -0,0 +1,36 @@
+#
+#  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                   = HiKey
+  PACKAGE_GUID                   = d6db414d-ea67-4312-94d5-9c9e5b224d25
+  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]
+  gHiKeyTokenSpaceGuid          =  { 0x91148425, 0xcdd2, 0x4830, { 0x8b, 0xd0, 0xc6, 0x1c, 0x6d, 0xea, 0x36, 0x21 } }
+
+[PcdsFixedAtBuild.common]
+  gHiKeyTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L""|VOID*|0x00000001
+  gHiKeyTokenSpaceGuid.PcdArmFastbootFlashLimit|L""|VOID*|0x00000002

+ 482 - 0
Platform/Hisilicon/HiKey/HiKey.dsc

@@ -0,0 +1,482 @@
+#
+#  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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = HiKey
+  PLATFORM_GUID                  = 8edf1480-da5c-4857-bc02-7530bd8e7b7a
+  PLATFORM_VERSION               = 0.2
+  DSC_SPECIFICATION              = 0x00010019
+  OUTPUT_DIRECTORY               = Build/HiKey
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Hisilicon/HiKey/HiKey.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
+
+  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
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  ArmPlatformLib|Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+  # UiApp dependencies
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.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
+
+  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+
+  #
+  # Assume everything is fixed at build
+  #
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.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
+
+  # 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
+
+  # It is not possible to prevent compilers from generating calls to generic
+  # intrinsic functions. This library provides the intrinsic functions
+  # generated by a given compiler.
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+  # Add support for GCC stack protector
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[LibraryClasses.common.SEC]
+  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
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[BuildOptions]
+  GCC:*_*_*_PLATFORM_FLAGS = -I$(WORKSPACE)/Silicon/Hisilicon/Hi6220/Include -I$(WORKSPACE)/Platform/Hisilicon/HiKey/Include
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  #
+  # 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  // Load File
+  #  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|0x8000000F
+
+  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|"hikey"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Alpha"
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"HiKey"
+
+  #
+  # NV Storage PCDs.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x30000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x30010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x30020000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
+
+  # System Memory (1GB)
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3E000000
+
+  # HiKey Dual-Cluster profile
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+  gArmPlatformTokenSpaceGuid.PcdClusterCount|2
+
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  #
+  # ARM PrimeCell
+  #
+
+  ## PL011 - Serial Terminal
+  DEFINE SERIAL_BASE = 0xF7113000 # UART3
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|$(SERIAL_BASE)
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+  gArmPlatformTokenSpaceGuid.PL011UartInteger|10
+  gArmPlatformTokenSpaceGuid.PL011UartFractional|26
+
+  ## PL031 RealTimeClock
+  gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0xF8003000
+
+  #
+  # ARM General Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0xF6801000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xF6802000
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|10
+
+  # 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
+
+  #
+  # DW MMC/SD card controller
+  #
+  gEmbeddedTokenSpaceGuid.PcdDwEmmcDxeBaseAddress|0xF723D000
+  gEmbeddedTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz|100000000
+
+  #
+  #
+  # Fastboot
+  #
+  gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId|0x18d1
+  gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xd00d
+
+################################################################################
+#
+# 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
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.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/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # GPIO
+  #
+  ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+
+  #
+  # MMC/SD
+  #
+  EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  EmbeddedPkg/Drivers/DwEmmcDxe/DwEmmcDxe.inf
+
+  #
+  # USB Host Support
+  #
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+
+  #
+  # USB Mass Storage Support
+  #
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # USB Peripheral Support
+  #
+  EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+  #
+  # Fastboot
+  #
+  EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf {
+    <LibraryClasses>
+      BdsLib|ArmPkg/Library/BdsLib/BdsLib.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
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.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
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.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
+  }

+ 351 - 0
Platform/Hisilicon/HiKey/HiKey.fdf

@@ -0,0 +1,351 @@
+#
+#  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.
+#
+
+################################################################################
+#
+# 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   = 0x35000000|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]
+FvNameGuid         = 69b7d469-55a2-49d8-a426-42bfb22f5b9d
+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 MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.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
+
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # GPIO
+  #
+  INF ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+
+  #
+  # Multimedia Card Interface
+  #
+  INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  INF EmbeddedPkg/Drivers/DwEmmcDxe/DwEmmcDxe.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 EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+  #
+  # Fastboot
+  #
+  INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.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
+
+  #
+  # 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
+
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.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
+  }

+ 26 - 0
Platform/Hisilicon/HiKey/Include/ArmPlatform.h

@@ -0,0 +1,26 @@
+/** @file
+*
+*  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.
+*
+**/
+
+#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__ */

+ 159 - 0
Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKey.c

@@ -0,0 +1,159 @@
+/** @file
+*
+*  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.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <Hi6220.h>
+
+ARM_CORE_INFO mHiKeyInfoTable[] = {
+  {
+    // 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 RETURN_SUCCESS;
+}
+
+/**
+  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(mHiKeyInfoTable) / sizeof(ARM_CORE_INFO);
+  *ArmCoreTable = mHiKeyInfoTable;
+  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;
+}

+ 49 - 0
Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyHelper.S

@@ -0,0 +1,49 @@
+#
+#  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.
+#
+#
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  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
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  MOV32 (w0, FixedPcdGet32(PcdArmPrimaryCore))
+  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

+ 51 - 0
Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyLib.inf

@@ -0,0 +1,51 @@
+#
+#  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]
+  INF_VERSION                    = 0x00010019
+  BASE_NAME                      = HiKeyLib
+  FILE_GUID                      = 1f6c5192-f35c-462d-877c-8ee3227fff01
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/Hisilicon/HiKey/HiKey.dec
+  Silicon/Hisilicon/Hi6220/Hi6220.dec
+
+[LibraryClasses]
+  ArmLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  SerialPortLib
+
+[Sources.common]
+  HiKey.c
+  HiKeyMem.c
+
+[Sources.AARCH64]
+  HiKeyHelper.S
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize

+ 204 - 0
Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyMem.c

@@ -0,0 +1,204 @@
+/** @file
+*
+*  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.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <Hi6220.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 HIKEY_EXTRA_SYSTEM_MEMORY_BASE  0x40000000
+#define HIKEY_EXTRA_SYSTEM_MEMORY_SIZE  0x40000000
+
+STATIC struct HiKeyReservedMemory {
+  EFI_PHYSICAL_ADDRESS         Offset;
+  EFI_PHYSICAL_ADDRESS         Size;
+} HiKeyReservedMemoryBuffer [] = {
+  { 0x05E00000, 0x00100000 },    // MCU
+  { 0x05F01000, 0x00001000 },    // ADB REBOOT "REASON"
+  { 0x06DFF000, 0x00001000 },    // MAILBOX
+  { 0x0740F000, 0x00001000 },    // MAILBOX
+  { 0x21F00000, 0x00100000 },    // PSTORE/RAMOOPS
+  { 0x3E000000, 0x02000000 }     // TEE OS
+};
+
+STATIC
+UINT64
+EFIAPI
+HiKeyInitMemorySize (
+  IN VOID
+  )
+{
+  UINT32               Data;
+  UINT64               MemorySize;
+
+  Data = MmioRead32 (MDDRC_AXI_BASE + AXI_REGION_MAP);
+  MemorySize = HIKEY_REGION_SIZE(Data);
+  return MemorySize;
+}
+
+/**
+  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;
+  UINTN                         Index = 0, Count, ReservedTop;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  EFI_PEI_HOB_POINTERS          NextHob;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+  UINT64                        ResourceLength;
+  EFI_PHYSICAL_ADDRESS          ResourceTop;
+  UINT64                        MemorySize, AdditionalMemorySize;
+
+  MemorySize = HiKeyInitMemorySize ();
+  if (MemorySize == 0) {
+    MemorySize = PcdGet64 (PcdSystemMemorySize);
+  }
+
+  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)
+  );
+
+  NextHob.Raw = GetHobList ();
+  Count = sizeof (HiKeyReservedMemoryBuffer) / sizeof (struct HiKeyReservedMemory);
+  while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
+    if (Index >= Count) {
+      break;
+    }
+    if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+        (HiKeyReservedMemoryBuffer[Index].Offset >= NextHob.ResourceDescriptor->PhysicalStart) &&
+        ((HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size) <=
+         NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) {
+      ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+      ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+      ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+      ReservedTop = HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size;
+
+      // Create the System Memory HOB for the reserved buffer
+      BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED,
+                                  EFI_RESOURCE_ATTRIBUTE_PRESENT,
+                                  HiKeyReservedMemoryBuffer[Index].Offset,
+                                  HiKeyReservedMemoryBuffer[Index].Size);
+      // Update the HOB
+      NextHob.ResourceDescriptor->ResourceLength = HiKeyReservedMemoryBuffer[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);
+  }
+
+  AdditionalMemorySize = MemorySize - PcdGet64 (PcdSystemMemorySize);
+  if (AdditionalMemorySize >= SIZE_1GB) {
+    // Declared the additional memory
+    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;
+
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      ResourceAttributes,
+      HIKEY_EXTRA_SYSTEM_MEMORY_BASE,
+      HIKEY_EXTRA_SYSTEM_MEMORY_SIZE);
+  }
+
+  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;
+
+  // Hi6220 SOC peripherals
+  VirtualMemoryTable[Index].PhysicalBase    = HI6220_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = HI6220_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length          = HI6220_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // DDR - predefined 1GB size
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // If DDR capacity is 2GB size, append a new entry to fill the gap.
+  if (AdditionalMemorySize >= SIZE_1GB) {
+    VirtualMemoryTable[++Index].PhysicalBase = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
+    VirtualMemoryTable[Index].VirtualBase    = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
+    VirtualMemoryTable[Index].Length         = HIKEY_EXTRA_SYSTEM_MEMORY_SIZE;
+    VirtualMemoryTable[Index].Attributes     = CacheAttributes;
+  }
+
+  // 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;
+}

+ 40 - 0
Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatform.c

@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2014, Applied Micro Curcuit Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+  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 <PiDxe.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/AcpiAml.h>
+#include "EthMac.h"
+
+EFI_STATUS
+EFIAPI
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  return EthMacInit();
+}

+ 72 - 0
Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf

@@ -0,0 +1,72 @@
+## @file
+#
+#  Copyright (c) 2014, Applied Micro Curcuit Corp. All rights reserved.<BR>
+#  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+#  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+#  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                      = AcpiPlatform
+  FILE_GUID                      = e0829681-e9fa-4117-a8d7-84efadff863d
+  MODULE_TYPE                    = DXE_DRIVER
+  #MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiPlatformEntryPoint
+
+[Sources]
+  AcpiPlatform.c
+  EthMac.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ShellPkg/ShellPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiLib
+  PcdLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  #UefiApplicationEntryPoint
+
+[Guids]
+  gShellVariableGuid                            # ALWAYS_CONSUMED
+  gArmMpCoreInfoGuid
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiSdtProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+  gHisiBoardNicProtocolGuid                           # PROTOCOL ALWAYS_CONSUMED
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol
+
+[Pcd]
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdGicDistributorBase
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+[Depex]
+  gEfiAcpiTableProtocolGuid AND gEfiAcpiSdtProtocolGuid AND gHisiBoardNicProtocolGuid
+

+ 508 - 0
Silicon/Hisilicon/Drivers/AcpiPlatformDxe/EthMac.c

@@ -0,0 +1,508 @@
+/** @file
+
+  Copyright (c) 2014, Applied Micro Curcuit Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+  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.
+
+  This driver is called to initialize the FW part of the PHY in preparation
+  for the OS.
+
+**/
+
+#include <Guid/ShellVariableGuid.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+
+#include <PiDxe.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/AcpiAml.h>
+
+#include <Protocol/HisiBoardNicProtocol.h>
+
+// Turn on debug message by enabling below define
+//#define ACPI_DEBUG
+
+#ifdef ACPI_DEBUG
+#define DBG(arg...) DEBUG((EFI_D_ERROR,## arg))
+#else
+#define DBG(arg...)
+#endif
+
+#define EFI_ACPI_MAX_NUM_TABLES         20
+#define DSDT_SIGNATURE                  0x54445344
+
+#define D02_ACPI_ETH_ID                     "HISI00C1"
+#define D03_ACPI_ETH_ID                     "HISI00C2"
+
+#define ACPI_ETH_MAC_KEY                "local-mac-address"
+
+#define PREFIX_VARIABLE_NAME            L"MAC"
+#define PREFIX_VARIABLE_NAME_COMPAT     L"RGMII_MAC"
+#define MAC_MAX_LEN                     30
+
+EFI_STATUS GetEnvMac(
+  IN          UINTN    MacNextID,
+  IN OUT      UINT8    *MacBuffer)
+{
+  EFI_MAC_ADDRESS Mac;
+  EFI_STATUS Status;
+  HISI_BOARD_NIC_PROTOCOL *OemNic = NULL;
+
+  Status = gBS->LocateProtocol(&gHisiBoardNicProtocolGuid, NULL, (VOID **)&OemNic);
+  if(EFI_ERROR(Status))
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol failed %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  Status = OemNic->GetMac(&Mac, MacNextID);
+  if(EFI_ERROR(Status))
+  {
+    DEBUG((EFI_D_ERROR, "[%a]:[%dL] GetMac failed %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  CopyMem (MacBuffer, &Mac, 6);
+  DEBUG((EFI_D_ERROR, "Port %d MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+        MacNextID,
+        MacBuffer[0],
+        MacBuffer[1],
+        MacBuffer[2],
+        MacBuffer[3],
+        MacBuffer[4],
+        MacBuffer[5]
+        ));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS _SearchReplacePackageMACAddress(
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiTableProtocol,
+  IN EFI_ACPI_HANDLE        ChildHandle,
+  IN UINTN                  Level,
+  IN OUT BOOLEAN            *Found,
+  IN UINTN                  MacNextID)
+{
+  // ASL template for ethernet driver:
+/*
+ *   Name (_DSD, Package () {
+ *   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *   Package () {
+ *     Package (2) {"mac-address", Package (6) { 00, 11, 22, 33, 44, 55 }}
+ *     Package (2) {"phy-channel", 0},
+ *     Package (2) {"phy-mode", "rgmii"},
+ *     Package (2) {"max-transfer-unit", 0x5dc},   // MTU of 1500
+ *     Package (2) {"max-speed", 0x3e8},            // 1000 Mbps
+ *   }
+ * })
+ */
+  EFI_STATUS          Status;
+  EFI_ACPI_DATA_TYPE  DataType;
+  CONST UINT8         *Data;
+  CONST VOID          *Buffer;
+  UINTN               DataSize;
+  UINTN               Count;
+  EFI_ACPI_HANDLE     CurrentHandle;
+  EFI_ACPI_HANDLE     NextHandle;
+  UINT8               MACBuffer[MAC_MAX_LEN];
+
+  DBG("In Level:%d\n", Level);
+  Status = EFI_SUCCESS;
+  for (CurrentHandle = NULL; ;) {
+    Status = AcpiTableProtocol->GetChild(ChildHandle, &CurrentHandle);
+    if (Level != 3 && (EFI_ERROR(Status) || CurrentHandle == NULL))
+       break;
+
+    Status = AcpiTableProtocol->GetOption(CurrentHandle, 0, &DataType, &Buffer, &DataSize);
+    Data = Buffer;
+    DBG("_DSD Child Subnode Store Op Code 0x%02X 0x%02X %02X\n",
+        DataSize, Data[0], DataSize > 1 ? Data[1] : 0);
+
+    if (Level < 2 && Data[0] != AML_PACKAGE_OP)
+      continue;
+
+    if (Level == 2 && Data[0] == AML_STRING_PREFIX) {
+      Status = AcpiTableProtocol->GetOption(CurrentHandle, 1, &DataType, &Buffer, &DataSize);
+      if (EFI_ERROR(Status))
+        break;
+
+      DBG("  _DSD Child Subnode Store Op Code 0x%02X 0x%02X %02X\n",
+              DataSize, Data[0], DataSize > 1 ? Data[1] : 0);
+
+      Data = Buffer;
+      if (DataType != EFI_ACPI_DATA_TYPE_STRING
+              || AsciiStrCmp((CHAR8 *) Data, ACPI_ETH_MAC_KEY) != 0)
+        continue;
+
+      DBG("_DSD Key Type %d. Found MAC address key\n", DataType);
+
+      //
+      // We found the node.
+      //
+      *Found = TRUE;
+      continue;
+    }
+
+    if (Level == 3 && *Found) {
+
+      //Update the MAC
+      Status = GetEnvMac(MacNextID, MACBuffer);
+      if (EFI_ERROR(Status))
+        break;
+
+      for (Count = 0; Count < 6; Count++) {
+        Status = AcpiTableProtocol->GetOption(CurrentHandle, 1, &DataType, &Buffer, &DataSize);
+        if (EFI_ERROR(Status))
+          break;
+
+        Data = Buffer;
+        DBG("    _DSD Child Subnode Store Op Code 0x%02X 0x%02X %02X DataType 0x%X\n",
+            DataSize, Data[0], DataSize > 1 ? Data[1] : 0, DataType);
+
+        if (DataType != EFI_ACPI_DATA_TYPE_UINT)
+          break;
+
+        // only need one byte.
+        // FIXME: Assume the CPU is little endian
+        Status = AcpiTableProtocol->SetOption(CurrentHandle, 1, (VOID *)&MACBuffer[Count], sizeof(UINT8));
+        if (EFI_ERROR(Status))
+          break;
+        Status = AcpiTableProtocol->GetChild(ChildHandle, &CurrentHandle);
+        if (EFI_ERROR(Status) || CurrentHandle == NULL)
+          break;
+      }
+      break;
+    }
+
+    if (Level > 3)
+      break;
+
+    //Search next package
+    AcpiTableProtocol->Open((VOID *) Buffer, &NextHandle);
+    Status = _SearchReplacePackageMACAddress(AcpiTableProtocol, NextHandle, Level + 1, Found, MacNextID);
+    AcpiTableProtocol->Close(NextHandle);
+    if (!EFI_ERROR(Status))
+      break;
+  }
+
+  return Status;
+}
+
+EFI_STATUS SearchReplacePackageMACAddress(
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiTableProtocol,
+  IN EFI_ACPI_HANDLE        ChildHandle,
+  IN UINTN                  MacNextID)
+{
+  BOOLEAN Found = FALSE;
+  UINTN Level = 0;
+
+  return _SearchReplacePackageMACAddress(AcpiTableProtocol, ChildHandle, Level, &Found, MacNextID);
+}
+
+EFI_STATUS
+GetEthID (
+  EFI_ACPI_SDT_PROTOCOL   *AcpiTableProtocol,
+  EFI_ACPI_HANDLE         ChildHandle,
+  UINTN                   *EthID
+  )
+{
+  EFI_STATUS Status;
+  EFI_ACPI_DATA_TYPE  DataType;
+  CHAR8               Data[5];
+  CONST VOID          *Buffer;
+  UINTN               DataSize;
+
+  // Get NameString ETHx
+  Status = AcpiTableProtocol->GetOption (ChildHandle, 1, &DataType, &Buffer, &DataSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "[%a:%d] Get NameString failed: %r\n", __FUNCTION__, __LINE__, Status));
+    return Status;
+  }
+
+  CopyMem (Data, Buffer, 4);
+  DBG("Size %p Data %02x %02x %02x %02x\n", DataSize, Data[0], Data[1], Data[2], Data[3]);
+
+  Data[4] = '\0';
+  if (DataSize != 4 ||
+      AsciiStrnCmp ("ETH", Data, 3) != 0 ||
+      Data[3] > '9' || Data[3] < '0') {
+    DEBUG ((EFI_D_ERROR, "[%a:%d] The NameString %a is not ETHn\n", __FUNCTION__, __LINE__, Data));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *EthID = Data[3] - '0';
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS ProcessDSDTDevice (
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
+  EFI_ACPI_HANDLE ChildHandle)
+{
+  EFI_STATUS          Status;
+  EFI_ACPI_DATA_TYPE  DataType;
+  CONST UINT8         *Data;
+  CONST VOID          *Buffer;
+  UINTN               DataSize;
+  EFI_ACPI_HANDLE     DevHandle;
+  INTN                Found = 0;
+  UINTN               MacNextID;
+
+  Status = AcpiTableProtocol->GetOption(ChildHandle, 0, &DataType, &Buffer, &DataSize);
+  if (EFI_ERROR(Status))
+    return EFI_SUCCESS;
+
+  Data = Buffer;
+  //
+  // Skip all non-device type
+  //
+  if (DataSize != 2 || Data[0] != AML_EXT_OP || Data[1] != AML_EXT_DEVICE_OP)
+    return EFI_SUCCESS;
+
+  //
+  // Walk the device type node
+  //
+  for (DevHandle = NULL; ; ) {
+    Status = AcpiTableProtocol->GetChild(ChildHandle, &DevHandle);
+    if (EFI_ERROR(Status) || DevHandle == NULL)
+      break;
+
+    //
+    // Search for _HID with Ethernet ID
+    //
+    Status = AcpiTableProtocol->GetOption(DevHandle, 0, &DataType, &Buffer, &DataSize);
+    if (EFI_ERROR(Status))
+      break;
+
+    Data = Buffer;
+    DBG("Data Type 0x%02X %02X\n", Data[0], DataSize > 1 ? Data[1] : 0);
+    if (DataSize == 1 && Data[0] == AML_NAME_OP) {
+      Status = AcpiTableProtocol->GetOption(DevHandle, 1, &DataType, &Buffer, &DataSize);
+      if (EFI_ERROR(Status))
+        break;
+
+      Data = Buffer;
+      if (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING) {
+        if (AsciiStrnCmp((CHAR8 *) Data, "_HID", 4) == 0) {
+          EFI_ACPI_HANDLE ValueHandle;
+
+          Status = AcpiTableProtocol->GetOption(DevHandle, 2, &DataType, &Buffer, &DataSize);
+          if (EFI_ERROR(Status))
+            break;
+
+          if (DataType != EFI_ACPI_DATA_TYPE_CHILD)
+            continue;
+
+          AcpiTableProtocol->Open((VOID *) Buffer, &ValueHandle);
+          Status = AcpiTableProtocol->GetOption(ValueHandle, 1, &DataType, &Buffer, &DataSize);
+
+          Data = Buffer;
+          DBG("[%a:%d] - _HID = %a\n", __FUNCTION__, __LINE__, Data);
+
+          if (EFI_ERROR(Status) ||
+              DataType != EFI_ACPI_DATA_TYPE_STRING ||
+              ((AsciiStrCmp((CHAR8 *) Data, D02_ACPI_ETH_ID) != 0) &&
+              (AsciiStrCmp((CHAR8 *) Data, D03_ACPI_ETH_ID) != 0))) {
+            AcpiTableProtocol->Close(ValueHandle);
+            Found = 0;
+            continue;
+          }
+
+          DBG("Found Ethernet device\n");
+          AcpiTableProtocol->Close(ValueHandle);
+          Status = GetEthID (AcpiTableProtocol, ChildHandle, &MacNextID);
+          if (EFI_ERROR (Status)) {
+            continue;
+          }
+          Found = 1;
+        } else if (Found == 1 && AsciiStrnCmp((CHAR8 *) Data, "_DSD", 4) == 0) {
+          //
+          // Patch MAC address for open source kernel
+          //
+          EFI_ACPI_HANDLE    PkgHandle;
+          Status = AcpiTableProtocol->GetOption(DevHandle, 2, &DataType, &Buffer, &DataSize);
+          if (EFI_ERROR(Status))
+            break;
+
+          if (DataType != EFI_ACPI_DATA_TYPE_CHILD)
+            continue;
+
+          //
+          // Open package data
+          //
+          AcpiTableProtocol->Open((VOID *) Buffer, &PkgHandle);
+          Status = AcpiTableProtocol->GetOption(PkgHandle, 0, &DataType, &Buffer, &DataSize);
+
+          Data = Buffer;
+          DBG("_DSD Subnode Store Op Code 0x%02X %02X\n",
+                Data[0], DataSize > 1 ? Data[1] : 0);
+
+          //
+          // Walk the _DSD node
+          //
+          if (DataSize == 1 && Data[0] == AML_PACKAGE_OP)
+            Status = SearchReplacePackageMACAddress(AcpiTableProtocol, PkgHandle, MacNextID);
+
+          AcpiTableProtocol->Close(PkgHandle);
+        }
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+BOOLEAN
+IsSbScope (
+  EFI_ACPI_SDT_PROTOCOL   *AcpiTableProtocol,
+  EFI_ACPI_HANDLE         ChildHandle
+  )
+{
+  EFI_STATUS          Status;
+  EFI_ACPI_DATA_TYPE  DataType;
+  CONST UINT8         *Data;
+  CONST VOID          *Buffer;
+  UINTN               DataSize;
+
+  Status = AcpiTableProtocol->GetOption (ChildHandle, 0, &DataType, &Buffer, &DataSize);
+  if (EFI_ERROR(Status)) return FALSE;
+
+  Data = Buffer;
+  if (DataSize != 1 || Data[0] != AML_SCOPE_OP) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+EFI_STATUS ProcessDSDTChild(
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
+  EFI_ACPI_HANDLE ChildHandle)
+{
+  EFI_STATUS          Status;
+  EFI_ACPI_HANDLE     DevHandle;
+
+  // Check Scope(_SB) at first
+  if (!IsSbScope (AcpiTableProtocol, ChildHandle)) {
+    return ProcessDSDTDevice (AcpiTableProtocol, ChildHandle);
+  }
+
+  for (DevHandle = NULL; ; ) {
+    Status = AcpiTableProtocol->GetChild (ChildHandle, &DevHandle);
+    if (EFI_ERROR(Status) || DevHandle == NULL) {
+      break;
+    }
+
+    ProcessDSDTDevice (AcpiTableProtocol, DevHandle);
+  }
+
+  return EFI_SUCCESS;
+}
+
+static EFI_STATUS ProcessDSDT(
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
+  EFI_ACPI_HANDLE TableHandle)
+{
+  EFI_STATUS              Status;
+  EFI_ACPI_HANDLE         ChildHandle;
+  //
+  // Parse table for device type
+  DBG ("[%a:%d] - TableHandle=%p\n", __FUNCTION__, __LINE__, TableHandle);
+  for (ChildHandle = NULL; ; ) {
+    Status = AcpiTableProtocol->GetChild(TableHandle, &ChildHandle);
+    DBG ("[%a:%d] - Child=%p, %r\n", __FUNCTION__, __LINE__, ChildHandle, Status);
+    if (EFI_ERROR(Status))
+      break;
+    if (ChildHandle == NULL)
+      break;
+
+    ProcessDSDTChild(AcpiTableProtocol, ChildHandle);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+AcpiCheckSum (
+  IN OUT  EFI_ACPI_SDT_HEADER *Table
+  )
+{
+  UINTN ChecksumOffset;
+  UINT8 *Buffer;
+
+  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
+  Buffer = (UINT8 *)Table;
+
+  //
+  // set checksum to 0 first
+  //
+  Buffer[ChecksumOffset] = 0;
+
+  //
+  // Update checksum value
+  //
+  Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Table->Length);
+}
+
+EFI_STATUS EthMacInit(void)
+{
+  EFI_STATUS              Status;
+  EFI_ACPI_SDT_PROTOCOL   *AcpiTableProtocol;
+  EFI_ACPI_SDT_HEADER     *Table;
+  EFI_ACPI_TABLE_VERSION  TableVersion;
+  UINTN                   TableKey;
+  EFI_ACPI_HANDLE         TableHandle;
+  UINTN                   i;
+
+  DEBUG ((EFI_D_ERROR, "Updating Ethernet MAC in ACPI DSDT...\n"));
+
+  //
+  // Find the AcpiTable protocol
+  Status = gBS->LocateProtocol(&gEfiAcpiSdtProtocolGuid, NULL, (VOID**) &AcpiTableProtocol);
+  if (EFI_ERROR(Status)) {
+    DBG("Unable to locate ACPI table protocol\n");
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Search for DSDT Table
+  for (i = 0; i < EFI_ACPI_MAX_NUM_TABLES; i++) {
+    Status = AcpiTableProtocol->GetAcpiTable(i, &Table, &TableVersion, &TableKey);
+    if (EFI_ERROR(Status))
+      break;
+    if (Table->Signature != DSDT_SIGNATURE)
+      continue;
+
+    Status = AcpiTableProtocol->OpenSdt(TableKey, &TableHandle);
+    if (EFI_ERROR(Status))
+      break;
+
+    ProcessDSDT(AcpiTableProtocol, TableHandle);
+
+    AcpiTableProtocol->Close(TableHandle);
+    AcpiCheckSum (Table);
+  }
+
+  return EFI_SUCCESS;
+}

+ 22 - 0
Silicon/Hisilicon/Drivers/AcpiPlatformDxe/EthMac.h

@@ -0,0 +1,22 @@
+/*
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+ * Copyright (c) 2015, Linaro Limited. All rights reserved.
+ * Author: Loc Ho <lho@apm.com>
+ *
+ * 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 _ETH_MAC_H_
+#define _ETH_MAC_H_
+
+EFI_STATUS EthMacInit(VOID);
+
+#endif
+

+ 109 - 0
Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashBlockIoDxe.c

@@ -0,0 +1,109 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 "FlashFvbDxe.h"
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoReadBlocks (
+    IN  EFI_BLOCK_IO_PROTOCOL*     This,
+    IN  UINT32                  MediaId,
+    IN  EFI_LBA                     Lba,
+    IN  UINTN         BufferSizeInBytes,
+    OUT VOID*                     Buffer
+)
+{
+    FLASH_INSTANCE*   Instance;
+    EFI_STATUS          Status;
+
+    Instance = INSTANCE_FROM_BLKIO_THIS(This);
+
+    DEBUG ((EFI_D_INFO, "FlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
+
+    if ( !This->Media->MediaPresent )
+    {
+        Status = EFI_NO_MEDIA;
+    }
+    else if ( This->Media->MediaId != MediaId )
+    {
+        Status = EFI_MEDIA_CHANGED;
+    }
+    else
+    {
+        Status = FlashReadBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
+    }
+
+    return Status;
+}
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoWriteBlocks (
+    IN  EFI_BLOCK_IO_PROTOCOL*     This,
+    IN  UINT32                  MediaId,
+    IN  EFI_LBA                     Lba,
+    IN  UINTN         BufferSizeInBytes,
+    IN  VOID*                     Buffer
+)
+{
+    FLASH_INSTANCE*   Instance;
+    EFI_STATUS          Status;
+
+    Instance = INSTANCE_FROM_BLKIO_THIS(This);
+
+    DEBUG ((EFI_D_INFO, "FlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
+
+    if ( !This->Media->MediaPresent )
+    {
+        Status = EFI_NO_MEDIA;
+    }
+    else if ( This->Media->MediaId != MediaId )
+    {
+        Status = EFI_MEDIA_CHANGED;
+    }
+    else if ( This->Media->ReadOnly )
+    {
+        Status = EFI_WRITE_PROTECTED;
+    }
+    else
+    {
+        Status = FlashWriteBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
+    }
+
+    return Status;
+}
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoFlushBlocks (
+    IN EFI_BLOCK_IO_PROTOCOL*  This
+)
+{
+    // No Flush required for the NOR Flash driver
+    // because cache operations are not permitted.
+
+    // Nothing to do so just return without error
+    return EFI_SUCCESS;
+}

+ 1243 - 0
Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.c

@@ -0,0 +1,1243 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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.
+*
+* Based on files under ArmPlatformPkg/Drivers/NorFlashDxe/
+**/
+
+#include "FlashFvbDxe.h"
+STATIC EFI_EVENT mFlashFvbVirtualAddrChangeEvent;
+STATIC UINTN     mFlashNvStorageVariableBase;
+
+
+//
+// Global variable declarations
+//
+
+FLASH_DESCRIPTION mFlashDevices[FLASH_DEVICE_COUNT] =
+{
+    {
+        // UEFI Variable Services non-volatile storage
+        0xa4000000,
+        FixedPcdGet32(PcdFlashNvStorageVariableBase),
+        0x20000,
+        SIZE_64KB,
+        {0xCC2CBF29, 0x1498, 0x4CDD, {0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09}}
+    }
+
+};
+
+FLASH_INSTANCE** mFlashInstances;
+
+FLASH_INSTANCE  mFlashInstanceTemplate =
+{
+    FLASH_SIGNATURE, // Signature
+    NULL, // Handle ... NEED TO BE FILLED
+
+    FALSE, // Initialized
+    NULL, // Initialize
+
+    0, // DeviceBaseAddress ... NEED TO BE FILLED
+    0, // RegionBaseAddress ... NEED TO BE FILLED
+    0, // Size ... NEED TO BE FILLED
+    0, // StartLba
+
+    {
+        EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
+        NULL, // Media ... NEED TO BE FILLED
+        NULL, //NorFlashBlockIoReset
+        FlashBlockIoReadBlocks,
+        FlashBlockIoWriteBlocks,
+        FlashBlockIoFlushBlocks
+    }, // BlockIoProtocol
+
+    {
+        0, // MediaId ... NEED TO BE FILLED
+        FALSE, // RemovableMedia
+        TRUE, // MediaPresent
+        FALSE, // LogicalPartition
+        FALSE, // ReadOnly
+        FALSE, // WriteCaching;
+        SIZE_64KB, // BlockSize ... NEED TO BE FILLED
+        4, //  IoAlign
+        0, // LastBlock ... NEED TO BE FILLED
+        0, // LowestAlignedLba
+        1, // LogicalBlocksPerPhysicalBlock
+    }, //Media;
+
+    FALSE, // SupportFvb ... NEED TO BE FILLED
+    {
+        FvbGetAttributes,
+        FvbSetAttributes,
+        FvbGetPhysicalAddress,
+        FvbGetBlockSize,
+        FvbRead,
+        FvbWrite,
+        FvbEraseBlocks,
+        NULL, //ParentHandle
+    }, //  FvbProtoccol;
+
+    {
+        {
+            {
+                HARDWARE_DEVICE_PATH,
+                HW_VENDOR_DP,
+                {(UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+                (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)},
+            },
+            { 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}, // GUID ... NEED TO BE FILLED
+        },
+        {
+            END_DEVICE_PATH_TYPE,
+            END_ENTIRE_DEVICE_PATH_SUBTYPE,
+            {sizeof (EFI_DEVICE_PATH_PROTOCOL),
+            0}
+        }
+    } // DevicePath
+};
+
+HISI_SPI_FLASH_PROTOCOL* mFlash;
+
+///
+/// The Firmware Volume Block Protocol is the low-level interface
+/// to a firmware volume. File-level access to a firmware volume
+/// should not be done using the Firmware Volume Block Protocol.
+/// Normal access to a firmware volume must use the Firmware
+/// Volume Protocol. Typically, only the file system driver that
+/// produces the Firmware Volume Protocol will bind to the
+/// Firmware Volume Block Protocol.
+///
+
+/**
+  Initialises the FV Header and Variable Store Header
+  to support variable operations.
+
+  @param[in]  Ptr - Location to initialise the headers
+
+**/
+EFI_STATUS
+InitializeFvAndVariableStoreHeaders (
+    IN FLASH_INSTANCE* Instance
+)
+{
+    EFI_STATUS                          Status;
+    VOID*                               Headers;
+    UINTN                               HeadersLength;
+    EFI_FIRMWARE_VOLUME_HEADER*          FirmwareVolumeHeader;
+    VARIABLE_STORE_HEADER*               VariableStoreHeader;
+
+    if (!Instance->Initialized && Instance->Initialize)
+    {
+        Instance->Initialize (Instance);
+    }
+
+    HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
+    Headers = AllocateZeroPool(HeadersLength);
+
+    // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous.
+    ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase));
+    ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase));
+
+    // Check if the size of the area is at least one block size
+    ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && ((UINT32)PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0));
+    ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && ((UINT32)PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0));
+    ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && ((UINT32)PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0));
+
+    // Ensure the Variable area Base Addresses are aligned on a block size boundaries
+    ASSERT((UINT32)PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0);
+    ASSERT((UINT32)PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0);
+    ASSERT((UINT32)PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);
+
+    //
+    // EFI_FIRMWARE_VOLUME_HEADER
+    //
+    FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
+    CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
+    FirmwareVolumeHeader->FvLength =
+        PcdGet32(PcdFlashNvStorageVariableSize) +
+        PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
+        PcdGet32(PcdFlashNvStorageFtwSpareSize);
+    FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
+    FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
+                                           EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
+                                           EFI_FVB2_READ_STATUS        | // Reads are currently enabled
+                                           EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+                                           EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
+                                           EFI_FVB2_ERASE_POLARITY     | // After erasure all bits take this value (i.e. '1')
+                                           EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
+                                           EFI_FVB2_WRITE_ENABLED_CAP    // Writes may be enabled
+                                       );
+    FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY);
+    FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
+    FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1;
+    FirmwareVolumeHeader->BlockMap[0].Length      = Instance->Media.BlockSize;
+    FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
+    FirmwareVolumeHeader->BlockMap[1].Length      = 0;
+    FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
+
+    //
+    // VARIABLE_STORE_HEADER
+    //
+    VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + (UINTN)FirmwareVolumeHeader->HeaderLength);
+    CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
+    VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
+    VariableStoreHeader->Format            = VARIABLE_STORE_FORMATTED;
+    VariableStoreHeader->State             = VARIABLE_STORE_HEALTHY;
+
+    // Install the combined super-header in the NorFlash
+    Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);
+
+    FreePool (Headers);
+    return Status;
+}
+
+/**
+  Check the integrity of firmware volume header.
+
+  @param[in] FwVolHeader - A pointer to a firmware volume header
+
+  @retval  EFI_SUCCESS   - The firmware volume is consistent
+  @retval  EFI_NOT_FOUND - The firmware volume has been corrupted.
+
+**/
+EFI_STATUS
+ValidateFvHeader (
+    IN  FLASH_INSTANCE* Instance
+)
+{
+    UINT16                      Checksum;
+    EFI_FIRMWARE_VOLUME_HEADER* FwVolHeader;
+    VARIABLE_STORE_HEADER*      VariableStoreHeader;
+    UINTN                       VariableStoreLength;
+    UINTN                       FvLength;
+
+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->RegionBaseAddress;
+
+    FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
+               PcdGet32(PcdFlashNvStorageFtwSpareSize);
+
+    //
+    // Verify the header revision, header signature, length
+    // Length of FvBlock cannot be 2**64-1
+    // HeaderLength cannot be an odd number
+    //
+    if (   (FwVolHeader->Revision  != EFI_FVH_REVISION)
+           || (FwVolHeader->Signature != EFI_FVH_SIGNATURE)
+           || (FwVolHeader->FvLength  != FvLength)
+       )
+    {
+        DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n"));
+        return EFI_NOT_FOUND;
+    }
+
+    // Check the Firmware Volume Guid
+    if ( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE )
+    {
+        DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n"));
+        return EFI_NOT_FOUND;
+    }
+
+    // Verify the header checksum
+    Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength);
+    if (Checksum != 0)
+    {
+        DEBUG ((EFI_D_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n", Checksum));
+        return EFI_NOT_FOUND;
+    }
+
+    VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + (UINTN)FwVolHeader->HeaderLength);
+
+    // Check the Variable Store Guid
+    if ( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE )
+    {
+        DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Guid non-compatible\n"));
+        return EFI_NOT_FOUND;
+    }
+
+    VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
+    if (VariableStoreHeader->Size != VariableStoreLength)
+    {
+        DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Length does not match\n"));
+        return EFI_NOT_FOUND;
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+ The FvbGetAttributes() function retrieves the attributes and
+ current settings of the block.
+
+ @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes   Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and
+                     current settings are returned.
+                     Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were returned.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetAttributes(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*    This,
+    OUT       EFI_FVB_ATTRIBUTES_2*                   Attributes
+)
+{
+    EFI_FVB_ATTRIBUTES_2  FlashFvbAttributes;
+    FLASH_INSTANCE*                 Instance;
+
+    Instance = INSTANCE_FROM_FVB_THIS(This);
+
+    FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) (
+
+                             EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
+                             EFI_FVB2_READ_STATUS      | // Reads are currently enabled
+                             EFI_FVB2_STICKY_WRITE     | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+                             EFI_FVB2_MEMORY_MAPPED    | // It is memory mapped
+                             EFI_FVB2_ERASE_POLARITY     // After erasure all bits take this value (i.e. '1')
+
+                         );
+
+    // Check if it is write protected
+    if (Instance->Media.ReadOnly != TRUE)
+    {
+
+        FlashFvbAttributes = FlashFvbAttributes         |
+                             EFI_FVB2_WRITE_STATUS      | // Writes are currently enabled
+                             EFI_FVB2_WRITE_ENABLED_CAP;  // Writes may be enabled
+    }
+
+    *Attributes = FlashFvbAttributes;
+
+    return EFI_SUCCESS;
+}
+
+/**
+ The FvbSetAttributes() function sets configurable firmware volume attributes
+ and returns the new settings of the firmware volume.
+
+
+ @param This                     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes               On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2
+                                 that contains the desired firmware volume settings.
+                                 On successful return, it contains the new settings of
+                                 the firmware volume.
+                                 Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS             The firmware volume attributes were returned.
+
+ @retval EFI_INVALID_PARAMETER   The attributes requested are in conflict with the capabilities
+                                 as declared in the firmware volume header.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*  This,
+    IN OUT    EFI_FVB_ATTRIBUTES_2*                 Attributes
+)
+{
+    DEBUG ((EFI_D_ERROR, "FvbSetAttributes(0x%X) is not supported\n", *Attributes));
+    return EFI_UNSUPPORTED;
+}
+
+/**
+ The GetPhysicalAddress() function retrieves the base address of
+ a memory-mapped firmware volume. This function should be called
+ only for memory-mapped firmware volumes.
+
+ @param This               Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Address            Pointer to a caller-allocated
+                           EFI_PHYSICAL_ADDRESS that, on successful
+                           return from GetPhysicalAddress(), contains the
+                           base address of the firmware volume.
+
+ @retval EFI_SUCCESS       The firmware volume base address was returned.
+
+ @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*  This,
+    OUT       EFI_PHYSICAL_ADDRESS*                 Address
+)
+{
+
+    if(NULL == Address)
+    {
+        return EFI_UNSUPPORTED;
+    };
+
+    *Address = mFlashNvStorageVariableBase;
+    return EFI_SUCCESS;
+}
+
+/**
+ The GetBlockSize() function retrieves the size of the requested
+ block. It also returns the number of additional blocks with
+ the identical size. The GetBlockSize() function is used to
+ retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+ @param This                     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba                      Indicates the block for which to return the size.
+
+ @param BlockSize                Pointer to a caller-allocated UINTN in which
+                                 the size of the block is returned.
+
+ @param NumberOfBlocks           Pointer to a caller-allocated UINTN in
+                                 which the number of consecutive blocks,
+                                 starting with Lba, is returned. All
+                                 blocks in this range have a size of
+                                 BlockSize.
+
+
+ @retval EFI_SUCCESS             The firmware volume base address was returned.
+
+ @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*  This,
+    IN        EFI_LBA                              Lba,
+    OUT       UINTN*                                BlockSize,
+    OUT       UINTN*                                NumberOfBlocks
+)
+{
+    EFI_STATUS Status;
+    FLASH_INSTANCE* Instance;
+
+    Instance = INSTANCE_FROM_FVB_THIS(This);
+
+    if (Lba > Instance->Media.LastBlock)
+    {
+        Status = EFI_INVALID_PARAMETER;
+    }
+    else
+    {
+        // This is easy because in this platform each NorFlash device has equal sized blocks.
+        *BlockSize = (UINTN) Instance->Media.BlockSize;
+        *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1);
+
+
+        Status = EFI_SUCCESS;
+    }
+
+    return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+FvbReset(
+  IN EFI_BLOCK_IO_PROTOCOL *This,
+  IN BOOLEAN                ExtendedVerification
+)
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+ Reads the specified number of bytes into a buffer from the specified block.
+
+ The Read() function reads the requested number of bytes from the
+ requested block and stores them in the provided buffer.
+ Implementations should be mindful that the firmware volume
+ might be in the ReadDisabled state. If it is in this state,
+ the Read() function must return the status code
+ EFI_ACCESS_DENIED without modifying the contents of the
+ buffer. The Read() function must also prevent spanning block
+ boundaries. If a read is requested that would span a block
+ boundary, the read must read up to the boundary but not
+ beyond. The output parameter NumBytes must be set to correctly
+ indicate the number of bytes actually read. The caller must be
+ aware that a read may be partially completed.
+
+ @param This                 Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba                  The starting logical block index from which to read.
+
+ @param Offset               Offset into the block at which to begin reading.
+
+ @param NumBytes             Pointer to a UINTN.
+                             At entry, *NumBytes contains the total size of the buffer.
+                             At exit, *NumBytes contains the total number of bytes read.
+
+ @param Buffer               Pointer to a caller-allocated buffer that will be used
+                             to hold the data that is read.
+
+ @retval EFI_SUCCESS         The firmware volume was read successfully,  and contents are
+                             in Buffer.
+
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary.
+                             On output, NumBytes contains the total number of bytes
+                             returned in Buffer.
+
+ @retval EFI_ACCESS_DENIED   The firmware volume is in the ReadDisabled state.
+
+ @retval EFI_DEVICE_ERROR    The block device is not functioning correctly and could not be read.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbRead (
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*   This,
+    IN        EFI_LBA                               Lba,
+    IN        UINTN                                 Offset,
+    IN OUT    UINTN*                                 NumBytes,
+    IN OUT    UINT8*                                 Buffer
+)
+{
+    EFI_STATUS                    Status;
+    UINTN                      BlockSize;
+    FLASH_INSTANCE*             Instance;
+
+    UINTN                   StartAddress;
+    UINTN                    ReadAddress;
+
+    Instance = INSTANCE_FROM_FVB_THIS(This);
+
+    if (!Instance->Initialized && Instance->Initialize)
+    {
+        if (EfiAtRuntime ()) {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL] Initialize at runtime is not supported!\n", __FUNCTION__, __LINE__));
+            return EFI_UNSUPPORTED;
+        }
+
+        Instance->Initialize(Instance);
+    }
+
+    Status = EFI_SUCCESS;
+
+    // Cache the block size to avoid de-referencing pointers all the time
+    BlockSize = Instance->Media.BlockSize;
+
+    // The read must not span block boundaries.
+    // We need to check each variable individually because adding two large values together overflows.
+    if ((Offset               >= BlockSize) ||
+        (*NumBytes            >  BlockSize) ||
+        ((Offset + *NumBytes) >  BlockSize))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL] ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", __FUNCTION__, __LINE__, Offset, *NumBytes, BlockSize ));
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // We must have some bytes to read
+    if (*NumBytes == 0)
+    {
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // Get the address to start reading from
+    StartAddress = GET_BLOCK_ADDRESS (Instance->RegionBaseAddress,
+                                      Lba,
+                                      BlockSize
+                                     );
+    ReadAddress = StartAddress - Instance->DeviceBaseAddress + Offset;
+
+    Status = mFlash->Read(mFlash, (UINT32)ReadAddress, Buffer, *NumBytes);
+    if (EFI_SUCCESS != Status)
+    {
+        // Return one of the pre-approved error statuses
+        Status = EFI_DEVICE_ERROR;
+        return Status;
+    }
+
+
+    return Status;
+}
+
+/**
+ Writes the specified number of bytes from the input buffer to the block.
+
+ The Write() function writes the specified number of bytes from
+ the provided buffer to the specified block and offset. If the
+ firmware volume is sticky write, the caller must ensure that
+ all the bits of the specified range to write are in the
+ EFI_FVB_ERASE_POLARITY state before calling the Write()
+ function, or else the result will be unpredictable. This
+ unpredictability arises because, for a sticky-write firmware
+ volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+ state but cannot flip it back again.  Before calling the
+ Write() function,  it is recommended for the caller to first call
+ the EraseBlocks() function to erase the specified block to
+ write. A block erase cycle will transition bits from the
+ (NOT)EFI_FVB_ERASE_POLARITY state back to the
+ EFI_FVB_ERASE_POLARITY state. Implementations should be
+ mindful that the firmware volume might be in the WriteDisabled
+ state. If it is in this state, the Write() function must
+ return the status code EFI_ACCESS_DENIED without modifying the
+ contents of the firmware volume. The Write() function must
+ also prevent spanning block boundaries. If a write is
+ requested that spans a block boundary, the write must store up
+ to the boundary but not beyond. The output parameter NumBytes
+ must be set to correctly indicate the number of bytes actually
+ written. The caller must be aware that a write may be
+ partially completed. All writes, partial or otherwise, must be
+ fully flushed to the hardware before the Write() service
+ returns.
+
+ @param This                 Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba                  The starting logical block index to write to.
+
+ @param Offset               Offset into the block at which to begin writing.
+
+ @param NumBytes             The pointer to a UINTN.
+                             At entry, *NumBytes contains the total size of the buffer.
+                             At exit, *NumBytes contains the total number of bytes actually written.
+
+ @param Buffer               The pointer to a caller-allocated buffer that contains the source for the write.
+
+ @retval EFI_SUCCESS         The firmware volume was written successfully.
+
+ @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.
+                             On output, NumBytes contains the total number of bytes
+                             actually written.
+
+ @retval EFI_ACCESS_DENIED   The firmware volume is in the WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR    The block device is malfunctioning and could not be written.
+
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*   This,
+    IN        EFI_LBA                               Lba,
+    IN        UINTN                                 Offset,
+    IN OUT    UINTN*                                 NumBytes,
+    IN        UINT8*                                 Buffer
+)
+{
+    EFI_STATUS                     Status;
+    UINTN                       BlockSize;
+    FLASH_INSTANCE*              Instance;
+    UINTN                    BlockAddress;
+    UINTN                    WriteAddress;
+
+    Instance = INSTANCE_FROM_FVB_THIS(This);
+    if (NULL == Instance)
+    {
+        return EFI_INVALID_PARAMETER;
+
+    }
+
+    if (!Instance->Initialized && Instance->Initialize)
+    {
+        if (EfiAtRuntime ()) {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL] Initialize at runtime is not supported!\n", __FUNCTION__, __LINE__));
+            return EFI_UNSUPPORTED;
+        }
+
+        Instance->Initialize(Instance);
+    }
+
+    Status = EFI_SUCCESS;
+
+    // Detect WriteDisabled state
+    if (Instance->Media.ReadOnly == TRUE)
+    {
+        DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not write: Device is in WriteDisabled state.\n"));
+        // It is in WriteDisabled state, return an error right away
+        return EFI_ACCESS_DENIED;
+    }
+
+    // Cache the block size to avoid de-referencing pointers all the time
+    BlockSize = Instance->Media.BlockSize;
+
+    // The write must not span block boundaries.
+    // We need to check each variable individually because adding two large values together overflows.
+    if ( ( Offset               >= BlockSize ) ||
+         ( *NumBytes            >  BlockSize ) ||
+         ( (Offset + *NumBytes) >  BlockSize )    )
+    {
+        DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // We must have some bytes to write
+    if (*NumBytes == 0)
+    {
+        DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    BlockAddress = GET_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSize);
+    WriteAddress = BlockAddress - Instance->DeviceBaseAddress + Offset;
+
+    Status = mFlash->Write(mFlash, (UINT32)WriteAddress, (UINT8*)Buffer, *NumBytes);
+    if (EFI_SUCCESS != Status)
+    {
+        DEBUG((EFI_D_ERROR, "%s - %d Status=%r\n", __FILE__, __LINE__, Status));
+        return Status;
+    }
+
+    return Status;
+
+}
+
+/**
+ Erases and initialises a firmware volume block.
+
+ The EraseBlocks() function erases one or more blocks as denoted
+ by the variable argument list. The entire parameter list of
+ blocks must be verified before erasing any blocks. If a block is
+ requested that does not exist within the associated firmware
+ volume (it has a larger index than the last block of the
+ firmware volume), the EraseBlocks() function must return the
+ status code EFI_INVALID_PARAMETER without modifying the contents
+ of the firmware volume. Implementations should be mindful that
+ the firmware volume might be in the WriteDisabled state. If it
+ is in this state, the EraseBlocks() function must return the
+ status code EFI_ACCESS_DENIED without modifying the contents of
+ the firmware volume. All calls to EraseBlocks() must be fully
+ flushed to the hardware before the EraseBlocks() service
+ returns.
+
+ @param This                     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+ instance.
+
+ @param ...                      The variable argument list is a list of tuples.
+                                 Each tuple describes a range of LBAs to erase
+                                 and consists of the following:
+                                 - An EFI_LBA that indicates the starting LBA
+                                 - A UINTN that indicates the number of blocks to erase.
+
+                                 The list is terminated with an EFI_LBA_LIST_TERMINATOR.
+                                 For example, the following indicates that two ranges of blocks
+                                 (5-7 and 10-11) are to be erased:
+                                 EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+ @retval EFI_SUCCESS             The erase request successfully completed.
+
+ @retval EFI_ACCESS_DENIED       The firmware volume is in the WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR        The block device is not functioning correctly and could not be written.
+                                 The firmware device may have been partially erased.
+
+ @retval EFI_INVALID_PARAMETER   One or more of the LBAs listed in the variable argument list do
+                                 not exist in the firmware volume.
+
+ **/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+    IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL* This,
+    ...
+)
+{
+    EFI_STATUS  Status;
+    VA_LIST     Args;
+    UINTN       BlockAddress; // Physical address of Lba to erase
+    EFI_LBA     StartingLba; // Lba from which we start erasing
+    UINTN       NumOfLba; // Number of Lba blocks to erase
+    FLASH_INSTANCE* Instance;
+
+    Instance = INSTANCE_FROM_FVB_THIS(This);
+
+    Status = EFI_SUCCESS;
+
+    // Detect WriteDisabled state
+    if (Instance->Media.ReadOnly == TRUE)
+    {
+        // Firmware volume is in WriteDisabled state
+        return EFI_ACCESS_DENIED;
+    }
+
+    // Before erasing, check the entire list of parameters to ensure all specified blocks are valid
+    VA_START (Args, This);
+    do
+    {
+        // Get the Lba from which we start erasing
+        StartingLba = VA_ARG (Args, EFI_LBA);
+
+        // Have we reached the end of the list?
+        if (StartingLba == EFI_LBA_LIST_TERMINATOR)
+        {
+            //Exit the while loop
+            break;
+        }
+
+        // How many Lba blocks are we requested to erase?
+        NumOfLba = VA_ARG (Args, UINT32);
+
+        // All blocks must be within range
+        if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->Media.LastBlock))
+        {
+            VA_END (Args);
+            Status = EFI_INVALID_PARAMETER;
+            goto EXIT;
+        }
+    }
+    while (TRUE);
+    VA_END (Args);
+
+    //
+    // To get here, all must be ok, so start erasing
+    //
+    VA_START (Args, This);
+    do
+    {
+        // Get the Lba from which we start erasing
+        StartingLba = VA_ARG (Args, EFI_LBA);
+
+        // Have we reached the end of the list?
+        if (StartingLba == EFI_LBA_LIST_TERMINATOR)
+        {
+            // Exit the while loop
+            break;
+        }
+
+        // How many Lba blocks are we requested to erase?
+        NumOfLba = VA_ARG (Args, UINT32);
+
+        // Go through each one and erase it
+        while (NumOfLba > 0)
+        {
+
+            // Get the physical address of Lba to erase
+            BlockAddress = GET_BLOCK_ADDRESS (
+                               Instance->RegionBaseAddress,
+                               Instance->StartLba + StartingLba,
+                               Instance->Media.BlockSize
+                           );
+
+            // Erase it
+
+            Status = FlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
+            if (EFI_ERROR(Status))
+            {
+                VA_END (Args);
+                Status = EFI_DEVICE_ERROR;
+                goto EXIT;
+            }
+
+            // Move to the next Lba
+            StartingLba++;
+            NumOfLba--;
+        }
+    }
+    while (TRUE);
+    VA_END (Args);
+
+EXIT:
+    return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+    IN FLASH_INSTANCE* Instance
+)
+{
+    EFI_STATUS  Status;
+    UINT32      FvbNumLba;
+
+    Instance->Initialized = TRUE;
+    mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
+
+    // Set the index of the first LBA for the FVB
+    Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
+
+    // Determine if there is a valid header at the beginning of the Flash
+    Status = ValidateFvHeader (Instance);
+    if (EFI_ERROR(Status))
+    {
+        // There is no valid header, so time to install one.
+        // Erase all the Flash that is reserved for variable storage
+        FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + (UINT32)PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;
+        Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
+        if (EFI_ERROR(Status))
+        {
+            return Status;
+        }
+
+        // Install all appropriate headers
+        Status = InitializeFvAndVariableStoreHeaders (Instance);
+        if (EFI_ERROR(Status))
+        {
+            return Status;
+        }
+    }
+    return Status;
+}
+
+
+EFI_STATUS
+FlashPlatformGetDevices (
+    OUT FLASH_DESCRIPTION**   FlashDevices,
+    OUT UINT32*                  Count
+)
+{
+    if ((FlashDevices == NULL) || (Count == NULL))
+    {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    *FlashDevices = mFlashDevices;
+    *Count = FLASH_DEVICE_COUNT;
+
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FlashCreateInstance (
+    IN UINTN                  FlashDeviceBase,
+    IN UINTN                  FlashRegionBase,
+    IN UINTN                  FlashSize,
+    IN UINT32                 MediaId,
+    IN UINT32                 BlockSize,
+    IN BOOLEAN                SupportFvb,
+    IN CONST GUID*             FlashGuid,
+    OUT FLASH_INSTANCE**  FlashInstance
+)
+{
+    EFI_STATUS Status;
+    FLASH_INSTANCE* Instance;
+
+    if (FlashInstance == NULL)
+    {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Instance = AllocateRuntimeCopyPool (sizeof(FLASH_INSTANCE), &mFlashInstanceTemplate);
+    if (Instance == NULL)
+    {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Instance->DeviceBaseAddress = FlashDeviceBase;
+    Instance->RegionBaseAddress = FlashRegionBase;
+    Instance->Size = FlashSize;
+
+    Instance->BlockIoProtocol.Media = &Instance->Media;
+    Instance->BlockIoProtocol.Reset = FvbReset;
+    Instance->Media.MediaId = MediaId;
+    Instance->Media.BlockSize = BlockSize;
+    Instance->Media.LastBlock = (FlashSize / BlockSize) - 1;
+
+    CopyGuid (&Instance->DevicePath.Vendor.Guid, FlashGuid);
+
+    if (SupportFvb)
+    {
+        Instance->SupportFvb = TRUE;
+        Instance->Initialize = FvbInitialize;
+
+        Status = gBS->InstallMultipleProtocolInterfaces (
+                     &Instance->Handle,
+                     &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
+                     &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
+                     &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
+                     NULL
+                 );
+
+        if (EFI_ERROR(Status))
+        {
+            FreePool(Instance);
+            return Status;
+        }
+    }
+    else
+    {
+        Instance->Initialized = TRUE;
+
+        Status = gBS->InstallMultipleProtocolInterfaces (
+                     &Instance->Handle,
+                     &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
+                     &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,
+                     NULL
+                 );
+        if (EFI_ERROR(Status))
+        {
+            FreePool(Instance);
+            return Status;
+        }
+    }
+
+    *FlashInstance = Instance;
+    return Status;
+}
+
+EFI_STATUS
+FlashUnlockSingleBlockIfNecessary (
+    IN FLASH_INSTANCE*           Instance,
+    IN UINTN                  BlockAddress
+)
+{
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FlashEraseSingleBlock (
+    IN FLASH_INSTANCE*           Instance,
+    IN UINTN                  BlockAddress
+)
+{
+    EFI_STATUS            Status;
+    UINTN                 EraseAddress;
+
+    Status = EFI_SUCCESS;
+    EraseAddress = BlockAddress - Instance->DeviceBaseAddress;
+
+    Status = mFlash->Erase(mFlash, (UINT32)EraseAddress, Instance->Media.BlockSize);
+    if (EFI_SUCCESS != Status)
+    {
+        DEBUG((EFI_D_ERROR, "%s - %d Status=%r\n", __FILE__, __LINE__, Status));
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+ * The following function presumes that the block has already been unlocked.
+ **/
+EFI_STATUS
+FlashUnlockAndEraseSingleBlock (
+    IN FLASH_INSTANCE*     Instance,
+    IN UINTN                  BlockAddress
+)
+{
+    EFI_STATUS      Status;
+    UINTN           Index;
+
+    Index = 0;
+    // The block erase might fail a first time (SW bug ?). Retry it ...
+    do
+    {
+        // Unlock the block if we have to
+        Status = FlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
+        if (!EFI_ERROR(Status))
+        {
+            Status = FlashEraseSingleBlock (Instance, BlockAddress);
+        }
+        Index++;
+    }
+    while ((Index < FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
+
+    if (Index == FLASH_ERASE_RETRY)
+    {
+        DEBUG((EFI_D_ERROR, "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress, Index));
+    }
+
+    return Status;
+}
+
+EFI_STATUS
+FlashWriteBlocks (
+    IN FLASH_INSTANCE*        Instance,
+    IN EFI_LBA                Lba,
+    IN UINTN                  BufferSizeInBytes,
+    IN VOID*                   Buffer
+)
+{
+    EFI_STATUS      Status = EFI_SUCCESS;
+    UINTN                   BlockAddress;
+    UINT32                     NumBlocks;
+    UINTN                   WriteAddress;
+
+    // The buffer must be valid
+    if (Buffer == NULL)
+    {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    if (Instance->Media.ReadOnly == TRUE)
+    {
+        return EFI_WRITE_PROTECTED;
+    }
+
+    // We must have some bytes to read
+    if (BufferSizeInBytes == 0)
+    {
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // The size of the buffer must be a multiple of the block size
+    if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0)
+    {
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // All blocks must be within the device
+    NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;
+    if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL]ERROR - Write will exceed last block.\n", __FUNCTION__, __LINE__ ));
+        return EFI_INVALID_PARAMETER;
+    }
+
+    BlockAddress = GET_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, Instance->Media.BlockSize);
+
+    WriteAddress = BlockAddress - Instance->DeviceBaseAddress;
+
+    Status = mFlash->Write(mFlash, (UINT32)WriteAddress, (UINT8*)Buffer, BufferSizeInBytes);
+    if (EFI_SUCCESS != Status)
+    {
+        DEBUG((EFI_D_ERROR, "%s - %d Status=%r\n", __FILE__, __LINE__, Status));
+        return Status;
+    }
+
+    return Status;
+}
+
+EFI_STATUS
+FlashReadBlocks (
+    IN FLASH_INSTANCE*   Instance,
+    IN EFI_LBA              Lba,
+    IN UINTN                BufferSizeInBytes,
+    OUT VOID*                Buffer
+)
+{
+    UINT32                     NumBlocks;
+    UINTN                   StartAddress;
+    UINTN                    ReadAddress;
+    EFI_STATUS                    Status;
+
+    // The buffer must be valid
+    if (Buffer == NULL)
+    {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    // We must have some bytes to read
+    if (BufferSizeInBytes == 0)
+    {
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // The size of the buffer must be a multiple of the block size
+    if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0)
+    {
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+    // All blocks must be within the device
+    NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;
+    if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1))
+    {
+        DEBUG((EFI_D_ERROR, "FlashReadBlocks: ERROR - Read will exceed last block\n"));
+        return EFI_INVALID_PARAMETER;
+    }
+
+    // Get the address to start reading from
+    StartAddress = GET_BLOCK_ADDRESS (Instance->RegionBaseAddress,
+                                      Lba,
+                                      Instance->Media.BlockSize
+                                     );
+
+
+    ReadAddress = StartAddress - Instance->DeviceBaseAddress;
+
+    Status = mFlash->Read(mFlash, (UINT32)ReadAddress, Buffer, BufferSizeInBytes);
+    if (EFI_SUCCESS != Status)
+    {
+        DEBUG((EFI_D_ERROR, "%s - %d Status=%r\n", __FILE__, __LINE__, Status));
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+FlashFvbVirtualNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EfiConvertPointer (0x0, (VOID**)&mFlash);
+  EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+FlashFvbInitialize (
+    IN EFI_HANDLE         ImageHandle,
+    IN EFI_SYSTEM_TABLE*   SystemTable
+)
+{
+    EFI_STATUS              Status;
+    UINT32                  Index;
+    FLASH_DESCRIPTION*      FlashDevices;
+    UINT32                  FlashDeviceCount;
+    BOOLEAN                 ContainVariableStorage;
+
+
+    Status = FlashPlatformGetDevices (&FlashDevices, &FlashDeviceCount);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Fail to get Flash devices\n", __FUNCTION__, __LINE__));
+        return Status;
+    }
+
+    mFlashInstances = AllocatePool ((UINT32)(sizeof(FLASH_INSTANCE*) * FlashDeviceCount));
+
+    Status = gBS->LocateProtocol (&gHisiSpiFlashProtocolGuid, NULL, (VOID*) &mFlash);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Status=%r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    for (Index = 0; Index < FlashDeviceCount; Index++)
+    {
+        // Check if this Flash device contain the variable storage region
+        ContainVariableStorage =
+            (FlashDevices[Index].RegionBaseAddress <= (UINT32)PcdGet32 (PcdFlashNvStorageVariableBase)) &&
+            ((UINT32)(PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize)) <= FlashDevices[Index].RegionBaseAddress + FlashDevices[Index].Size);
+
+        Status = FlashCreateInstance (
+                     FlashDevices[Index].DeviceBaseAddress,
+                     FlashDevices[Index].RegionBaseAddress,
+                     FlashDevices[Index].Size,
+                     Index,
+                     FlashDevices[Index].BlockSize,
+                     ContainVariableStorage,
+                     &FlashDevices[Index].Guid,
+                     &mFlashInstances[Index]
+                 );
+        if (EFI_ERROR(Status))
+        {
+            DEBUG((EFI_D_ERROR, "[%a]:[%dL] Fail to create instance for Flash[%d]\n", __FUNCTION__, __LINE__, Index));
+        }
+    }
+    //
+    // Register for the virtual address change event
+    //
+    Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  FlashFvbVirtualNotifyEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mFlashFvbVirtualAddrChangeEvent
+                  );
+    ASSERT_EFI_ERROR (Status);
+
+    return Status;
+}

+ 228 - 0
Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.h

@@ -0,0 +1,228 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 __FLASH_FVB_DXE_H__
+#define __FLASH_FVB_DXE_H__
+
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Library/DebugLib.h>
+
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/HisiSpiFlashProtocol.h>
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#include <Guid/VariableFormat.h>
+#include <Guid/SystemNvDataGuid.h>
+
+
+#define FLASH_ERASE_RETRY                     10
+#define FLASH_DEVICE_COUNT                     1
+
+// Device access macros
+// These are necessary because we use 2 x 16bit parts to make up 32bit data
+typedef struct
+{
+    UINTN       DeviceBaseAddress;    // Start address of the Device Base Address (DBA)
+    UINTN       RegionBaseAddress;    // Start address of one single region
+    UINTN       Size;
+    UINTN       BlockSize;
+    EFI_GUID    Guid;
+} FLASH_DESCRIPTION;
+
+#define GET_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) )
+
+#define FLASH_SIGNATURE                       SIGNATURE_32('s', 'p', 'i', '0')
+#define INSTANCE_FROM_FVB_THIS(a)             CR(a, FLASH_INSTANCE, FvbProtocol, FLASH_SIGNATURE)
+#define INSTANCE_FROM_BLKIO_THIS(a)           CR(a, FLASH_INSTANCE, BlockIoProtocol, FLASH_SIGNATURE)
+
+typedef struct _FLASH_INSTANCE                FLASH_INSTANCE;
+
+typedef EFI_STATUS (*FLASH_INITIALIZE)        (FLASH_INSTANCE* Instance);
+
+typedef struct
+{
+    VENDOR_DEVICE_PATH                  Vendor;
+    EFI_DEVICE_PATH_PROTOCOL            End;
+} FLASH_DEVICE_PATH;
+
+struct _FLASH_INSTANCE
+{
+    UINT32                              Signature;
+    EFI_HANDLE                          Handle;
+
+    BOOLEAN                             Initialized;
+    FLASH_INITIALIZE                    Initialize;
+
+    UINTN                               DeviceBaseAddress;
+    UINTN                               RegionBaseAddress;
+    UINTN                               Size;
+    EFI_LBA                             StartLba;
+
+    EFI_BLOCK_IO_PROTOCOL               BlockIoProtocol;
+    EFI_BLOCK_IO_MEDIA                  Media;
+
+    BOOLEAN                             SupportFvb;
+    EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
+
+    FLASH_DEVICE_PATH                   DevicePath;
+};
+
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoReadBlocks (
+    IN  EFI_BLOCK_IO_PROTOCOL*   This,
+    IN  UINT32                   MediaId,
+    IN  EFI_LBA                  Lba,
+    IN  UINTN                    BufferSizeInBytes,
+    OUT VOID*                    Buffer
+);
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoWriteBlocks (
+    IN  EFI_BLOCK_IO_PROTOCOL*   This,
+    IN  UINT32                   MediaId,
+    IN  EFI_LBA                  Lba,
+    IN  UINTN                    BufferSizeInBytes,
+    IN  VOID*                    Buffer
+);
+
+//
+// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
+//
+EFI_STATUS
+EFIAPI
+FlashBlockIoFlushBlocks (
+    IN EFI_BLOCK_IO_PROTOCOL*    This
+);
+
+
+//
+// FvbHw.c
+//
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+    IN FLASH_INSTANCE*                            Instance
+);
+
+EFI_STATUS
+EFIAPI
+FvbGetAttributes(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    OUT       EFI_FVB_ATTRIBUTES_2*                    Attributes
+);
+
+EFI_STATUS
+EFIAPI
+FvbSetAttributes(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    IN OUT    EFI_FVB_ATTRIBUTES_2*                    Attributes
+);
+
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    OUT       EFI_PHYSICAL_ADDRESS*                    Address
+);
+
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    IN        EFI_LBA                                  Lba,
+    OUT       UINTN*                                   BlockSize,
+    OUT       UINTN*                                   NumberOfBlocks
+);
+
+EFI_STATUS
+EFIAPI
+FvbRead(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    IN        EFI_LBA                                  Lba,
+    IN        UINTN                                   Offset,
+    IN OUT    UINTN*                                   NumBytes,
+    IN OUT    UINT8*                                   Buffer
+);
+
+EFI_STATUS
+EFIAPI
+FvbWrite(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    IN        EFI_LBA                                  Lba,
+    IN        UINTN                                    Offset,
+    IN OUT    UINTN*                                   NumBytes,
+    IN        UINT8*                                   Buffer
+);
+
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks(
+    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
+    ...
+);
+
+//
+// FlashFvbDxe.c
+//
+
+EFI_STATUS
+FlashUnlockAndEraseSingleBlock (
+    IN FLASH_INSTANCE*         Instance,
+    IN UINTN                   BlockAddress
+);
+
+EFI_STATUS
+FlashWriteBlocks (
+    IN  FLASH_INSTANCE*    Instance,
+    IN  EFI_LBA            Lba,
+    IN  UINTN              BufferSizeInBytes,
+    IN  VOID*              Buffer
+);
+
+EFI_STATUS
+FlashReadBlocks (
+    IN FLASH_INSTANCE*       Instance,
+    IN EFI_LBA               Lba,
+    IN UINTN                 BufferSizeInBytes,
+    OUT VOID*                Buffer
+);
+
+#endif

+ 69 - 0
Silicon/Hisilicon/Drivers/FlashFvbDxe/FlashFvbDxe.inf

@@ -0,0 +1,69 @@
+#/** @file
+#
+#    Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = FlashFvbDxe
+  FILE_GUID                      = 93E34C7E-B50E-11DF-9223-2443DFD72085
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FlashFvbInitialize
+
+[Sources.common]
+  FlashFvbDxe.c
+  FlashBlockIoDxe.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  BaseLib
+  DebugLib
+  HobLib
+  UefiLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeLib
+
+[Guids]
+  gEfiSystemNvDataFvGuid
+  gEfiVariableGuid
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiFirmwareVolumeBlockProtocolGuid
+  gHisiSpiFlashProtocolGuid
+
+[Pcd.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+  gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
+
+[Depex]
+  gHisiSpiFlashProtocolGuid
+
+[BuildOptions]

+ 269 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c

@@ -0,0 +1,269 @@
+/** @file
+  Sample ACPI Platform Driver
+
+  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+  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 <PiDxe.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Acpi.h>
+#include "UpdateAcpiTable.h"
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param  Instance      Return pointer to the first instance of the protocol
+
+  @return EFI_SUCCESS           The function completed successfully.
+  @return EFI_NOT_FOUND         The protocol could not be located.
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+
+**/
+EFI_STATUS
+LocateFvInstanceWithTables (
+  OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         NumberOfHandles;
+  EFI_FV_FILETYPE               FileType;
+  UINT32                        FvStatus;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINTN                         Size;
+  UINTN                         Index;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
+
+  FvStatus = 0;
+
+  //
+  // Locate protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                   ByProtocol,
+                   &gEfiFirmwareVolume2ProtocolGuid,
+                   NULL,
+                   &NumberOfHandles,
+                   &HandleBuffer
+                   );
+  if (EFI_ERROR (Status)) {
+    //
+    // Defined errors at this time are not found and out of resources.
+    //
+    return Status;
+  }
+
+
+
+  //
+  // Looking for FV with ACPI storage file
+  //
+
+  for (Index = 0; Index < NumberOfHandles; Index++) {
+    //
+    // Get the protocol on this handle
+    // This should not fail because of LocateHandleBuffer
+    //
+    Status = gBS->HandleProtocol (
+                     HandleBuffer[Index],
+                     &gEfiFirmwareVolume2ProtocolGuid,
+                     (VOID**) &FvInstance
+                     );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // See if it has the ACPI storage file
+    //
+    Status = FvInstance->ReadFile (
+                           FvInstance,
+                           (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
+                           NULL,
+                           &Size,
+                           &FileType,
+                           &Attributes,
+                           &FvStatus
+                           );
+
+    //
+    // If we found it, then we are done
+    //
+    if (Status == EFI_SUCCESS) {
+      *Instance = FvInstance;
+      break;
+    }
+  }
+
+  //
+  // Our exit status is determined by the success of the previous operations
+  // If the protocol was found, Instance already points to it.
+  //
+
+  //
+  // Free any allocated buffers
+  //
+  gBS->FreePool (HandleBuffer);
+
+  return Status;
+}
+
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param  Buffer          Pointer to buffer to checksum
+  @param  Size            Number of bytes to checksum
+
+**/
+VOID
+AcpiPlatformChecksum (
+  IN UINT8      *Buffer,
+  IN UINTN      Size
+  )
+{
+  UINTN ChecksumOffset;
+
+  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
+
+  //
+  // Set checksum to 0 first
+  //
+  Buffer[ChecksumOffset] = 0;
+
+  //
+  // Update checksum value
+  //
+  Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
+}
+
+
+/**
+  Entrypoint of Acpi Platform driver.
+
+  @param  ImageHandle
+  @param  SystemTable
+
+  @return EFI_SUCCESS
+  @return EFI_LOAD_ERROR
+  @return EFI_OUT_OF_RESOURCES
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;
+  INTN                           Instance;
+  EFI_ACPI_COMMON_HEADER         *CurrentTable;
+  UINTN                          TableHandle;
+  UINT32                         FvStatus;
+  UINTN                          TableSize;
+  UINTN                          Size;
+  EFI_STATUS                     TableStatus;
+  EFI_ACPI_DESCRIPTION_HEADER    *TableHeader;
+
+  Instance     = 0;
+  CurrentTable = NULL;
+  TableHandle  = 0;
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
+  if (EFI_ERROR (Status)) {
+    return EFI_ABORTED;
+  }
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateFvInstanceWithTables (&FwVol);
+  if (EFI_ERROR (Status)) {
+    return EFI_ABORTED;
+  }
+  //
+  // Read tables from the storage file.
+  //
+  while (Status == EFI_SUCCESS) {
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID**) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+    if (!EFI_ERROR(Status)) {
+      //
+      // Add the table
+      //
+      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (CurrentTable);
+      //Update specfic Acpi Table
+      //If the Table is updated failed, doesn't install it,
+      //go to find next section.
+      TableStatus = UpdateAcpiTable(TableHeader);
+      if (TableStatus == EFI_SUCCESS) {
+        TableHandle = 0;
+
+        TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
+        ASSERT (Size >= TableSize);
+
+        //
+        // Checksum ACPI table
+        //
+        AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
+
+        //
+        // Install ACPI table
+        //
+        Status = AcpiTable->InstallAcpiTable (
+                              AcpiTable,
+                              CurrentTable,
+                              TableSize,
+                              &TableHandle
+                              );
+      }
+      //
+      // Free memory allocated by ReadSection
+      //
+      gBS->FreePool (CurrentTable);
+
+      if (EFI_ERROR(Status)) {
+        return EFI_ABORTED;
+      }
+
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+

+ 22 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni

@@ -0,0 +1,22 @@
+// /** @file
+// Sample ACPI Platform Driver
+//
+// Sample ACPI Platform Driver
+//
+// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Sample ACPI Platform Driver"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Sample ACPI Platform Driver"
+

+ 62 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf

@@ -0,0 +1,62 @@
+## @file
+#  Sample ACPI Platform Driver
+#
+#  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+#  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                      = AcpiPlatform
+  MODULE_UNI_FILE                = AcpiPlatform.uni
+  FILE_GUID                      = cb933912-df8f-4305-b1f9-7b44fa11395c
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiPlatformEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  AcpiPlatform.c
+  UpdateAcpiTable.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiLib
+  DxeServicesLib
+  PcdLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## CONSUMES
+
+[Guids]
+  gHisiEfiMemoryMapGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile    ## CONSUMES
+
+[Depex]
+  gEfiAcpiTableProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  AcpiPlatformExtra.uni

+ 20 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni

@@ -0,0 +1,20 @@
+// /** @file
+// AcpiPlatform Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// 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.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"ACPI Platform Sample DXE Driver"
+
+

+ 137 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c

@@ -0,0 +1,137 @@
+/** @file
+  Copyright (c) 2016, Hisilicon 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 <PlatformArch.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/AcpiNextLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/HwMemInitLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define CORE_NUM_PER_SOCKET  32
+#define NODE_IN_SOCKET       2
+#define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)
+
+STATIC
+VOID
+RemoveUnusedMemoryNode (
+  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE  *Table,
+  IN     UINTN                        MemoryNodeNum
+)
+{
+  UINTN                   CurrPtr, NewPtr;
+
+  if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
+    return;
+  }
+
+  CurrPtr = (UINTN) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
+  NewPtr = (UINTN) &(Table->Memory[MemoryNodeNum]);
+
+  CopyMem ((VOID *)NewPtr, (VOID *)CurrPtr, (UINTN)Table + Table->Header.Header.Length - CurrPtr);
+
+  Table->Header.Header.Length -= CurrPtr - NewPtr;
+
+  return;
+}
+
+STATIC
+EFI_STATUS
+UpdateSrat (
+  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
+  )
+{
+  UINT8               Skt = 0;
+  UINTN               Index = 0;
+  VOID                *HobList;
+  GBL_DATA            *Gbl_Data;
+  UINTN               Base;
+  UINTN               Size;
+  UINT8               NodeId;
+  UINT32              ScclInterleaveEn;
+  UINTN               MemoryNode = 0;
+
+  DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
+
+  HobList = GetHobList();
+  if (HobList == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+  Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
+  if (Gbl_Data == NULL) {
+    DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
+    return EFI_NOT_FOUND;
+  }
+  Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
+  for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
+    for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
+      NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
+      Base = Gbl_Data->NumaInfo[Skt][Index].Base;
+      Size = Gbl_Data->NumaInfo[Skt][Index].Length;
+      DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
+      if (Size > 0) {
+        Table->Memory[MemoryNode].ProximityDomain = NodeId;
+        Table->Memory[MemoryNode].AddressBaseLow = Base;
+        Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
+        Table->Memory[MemoryNode].LengthLow = Size;
+        Table->Memory[MemoryNode].LengthHigh = Size >> 32;
+        MemoryNode = MemoryNode + 1;
+      }
+    }
+    ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
+    DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
+    //update gicc structure
+    if (ScclInterleaveEn != 0) {
+      DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n"));
+      for (Index = CORECOUNT (Skt); Index < CORECOUNT (Skt + 1); Index++) {
+        Table->Gicc[Index].ProximityDomain = Skt * NODE_IN_SOCKET;
+      }
+    }
+  }
+
+  //remove invalid memory node
+  RemoveUnusedMemoryNode (Table, MemoryNode);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateSlit (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Table
+  )
+{
+  return  EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateAcpiTable (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
+)
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  switch (TableHeader->Signature) {
+
+  case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
+    Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
+    break;
+
+  case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
+    Status = UpdateSlit (TableHeader);
+    break;
+  }
+  return Status;
+}

+ 16 - 0
Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h

@@ -0,0 +1,16 @@
+/** @file
+  Copyright (c) 2016, Hisilicon 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.
+**/
+
+EFI_STATUS
+UpdateAcpiTable (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
+);
+

+ 162 - 0
Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashConfig.c

@@ -0,0 +1,162 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 "NorFlashHw.h"
+
+
+#define COMMAND_TYPE1 0x1
+#define COMMAND_TYPE2 0x2
+#define COMMAND_TYPE3 0x4
+#define COMMAND_TYPE4 0x8
+#define COMMAND_TYPE5 0x10
+
+
+NOR_FLASH_INFO_TABLE gFlashInfo[]=
+{
+
+    {//S29GL512m
+      0x00010001,
+      0x227E227E,
+      0x22232223,
+      0x22012201,
+      1,
+      0x20000000,
+      0x20000,
+      0x0010,
+      COMMAND_TYPE1
+    },
+    {//S29GL1g
+      0x00010001,
+      0x227E227E,
+      0x22282228,
+      0x22012201,
+      1,
+      0x40000000,
+      0x20000,
+      0x0020,
+      COMMAND_TYPE1
+    },
+    {//M29ew512m
+      0x00890089,
+      0x227E227E,
+      0x22232223,
+      0x22012201,
+      1,
+      0x20000000,
+      0x20000,
+      0x0010,
+      COMMAND_TYPE1
+    },
+    {//M29EW2g
+      0x00890089,
+      0x227E227E,
+      0x22482248,
+      0x22012201,
+      1,
+      0x80000000,
+      0x20000,
+      0x0020,
+      COMMAND_TYPE1
+    },
+    {
+      0x00890089,
+      0x227E227E,
+      0x22282228,
+      0x22012201,
+      1,
+      0x10000000,
+      0x20000,
+      0x0020,
+      COMMAND_TYPE1
+    },
+    {
+      0x00890089,
+      0x227E227E,
+      0x22282228,
+      0x22012201,
+      2,
+      0x10000000,
+      0x20000,
+      0x0020,
+      COMMAND_TYPE1
+    }
+};
+
+
+
+FLASH_COMMAND_RESET gFlashCommandReset[]=
+{
+    {
+       COMMAND_TYPE1,
+       (0x00F000F0)
+    }
+
+};
+
+
+FLASH_COMMAND_ID gFlashCommandId[]=
+{
+     {
+       COMMAND_TYPE1,
+       (0x0555),
+       (0x00AA00AA),
+       (0x02AA),
+       (0x00550055),
+       (0x0555),
+       (0x00900090),
+       (0x0000),
+
+       (0x0001),
+       (0x000E),
+       (0x000F)
+    }
+};
+
+
+FLASH_COMMAND_WRITE gFlashCommandWrite[]=
+{
+    {
+       COMMAND_TYPE1,
+       (0x0555),
+       (0x00AA00AA),
+       (0x02AA),
+       (0x00550055),
+       (0x00250025),
+       (0x00290029)
+    }
+
+};
+
+
+FLASH_COMMAND_ERASE gFlashCommandErase[]=
+{
+    {
+       COMMAND_TYPE1,
+       (0x0555),
+       (0x00AA00AA),
+       (0x02AA),
+       (0x00550055),
+       (0x0555),
+       (0x00800080),
+       (0x0555),
+       (0x00AA00AA),
+       (0x02AA),
+       (0x00550055),
+       (0x00300030)
+    }
+
+};
+

+ 594 - 0
Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.c

@@ -0,0 +1,594 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/NorFlashProtocol.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Protocol/Cpu.h>
+#include "NorFlashHw.h"
+
+
+EFI_STATUS Erase(
+   IN UNI_NOR_FLASH_PROTOCOL   *This,
+   IN  UINT32                   Offset,
+   IN  UINT32                   Length
+  );
+
+EFI_STATUS  Write(
+  IN UNI_NOR_FLASH_PROTOCOL   *This,
+  IN  UINT32                  Offset,
+  IN  UINT8                  *Buffer,
+  UINT32                     ulLength
+  );
+
+EFI_STATUS Read(
+  IN UNI_NOR_FLASH_PROTOCOL   *This,
+  IN UINT32                   Offset,
+  IN OUT UINT8               *Buffer,
+  IN UINT32                   ulLen
+  );
+
+UNI_NOR_FLASH_PROTOCOL gUniNorFlash = {
+    Erase,
+    Write,
+    Read
+};
+
+
+EFI_STATUS
+EFIAPI Read(
+  IN UNI_NOR_FLASH_PROTOCOL   *This,
+  IN UINT32                   Offset,
+  IN OUT UINT8               *Buffer,
+  IN UINT32                    ulLen
+  )
+{
+    UINT32       index;
+    UINT64 ullAddr;
+    UINT32 ullCnt = 0;
+    UINT32 *puiBuffer32 = NULL;
+    UINT32 *puiDst32 = NULL;
+    UINT8 *pucBuffer8 = NULL;
+    UINT8 *pucDst8 = NULL;
+
+    if (Offset + ulLen > (gFlashInfo[gIndex.InfIndex].SingleChipSize * gFlashInfo[gIndex.InfIndex].ParallelNum))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Exceed the flash scope!\n", __FUNCTION__,__LINE__));
+        return EFI_INVALID_PARAMETER;
+    }
+    if (0 == ulLen)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Length is Zero!\n", __FUNCTION__,__LINE__));
+        return EFI_INVALID_PARAMETER;
+    }
+    if (NULL == Buffer)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Buffer is NULL!\n", __FUNCTION__,__LINE__));
+        return EFI_BAD_BUFFER_SIZE;
+    }
+
+
+    ullAddr = gIndex.Base + Offset;
+
+    pucBuffer8 = (UINT8 *)Buffer;
+    pucDst8    = (UINT8 *)((UINTN)ullAddr);
+
+
+    if (ulLen < FOUR_BYTE_UNIT)
+    {
+        for(index = 0; index< ulLen; index++)
+        {
+            *pucBuffer8++ = *pucDst8++;
+        }
+    }
+    else
+    {
+
+        ullCnt = Offset % FOUR_BYTE_UNIT;
+        ullCnt = FOUR_BYTE_UNIT - ullCnt;
+
+        for(index = 0; index < ullCnt; index++)
+        {
+            *pucBuffer8++ = *pucDst8++;
+        }
+
+        ulLen -= ullCnt;
+
+        puiBuffer32 = (UINT32 *)pucBuffer8;
+        puiDst32    = (UINT32 *)pucDst8;
+        ullCnt      = ulLen / FOUR_BYTE_UNIT;
+
+        for(index = 0; index < ullCnt; index++)
+        {
+            *puiBuffer32++ = *puiDst32++;
+        }
+
+        ullCnt     = ulLen % FOUR_BYTE_UNIT;
+        pucBuffer8 = (UINT8 *)puiBuffer32;
+        pucDst8    = (UINT8 *)puiDst32;
+
+        for(index = 0; index < ullCnt; index++)
+        {
+            *pucBuffer8++ = *pucDst8++;
+        }
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+
+static EFI_STATUS WriteAfterErase_Fill(
+    IN  const UINT32       Offset,
+    IN  const UINT8       *Buffer,
+    IN  const UINT32       Length
+    )
+{
+    EFI_STATUS Status;
+    UINT32 Loop;
+    UINT32 DataOffset;
+    UINT32 NewOffset;
+    UINT8 *NewDataUnit;
+
+    UINT32 FlashUnitLength;
+
+    FlashUnitLength = gFlashInfo[gIndex.InfIndex].BufferProgramSize << gFlashInfo[gIndex.InfIndex].ParallelNum;
+
+    if (0 == Length)
+    {
+        return EFI_SUCCESS;
+    }
+    if ((Offset % FlashUnitLength + Length) > FlashUnitLength)
+    {
+        DEBUG ((EFI_D_INFO, "[%a]:[%dL]:Exceed the Flash Size!\n", __FUNCTION__,__LINE__));
+        return EFI_UNSUPPORTED;
+    }
+
+
+    Status = gBS->AllocatePool(EfiBootServicesData, FlashUnitLength, (VOID *)&NewDataUnit);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Allocate Pool failed, %r!\n", __FUNCTION__,__LINE__, Status));
+        return Status;
+    }
+
+
+    NewOffset = Offset - (Offset % FlashUnitLength);
+
+    gBS->CopyMem((VOID *)NewDataUnit, (VOID *)(UINTN)(gIndex.Base + NewOffset), FlashUnitLength);
+
+    DataOffset = Offset % FlashUnitLength;
+    for (Loop = 0; Loop < Length; Loop ++)
+    {
+        NewDataUnit[(UINT32)(DataOffset + Loop)] = Buffer[Loop];
+    }
+
+    Status = BufferWrite(NewOffset, (void *)NewDataUnit, FlashUnitLength);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:BufferWrite %r!\n", __FUNCTION__,__LINE__, Status));
+        return Status;
+    }
+
+    (void)gBS->FreePool((VOID *)NewDataUnit);
+    return Status;
+}
+
+
+static EFI_STATUS WriteAfterErase_Final(
+    IN  UINT32       Offset,
+    IN  UINT8       *Buffer,
+    IN  UINT32       Length
+    )
+{
+    EFI_STATUS Status;
+    UINT32 Loop;
+    UINT32 FlashUnitLength;
+
+    FlashUnitLength = gFlashInfo[gIndex.InfIndex].BufferProgramSize << gFlashInfo[gIndex.InfIndex].ParallelNum;
+
+    if (0 == Length)
+    {
+        return EFI_SUCCESS;
+    }
+
+    if (0 != (Offset % FlashUnitLength))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]: Offset must be a multiple of 0x%x!\n", __FUNCTION__,__LINE__,FlashUnitLength));
+        return EFI_UNSUPPORTED;
+    }
+
+
+    Loop = Length / FlashUnitLength;
+    while (Loop --)
+    {
+        Status = BufferWrite(Offset, (void *)Buffer, FlashUnitLength);
+        if (EFI_ERROR(Status))
+        {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:BufferWrite Failed: %r!\n", __FUNCTION__,__LINE__, Status));
+            return EFI_DEVICE_ERROR;
+        }
+        Offset += FlashUnitLength;
+        Buffer += FlashUnitLength;
+    }
+
+
+    Length = Length % FlashUnitLength;
+    if (Length)
+    {
+        Status = WriteAfterErase_Fill(Offset, Buffer, Length);
+        if (EFI_ERROR(Status))
+        {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:WriteAfterErase_Fill failed,%r!\n", __FUNCTION__,__LINE__, Status));
+            return Status;
+        }
+    }
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteAfterErase(
+    UINT32       TempBase,
+    UINT32       Offset,
+    UINT8       *Buffer,
+    UINT32       Length
+  )
+{
+    EFI_STATUS Status;
+    UINT32 FlashUnitLength;
+
+    FlashUnitLength = gFlashInfo[gIndex.InfIndex].BufferProgramSize << gFlashInfo[gIndex.InfIndex].ParallelNum;
+
+    if (0 == Length)
+    {
+        return EFI_SUCCESS;
+    }
+
+
+    if (Offset % FlashUnitLength)
+    {
+        UINT32 TempLength;
+
+
+        TempLength = FlashUnitLength - (Offset % FlashUnitLength);
+        if (TempLength > Length)
+        {
+            TempLength = Length;
+        }
+        Status = WriteAfterErase_Fill(Offset, Buffer, TempLength);
+        if (EFI_ERROR(Status))
+        {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL]: %r!\n", __FUNCTION__,__LINE__, Status));
+            return Status;
+        }
+
+        Offset += TempLength;
+        Length -= TempLength;
+        Buffer += TempLength;
+
+        //Desc:if Offset >= gOneFlashSize,modify base
+        if (0 < (Offset / gFlashInfo[gIndex.InfIndex].SingleChipSize))
+        {
+            TempBase += gFlashInfo[gIndex.InfIndex].SingleChipSize;
+            gIndex.Base = TempBase;
+            Offset = 0;
+        }
+    }
+
+
+    Status = WriteAfterErase_Final(Offset, Buffer, Length);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]: %r!\n", __FUNCTION__,__LINE__, Status));
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FlashSectorErase(
+    UINT32      TempBase,
+    UINT32      Offset,
+    UINT32      Length
+  )
+{
+    EFI_STATUS  Status;
+    UINT32 SectorOffset;
+    UINT8 *StaticBuffer;
+    UINT8 *Buffer;
+    UINT32 TempOffset;
+    UINT32 TempLength;
+    UINT32 LeftLength;
+
+
+    if (0 == Length)
+    {
+        return EFI_SUCCESS;
+    }
+
+    LeftLength = gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum - (Offset % (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum));
+    if (LeftLength < Length)
+    {
+        return EFI_UNSUPPORTED;
+    }
+
+
+    SectorOffset = Offset - (Offset % (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum));
+
+    Status = gBS->AllocatePool(EfiBootServicesData, gFlashInfo[gIndex.InfIndex].BlockSize * (UINTN)gFlashInfo[gIndex.InfIndex].ParallelNum, (VOID *)&StaticBuffer);
+    if (EFI_ERROR(Status))
+    {
+        return Status;
+    }
+
+    Buffer = StaticBuffer;
+
+    gBS->CopyMem((VOID *)Buffer, (VOID *)(UINTN)(TempBase + SectorOffset),
+                 (gFlashInfo[gIndex.InfIndex].BlockSize * (UINTN)gFlashInfo[gIndex.InfIndex].ParallelNum));
+
+
+    Status = SectorErase(TempBase, SectorOffset);
+    if (EFI_ERROR(Status))
+    {
+        goto DO;
+    }
+
+
+    TempOffset = SectorOffset;
+    TempLength = Offset % (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum);
+
+    Status = WriteAfterErase(TempBase, TempOffset, Buffer, TempLength);
+    if (EFI_ERROR(Status))
+    {
+        goto DO;
+    }
+
+
+    Buffer = Buffer + TempLength + Length;
+    TempOffset = Offset + Length;
+    TempLength = SectorOffset + (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum) - TempOffset;
+
+    Status = WriteAfterErase(TempBase, TempOffset, Buffer, TempLength);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]: %r!\n", __FUNCTION__,__LINE__,Status));
+        goto DO;
+    }
+
+    (void)gBS->FreePool((VOID *)StaticBuffer);
+    return EFI_SUCCESS;
+
+DO:
+    (void)gBS->FreePool((VOID *)StaticBuffer);
+    return Status;
+}
+
+
+EFI_STATUS
+EFIAPI Erase(
+   IN UNI_NOR_FLASH_PROTOCOL   *This,
+   IN UINT32                   Offset,
+   IN UINT32                   Length
+  )
+{
+    EFI_STATUS  Status = EFI_SUCCESS;
+    UINT32 Sectors;
+    UINT32 TempLength;
+    UINT32 TempBase;
+    UINT32 Loop;
+
+
+    if (Offset + Length > (gFlashInfo[gIndex.InfIndex].SingleChipSize * gFlashInfo[gIndex.InfIndex].ParallelNum))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Exceed the Flash Size!\n", __FUNCTION__,__LINE__));
+        return EFI_ABORTED;
+    }
+    if (0 == Length)
+    {
+        return EFI_SUCCESS;
+    }
+
+
+    Sectors = ((Offset + Length - 1) / (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum)) - (Offset / (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum)) + 1;
+    TempBase = gIndex.Base;
+
+    //if Offset >= gOneFlashSize,modify base
+    if(0 < (Offset / gFlashInfo[gIndex.InfIndex].SingleChipSize))
+    {
+        TempBase +=  gFlashInfo[gIndex.InfIndex].SingleChipSize * (Offset/gFlashInfo[gIndex.InfIndex].SingleChipSize);
+        Offset = Offset - (Offset & gFlashInfo[gIndex.InfIndex].SingleChipSize);
+    }
+
+    for (Loop = 0; Loop <= Sectors; Loop ++)
+    {
+
+        TempLength = gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum - (Offset % (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum));
+
+
+        if (TempLength > Length)
+        {
+            TempLength = Length;
+        }
+
+        Status = FlashSectorErase(TempBase, Offset, TempLength);
+        if (EFI_ERROR(Status))
+        {
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL]: FlashErase One Sector Error, Status = %r!\n", __FUNCTION__,__LINE__,Status));
+            return Status;
+        }
+
+        Offset += TempLength;
+
+         //if Offset >= gOneFlashSize,modify base
+        if (0 < (Offset / gFlashInfo[gIndex.InfIndex].SingleChipSize))
+        {
+            TempBase += gFlashInfo[gIndex.InfIndex].SingleChipSize;
+            Offset = 0;
+        }
+        Length -= TempLength;
+    }
+
+    return Status;
+}
+
+
+EFI_STATUS
+EFIAPI Write(
+  IN UNI_NOR_FLASH_PROTOCOL   *This,
+  IN UINT32                   Offset,
+  IN UINT8                   *Buffer,
+  UINT32                     ulLength
+  )
+{
+    EFI_STATUS  Status;
+    UINT32     TempLength;
+    UINT32       TempBase;
+    UINT32           Loop;
+    UINT32        Sectors;
+
+    if((Offset + ulLength) > (gFlashInfo[gIndex.InfIndex].SingleChipSize * gFlashInfo[gIndex.InfIndex].ParallelNum))
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Exceed the Flash Size!\n", __FUNCTION__,__LINE__));
+        return EFI_INVALID_PARAMETER;
+    }
+    if (0 == ulLength)
+    {
+        return EFI_SUCCESS;
+    }
+
+
+    Sectors = ((Offset + ulLength - 1) / (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum)) - (Offset / (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum)) + 1;
+    TempBase = gIndex.Base;
+
+    //if Offset >= gOneFlashSize,modify base
+    if(0 < (Offset / gFlashInfo[gIndex.InfIndex].SingleChipSize))
+    {
+        TempBase +=  gFlashInfo[gIndex.InfIndex].SingleChipSize * (Offset/gFlashInfo[gIndex.InfIndex].SingleChipSize);
+        Offset = Offset - (Offset & gFlashInfo[gIndex.InfIndex].SingleChipSize);
+    }
+
+    for (Loop = 0; Loop <= Sectors; Loop ++)
+    {
+
+        TempLength = gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum - (Offset % (gFlashInfo[gIndex.InfIndex].BlockSize * gFlashInfo[gIndex.InfIndex].ParallelNum));
+
+
+        if (TempLength > ulLength)
+        {
+            TempLength = ulLength;
+        }
+
+
+        if (TRUE == IsNeedToWrite(TempBase, Offset, Buffer, TempLength))
+        {
+            Status = FlashSectorErase(TempBase, Offset, TempLength);
+            if (EFI_ERROR(Status))
+            {
+                DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:FlashErase One Sector Error, Status = %r!\n", __FUNCTION__,__LINE__,Status));
+                return Status;
+            }
+
+
+            Status = WriteAfterErase(TempBase, Offset, Buffer, TempLength);
+            if (EFI_ERROR(Status))
+            {
+                DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:WriteAfterErase Status = %r!\n", __FUNCTION__,__LINE__,Status));
+                return Status;
+            }
+        }
+
+        Offset += TempLength;
+        Buffer += TempLength;
+
+         //if Offset >= gOneFlashSize,modify base
+        if (0 < (Offset / gFlashInfo[gIndex.InfIndex].SingleChipSize))
+        {
+            TempBase += gFlashInfo[gIndex.InfIndex].SingleChipSize;
+            Offset = 0;
+        }
+        ulLength -= TempLength;
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+VOID SetFlashAttributeToUncache(VOID)
+{
+    EFI_CPU_ARCH_PROTOCOL             *gCpu           = NULL;
+    EFI_STATUS Status;
+
+    Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "LocateProtocol gEfiCpuArchProtocolGuid Status = %r !\n", Status));
+    }
+
+    Status = gCpu->SetMemoryAttributes(
+                     gCpu,
+                     PcdGet64(PcdNORFlashBase),
+                     PcdGet32(PcdNORFlashCachableSize),
+                     EFI_MEMORY_UC
+                     );
+
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "gCpu->SetMemoryAttributes Status = %r !\n", Status));
+    }
+
+}
+
+EFI_STATUS
+EFIAPI InitializeFlash (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable)
+{
+    EFI_STATUS Status;
+
+
+    gIndex.Base = (UINT32)PcdGet64(PcdNORFlashBase);
+
+    SetFlashAttributeToUncache();
+    Status = FlashInit(gIndex.Base);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "Init Flash Error !\n"));
+        return Status;
+    }
+    else
+    {
+        DEBUG((EFI_D_ERROR, "Init Flash OK!\n"));
+    }
+
+    Status = gBS->InstallProtocolInterface (
+                            &ImageHandle,
+                            &gUniNorFlashProtocolGuid,
+                            EFI_NATIVE_INTERFACE,
+                            &gUniNorFlash);
+    if(EFI_SUCCESS != Status)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Install Protocol Interface %r!\n", __FUNCTION__,__LINE__,Status));
+    }
+
+    return Status;
+}

+ 64 - 0
Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashDxe.inf

@@ -0,0 +1,64 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = NorFlashDxe
+  FILE_GUID                      = E29977F9-20A4-4551-B0EC-BCE246592E73
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeFlash
+
+[Sources.common]
+  NorFlashDxe.c
+  NorFlashHw.c
+  NorFlashConfig.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  BaseLib
+  DebugLib
+  IoLib
+  SerialPortLib
+  ArmLib
+  CacheMaintenanceLib
+  UefiLib
+  PrintLib
+  PcdLib
+
+  DxeServicesTableLib
+[Guids]
+
+[Protocols]
+  gUniNorFlashProtocolGuid
+  gEfiCpuArchProtocolGuid
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdNORFlashBase
+  gHisiTokenSpaceGuid.PcdNORFlashCachableSize
+
+
+[Depex]
+ TRUE
+

+ 628 - 0
Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashHw.c

@@ -0,0 +1,628 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IoLib.h>
+#include "NorFlashHw.h"
+
+
+BOOLEAN  gFlashBusy = FALSE;
+FLASH_INDEX gIndex = {
+    0,
+    0,
+    0,
+    0,
+    0,
+    0
+};
+
+
+UINT32 PortReadData (
+    UINT32 Index,
+    UINT32 FlashAddr
+  )
+{
+
+    switch (gFlashInfo[Index].ParallelNum)
+    {
+        case 2:
+            return MmioRead32 (FlashAddr);
+        case 1:
+            return MmioRead16 (FlashAddr);
+
+        default:
+            DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:illegal PortWidth!\n", __FUNCTION__,__LINE__));
+            return 0xffffffff;
+    }
+}
+
+EFI_STATUS
+PortWriteData (
+    UINT32 Index,
+    UINT32 FlashAddr,
+    UINT32 InputData
+  )
+{
+
+    switch (gFlashInfo[Index].ParallelNum)
+    {
+        case 2:
+             MmioWrite32 (FlashAddr, InputData);
+             break;
+        case 1:
+             MmioWrite16 (FlashAddr, InputData);
+             break;
+        default:
+             DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:illegal PortWidth!\n", __FUNCTION__,__LINE__));
+             return EFI_DEVICE_ERROR;
+    }
+    return EFI_SUCCESS;
+}
+
+UINT32 PortAdjustData(
+    UINT32 Index,
+    UINT32 ulInputData
+  )
+{
+
+    switch (gFlashInfo[Index].ParallelNum)
+    {
+        case 2:
+             return ulInputData;
+        case 1:
+             return (0x0000ffff & ulInputData );
+        default:
+            DEBUG((EFI_D_ERROR,"[FLASH_S29GL256N_PortAdjustData]: Error--illegal g_ulFlashS29Gl256NPortWidth!\n\r"));
+            return 0xffffffff;
+    }
+}
+
+
+EFI_STATUS GetCommandIndex(
+    UINT32 Index
+  )
+{
+    UINT32 CommandCount = 0;
+    UINT32 i;
+    UINT8 Flag = 1;
+
+    CommandCount = sizeof(gFlashCommandReset) / sizeof(FLASH_COMMAND_RESET);
+    for(i = 0;i < CommandCount; i ++ )
+    {
+        if(gFlashInfo[Index].CommandType & gFlashCommandReset[i].CommandType)
+        {
+            Flag = 0;
+            gIndex.ReIndex = i;
+            break;
+        }
+    }
+
+    if(Flag)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Reset Command!\n", __FUNCTION__,__LINE__));
+        return EFI_DEVICE_ERROR;
+    }
+
+    CommandCount = sizeof(gFlashCommandId) / sizeof(FLASH_COMMAND_ID);
+    for(Flag = 1,i = 0;i < CommandCount; i ++ )
+    {
+        if(gFlashInfo[Index].CommandType & gFlashCommandId[i].CommandType)
+        {
+            Flag = 0;
+            gIndex.IdIndex = i;
+            break;
+        }
+    }
+
+    if(Flag)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get ID Command!\n", __FUNCTION__,__LINE__));
+        return EFI_DEVICE_ERROR;
+    }
+
+    CommandCount = sizeof(gFlashCommandWrite) / sizeof(FLASH_COMMAND_WRITE);
+    for(Flag = 1, i = 0;i < CommandCount; i ++ )
+    {
+        if(gFlashInfo[Index].CommandType & gFlashCommandWrite[i].CommandType)
+        {
+            Flag = 0;
+            gIndex.WIndex = i;
+            break;
+        }
+    }
+
+    if(Flag)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Write Command!\n", __FUNCTION__,__LINE__));
+        return EFI_DEVICE_ERROR;
+    }
+
+    CommandCount = sizeof(gFlashCommandErase) / sizeof(FLASH_COMMAND_ERASE);
+    for(Flag = 1, i = 0;i < CommandCount; i ++ )
+    {
+        if(gFlashInfo[Index].CommandType & gFlashCommandErase[i].CommandType)
+        {
+            Flag = 0;
+            gIndex.WIndex = i;
+            break;
+        }
+    }
+
+    if(Flag)
+    {
+        DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Erase Command!\n", __FUNCTION__,__LINE__));
+        return EFI_DEVICE_ERROR;
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+VOID FlashReset(UINT32 Base)
+{
+    (VOID)PortWriteData(gIndex.InfIndex, Base, gFlashCommandReset[gIndex.ReIndex].ResetData);
+    (void)gBS->Stall(20000);
+}
+
+
+void GetManufacturerID(UINT32 Index, UINT32 Base, UINT8 *pbyData)
+{
+
+    UINT32 dwAddr;
+
+    FlashReset(Base);
+
+    dwAddr = Base +  (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep1 << gFlashInfo[Index].ParallelNum);
+    (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep1);
+
+    dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep2 << gFlashInfo[Index].ParallelNum);
+    (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep2);
+
+    dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep3 << gFlashInfo[Index].ParallelNum);
+    (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep3);
+
+    *pbyData = (UINT8)PortReadData(Index, Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddress << gFlashInfo[Index].ParallelNum));
+
+    FlashReset(Base);    //must reset to return to the read mode
+}
+
+
+EFI_STATUS FlashInit(UINT32 Base)
+{
+    UINT32 FlashCount = 0;
+    UINT32 i = 0;
+    EFI_STATUS Status;
+    UINT8 Flag = 1;
+    UINT32 TempData = 0;
+    UINT32 TempDev1 = 0;
+    UINT32 TempDev2 = 0;
+    UINT32 TempDev3 = 0;
+    UINT32 dwAddr;
+
+    FlashCount = sizeof(gFlashInfo) / sizeof(NOR_FLASH_INFO_TABLE);
+    for(;i < FlashCount; i ++ )
+    {
+
+        Status = GetCommandIndex(i);
+        if (EFI_ERROR(Status))
+         {
+             DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Get Command Index %r!\n", __FUNCTION__,__LINE__, Status));
+             return Status;
+         }
+
+        FlashReset(Base);
+
+        dwAddr = Base +  (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep1 << gFlashInfo[i].ParallelNum);
+        (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep1);
+
+        dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep2 << gFlashInfo[i].ParallelNum);
+        (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep2);
+
+        dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep3 << gFlashInfo[i].ParallelNum);
+        (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep3);
+        //Get manufacture ID
+        TempData = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddress << gFlashInfo[i].ParallelNum));
+
+        //Get Device Id
+        TempDev1 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress1 << gFlashInfo[i].ParallelNum));
+        TempDev2 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress2 << gFlashInfo[i].ParallelNum));
+        TempDev3 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress3 << gFlashInfo[i].ParallelNum));
+        DEBUG ((EFI_D_ERROR, "[cdtest]manufactor ID 0x%x!\n",TempData));
+        DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 1 0x%x!\n",TempDev1));
+        DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 2 0x%x!\n",TempDev2));
+        DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 3 0x%x!\n",TempDev3));
+
+        FlashReset(Base);
+
+
+        if((0xffffffff != TempData)
+            && (PortAdjustData(i, gFlashInfo[i].ManufacturerID) == TempData))
+        {
+            if((0xffffffff != TempDev1)
+                && (PortAdjustData(i, gFlashInfo[i].DeviceID1) == TempDev1))
+            {
+                if((0xffffffff != TempDev2)
+                    && (PortAdjustData(i, gFlashInfo[i].DeviceID2) == TempDev2))
+                {
+                    if((0xffffffff != TempDev3)
+                        && (PortAdjustData(i, gFlashInfo[i].DeviceID3) == TempDev3))
+                    {
+                        Flag = 0;
+                        gIndex.InfIndex = i;
+                        break;
+                    }
+                }
+            }
+         }
+    }
+
+    if(Flag)
+    {
+        return EFI_DEVICE_ERROR;
+    }
+
+    return EFI_SUCCESS;
+}
+
+
+static BOOLEAN width8IsAll(
+    const UINT64       Base,
+    const UINT64       Offset,
+    const UINT64       Length,
+    const UINT8        Value
+)
+{
+    UINT64 NewAddr = Base + Offset;
+    UINT64 NewLength = Length;
+    while (NewLength --)
+    {
+        if (*(UINT8 *)(UINTN)NewAddr == Value)
+        {
+            NewAddr ++;
+            continue;
+        }
+        else
+        {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
+
+EFI_STATUS BufferWriteCommand(UINTN Base, UINTN Offset, void *pData)
+{
+    UINT32 dwCommAddr;
+    UINT32 *pdwData;
+    UINT16 *pwData;
+    UINT32 dwLoop;
+    UINT32 ulWriteWordCount;
+    UINT32 dwAddr;
+
+    if(gFlashBusy)
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
+        return EFI_NOT_READY;
+    }
+    gFlashBusy = TRUE;
+
+    if(2 == gFlashInfo[gIndex.InfIndex].ParallelNum)
+    {
+        pdwData = (UINT32 *)pData;
+
+        dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep1);
+
+        dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr,  gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep2);
+
+        //dwAddr = Base + (Offset << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        dwAddr = (UINT32)Base + Offset;
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep3);
+
+
+       ulWriteWordCount = ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << 16) | (gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1);
+       (VOID)PortWriteData(gIndex.InfIndex, dwAddr, ulWriteWordCount);
+
+
+       for (dwLoop = 0; dwLoop < gFlashInfo[gIndex.InfIndex].BufferProgramSize; dwLoop ++)
+       {
+           dwCommAddr = (UINT32)Base + (UINT32)Offset + (dwLoop << gFlashInfo[gIndex.InfIndex].ParallelNum);
+           MmioWrite32 (dwCommAddr, *pdwData);
+           pdwData ++;
+       }
+
+       dwAddr = (UINT32)Base + (UINT32)Offset + ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << gFlashInfo[gIndex.InfIndex].ParallelNum);
+       (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramtoFlash);
+
+
+
+    }
+    else
+    {
+        pwData  = (UINT16 *)pData;
+
+        dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep1);
+
+        dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr,  gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep2);
+
+        //dwAddr = Base + (Offset << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        dwAddr = (UINT32)Base + Offset;
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep3);
+
+
+        ulWriteWordCount = gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1;
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, ulWriteWordCount);
+
+
+        for (dwLoop = 0; dwLoop < gFlashInfo[gIndex.InfIndex].BufferProgramSize; dwLoop ++)
+        {
+            dwCommAddr = (UINT32)Base + (UINT32)Offset + (dwLoop << gFlashInfo[gIndex.InfIndex].ParallelNum);
+            MmioWrite16 (dwCommAddr, *pwData);
+            pwData ++;
+        }
+
+        dwAddr = (UINT32)Base + (UINT32)Offset + ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << gFlashInfo[gIndex.InfIndex].ParallelNum);
+        (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramtoFlash);
+
+    }
+
+    (void)gBS->Stall(200);
+
+    gFlashBusy = FALSE;
+    return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS SectorEraseCommand(UINTN Base, UINTN Offset)
+{
+    UINT32 dwAddr;
+
+    if(gFlashBusy)
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
+        return EFI_NOT_READY;
+    }
+
+    gFlashBusy = TRUE;
+
+    dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep1);
+
+    dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep2);
+
+    dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep3 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep3);
+
+    dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep4 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep4);
+
+    dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep5 << gFlashInfo[gIndex.InfIndex].ParallelNum);
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep5);
+
+    dwAddr = (UINT32)Base + Offset;
+    (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep6);
+
+    (void)gBS->Stall(500000);
+
+    gFlashBusy = FALSE;
+    return EFI_SUCCESS;
+}
+
+
+EFI_STATUS CompleteCheck(UINT32 Base, UINT32 Offset, void *pData, UINT32 Length)
+{
+    UINT32 dwTestAddr;
+    UINT32 dwTestData;
+    UINT32 dwTemp = 0;
+    UINT32 dwTemp1 = 0;
+    UINT32 i;
+    UINT32 dwTimeOut = 3000000;
+
+    if(gFlashBusy)
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
+        return EFI_NOT_READY;
+    }
+    gFlashBusy = TRUE;
+
+    if(2 == gFlashInfo[gIndex.InfIndex].ParallelNum)
+    {
+        dwTestAddr = Base + Offset + Length - sizeof(UINT32);
+        dwTestData = *((UINT32 *)((UINT8 *)pData + Length - sizeof(UINT32)));
+
+        while(dwTimeOut--)
+        {
+            dwTemp1 = MmioRead32 (dwTestAddr);
+            if (dwTestData == dwTemp1)
+            {
+                dwTemp = MmioRead32 (dwTestAddr);
+                dwTemp1 = MmioRead32 (dwTestAddr);
+                if ((dwTemp == dwTemp1) && (dwTestData == dwTemp1))
+                {
+                    gFlashBusy = FALSE;
+                    return EFI_SUCCESS;
+                }
+            }
+
+            (void)gBS->Stall(1);
+        }
+
+        if((UINT16)(dwTemp1 >> 16) != (UINT16)(dwTestData >> 16))
+        {
+            DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: chip1 address %x, buffer %x, flash %x!\n", Offset, dwTestData, dwTemp1));
+        }
+        if((UINT16)(dwTemp1) != (UINT16)(dwTestData))
+        {
+            DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: chip2 address %x, buffer %x, flash %x!\n", Offset, dwTestData, dwTemp1));
+        }
+    }
+    else
+    {
+        dwTestAddr = Base + Offset + Length - sizeof(UINT16);
+        dwTestData = *((UINT16 *)((UINT8 *)pData + Length - sizeof(UINT16)));
+
+        while(dwTimeOut--)
+        {
+            dwTemp1 = MmioRead16 (dwTestAddr);
+            if (dwTestData == dwTemp1)
+            {
+                dwTemp = MmioRead16 (dwTestAddr);
+                dwTemp1 = MmioRead16 (dwTestAddr);
+                if ((dwTemp == dwTemp1) && (dwTestData == dwTemp1))
+                {
+                    gFlashBusy = FALSE;
+                    return EFI_SUCCESS;
+                }
+            }
+
+            (void)gBS->Stall(1);
+        }
+    }
+
+    for(i = 0; i < 5; i ++)
+    {
+        DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: flash %x\n",PortReadData(gIndex.InfIndex, dwTestAddr)));
+    }
+
+    FlashReset(Base);
+
+    gFlashBusy = FALSE;
+    DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: timeout address %x, buffer %x, flash %x\n", Offset, dwTestData, dwTemp1));
+    return EFI_TIMEOUT;
+}
+
+EFI_STATUS IsNeedToWrite(
+    IN  UINT32         Base,
+    IN  UINT32       Offset,
+    IN  UINT8       *Buffer,
+    IN  UINT32       Length
+  )
+{
+    UINTN NewAddr = Base + Offset;
+    UINT8 FlashData = 0;
+    UINT8 BufferData = 0;
+
+    for(; Length > 0; Length --)
+    {
+        BufferData = *Buffer;
+        //lint -epn -e511
+        FlashData = *(UINT8 *)NewAddr;
+        if (BufferData != FlashData)
+        {
+            return TRUE;
+        }
+        NewAddr ++;
+        Buffer ++;
+    }
+
+    return FALSE;
+}
+
+
+EFI_STATUS BufferWrite(UINT32 Offset, void *pData, UINT32 Length)
+{
+    EFI_STATUS Status;
+    UINT32 dwLoop;
+    UINT32 Retry = 3;
+
+    if (FALSE == IsNeedToWrite(gIndex.Base, Offset, (UINT8 *)pData, Length))
+    {
+        return EFI_SUCCESS;
+    }
+
+    do
+    {
+        (void)BufferWriteCommand(gIndex.Base, Offset, pData);
+        Status = CompleteCheck(gIndex.Base, Offset, pData, Length);
+
+
+        if (EFI_SUCCESS == Status)
+        {
+            for (dwLoop = 0; dwLoop < Length; dwLoop ++)
+            {
+                if (*(UINT8 *)(UINTN)(gIndex.Base + Offset + dwLoop) != *((UINT8 *)pData + dwLoop))
+                {
+                    DEBUG((EFI_D_ERROR, "Flash_WriteUnit ERROR: address %x, buffer %x, flash %x\n", Offset, *((UINT8 *)pData + dwLoop), *(UINT8 *)(UINTN)(gIndex.Base + Offset + dwLoop)));
+                    Status = EFI_ABORTED;
+                    continue;
+                }
+            }
+        }
+        else
+        {
+            DEBUG((EFI_D_ERROR, "Flash_WriteUnit ERROR: complete check failed, %r\n", Status));
+            continue;
+        }
+    } while ((Retry--) && EFI_ERROR(Status));
+
+    return Status;
+}
+
+
+EFI_STATUS SectorErase(UINT32 Base, UINT32 Offset)
+{
+    UINT8 gTemp[FLASH_MAX_UNIT];
+    UINT64 dwLoop = FLASH_MAX_UNIT - 1;
+    UINT32 Retry = 3;
+    EFI_STATUS Status;
+
+    do
+    {
+        gTemp[dwLoop] = 0xFF;
+    }while (dwLoop --);
+
+    do
+    {
+        (void)SectorEraseCommand(Base, Offset);
+        Status = CompleteCheck(Base, Offset, (void *)gTemp, FLASH_MAX_UNIT);
+
+
+        if (EFI_SUCCESS == Status)
+        {
+
+            if (width8IsAll(Base,Offset - (Offset % gFlashInfo[gIndex.InfIndex].BlockSize), gFlashInfo[gIndex.InfIndex].BlockSize, 0xFF))
+            {
+                return EFI_SUCCESS;
+            }
+            else
+            {
+                DEBUG((EFI_D_ERROR, "Flash_SectorErase ERROR: not all address equal 0xFF\n"));
+
+                Status = EFI_ABORTED;
+                continue;
+            }
+        }
+        else
+        {
+            DEBUG((EFI_D_ERROR, "Flash_SectorErase ERROR: complete check failed, %r\n", Status));
+            continue;
+        }
+    }while ((Retry--) && EFI_ERROR(Status));
+
+    if(Retry)
+    {
+        //do nothing for pclint
+    }
+
+    return Status;
+}

+ 116 - 0
Silicon/Hisilicon/Drivers/NorFlashDxe/NorFlashHw.h

@@ -0,0 +1,116 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 _NOR_FLASH_HW_H_
+#define _NOR_FLASH_HW_H_
+
+#include <Uefi/UefiBaseType.h>
+
+
+#define FOUR_BYTE_UNIT    4
+#define FLASH_MAX_UNIT    4
+
+#define FLASH_DEVICE_NUM  0x10
+
+
+
+typedef struct {
+    UINT32 ManufacturerID;
+    UINT32 DeviceID1;
+    UINT32 DeviceID2;
+    UINT32 DeviceID3;
+    UINT8  ParallelNum;
+    UINT32 SingleChipSize;
+    UINT32 BlockSize;
+    UINT32 BufferProgramSize;
+    UINT32 CommandType;
+}NOR_FLASH_INFO_TABLE;
+
+/*Define Command Address And Data*/
+/*reset*/
+typedef struct {
+    UINT32 CommandType;
+    UINT32 ResetData;
+}FLASH_COMMAND_RESET;
+
+/*manufacture ID & Device ID*/
+typedef struct {
+    UINT32 CommandType;
+    UINT32 ManuIDAddressStep1;
+    UINT32 ManuIDDataStep1;
+    UINT32 ManuIDAddressStep2;
+    UINT32 ManuIDDataStep2;
+    UINT32 ManuIDAddressStep3;
+    UINT32 ManuIDDataStep3;
+    UINT32 ManuIDAddress;
+
+    UINT32 DeviceIDAddress1;
+    UINT32 DeviceIDAddress2;
+    UINT32 DeviceIDAddress3;
+}FLASH_COMMAND_ID;
+
+/*Write Buffer*/
+typedef struct {
+    UINT32 CommandType;
+    UINT32 BufferProgramAddressStep1;
+    UINT32 BufferProgramDataStep1;
+    UINT32 BufferProgramAddressStep2;
+    UINT32 BufferProgramDataStep2;
+    UINT32 BufferProgramDataStep3;
+    UINT32 BufferProgramtoFlash;
+}FLASH_COMMAND_WRITE;
+
+/*erase*/
+typedef struct {
+    UINT32 CommandType;
+    UINT32 SectorEraseAddressStep1;
+    UINT32 SectorEraseDataStep1;
+    UINT32 SectorEraseAddressStep2;
+    UINT32 SectorEraseDataStep2;
+    UINT32 SectorEraseAddressStep3;
+    UINT32 SectorEraseDataStep3;
+    UINT32 SectorEraseAddressStep4;
+    UINT32 SectorEraseDataStep4;
+    UINT32 SectorEraseAddressStep5;
+    UINT32 SectorEraseDataStep5;
+    UINT32 SectorEraseDataStep6;
+}FLASH_COMMAND_ERASE;
+
+
+typedef struct {
+    UINT32 Base;
+    UINT32 InfIndex;
+    UINT32 ReIndex;
+    UINT32 IdIndex;
+    UINT32 WIndex;
+    UINT32 EIndex;
+}FLASH_INDEX;
+
+
+extern EFI_STATUS FlashInit(UINT32 Base);
+extern EFI_STATUS SectorErase(UINT32 Base, UINT32 Offset);
+extern EFI_STATUS BufferWrite(UINT32 Offset, void *pData, UINT32 Length);
+extern EFI_STATUS IsNeedToWrite(UINT32 Base, UINT32 Offset, UINT8 *Buffer, UINT32 Length);
+
+
+extern NOR_FLASH_INFO_TABLE gFlashInfo[FLASH_DEVICE_NUM];
+extern FLASH_COMMAND_RESET gFlashCommandReset[FLASH_DEVICE_NUM];
+extern FLASH_COMMAND_ID gFlashCommandId[FLASH_DEVICE_NUM];
+extern FLASH_COMMAND_WRITE gFlashCommandWrite[FLASH_DEVICE_NUM];
+extern FLASH_COMMAND_ERASE gFlashCommandErase[FLASH_DEVICE_NUM];
+extern FLASH_INDEX gIndex;
+
+
+#endif

+ 1651 - 0
Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c

@@ -0,0 +1,1651 @@
+/**
+ * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
+ * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+ * Copyright (c) 2016, 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 <Uefi.h>
+#include <Protocol/EmbeddedGpio.h>
+#include <Guid/EventGroup.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/OemMiscLib.h>
+
+#include "PciHostBridge.h"
+
+UINTN RootBridgeNumber[PCIE_MAX_HOSTBRIDGE] = { PCIE_MAX_ROOTBRIDGE,PCIE_MAX_ROOTBRIDGE };
+
+UINT64 RootBridgeAttribute[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
+    { //Host Bridge0
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+    },
+    { //Host Bridge1
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+            EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+    }
+    };
+
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
+  { //Host Bridge0
+  /* Port 0 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A03),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 1 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A04),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 2 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A05),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 3 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A06),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 4 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A07),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 5 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A08),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 6 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A09),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 7 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0A),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    }
+},
+{ // Host Bridge1
+  /* Port 0 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0B),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 1 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0C),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 2 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0D),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+  /* Port 3 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0E),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+   /* Port 4 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A0F),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 5 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A10),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 6 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A11),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    },
+    /* Port 7 */
+    {
+      {
+        {
+          ACPI_DEVICE_PATH,
+          ACPI_DP,
+          {
+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+          }
+        },
+        EISA_PNP_ID(0x0A12),
+        0
+      },
+
+      {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+          END_DEVICE_PATH_LENGTH,
+          0
+        }
+      }
+    }
+  }
+};
+
+EFI_HANDLE mDriverImageHandle;
+
+PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
+  PCI_HOST_BRIDGE_SIGNATURE,  // Signature
+  NULL,                       // HostBridgeHandle
+  0,                          // RootBridgeNumber
+  {NULL, NULL},               // Head
+  FALSE,                      // ResourceSubiteed
+  TRUE,                       // CanRestarted
+  {
+    NotifyPhase,
+    GetNextRootBridge,
+    GetAttributes,
+    StartBusEnumeration,
+    SetBusNumbers,
+    SubmitResources,
+    GetProposedResources,
+    PreprocessController
+  }
+};
+
+/**
+  Entry point of this driver
+
+  @param ImageHandle     Handle of driver image
+  @param SystemTable     Point to EFI_SYSTEM_TABLE
+
+  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
+  @retval EFI_DEVICE_ERROR      Can not install the protocol instance
+  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       Loop1;
+  UINTN                       Loop2;
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridge = NULL;
+  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
+  UINT32       PcieRootBridgeMask;
+
+  if (!OemIsMpBoot())
+  {
+    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask);
+  }
+  else
+  {
+    PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask2P);
+  }
+
+  mDriverImageHandle = ImageHandle;
+  //
+  // Create Host Bridge Device Handle
+  //
+  //Each Host Bridge have 8 Root Bridges max, every bits of 0xFF(8 bit) stands for the according PCIe Port
+  //is enable or not
+  for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
+    if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
+      continue;
+    }
+
+
+    HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);
+    if (HostBridge == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];
+    InitializeListHead (&HostBridge->Head);
+
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                  &HostBridge->HostBridgeHandle,
+                  &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
+                  NULL
+                  );
+    if (EFI_ERROR (Status)) {
+      FreePool (HostBridge);
+      return EFI_DEVICE_ERROR;
+    }
+
+    //
+    // Create Root Bridge Device Handle in this Host Bridge
+    //
+    for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {
+      if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
+        continue;
+      }
+
+      PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));
+      if (PrivateData == NULL) {
+        FreePool (HostBridge);
+        return EFI_OUT_OF_RESOURCES;
+      }
+      PrivateData->Port = Loop2;
+      PrivateData->SocType = PcdGet32(Pcdsoctype);
+      PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
+      PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];
+
+      (VOID)RootBridgeConstructor (
+           &PrivateData->Io,
+           HostBridge->HostBridgeHandle,
+           RootBridgeAttribute[Loop1][Loop2],
+           &mResAppeture[Loop1][Loop2],
+           Loop1
+      );
+
+      Status = gBS->InstallMultipleProtocolInterfaces(
+                      &PrivateData->Handle,
+                      &gEfiDevicePathProtocolGuid,      PrivateData->DevicePath,
+                      &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,
+                      NULL
+                      );
+      if (EFI_ERROR (Status)) {
+        (VOID)gBS->UninstallMultipleProtocolInterfaces (
+                HostBridge->HostBridgeHandle,
+                &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
+                NULL
+                );
+        FreePool(PrivateData);
+        FreePool (HostBridge);
+        return EFI_DEVICE_ERROR;
+      }
+      // PCI  Memory Space
+      Status = gDS->AddMemorySpace (
+             EfiGcdMemoryTypeMemoryMappedIo,
+             mResAppeture[Loop1][Loop2] .MemBase,
+             mResAppeture[Loop1][Loop2] .MemLimit -mResAppeture[Loop1][Loop2] .MemBase + 1,
+             0
+      );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR,"PCIE AddMemorySpace Error\n"));
+      }
+      InsertTailList (&HostBridge->Head, &PrivateData->Link);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+NotifyAllocateMemResources(
+ IN PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
+ IN PCI_RESOURCE_TYPE                     Index,
+ IN OUT UINT64                            *AllocatedLenMem
+)
+{
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+  EFI_STATUS                            ReturnStatus;
+  UINT64                                AddrLen;
+  UINTN                                 BitsOfAlignment;
+
+  AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+  PCIE_DEBUG("Addrlen:%llx\n", AddrLen);
+  // Get the number of '1' in Alignment.
+  BitsOfAlignment = (UINTN) (HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1);
+
+  BaseAddress = (RootBridgeInstance->MemBase + *AllocatedLenMem +
+                       RootBridgeInstance->ResAllocNode[Index].Alignment)
+                        & ~(RootBridgeInstance->ResAllocNode[Index].Alignment);
+  if ((BaseAddress + AddrLen - 1) > RootBridgeInstance->MemLimit) {
+          ReturnStatus = EFI_OUT_OF_RESOURCES;
+          RootBridgeInstance->ResAllocNode[Index].Length = 0;
+          return ReturnStatus;
+  }
+
+  PCIE_DEBUG("(P)Mem32/64 request memory at:%llx\n", BaseAddress);
+  ReturnStatus = gDS->AllocateMemorySpace (
+                     EfiGcdAllocateAddress,
+                     EfiGcdMemoryTypeMemoryMappedIo,
+                     BitsOfAlignment,
+                     AddrLen,
+                     &BaseAddress,
+                     mDriverImageHandle,
+                     NULL
+                 );
+
+  if (!EFI_ERROR (ReturnStatus)) {
+     // We were able to allocate the PCI memory
+     RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;
+     RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
+     *AllocatedLenMem += AddrLen;
+     PCIE_DEBUG("(P)Mem32/64 resource allocated:%llx\n", BaseAddress);
+
+  } else {
+      // Not able to allocate enough PCI memory
+      if (ReturnStatus != EFI_OUT_OF_RESOURCES) {
+        RootBridgeInstance->ResAllocNode[Index].Length = 0;
+      }
+    }
+  return ReturnStatus;
+}
+
+EFI_STATUS
+EFIAPI
+NotifyAllocateResources(
+ IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
+)
+{
+  EFI_STATUS                            ReturnStatus;
+  LIST_ENTRY                            *List;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  PCI_RESOURCE_TYPE                     Index;
+
+  ReturnStatus = EFI_SUCCESS;
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+
+    UINT64 AllocatedLenMem = 0;
+    for (Index = TypeIo; Index < TypeBus; Index++) {
+      if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+        if(Index == TypeIo) {
+          PCIE_DEBUG("NOT SUPPOER IO RESOURCES ON THIS PLATFORM\n");
+        } else if ((Index >= TypeMem32) && (Index <= TypePMem64)) {
+          ReturnStatus = NotifyAllocateMemResources(RootBridgeInstance,Index,&AllocatedLenMem);
+        } else {
+               ASSERT (FALSE);
+        }
+      }
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return ReturnStatus;
+}
+
+EFI_STATUS
+EFIAPI
+NotifyFreeResources(
+  IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
+)
+{
+  EFI_STATUS                            ReturnStatus;
+  LIST_ENTRY                            *List;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  PCI_RESOURCE_TYPE                     Index;
+  UINT64                                AddrLen;
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+
+  ReturnStatus = EFI_SUCCESS;
+  List = HostBridgeInstance->Head.ForwardLink;
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    for (Index = TypeIo; Index < TypeBus; Index++) {
+      if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
+        AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;
+
+        if(Index <= TypePMem64){
+          ReturnStatus = gDS->FreeMemorySpace (BaseAddress, AddrLen);
+        }else{
+          ASSERT (FALSE);
+        }
+
+        RootBridgeInstance->ResAllocNode[Index].Type      = Index;
+        RootBridgeInstance->ResAllocNode[Index].Base      = 0;
+        RootBridgeInstance->ResAllocNode[Index].Length    = 0;
+        RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
+      }
+    }
+
+    List = List->ForwardLink;
+  }
+
+  HostBridgeInstance->ResourceSubmited = FALSE;
+  HostBridgeInstance->CanRestarted     = TRUE;
+  return ReturnStatus;
+
+}
+
+VOID
+EFIAPI
+NotifyBeginEnumeration(
+  IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
+)
+{
+  LIST_ENTRY                            *List;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  PCI_RESOURCE_TYPE                     Index;
+
+  //
+  // Reset the Each Root Bridge
+  //
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    for (Index = TypeIo; Index < TypeMax; Index++) {
+      RootBridgeInstance->ResAllocNode[Index].Type      = Index;
+      RootBridgeInstance->ResAllocNode[Index].Base      = 0;
+      RootBridgeInstance->ResAllocNode[Index].Length    = 0;
+      RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  HostBridgeInstance->ResourceSubmited = FALSE;
+  HostBridgeInstance->CanRestarted     = TRUE;
+}
+
+/**
+   These are the notifications from the PCI bus driver that it is about to enter a certain
+   phase of the PCI enumeration process.
+
+   This member function can be used to notify the host bridge driver to perform specific actions,
+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
+   Eight notification points are defined at this time. See belows:
+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
+                                          structures. The PCI enumerator should issue this notification
+                                          before starting a fresh enumeration process. Enumeration cannot
+                                          be restarted after sending any other notification such as
+                                          EfiPciHostBridgeBeginBusAllocation.
+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
+                                          required here. This notification can be used to perform any
+                                          chipset-specific programming.
+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
+                                          specific action is required here. This notification can be used to
+                                          perform any chipset-specific programming.
+   EfiPciHostBridgeBeginResourceAllocation
+                                          The resource allocation phase is about to begin. No specific
+                                          action is required here. This notification can be used to perform
+                                          any chipset-specific programming.
+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
+                                          root bridges. These resource settings are returned on the next call to
+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
+                                          for gathering I/O and memory requests for
+                                          all the PCI root bridges and submitting these requests using
+                                          SubmitResources(). This function pads the resource amount
+                                          to suit the root bridge hardware, takes care of dependencies between
+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
+                                          with the allocation request. In the case of padding, the allocated range
+                                          could be bigger than what was requested.
+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
+                                          resources (proposed resources) for all the PCI root bridges. After the
+                                          hardware is programmed, reassigning resources will not be supported.
+                                          The bus settings are not affected.
+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
+                                          root bridges and resets the I/O and memory apertures to their initial
+                                          state. The bus settings are not affected. If the request to allocate
+                                          resources fails, the PCI enumerator can use this notification to
+                                          deallocate previous resources, adjust the requests, and retry
+                                          allocation.
+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
+                                          required here. This notification can be used to perform any chipsetspecific
+                                          programming.
+
+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in] Phase               The phase during enumeration
+
+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
+                                  SubmitResources() has not been called for one or more
+                                  PCI root bridges before this call
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
+                                  for a Phase of EfiPciHostBridgeSetResources.
+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
+                                  previously submitted resource requests cannot be fulfilled or
+                                  were only partially fulfilled.
+   @retval EFI_SUCCESS            The notification was accepted without any errors.
+
+**/
+EFI_STATUS
+EFIAPI
+NotifyPhase(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  EFI_STATUS                            ReturnStatus;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  ReturnStatus = EFI_SUCCESS;
+
+  switch (Phase) {
+
+  case EfiPciHostBridgeBeginEnumeration:
+  PCIE_DEBUG("Case EfiPciHostBridgeBeginEnumeration\n");
+    if (HostBridgeInstance->CanRestarted) {
+      NotifyBeginEnumeration(HostBridgeInstance);
+    } else {
+      //
+      // Can not restart
+      //
+      return EFI_NOT_READY;
+    }
+    break;
+
+  case EfiPciHostBridgeEndEnumeration:
+    PCIE_DEBUG("Case EfiPciHostBridgeEndEnumeration\n");
+    break;
+
+  case EfiPciHostBridgeBeginBusAllocation:
+    PCIE_DEBUG("Case EfiPciHostBridgeBeginBusAllocation\n");
+    //
+    // No specific action is required here, can perform any chipset specific programing
+    //
+
+    HostBridgeInstance->CanRestarted = FALSE;
+    break;
+
+  case EfiPciHostBridgeEndBusAllocation:
+    PCIE_DEBUG("Case EfiPciHostBridgeEndBusAllocation\n");
+    //
+    // No specific action is required here, can perform any chipset specific programing
+    //
+    break;
+
+  case EfiPciHostBridgeBeginResourceAllocation:
+    PCIE_DEBUG("Case EfiPciHostBridgeBeginResourceAllocation\n");
+    //
+    // No specific action is required here, can perform any chipset specific programing
+    //
+    break;
+
+  case EfiPciHostBridgeAllocateResources:
+    PCIE_DEBUG("Case EfiPciHostBridgeAllocateResources\n");
+
+    if (HostBridgeInstance->ResourceSubmited) {
+      //
+      // Take care of the resource dependencies between the root bridges
+      //
+     ReturnStatus = NotifyAllocateResources(HostBridgeInstance);
+    } else {
+      return EFI_NOT_READY;
+    }
+    //break;
+
+  case EfiPciHostBridgeSetResources:
+    PCIE_DEBUG("Case EfiPciHostBridgeSetResources\n");
+    break;
+
+  case EfiPciHostBridgeFreeResources:
+    PCIE_DEBUG("Case EfiPciHostBridgeFreeResources\n");
+
+    ReturnStatus = NotifyFreeResources(HostBridgeInstance);
+    break;
+
+  case EfiPciHostBridgeEndResourceAllocation:
+    PCIE_DEBUG("Case EfiPciHostBridgeEndResourceAllocation\n");
+    HostBridgeInstance->CanRestarted = FALSE;
+    break;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return ReturnStatus;
+}
+
+/**
+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
+
+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
+   root bridges. On each call, the handle that was returned by the previous call is passed into the
+   interface, and on output the interface returns the device handle of the next PCI root bridge. The
+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+   for that root bridge. When there are no more PCI root bridges to report, the interface returns
+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
+   are returned by this function.
+   For D945 implementation, there is only one root bridge in PCI host bridge.
+
+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
+
+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
+                                  specific Host bridge and return EFI_SUCCESS.
+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
+                                  returned on a previous call to GetNextRootBridge().
+**/
+EFI_STATUS
+EFIAPI
+GetNextRootBridge(
+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
+  )
+{
+  BOOLEAN                               NoRootBridge;
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+
+  NoRootBridge = TRUE;
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+
+  while (List != &HostBridgeInstance->Head) {
+    NoRootBridge = FALSE;
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (*RootBridgeHandle == NULL) {
+      //
+      // Return the first Root Bridge Handle of the Host Bridge
+      //
+      *RootBridgeHandle = RootBridgeInstance->Handle;
+      return EFI_SUCCESS;
+    } else {
+      if (*RootBridgeHandle == RootBridgeInstance->Handle) {
+        //
+        // Get next if have
+        //
+        List = List->ForwardLink;
+        if (List!=&HostBridgeInstance->Head) {
+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+          *RootBridgeHandle = RootBridgeInstance->Handle;
+          return EFI_SUCCESS;
+        } else {
+          return EFI_NOT_FOUND;
+        }
+      }
+    }
+
+    List = List->ForwardLink;
+  } //end while
+
+  if (NoRootBridge) {
+    return EFI_NOT_FOUND;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+/**
+   Returns the allocation attributes of a PCI root bridge.
+
+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
+   from one PCI root bridge to another. These attributes are different from the decode-related
+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
+   handles of all the root bridges that are associated with this host bridge must be obtained by calling
+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
+   after the enumeration process. The hardware may provide mechanisms to change the attributes on
+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
+   prefetchable memory.
+      Attribute                                 Description
+   ------------------------------------         ----------------------------------------------------------------------
+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
+                                                windows for nonprefetchable and prefetchable memory. A PCI bus
+                                                driver needs to include requests for prefetchable memory in the
+                                                nonprefetchable memory pool.
+
+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
+                                                windows. If this bit is not set, the PCI bus driver needs to include
+                                                requests for a 64-bit memory address in the corresponding 32-bit
+                                                memory pool.
+
+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
+
+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAttributes(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  )
+{
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+
+  if (Attributes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      *Attributes = RootBridgeInstance->RootBridgeAttrib;
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  //
+  // RootBridgeHandle is not an EFI_HANDLE
+  // that was returned on a previous call to GetNextRootBridge()
+  //
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Sets up the specified PCI root bridge for the bus enumeration process.
+
+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
+   over which the search should be performed in ACPI 2.0 resource descriptor format.
+
+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
+
+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+StartBusEnumeration(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+{
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  VOID                                  *Buffer;
+  UINT8                                 *Temp;
+  UINT64                                BusStart;
+  UINT64                                BusEnd;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      //
+      // Set up the Root Bridge for Bus Enumeration
+      //
+      BusStart = RootBridgeInstance->BusBase;
+      BusEnd   = RootBridgeInstance->BusLimit;
+      //
+      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
+      //
+
+      Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
+      if (Buffer == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Temp = (UINT8 *)Buffer;
+
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = 0x2B;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
+
+      Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
+
+      *Configuration = Buffer;
+      return EFI_SUCCESS;
+    }
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
+
+   This member function programs the specified PCI root bridge to decode the bus range that is
+   specified by the input parameter Configuration.
+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
+
+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
+   @param[in] Configuration     The pointer to the PCI bus resource descriptor
+
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
+                                  bus descriptors.
+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusNumbers(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+{
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  UINT8                                 *Ptr;
+  UINTN                                 BusStart;
+  UINTN                                 BusEnd;
+  UINTN                                 BusLen;
+
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr = Configuration;
+
+  //
+  // Check the Configuration is valid
+  //
+  if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  Ptr = Configuration;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
+      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
+      BusEnd = BusStart + BusLen - 1;
+
+      if (BusStart > BusEnd) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      //
+      // Update the Bus Range
+      //
+      RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;
+      RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;
+      RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;
+
+      //
+      // Program the Root Bridge Hardware
+      //
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+VOID
+EFIAPI
+SubmitGetResourceType(
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr,
+ OUT   UINT64*                            Index
+)
+{
+  switch (Ptr->ResType) {
+    case 0:
+      if (Ptr->AddrSpaceGranularity == 32) {
+        if (Ptr->SpecificFlag == 0x06)
+          *Index = TypePMem32;
+        else
+          *Index = TypeMem32;
+      }
+
+      if (Ptr->AddrSpaceGranularity == 64) {
+        if (Ptr->SpecificFlag == 0x06)
+          *Index = TypePMem64;
+        else
+          *Index = TypeMem64;
+      }
+      break;
+
+    case 1:
+      *Index = TypeIo;
+      break;
+
+    default:
+      break;
+  };
+
+}
+
+/**
+   Submits the I/O and memory resource requirements for the specified PCI root bridge.
+
+   This function is used to submit all the I/O and memory resources that are required by the specified
+   PCI root bridge. The input parameter Configuration is used to specify the following:
+   - The various types of resources that are required
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
+
+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
+                                  not supported by this PCI root bridge. This error will happen if the caller
+                                  did not combine resources according to Attributes that were returned by
+                                  GetAllocAttributes().
+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+SubmitResources(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+{
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  UINT8                                 *Temp;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
+  UINT64                                AddrLen;
+  UINT64                                Alignment;
+  UINTN                                 Index;
+
+  PCIE_DEBUG("In SubmitResources\n");
+  //
+  // Check the input parameter: Configuration
+  //
+  if (Configuration == NULL)
+    return EFI_INVALID_PARAMETER;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  Temp = (UINT8 *)Configuration;
+  while ( *Temp == 0x8A)
+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+
+  if (*Temp != 0x79)
+    return EFI_INVALID_PARAMETER;
+
+  Temp = (UINT8 *)Configuration;
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      while ( *Temp == 0x8A) {
+        Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
+        PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
+        PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
+        PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
+        PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
+        PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
+        PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
+        PCIE_DEBUG("RootBridgeInstance->RootBridgeAttrib:%llx\n", RootBridgeInstance->RootBridgeAttrib);
+        //
+        // Check address range alignment
+        //
+        if (Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
+          return EFI_INVALID_PARAMETER;
+        }
+        Index = 0;
+        SubmitGetResourceType(Ptr,&Index);
+        AddrLen = (UINTN) Ptr->AddrLen;
+        Alignment = (UINTN) Ptr->AddrRangeMax;
+        RootBridgeInstance->ResAllocNode[Index].Length  = AddrLen;
+        RootBridgeInstance->ResAllocNode[Index].Alignment = Alignment;
+        RootBridgeInstance->ResAllocNode[Index].Status  = ResRequested;
+        HostBridgeInstance->ResourceSubmited = TRUE;
+
+        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Returns the proposed resource settings for the specified PCI root bridge.
+
+   This member function returns the proposed resource settings for the specified PCI root bridge. The
+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+   EfiPciHostBridgeAllocateResources. The output parameter Configuration
+   specifies the following:
+   - The various types of resources, excluding bus resources, that are allocated
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+   @retval EFI_SUCCESS            The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+SetResource(
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
+  VOID                                  *Buffer
+
+)
+{
+  UINTN                                 Index;
+  UINT8                                 *Temp;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
+  UINT64                                ResStatus;
+
+  Temp = Buffer;
+
+  for (Index = 0; Index < TypeBus; Index ++)
+  {
+    if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+      Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
+      ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
+
+      switch (Index) {
+
+      case TypeIo:
+        //
+        // Io
+        //
+        Ptr->Desc = 0x8A;
+        Ptr->Len  = 0x2B;
+        Ptr->ResType = 1;
+        Ptr->GenFlag = 0;
+        Ptr->SpecificFlag = 0;
+        /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
+        Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
+                            (RootBridgeInstance->MemBase & 0xFFFFFFFF);
+        Ptr->AddrRangeMax = 0;
+        Ptr->AddrTranslationOffset = \
+             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        break;
+
+      case TypeMem32:
+        //
+        // Memory 32
+        //
+        Ptr->Desc = 0x8A;
+        Ptr->Len  = 0x2B;
+        Ptr->ResType = 0;
+        Ptr->GenFlag = 0;
+        Ptr->SpecificFlag = 0;
+        Ptr->AddrSpaceGranularity = 32;
+        /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
+        Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
+                             (RootBridgeInstance->MemBase & 0xFFFFFFFF);
+        Ptr->AddrRangeMax = 0;
+        Ptr->AddrTranslationOffset = \
+             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        break;
+
+      case TypePMem32:
+        //
+        // Prefetch memory 32
+        //
+        Ptr->Desc = 0x8A;
+        Ptr->Len  = 0x2B;
+        Ptr->ResType = 0;
+        Ptr->GenFlag = 0;
+        Ptr->SpecificFlag = 6;
+        Ptr->AddrSpaceGranularity = 32;
+        /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
+        Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
+                             (RootBridgeInstance->MemBase & 0xFFFFFFFF);
+        Ptr->AddrRangeMax = 0;
+        Ptr->AddrTranslationOffset = \
+             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        break;
+
+      case TypeMem64:
+        //
+        // Memory 64
+        //
+        Ptr->Desc = 0x8A;
+        Ptr->Len  = 0x2B;
+        Ptr->ResType = 0;
+        Ptr->GenFlag = 0;
+        Ptr->SpecificFlag = 0;
+        Ptr->AddrSpaceGranularity = 64;
+        /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
+        Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
+                             (RootBridgeInstance->MemBase & 0xFFFFFFFFFFFFFFFF);
+        Ptr->AddrRangeMax = 0;
+        Ptr->AddrTranslationOffset = \
+             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        break;
+
+      case TypePMem64:
+        //
+        // Prefetch memory 64
+        //
+        Ptr->Desc = 0x8A;
+        Ptr->Len  = 0x2B;
+        Ptr->ResType = 0;
+        Ptr->GenFlag = 0;
+        Ptr->SpecificFlag = 6;
+        Ptr->AddrSpaceGranularity = 64;
+        /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
+        Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
+                             (RootBridgeInstance->MemBase & 0xFFFFFFFFFFFFFFFF);
+        Ptr->AddrRangeMax = 0;
+        Ptr->AddrTranslationOffset = \
+             (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+        Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+        break;
+      };
+      PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
+      PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
+      PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
+      PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
+      PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
+      PCIE_DEBUG("Ptr->AddrTranslationOffset:%d\n", Ptr->AddrTranslationOffset);
+      PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
+
+      Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+    }
+  }
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
+
+  return EFI_SUCCESS;
+}
+/**
+   Returns the proposed resource settings for the specified PCI root bridge.
+
+   This member function returns the proposed resource settings for the specified PCI root bridge. The
+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+   EfiPciHostBridgeAllocateResources. The output parameter Configuration
+   specifies the following:
+   - The various types of resources, excluding bus resources, that are allocated
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+   @retval EFI_SUCCESS            The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProposedResources(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+{
+  LIST_ENTRY                            *List;
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  UINTN                                 Index;
+  UINTN                                 Number;
+  VOID                                  *Buffer;
+
+  Buffer = NULL;
+  Number = 0;
+
+  PCIE_DEBUG("In GetProposedResources\n");
+  //
+  // Get the Host Bridge Instance from the resource allocation protocol
+  //
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Enumerate the root bridges in this host bridge
+  //
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      for (Index = 0; Index < TypeBus; Index ++) {
+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+          Number ++;
+        }
+      }
+
+      Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
+      if (Buffer == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      (VOID)SetResource(RootBridgeInstance,Buffer);
+
+      *Configuration = Buffer;
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
+   PCI controllers before enumeration.
+
+   This function is called during the PCI enumeration process. No specific action is expected from this
+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
+   enumeration.
+
+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
+                            InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
+   @param Phase             The phase of the PCI device enumeration.
+
+   @retval EFI_SUCCESS              The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
+                                    bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
+  IN  EFI_HANDLE                                                RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  LIST_ENTRY                            *List;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Enumerate the root bridges in this host bridge
+  //
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      break;
+    }
+    List = List->ForwardLink;
+  }
+  if (List == &HostBridgeInstance->Head) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}

+ 521 - 0
Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h

@@ -0,0 +1,521 @@
+/**
+ * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
+ * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+ * Copyright (c) 2016, 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 _PCI_HOST_BRIDGE_H_
+#define _PCI_HOST_BRIDGE_H_
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/Metronome.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/CpuIo2.h>
+
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformPciLib.h>
+
+// Enable below statments to enable PCIE debug
+//#define  PCIE_DEBUG_ENABLE
+//#define  PCIE_VDEBUG_ENABLE
+//#define  PCIE_CDEBUG_ENABLE
+
+#ifdef PCIE_CDEBUG_ENABLE
+# define PCIE_CSR_DEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
+#else
+# define PCIE_CSR_DEBUG(arg...)
+#endif
+
+#ifdef PCIE_VDEBUG_ENABLE
+# define PCIE_VDEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
+#else
+# define PCIE_VDEBUG(arg...)
+#endif
+
+#ifdef PCIE_DEBUG_ENABLE
+# define PCIE_DEBUG(arg...) DEBUG((EFI_D_VERBOSE,## arg))
+#else
+# define PCIE_DEBUG(arg...)
+#endif
+#define PCIE_WARN(arg...) DEBUG((EFI_D_WARN,## arg))
+#define PCIE_ERR(arg...) DEBUG((EFI_D_ERROR,## arg))
+#define PCIE_INFO(arg...) DEBUG((EFI_D_INFO,## arg))
+
+#define MAX_PCI_DEVICE_NUMBER      31
+#define MAX_PCI_FUNCTION_NUMBER    7
+#define MAX_PCI_REG_ADDRESS        0xFFFF
+
+typedef enum {
+  IoOperation,
+  MemOperation,
+  PciOperation
+} OPERATION_TYPE;
+
+#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')
+typedef struct {
+  UINTN                                             Signature;
+  EFI_HANDLE                                        HostBridgeHandle;
+  UINTN                                             RootBridgeNumber;
+  LIST_ENTRY                                        Head;
+  BOOLEAN                                           ResourceSubmited;
+  BOOLEAN                                           CanRestarted;
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;
+} PCI_HOST_BRIDGE_INSTANCE;
+
+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \
+  CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+
+//
+//  HostBridge Resource Allocation interface
+//
+
+/**
+   These are the notifications from the PCI bus driver that it is about to enter a certain
+   phase of the PCI enumeration process.
+
+   This member function can be used to notify the host bridge driver to perform specific actions,
+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
+   Eight notification points are defined at this time. See belows:
+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
+                                          structures. The PCI enumerator should issue this notification
+                                          before starting a fresh enumeration process. Enumeration cannot
+                                          be restarted after sending any other notification such as
+                                          EfiPciHostBridgeBeginBusAllocation.
+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
+                                          required here. This notification can be used to perform any
+                                          chipset-specific programming.
+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
+                                          specific action is required here. This notification can be used to
+                                          perform any chipset-specific programming.
+   EfiPciHostBridgeBeginResourceAllocation
+                                          The resource allocation phase is about to begin. No specific
+                                          action is required here. This notification can be used to perform
+                                          any chipset-specific programming.
+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
+                                          root bridges. These resource settings are returned on the next call to
+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
+                                          for gathering I/O and memory requests for
+                                          all the PCI root bridges and submitting these requests using
+                                          SubmitResources(). This function pads the resource amount
+                                          to suit the root bridge hardware, takes care of dependencies between
+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
+                                          with the allocation request. In the case of padding, the allocated range
+                                          could be bigger than what was requested.
+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
+                                          resources (proposed resources) for all the PCI root bridges. After the
+                                          hardware is programmed, reassigning resources will not be supported.
+                                          The bus settings are not affected.
+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
+                                          root bridges and resets the I/O and memory apertures to their initial
+                                          state. The bus settings are not affected. If the request to allocate
+                                          resources fails, the PCI enumerator can use this notification to
+                                          deallocate previous resources, adjust the requests, and retry
+                                          allocation.
+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
+                                          required here. This notification can be used to perform any chipsetspecific
+                                          programming.
+
+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in] Phase               The phase during enumeration
+
+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
+                                  SubmitResources() has not been called for one or more
+                                  PCI root bridges before this call
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
+                                  for a Phase of EfiPciHostBridgeSetResources.
+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
+                                  previously submitted resource requests cannot be fulfilled or
+                                  were only partially fulfilled.
+   @retval EFI_SUCCESS            The notification was accepted without any errors.
+
+**/
+EFI_STATUS
+EFIAPI
+NotifyPhase(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
+  );
+
+/**
+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
+
+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
+   root bridges. On each call, the handle that was returned by the previous call is passed into the
+   interface, and on output the interface returns the device handle of the next PCI root bridge. The
+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+   for that root bridge. When there are no more PCI root bridges to report, the interface returns
+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
+   are returned by this function.
+   For D945 implementation, there is only one root bridge in PCI host bridge.
+
+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
+
+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
+                                  specific Host bridge and return EFI_SUCCESS.
+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
+                                  returned on a previous call to GetNextRootBridge().
+**/
+EFI_STATUS
+EFIAPI
+GetNextRootBridge(
+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
+  );
+
+/**
+   Returns the allocation attributes of a PCI root bridge.
+
+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
+   from one PCI root bridge to another. These attributes are different from the decode-related
+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
+   handles of all the root bridges that are associated with this host bridge must be obtained by calling
+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
+   after the enumeration process. The hardware may provide mechanisms to change the attributes on
+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
+   prefetchable memory.
+      Attribute                                 Description
+   ------------------------------------         ----------------------------------------------------------------------
+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
+                                                windows for nonprefetchable and prefetchable memory. A PCI bus
+                                                driver needs to include requests for prefetchable memory in the
+                                                nonprefetchable memory pool.
+
+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
+                                                windows. If this bit is not set, the PCI bus driver needs to include
+                                                requests for a 64-bit memory address in the corresponding 32-bit
+                                                memory pool.
+
+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
+
+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAttributes(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  );
+
+/**
+   Sets up the specified PCI root bridge for the bus enumeration process.
+
+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
+   over which the search should be performed in ACPI 2.0 resource descriptor format.
+
+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
+
+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+StartBusEnumeration(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  );
+
+/**
+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
+
+   This member function programs the specified PCI root bridge to decode the bus range that is
+   specified by the input parameter Configuration.
+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
+
+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
+   @param[in] Configuration     The pointer to the PCI bus resource descriptor
+
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
+                                  bus descriptors.
+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusNumbers(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  );
+
+/**
+   Submits the I/O and memory resource requirements for the specified PCI root bridge.
+
+   This function is used to submit all the I/O and memory resources that are required by the specified
+   PCI root bridge. The input parameter Configuration is used to specify the following:
+   - The various types of resources that are required
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
+
+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
+                                  not supported by this PCI root bridge. This error will happen if the caller
+                                  did not combine resources according to Attributes that were returned by
+                                  GetAllocAttributes().
+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+SubmitResources(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  );
+
+/**
+   Returns the proposed resource settings for the specified PCI root bridge.
+
+   This member function returns the proposed resource settings for the specified PCI root bridge. The
+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+   EfiPciHostBridgeAllocateResources. The output parameter Configuration
+   specifies the following:
+   - The various types of resources, excluding bus resources, that are allocated
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+   @retval EFI_SUCCESS            The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProposedResources(
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  );
+
+/**
+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
+   PCI controllers before enumeration.
+
+   This function is called during the PCI enumeration process. No specific action is expected from this
+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
+   enumeration.
+
+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
+                            InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
+   @param Phase             The phase of the PCI device enumeration.
+
+   @retval EFI_SUCCESS              The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
+                                    bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
+  );
+
+
+//
+// Define resource status constant
+//
+#define EFI_RESOURCE_NONEXISTENT   0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS          0xFFFFFFFFFFFFFFFEULL
+
+
+//
+// Driver Instance Data Prototypes
+//
+
+typedef struct {
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation;
+  UINTN                                      NumberOfBytes;
+  UINTN                                      NumberOfPages;
+  EFI_PHYSICAL_ADDRESS                       HostAddress;
+  EFI_PHYSICAL_ADDRESS                       MappedHostAddress;
+} MAP_INFO;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH              AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL          EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+typedef enum {
+  TypeIo = 0,
+  TypeMem32,
+  TypePMem32,
+  TypeMem64,
+  TypePMem64,
+  TypeBus,
+  TypeMax
+} PCI_RESOURCE_TYPE;
+
+typedef enum {
+  ResNone = 0,
+  ResSubmitted,
+  ResRequested,
+  ResAllocated,
+  ResStatusMax
+} RES_STATUS;
+
+typedef struct {
+  PCI_RESOURCE_TYPE Type;
+  UINT64            Base;
+  UINT64            Length;
+  UINT64            Alignment;
+  RES_STATUS        Status;
+} PCI_RES_NODE;
+
+#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')
+
+typedef struct {
+  UINT32                 Signature;
+  LIST_ENTRY             Link;
+  EFI_HANDLE             Handle;
+  UINT64                 RootBridgeAttrib;
+  UINT64                 Attributes;
+  UINT64                 Supports;
+
+  //
+  // Specific for this memory controller: Bus, I/O, Mem
+  //
+  PCI_RES_NODE           ResAllocNode[6];
+
+  //
+  // Addressing for Memory and I/O and Bus arrange
+  //
+  UINT64                 BusBase;
+  UINT64                 MemBase;
+  UINT64                 IoBase;
+  UINT64                 BusLimit;
+  UINT64                 MemLimit;
+  UINT64                 IoLimit;
+  UINT64                 RbPciBar;
+  UINT64                 Ecam;
+
+  UINTN                  PciAddress;
+  UINTN                  PciData;
+  UINTN                  Port;
+  UINT32                 SocType;
+  UINT64                 CpuMemRegionBase;
+  UINT64                 CpuIoRegionBase;
+  UINT64                 PciRegionBase;
+  UINT64                 PciRegionLimit;
+
+  EFI_DEVICE_PATH_PROTOCOL                *DevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         Io;
+
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+
+//
+// Driver Instance Data Macros
+//
+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+
+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \
+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
+
+/**
+
+  Construct the Pci Root Bridge Io protocol
+
+  @param Protocol         Point to protocol instance
+  @param HostBridgeHandle Handle of host bridge
+  @param Attri            Attribute of host bridge
+  @param ResAppeture      ResourceAppeture for host bridge
+
+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
+
+**/
+EFI_STATUS
+RootBridgeConstructor (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
+  IN EFI_HANDLE                         HostBridgeHandle,
+  IN UINT64                             Attri,
+  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture,
+  IN UINT32                             Seg
+  );
+
+#endif

+ 74 - 0
Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf

@@ -0,0 +1,74 @@
+## @file
+#
+#  Component description file PCI Host Bridge driver.
+#  Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
+#  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#  Copyright (c) 2016, 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                      = PciHostBridge
+  FILE_GUID                      = B0E61270-263F-11E3-8224-0800200C9A66
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializePciHostBridge
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  DxeServicesTableLib
+  CacheMaintenanceLib
+  DmaLib
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  TimerLib
+  ArmLib
+  DevicePathLib
+  PcdLib
+  OemMiscLib
+
+[Sources]
+  PciHostBridge.c
+  PciRootBridgeIo.c
+  PciHostBridge.h
+
+[Protocols]
+  gEfiPciHostBridgeResourceAllocationProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiMetronomeArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEmbeddedGpioProtocolGuid
+
+[depex]
+  gEfiMetronomeArchProtocolGuid
+
+[FeaturePcd]
+
+[Pcd]
+
+[FixedPcd]
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask
+  gHisiTokenSpaceGuid.PcdPcieRootBridgeMask2P
+  gHisiTokenSpaceGuid.Pcdsoctype
+
+[Guids]
+  gEfiEventExitBootServicesGuid                 ## PRODUCES ## Event

+ 2313 - 0
Silicon/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c

@@ -0,0 +1,2313 @@
+/**
+ * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
+ * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+ * Copyright (c) 2016, 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 "PciHostBridge.h"
+#include <Library/DevicePathLib.h>
+#include <Library/DmaLib.h>
+#include <Library/PciExpressLib.h>
+#include <Regs/HisiPcieV1RegOffset.h>
+
+
+typedef struct {
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];
+  EFI_ACPI_END_TAG_DESCRIPTOR           EndDesp;
+} RESOURCE_CONFIGURATION;
+
+RESOURCE_CONFIGURATION Configuration = {
+  {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},
+  {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0},
+  {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},
+  {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},
+  {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},
+  {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},
+  {0x79, 0}
+};
+
+//
+// Protocol Member Function Prototypes
+//
+
+/**
+   Polls an address in memory mapped I/O space until an exit condition is met, or
+   a timeout occurs.
+
+   This function provides a standard way to poll a PCI memory location. A PCI memory read
+   operation is performed at the PCI memory address specified by Address for the width specified
+   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
+   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
+   Mask) is equal to Value.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The base address of the memory operations. The caller is
+                          responsible for aligning Address if required.
+   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
+                          are ignored. The bits in the bytes below Width which are zero in
+                          Mask are ignored when polling the memory address.
+   @param[in]   Value     The comparison value used for the polling exit criteria.
+   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
+                          be of poorer granularity.
+   @param[out]  Result    Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  );
+
+/**
+   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
+   satisfied or after a defined duration.
+
+   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
+   performed at the PCI I/O address specified by Address for the width specified by Width.
+   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
+   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
+   to Value.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Width     Signifies the width of the I/O operations.
+   @param[in] Address   The base address of the I/O operations. The caller is responsible
+                        for aligning Address if required.
+   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
+                        are ignored. The bits in the bytes below Width which are zero in
+                        Mask are ignored when polling the I/O address.
+   @param[in] Value     The comparison value used for the polling exit criteria.
+   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
+                        be of poorer granularity.
+   @param[out] Result   Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+                          responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  OUT    VOID                                   *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+                          responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN     VOID                                   *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
+                            aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+                            size * Count, starting at Address.
+   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For
+                            write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  OUT    VOID                                   *UserBuffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
+                            aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+                            size * Count, starting at Address.
+   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For
+                            write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN     VOID                                   *UserBuffer
+  );
+
+/**
+   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
+   root bridge memory space.
+
+   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
+   space to another region of PCI root bridge memory space. This is especially useful for video scroll
+   operation on a memory mapped video buffer.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
+
+   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+   @param[in] Width       Signifies the width of the memory operations.
+   @param[in] DestAddress The destination address of the memory operation. The caller is
+                          responsible for aligning the DestAddress if required.
+   @param[in] SrcAddress  The source address of the memory operation. The caller is
+                          responsible for aligning the SrcAddress if required.
+   @param[in] Count       The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at DestAddress and SrcAddress.
+
+   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
+   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
+   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 DestAddress,
+  IN     UINT64                                 SrcAddress,
+  IN     UINTN                                  Count
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+                          moved is Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  OUT    VOID                                   *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+                          moved is Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN     VOID                                   *Buffer
+  );
+
+/**
+   Provides the PCI controller-specific addresses required to access system memory from a
+   DMA bus master.
+
+   The Map() function provides the PCI controller specific addresses needed to access system
+   memory. This function is used to map system memory for PCI bus master DMA accesses.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
+   @param[in]       HostAddress     The system memory address to map to the PCI controller.
+   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
+   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
+                                    to access the system memory's HostAddress.
+   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
+
+   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
+   @retval EFI_INVALID_PARAMETER  Operation is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
+   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
+   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
+   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  );
+
+/**
+   Completes the Map() operation and releases any corresponding resources.
+
+   The Unmap() function completes the Map() operation and releases any corresponding resources.
+   If the operation was an EfiPciOperationBusMasterWrite or
+   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
+   Any resources used for the mapping are freed.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Mapping   The mapping value returned from Map().
+
+   @retval EFI_SUCCESS            The range was unmapped.
+   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
+   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  VOID                             *Mapping
+  );
+
+/**
+   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
+   EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Type        This parameter is not used and must be ignored.
+   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
+   @param Pages       The number of pages to allocate.
+   @param HostAddress A pointer to store the base system memory address of the allocated range.
+   @param Attributes  The requested bit mask of attributes for the allocated range. Only
+                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
+                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
+
+   @retval EFI_SUCCESS            The requested memory pages were allocated.
+   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
+                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  EFI_ALLOCATE_TYPE                Type,
+  IN  EFI_MEMORY_TYPE                  MemoryType,
+  IN  UINTN                            Pages,
+  OUT VOID                             **HostAddress,
+  IN  UINT64                           Attributes
+  );
+
+/**
+   Frees memory that was allocated with AllocateBuffer().
+
+   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Pages       The number of pages to free.
+   @param HostAddress The base system memory address of the allocated range.
+
+   @retval EFI_SUCCESS            The requested memory pages were freed.
+   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
+                                  was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  UINTN                            Pages,
+  OUT VOID                             *HostAddress
+  );
+
+/**
+   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
+   memory. Posted write transactions are generated by PCI bus masters when they perform write
+   transactions to target addresses in system memory.
+   This function does not flush posted write transactions from any PCI bridges. A PCI controller
+   specific action must be taken to guarantee that the posted write transactions have been flushed from
+   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
+   a PCI read transaction from the PCI controller prior to calling Flush().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
+                              bridge to system memory.
+   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
+                              host bridge due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
+  );
+
+/**
+   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
+   attributes that a PCI root bridge is currently using.
+
+   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
+   and the mask of attributes that the PCI root bridge is currently using.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Supported   A pointer to the mask of attributes that this PCI root bridge
+                      supports setting with SetAttributes().
+   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
+                      currently using.
+
+   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
+                                  bridge supports is returned in Supports. If Attributes is
+                                  not NULL, then the attributes that the PCI root bridge is currently
+                                  using is returned in Attributes.
+   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT UINT64                           *Supported,
+  OUT UINT64                           *Attributes
+  );
+
+/**
+   Sets attributes for a resource range on a PCI root bridge.
+
+   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
+   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
+   granularity of setting these attributes may vary from resource type to resource type, and from
+   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
+   result, this function may set the attributes specified by Attributes on a larger resource range
+   than the caller requested. The actual range is returned in ResourceBase and
+   ResourceLength. The caller is responsible for verifying that the actual range for which the
+   attributes were set is acceptable.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
+                                    MEMORY_DISABLE is set, then the resource range is specified by
+                                    ResourceBase and ResourceLength. If
+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+                                    MEMORY_DISABLE are not set, then ResourceBase and
+                                    ResourceLength are ignored, and may be NULL.
+   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
+                                    by the attributes specified by Attributes.
+   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
+                                    attributes specified by Attributes.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN     UINT64                           Attributes,
+  IN OUT UINT64                           *ResourceBase,
+  IN OUT UINT64                           *ResourceLength
+  );
+
+/**
+   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
+   resource descriptors.
+
+   There are only two resource descriptor types from the ACPI Specification that may be used to
+   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
+   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
+   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
+   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
+   Address Space Descriptors followed by an End Tag.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
+                            current configuration of this PCI root bridge. The storage for the
+                            ACPI 2.0 resource descriptors is allocated by this function. The
+                            caller must treat the return buffer as read-only data, and the buffer
+                            must not be freed by the caller.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT    VOID                             **Resources
+  );
+
+//
+// Memory Controller Pci Root Bridge Io Module Variables
+//
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mInStride[] = {
+  1, // EfiPciWidthUint8
+  2, // EfiPciWidthUint16
+  4, // EfiPciWidthUint32
+  8, // EfiPciWidthUint64
+  0, // EfiPciWidthFifoUint8
+  0, // EfiPciWidthFifoUint16
+  0, // EfiPciWidthFifoUint32
+  0, // EfiPciWidthFifoUint64
+  1, // EfiPciWidthFillUint8
+  2, // EfiPciWidthFillUint16
+  4, // EfiPciWidthFillUint32
+  8  // EfiPciWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mOutStride[] = {
+  1, // EfiPciWidthUint8
+  2, // EfiPciWidthUint16
+  4, // EfiPciWidthUint32
+  8, // EfiPciWidthUint64
+  1, // EfiPciWidthFifoUint8
+  2, // EfiPciWidthFifoUint16
+  4, // EfiPciWidthFifoUint32
+  8, // EfiPciWidthFifoUint64
+  0, // EfiPciWidthFillUint8
+  0, // EfiPciWidthFillUint16
+  0, // EfiPciWidthFillUint32
+  0  // EfiPciWidthFillUint64
+};
+
+
+UINT64 GetPcieCfgAddress (
+    UINT64 Ecam,
+    UINTN Bus,
+    UINTN Device,
+    UINTN Function,
+    UINTN Reg
+    )
+{
+  return Ecam + PCI_EXPRESS_LIB_ADDRESS (Bus, Device, Function, Reg);
+}
+
+
+void SetAtuConfig0RW (
+    PCI_ROOT_BRIDGE_INSTANCE *Private,
+    UINT32 Index
+    )
+{
+    UINTN RbPciBase = Private->RbPciBar;
+    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusBase + 1, 1, 0, 0) - 1;
+
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG0);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+void SetAtuConfig1RW (
+    PCI_ROOT_BRIDGE_INSTANCE *Private,
+    UINT32 Index
+    )
+{
+    UINTN RbPciBase = Private->RbPciBar;
+    UINT64 MemLimit = GetPcieCfgAddress (Private->Ecam, Private->BusLimit + 1, 0, 0, 0) - 1;
+
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_CONFIG1);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(Private->Ecam));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(Private->Ecam) >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, 0);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, 0);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_SHIIF_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+void SetAtuIoRW(UINT64 RbPciBase,UINT64 IoBase,UINT64 CpuIoRegionLimit, UINT64 CpuIoRegionBase, UINT32 Index)
+{
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_IO);
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuIoRegionBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)CpuIoRegionBase >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuIoRegionLimit));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(IoBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(IoBase) >> 32));
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+void SetAtuMemRW(UINT64 RbPciBase,UINT64 MemBase,UINT64 CpuMemRegionLimit, UINT64 CpuMemRegionBase, UINT32 Index)
+{
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, Index);
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL1, IATU_CTRL1_TYPE_MEM);
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LOW, (UINT32)(CpuMemRegionBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_HIGH, (UINT32)((UINT64)(CpuMemRegionBase) >> 32));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32)(CpuMemRegionLimit));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_LOW, (UINT32)(MemBase));
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_TARGET_HIGH, (UINT32)((UINT64)(MemBase) >> 32));
+
+    MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_CTRL2, IATU_NORMAL_MODE);
+
+    {
+      UINTN i;
+      for (i=0; i<0x20; i+=4) {
+        DEBUG ((EFI_D_ERROR, "[%a:%d] - Base=%p value=%x\n", __FUNCTION__, __LINE__, RbPciBase + 0x900 + i, MmioRead32(RbPciBase + 0x900 + i)));
+      }
+    }
+}
+
+VOID InitAtu (PCI_ROOT_BRIDGE_INSTANCE *Private)
+{
+  SetAtuMemRW (Private->RbPciBar, Private->PciRegionBase, Private->PciRegionLimit, Private->CpuMemRegionBase, 0);
+  SetAtuConfig0RW (Private, 1);
+  SetAtuConfig1RW (Private, 2);
+  SetAtuIoRW (Private->RbPciBar, Private->IoBase, Private->IoLimit, Private->CpuIoRegionBase, 3);
+}
+
+
+BOOLEAN PcieIsLinkUp (UINT32 SocType, UINTN RbPciBar, UINTN Port)
+{
+    UINT32                     Value = 0;
+
+    if (0x1610 == SocType)
+    {
+        Value = MmioRead32(RbPciBar + 0x131C);
+        if ((Value & 0x3F) == 0x11)
+        {
+            return TRUE;
+        }
+        return FALSE;
+    }
+    else
+    {
+        Value = MmioRead32 (0xb0000000 + 0x6818 + 0x100 * Port);
+        if ((Value & 0x3F) == 0x11)
+        {
+            return TRUE;
+        }
+        return FALSE;
+    }
+}
+
+/**
+
+  Construct the Pci Root Bridge Io protocol
+
+  @param Protocol         Point to protocol instance
+  @param HostBridgeHandle Handle of host bridge
+  @param Attri            Attribute of host bridge
+  @param ResAppeture      ResourceAppeture for host bridge
+
+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
+
+**/
+EFI_STATUS
+RootBridgeConstructor (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
+  IN EFI_HANDLE                         HostBridgeHandle,
+  IN UINT64                             Attri,
+  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture,
+  IN UINT32                             Seg
+  )
+{
+  EFI_STATUS                        Status;
+  PCI_ROOT_BRIDGE_INSTANCE          *PrivateData;
+  PCI_RESOURCE_TYPE                 Index;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
+
+  //
+  // The host to pci bridge, the host memory and io addresses are
+  // direct mapped to pci addresses, so no need translate, set bases to 0.
+  //
+  PrivateData->MemBase = ResAppeture->MemBase;
+  PrivateData->IoBase  = ResAppeture->IoBase;
+  PrivateData->RbPciBar = ResAppeture->RbPciBar;
+  PrivateData->MemLimit = ResAppeture->MemLimit;
+  PrivateData->IoLimit  = ResAppeture->IoLimit;
+  PrivateData->Ecam = ResAppeture->Ecam;
+  PrivateData->CpuMemRegionBase = ResAppeture->CpuMemRegionBase;
+  PrivateData->CpuIoRegionBase = ResAppeture->CpuIoRegionBase;
+  PrivateData->PciRegionBase = ResAppeture->PciRegionBase;
+  PrivateData->PciRegionLimit = ResAppeture->PciRegionLimit;
+
+  //
+  // Bus Appeture for this Root Bridge (Possible Range)
+  //
+  PrivateData->BusBase  = ResAppeture->BusBase;
+  PrivateData->BusLimit = ResAppeture->BusLimit;
+
+  //
+  // Specific for this chipset
+  //
+  for (Index = TypeIo; Index < TypeMax; Index++) {
+    PrivateData->ResAllocNode[Index].Type      = Index;
+    PrivateData->ResAllocNode[Index].Base      = 0;
+    PrivateData->ResAllocNode[Index].Length    = 0;
+    PrivateData->ResAllocNode[Index].Status    = ResNone;
+  }
+
+  PrivateData->RootBridgeAttrib = Attri;
+
+  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \
+                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
+                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
+                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 | \
+                             EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER;
+  PrivateData->Attributes  = PrivateData->Supports;
+
+  Protocol->ParentHandle   = HostBridgeHandle;
+
+  Protocol->PollMem        = RootBridgeIoPollMem;
+  Protocol->PollIo         = RootBridgeIoPollIo;
+
+  Protocol->Mem.Read       = RootBridgeIoMemRead;
+  Protocol->Mem.Write      = RootBridgeIoMemWrite;
+
+  Protocol->Io.Read        = RootBridgeIoIoRead;
+  Protocol->Io.Write       = RootBridgeIoIoWrite;
+
+  Protocol->CopyMem        = RootBridgeIoCopyMem;
+
+  Protocol->Pci.Read       = RootBridgeIoPciRead;
+  Protocol->Pci.Write      = RootBridgeIoPciWrite;
+
+  Protocol->Map            = RootBridgeIoMap;
+  Protocol->Unmap          = RootBridgeIoUnmap;
+
+  Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
+  Protocol->FreeBuffer     = RootBridgeIoFreeBuffer;
+
+  Protocol->Flush          = RootBridgeIoFlush;
+
+  Protocol->GetAttributes  = RootBridgeIoGetAttributes;
+  Protocol->SetAttributes  = RootBridgeIoSetAttributes;
+
+  Protocol->Configuration  = RootBridgeIoConfiguration;
+
+  Protocol->SegmentNumber  = Seg;
+
+  InitAtu (PrivateData);
+
+  Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
+  if (EFI_ERROR(Status))
+  {
+      DEBUG((EFI_D_ERROR,"LocateProtocol MetronomeArchProtocol Error\n"));
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+  @param[in] Address        The base address of the I/O operation.
+  @param[in] Count          The number of I/O operations to perform. The number of
+                            bytes moved is Width size * Count, starting at Address.
+  @param[in] Buffer         For read operations, the destination buffer to store the results.
+                            For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+RootBridgeIoCheckParameter (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN OPERATION_TYPE                         OperationType,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                                 Address,
+  IN UINTN                                  Count,
+  IN VOID                                   *Buffer
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;
+  UINT64                                       MaxCount;
+  UINT64                                       Base;
+  UINT64                                       Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the access,
+  // so treat Count as 1
+  //
+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Address is aligned
+  //
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  //
+  // Check to see if any address associated with this transfer exceeds the maximum
+  // allowed address.  The maximum address implied by the parameters passed in is
+  // Address + Size * Count.  If the following condition is met, then the transfer
+  // is not supported.
+  //
+  //    Address + Size * Count > Limit + 1
+  //
+  // Since Limit can be the maximum integer value supported by the CPU and Count
+  // can also be the maximum integer value supported by the CPU, this range
+  // check must be adjusted to avoid all oveflow conditions.
+  //
+  // The following form of the range check is equivalent but assumes that
+  // Limit is of the form (2^n - 1).
+  //
+  if (OperationType == IoOperation) {
+    Base = PrivateData->IoBase;
+    Limit = PrivateData->IoLimit;
+  } else if (OperationType == MemOperation) {
+    Base = PrivateData->MemBase;
+    Limit = PrivateData->MemLimit;
+  } else {
+    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
+    if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    /* The root complex has only one device / function */
+    if (PciRbAddr->Bus == PrivateData->BusBase && PciRbAddr->Device != 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    /* The other side of the RC has only one device as well */
+    if (PciRbAddr->Bus == (PrivateData->BusBase + 1 ) && PciRbAddr->Device != 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (PciRbAddr->ExtendedRegister != 0) {
+      Address = PciRbAddr->ExtendedRegister;
+    } else {
+      Address = PciRbAddr->Register;
+    }
+    Base = 0;
+    Limit = MAX_PCI_REG_ADDRESS;
+  }
+
+  if (Address < Base) {
+      return EFI_INVALID_PARAMETER;
+  }
+
+  if (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Internal help function for read and write memory space.
+
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Write         Switch value for Read or Write.
+   @param[in]   Width         Signifies the width of the memory operations.
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
+                              moved is Width size * Count, starting at Address.
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+                              write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+RootBridgeIoMemRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     BOOLEAN                                Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+{
+  EFI_STATUS                             Status;
+  UINT8                                  InStride;
+  UINT8                                  OutStride;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                                  *Uint8Buffer;
+  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+  /* Address is bus resource */
+  Address -= PrivateData->PciRegionBase;
+  Address += PrivateData->CpuMemRegionBase;
+
+  PCIE_DEBUG("RootBridgeIoMemRW Address:0x%llx\n", Address);
+  PCIE_DEBUG("RootBridgeIoMemRW Count:0x%llx\n", Count);
+  PCIE_DEBUG("RootBridgeIoMemRW Write:0x%llx\n", Write);
+  PCIE_DEBUG("RootBridgeIoMemRW Width:0x%llx\n", Width);
+
+  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (Write) {
+      switch (OperationWidth) {
+        case EfiPciWidthUint8:
+          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+          break;
+        case EfiPciWidthUint16:
+          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+          break;
+        case EfiPciWidthUint32:
+          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+          break;
+        case EfiPciWidthUint64:
+          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+          break;
+        default:
+          //
+          // The RootBridgeIoCheckParameter call above will ensure that this
+          // path is not taken.
+          //
+          ASSERT (FALSE);
+          break;
+      }
+    } else {
+      switch (OperationWidth) {
+        case EfiPciWidthUint8:
+          *Uint8Buffer = MmioRead8 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint16:
+          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint32:
+          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint64:
+          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+          break;
+        default:
+          //
+          // The RootBridgeIoCheckParameter call above will ensure that this
+          // path is not taken.
+          //
+          ASSERT (FALSE);
+          break;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+   Internal help function for read and write IO space.
+
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Write         Switch value for Read or Write.
+   @param[in]   Width         Signifies the width of the memory operations.
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
+                              moved is Width size * Count, starting at Address.
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+                              write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+RootBridgeIoIoRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     BOOLEAN                                Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+{
+  EFI_STATUS                             Status;
+  UINT8                                  InStride;
+  UINT8                                  OutStride;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                                  *Uint8Buffer;
+  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+  /* Address is bus resource */
+  Address -= PrivateData->IoBase;
+  Address += PrivateData->CpuIoRegionBase;
+
+  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (Write) {
+      switch (OperationWidth) {
+        case EfiPciWidthUint8:
+          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+          break;
+        case EfiPciWidthUint16:
+          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+          break;
+        case EfiPciWidthUint32:
+          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+          break;
+        case EfiPciWidthUint64:
+          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+          break;
+        default:
+          //
+          // The RootBridgeIoCheckParameter call above will ensure that this
+          // path is not taken.
+          //
+          ASSERT (FALSE);
+          break;
+      }
+    } else {
+      switch (OperationWidth) {
+        case EfiPciWidthUint8:
+          *Uint8Buffer = MmioRead8 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint16:
+          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint32:
+          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+          break;
+        case EfiPciWidthUint64:
+          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+          break;
+        default:
+          //
+          // The RootBridgeIoCheckParameter call above will ensure that this
+          // path is not taken.
+          //
+          ASSERT (FALSE);
+          break;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+   Polls an address in memory mapped I/O space until an exit condition is met, or
+   a timeout occurs.
+
+   This function provides a standard way to poll a PCI memory location. A PCI memory read
+   operation is performed at the PCI memory address specified by Address for the width specified
+   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
+   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
+   Mask) is equal to Value.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The base address of the memory operations. The caller is
+                          responsible for aligning Address if required.
+   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
+                          are ignored. The bits in the bytes below Width which are zero in
+                          Mask are ignored when polling the memory address.
+   @param[in]   Value     The comparison value used for the polling exit criteria.
+   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
+                          be of poorer granularity.
+   @param[out]  Result    Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      NumberOfTicks;
+  UINT32      Remainder;
+
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // No matter what, always do a single poll.
+  //
+  Status = This->Mem.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+
+  } else {
+
+    //
+    // Determine the proper # of metronome ticks to wait for polling the
+    // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+    // The "+1" to account for the possibility of the first tick being short
+    // because we started in the middle of a tick.
+    //
+    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
+    // protocol definition is updated.
+    //
+    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
+    if (Remainder != 0) {
+      NumberOfTicks += 1;
+    }
+    NumberOfTicks += 1;
+
+    while (NumberOfTicks != 0) {
+
+      mMetronome->WaitForTick (mMetronome, 1);
+
+      Status = This->Mem.Read (This, Width, Address, 1, Result);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      if ((*Result & Mask) == Value) {
+        return EFI_SUCCESS;
+      }
+
+      NumberOfTicks -= 1;
+    }
+  }
+  return EFI_TIMEOUT;
+}
+
+/**
+   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
+   satisfied or after a defined duration.
+
+   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
+   performed at the PCI I/O address specified by Address for the width specified by Width.
+   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
+   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
+   to Value.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Width     Signifies the width of the I/O operations.
+   @param[in] Address   The base address of the I/O operations. The caller is responsible
+                        for aligning Address if required.
+   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
+                        are ignored. The bits in the bytes below Width which are zero in
+                        Mask are ignored when polling the I/O address.
+   @param[in] Value     The comparison value used for the polling exit criteria.
+   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
+                        be of poorer granularity.
+   @param[out] Result   Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      NumberOfTicks;
+  UINT32      Remainder;
+
+  //
+  // No matter what, always do a single poll.
+  //
+
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = This->Io.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_SUCCESS;
+
+  } else {
+
+    //
+    // Determine the proper # of metronome ticks to wait for polling the
+    // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+    // The "+1" to account for the possibility of the first tick being short
+    // because we started in the middle of a tick.
+    //
+    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);
+    if (Remainder != 0) {
+      NumberOfTicks += 1;
+    }
+    NumberOfTicks += 1;
+
+    while (NumberOfTicks != 0) {
+
+      mMetronome->WaitForTick (mMetronome, 1);
+
+      Status = This->Io.Read (This, Width, Address, 1, Result);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      if ((*Result & Mask) == Value) {
+        return EFI_SUCCESS;
+      }
+
+      NumberOfTicks -= 1;
+    }
+  }
+  return EFI_TIMEOUT;
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+                          responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  OUT    VOID                                   *Buffer
+  )
+{
+  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+                          responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN     VOID                                   *Buffer
+  )
+{
+  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
+                            aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+                            size * Count, starting at Address.
+   @param[out]  Buffer      For read operations, the destination buffer to store the results. For
+                            write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  OUT    VOID                                   *Buffer
+  )
+{
+  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
+                            aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+                            size * Count, starting at Address.
+   @param[in]   Buffer       For read operations, the destination buffer to store the results. For
+                            write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *This,
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,
+  IN       UINT64                                  Address,
+  IN       UINTN                                   Count,
+  IN       VOID                                    *Buffer
+  )
+{
+  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
+   root bridge memory space.
+
+   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
+   space to another region of PCI root bridge memory space. This is especially useful for video scroll
+   operation on a memory mapped video buffer.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
+
+   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+   @param[in] Width       Signifies the width of the memory operations.
+   @param[in] DestAddress The destination address of the memory operation. The caller is
+                          responsible for aligning the DestAddress if required.
+   @param[in] SrcAddress  The source address of the memory operation. The caller is
+                          responsible for aligning the SrcAddress if required.
+   @param[in] Count       The number of memory operations to perform. Bytes moved is
+                          Width size * Count, starting at DestAddress and SrcAddress.
+
+   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
+   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
+   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,
+  IN UINT64                                       DestAddress,
+  IN UINT64                                       SrcAddress,
+  IN UINTN                                        Count
+  )
+{
+  EFI_STATUS  Status;
+  BOOLEAN     Direction;
+  UINTN       Stride;
+  UINTN       Index;
+  UINT64      Result;
+
+  if ((UINT32)Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestAddress == SrcAddress) {
+    return EFI_SUCCESS;
+  }
+
+  Stride = (UINTN)((UINTN)1 << Width);
+
+  Direction = TRUE;
+  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
+    Direction   = FALSE;
+    SrcAddress  = SrcAddress  + (Count-1) * Stride;
+    DestAddress = DestAddress + (Count-1) * Stride;
+  }
+
+  for (Index = 0;Index < Count;Index++) {
+    Status = RootBridgeIoMemRead (
+               This,
+               Width,
+               SrcAddress,
+               1,
+               &Result
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    Status = RootBridgeIoMemWrite (
+               This,
+               Width,
+               DestAddress,
+               1,
+               &Result
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    if (Direction) {
+      SrcAddress  += Stride;
+      DestAddress += Stride;
+    } else {
+      SrcAddress  -= Stride;
+      DestAddress -= Stride;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+CpuMemoryServiceRead (
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+  UINT32                     Uint32Buffer = 0;
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+      Uint32Buffer &= (0xFF << ((Address & 0x3) * 8));
+      *((UINT8*)Uint8Buffer) = (UINT8)(Uint32Buffer >> (((Address & 0x3) * 8)));
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
+        return EFI_INVALID_PARAMETER;
+      }
+      Uint32Buffer = MmioRead32((UINTN)(Address & (~0x3)));
+      Uint32Buffer &= (0xFFFF << ((Address & 0x3) * 8));
+      *(UINT16 *)Uint8Buffer = (UINT16)(Uint32Buffer >> (((Address & 0x3) * 8)));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+                          moved is Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN       UINT64                                 EfiAddress,
+  IN       UINTN                                  Count,
+  OUT      VOID                                   *Buffer
+  )
+{
+  UINT32                      Offset;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
+  UINT64                      Address;
+  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (EfiPciAddress->ExtendedRegister) {
+    Offset = EfiPciAddress->ExtendedRegister;
+  } else {
+    Offset = EfiPciAddress->Register;
+  }
+
+  PCIE_DEBUG ("[%a:%d] - bus %x dev %x func %x Off %x\n", __FUNCTION__, __LINE__,
+         EfiPciAddress->Bus,
+         EfiPciAddress->Device,
+         EfiPciAddress->Function,
+         Offset
+        );
+  if (EfiPciAddress->Bus < PrivateData->BusBase || EfiPciAddress->Bus > PrivateData->BusLimit) {
+    PCIE_DEBUG ("[%a:%d] - Bus number out of range %d\n", __FUNCTION__, __LINE__, EfiPciAddress->Bus);
+    SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // The UEFI PCI enumerator scans for devices at all possible addresses,
+  // and ignores some PCI rules - this results in some hardware being
+  // detected multiple times. We work around this by faking absent
+  // devices
+  if(EfiPciAddress->Bus == PrivateData->BusBase)
+  {
+    if((EfiPciAddress->Device != 0x0) || (EfiPciAddress->Function != 0)) {
+      SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  if (EfiPciAddress->Bus == PrivateData->BusBase){
+    Address = PrivateData->RbPciBar + Offset;
+  }
+  else if(EfiPciAddress->Bus == PrivateData->BusBase + 1)
+  {
+    if (!PcieIsLinkUp(PrivateData->SocType,PrivateData->RbPciBar, PrivateData->Port))
+    {
+      SetMem (Buffer, mOutStride[Width] * Count, 0xFF);
+      return EFI_NOT_READY;
+    }
+    Address = GetPcieCfgAddress (
+        PrivateData->Ecam,
+        EfiPciAddress->Bus,
+        EfiPciAddress->Device,
+        EfiPciAddress->Function,
+        Offset
+        );
+  }
+  else
+  {
+    Address = GetPcieCfgAddress (
+         PrivateData->Ecam,
+         EfiPciAddress->Bus,
+         EfiPciAddress->Device,
+         EfiPciAddress->Function,
+         Offset
+         );
+  }
+
+  (VOID)CpuMemoryServiceRead((EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, Count, Buffer);
+  PCIE_DEBUG ("[%a:%d] - %x\n", __FUNCTION__, __LINE__, *(UINT32 *)Buffer);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+CpuMemoryServiceWrite (
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+  UINT32                     Uint32Buffer;
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      Uint32Buffer = MmioRead32 ((UINTN)(Address & (~0x03)));
+      Uint32Buffer &= ~(UINT32)(0xFF << ((Address & 0x3) * 8));
+      Uint32Buffer |= (UINT32)(*(UINT8 *)Uint8Buffer) << ((Address & 0x3) * 8);
+      MmioWrite32 ((UINTN)(Address & (~0x03)), Uint32Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      if (((Address & 0x3) == 1) || ((Address & 0x3) == 3)) {
+        return EFI_INVALID_PARAMETER;
+      }
+      Uint32Buffer = MmioRead32 ((UINTN)(Address & (~0x03)));
+      Uint32Buffer &= ~(UINT32)(0xFFFF << ((Address & 0x3) * 8));
+      Uint32Buffer |= (UINT32)(*(UINT16 *)Uint8Buffer) << ((Address & 0x3) * 8);
+      MmioWrite32 ((UINTN)(Address & (~0x03)), Uint32Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+                          moved is Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+                          write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN       UINT64                                 EfiAddress,
+  IN       UINTN                                  Count,
+  IN       VOID                                   *Buffer
+  )
+{
+  UINT32                      Offset;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
+  UINT64                      Address;
+  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
+
+  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (EfiPciAddress->ExtendedRegister)
+    Offset = EfiPciAddress->ExtendedRegister;
+  else
+    Offset = EfiPciAddress->Register;
+
+  PCIE_DEBUG ("[%a:%d] - bus %x dev %x func %x Off %x\n", __FUNCTION__, __LINE__,
+         EfiPciAddress->Bus,
+         EfiPciAddress->Device,
+         EfiPciAddress->Function,
+         Offset
+        );
+  if (((EfiPciAddress->Bus == PrivateData->BusBase) && (EfiPciAddress->Device == 0x00) && (EfiPciAddress->Function == 0))){
+    Address = PrivateData->RbPciBar + Offset;
+    if ((Offset == 0x14) || (Offset == 0x10)) {
+      return EFI_SUCCESS;
+    }
+  }
+  else if (EfiPciAddress->Bus == PrivateData->BusBase + 1)
+  {
+     if (!PcieIsLinkUp(PrivateData->SocType,PrivateData->RbPciBar, PrivateData->Port)) {
+      return EFI_NOT_READY;
+    }
+    Address = GetPcieCfgAddress (
+        PrivateData->Ecam,
+        EfiPciAddress->Bus,
+        EfiPciAddress->Device,
+        EfiPciAddress->Function,
+        Offset
+    );
+  }
+  else
+  {
+    Address = GetPcieCfgAddress (
+       PrivateData->Ecam,
+       EfiPciAddress->Bus,
+       EfiPciAddress->Device,
+       EfiPciAddress->Function,
+       Offset
+       );
+  }
+
+  (VOID)CpuMemoryServiceWrite ((EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, Count, Buffer);
+  PCIE_DEBUG ("[%a:%d] - 0x%08x\n", __FUNCTION__, __LINE__, *(UINT32 *)Buffer);
+  return EFI_SUCCESS;
+}
+
+/**
+   Provides the PCI controller-specific addresses required to access system memory from a
+   DMA bus master.
+
+   The Map() function provides the PCI controller specific addresses needed to access system
+   memory. This function is used to map system memory for PCI bus master DMA accesses.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
+   @param[in]       HostAddress     The system memory address to map to the PCI controller.
+   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
+   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
+                                    to access the system memory's HostAddress.
+   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
+
+   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
+   @retval EFI_INVALID_PARAMETER  Operation is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
+   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
+   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
+   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  )
+{
+  DMA_MAP_OPERATION   DmaOperation;
+
+  if (Operation == EfiPciOperationBusMasterRead) {
+    DmaOperation = MapOperationBusMasterRead;
+  } else if (Operation == EfiPciOperationBusMasterWrite) {
+    DmaOperation = MapOperationBusMasterWrite;
+  } else if (Operation == EfiPciOperationBusMasterCommonBuffer) {
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+  } else if (Operation == EfiPciOperationBusMasterRead64) {
+    DmaOperation = MapOperationBusMasterRead;
+  } else if (Operation == EfiPciOperationBusMasterWrite64) {
+     DmaOperation = MapOperationBusMasterWrite;
+  } else if (Operation == EfiPciOperationBusMasterCommonBuffer64) {
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+  (VOID)DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
+  return EFI_SUCCESS;
+}
+
+/**
+   Completes the Map() operation and releases any corresponding resources.
+
+   The Unmap() function completes the Map() operation and releases any corresponding resources.
+   If the operation was an EfiPciOperationBusMasterWrite or
+   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
+   Any resources used for the mapping are freed.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Mapping   The mapping value returned from Map().
+
+   @retval EFI_SUCCESS            The range was unmapped.
+   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
+   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN VOID                             *Mapping
+  )
+{
+  return DmaUnmap (Mapping);
+}
+
+/**
+   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
+   EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Type        This parameter is not used and must be ignored.
+   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
+   @param Pages       The number of pages to allocate.
+   @param HostAddress A pointer to store the base system memory address of the allocated range.
+   @param Attributes  The requested bit mask of attributes for the allocated range. Only
+                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
+                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
+
+   @retval EFI_SUCCESS            The requested memory pages were allocated.
+   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
+                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  EFI_ALLOCATE_TYPE                Type,
+  IN  EFI_MEMORY_TYPE                  MemoryType,
+  IN  UINTN                            Pages,
+  OUT VOID                             **HostAddress,
+  IN  UINT64                           Attributes
+  )
+{
+  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
+
+}
+
+/**
+   Frees memory that was allocated with AllocateBuffer().
+
+   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Pages       The number of pages to free.
+   @param HostAddress The base system memory address of the allocated range.
+
+   @retval EFI_SUCCESS            The requested memory pages were freed.
+   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
+                                  was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  UINTN                            Pages,
+  OUT VOID                             *HostAddress
+  )
+{
+  return DmaFreeBuffer (Pages, HostAddress);
+}
+
+/**
+   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
+   memory. Posted write transactions are generated by PCI bus masters when they perform write
+   transactions to target addresses in system memory.
+   This function does not flush posted write transactions from any PCI bridges. A PCI controller
+   specific action must be taken to guarantee that the posted write transactions have been flushed from
+   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
+   a PCI read transaction from the PCI controller prior to calling Flush().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
+                              bridge to system memory.
+   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
+                              host bridge due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This
+  )
+{
+  //
+  // not supported yet
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
+   attributes that a PCI root bridge is currently using.
+
+   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
+   and the mask of attributes that the PCI root bridge is currently using.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Supported   A pointer to the mask of attributes that this PCI root bridge
+                      supports setting with SetAttributes().
+   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
+                      currently using.
+
+   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
+                                  bridge supports is returned in Supports. If Attributes is
+                                  not NULL, then the attributes that the PCI root bridge is currently
+                                  using is returned in Attributes.
+   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT UINT64                           *Supported,
+  OUT UINT64                           *Attributes
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  if (Attributes == NULL && Supported == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Set the return value for Supported and Attributes
+  //
+  if (Supported != NULL) {
+    *Supported  = PrivateData->Supports;
+  }
+
+  if (Attributes != NULL) {
+    *Attributes = PrivateData->Attributes;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Sets attributes for a resource range on a PCI root bridge.
+
+   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
+   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
+   granularity of setting these attributes may vary from resource type to resource type, and from
+   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
+   result, this function may set the attributes specified by Attributes on a larger resource range
+   than the caller requested. The actual range is returned in ResourceBase and
+   ResourceLength. The caller is responsible for verifying that the actual range for which the
+   attributes were set is acceptable.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
+                                    MEMORY_DISABLE is set, then the resource range is specified by
+                                    ResourceBase and ResourceLength. If
+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+                                    MEMORY_DISABLE are not set, then ResourceBase and
+                                    ResourceLength are ignored, and may be NULL.
+   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
+                                    by the attributes specified by Attributes.
+   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
+                                    attributes specified by Attributes.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN     UINT64                           Attributes,
+  IN OUT UINT64                           *ResourceBase,
+  IN OUT UINT64                           *ResourceLength
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE            *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  if (Attributes != 0) {
+    if ((Attributes & (~(PrivateData->Supports))) != 0) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // This is a generic driver for a PC-AT class system.  It does not have any
+  // chipset specific knowlegde, so none of the attributes can be set or
+  // cleared.  Any attempt to set attribute that are already set will succeed,
+  // and any attempt to set an attribute that is not supported will fail.
+  //
+  if (Attributes & (~PrivateData->Attributes)) {
+    /* FIXME: */
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
+   resource descriptors.
+
+   There are only two resource descriptor types from the ACPI Specification that may be used to
+   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
+   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
+   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
+   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
+   Address Space Descriptors followed by an End Tag.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
+                            current configuration of this PCI root bridge. The storage for the
+                            ACPI 2.0 resource descriptors is allocated by this function. The
+                            caller must treat the return buffer as read-only data, and the buffer
+                            must not be freed by the caller.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *This,
+  OUT VOID                                **Resources
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
+  UINTN                                 Index;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+  for (Index = 0; Index < TypeMax; Index++) {
+    if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {
+      Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;
+      Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;
+      Configuration.SpaceDesp[Index].AddrLen      = PrivateData->ResAllocNode[Index].Length;
+    }
+  }
+
+  *Resources = &Configuration;
+  return EFI_SUCCESS;
+}
+

+ 1049 - 0
Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.c

@@ -0,0 +1,1049 @@
+/** @file
+
+  Copyright (c) 2016 Linaro Ltd.
+  Copyright (c) 2016 Hisilicon Limited.
+
+  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 <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DmaLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+
+#include <Protocol/PlatformSasProtocol.h>
+#include <Protocol/ScsiPassThruExt.h>
+#include <IndustryStandard/Scsi.h>
+
+#define READ_REG32(Base, Offset) MmioRead32 ((Base) + (Offset))
+#define WRITE_REG32(Base, Offset, Val)  MmioWrite32 ((Base) + (Offset), (Val))
+
+#define PHY_READ_REG32(Base, Offset, phy) MmioRead32 ((Base) + (Offset) + 0x400 * (phy))
+#define PHY_WRITE_REG32(Base, Offset, phy, Val)  MmioWrite32 ((Base) + (Offset) + 0x400 * (phy), (Val))
+
+#define DLVRY_QUEUE_ENABLE              0x0
+#define IOST_BASE_ADDR_LO               0x8
+#define IOST_BASE_ADDR_HI               0xc
+#define ITCT_BASE_ADDR_LO               0x10
+#define ITCT_BASE_ADDR_HI               0x14
+#define BROKEN_MSG_ADDR_LO              0x18
+#define BROKEN_MSG_ADDR_HI              0x1c
+#define PHY_CONTEXT                     0x20
+#define PHY_PORT_NUM_MA                 0x28
+#define HGC_TRANS_TASK_CNT_LIMIT        0x38
+#define AXI_AHB_CLK_CFG                 0x3c
+#define HGC_SAS_TXFAIL_RETRY_CTRL       0x84
+#define HGC_GET_ITV_TIME                0x90
+#define DEVICE_MSG_WORK_MODE            0x94
+#define I_T_NEXUS_LOSS_TIME             0xa0
+#define BUS_INACTIVE_LIMIT_TIME         0xa8
+#define REJECT_TO_OPEN_LIMIT_TIME       0xac
+#define CFG_AGING_TIME                  0xbc
+#define HGC_DFX_CFG2                    0xc0
+#define FIS_LIST_BADDR_L                0xc4
+#define CFG_1US_TIMER_TRSH              0xcc
+#define CFG_SAS_CONFIG                  0xd4
+#define INT_COAL_EN                     0x1bc
+#define OQ_INT_COAL_TIME                0x1c0
+#define OQ_INT_COAL_CNT                 0x1c4
+#define ENT_INT_COAL_TIME               0x1c8
+#define ENT_INT_COAL_CNT                0x1cc
+#define OQ_INT_SRC                      0x1d0
+#define OQ_INT_SRC_MSK                  0x1d4
+#define ENT_INT_SRC1                    0x1d8
+#define ENT_INT_SRC2                    0x1dc
+#define ENT_INT_SRC_MSK1                0x1e0
+#define ENT_INT_SRC_MSK2                0x1e4
+#define SAS_ECC_INTR_MSK                0x1ec
+#define HGC_ERR_STAT_EN                 0x238
+#define DLVRY_Q_0_BASE_ADDR_LO          0x260
+#define DLVRY_Q_0_BASE_ADDR_HI          0x264
+#define DLVRY_Q_0_DEPTH                 0x268
+#define DLVRY_Q_0_WR_PTR                0x26c
+#define DLVRY_Q_0_RD_PTR                0x270
+#define COMPL_Q_0_BASE_ADDR_LO          0x4e0
+#define COMPL_Q_0_BASE_ADDR_HI          0x4e4
+#define COMPL_Q_0_DEPTH                 0x4e8
+#define COMPL_Q_0_WR_PTR                0x4ec
+#define COMPL_Q_0_RD_PTR                0x4f0
+#define AXI_CFG                         0x5100
+
+#define PORT_BASE                       0x800
+#define PHY_CFG                         (PORT_BASE + 0x0)
+#define PHY_CFG_ENA_OFF                 0
+#define PHY_CFG_ENA_MSK                 (0x1 << PHY_CFG_ENA_OFF)
+#define PHY_CFG_DC_OPT_OFF              2
+#define PHY_CFG_DC_OPT_MSK              (0x1 << PHY_CFG_DC_OPT_OFF)
+#define PROG_PHY_LINK_RATE              (PORT_BASE + 0xc)
+#define PHY_CTRL                        (PORT_BASE + 0x14)
+#define PHY_CTRL_RESET                  BIT0
+#define PHY_RATE_NEGO                   (PORT_BASE + 0x30)
+#define PHY_PCN                         (PORT_BASE + 0x44)
+#define SL_TOUT_CFG                     (PORT_BASE + 0x8c)
+#define SL_CONTROL                      (PORT_BASE + 0x94)
+#define SL_CONTROL_NOTIFY_EN            BIT0
+#define TX_ID_DWORD0                    (PORT_BASE + 0x9c)
+#define TX_ID_DWORD1                    (PORT_BASE + 0xa0)
+#define TX_ID_DWORD2                    (PORT_BASE + 0xa4)
+#define TX_ID_DWORD3                    (PORT_BASE + 0xa8)
+#define TX_ID_DWORD4                    (PORT_BASE + 0xaC)
+#define TX_ID_DWORD5                    (PORT_BASE + 0xb0)
+#define TX_ID_DWORD6                    (PORT_BASE + 0xb4)
+#define RX_IDAF_DWORD3                  (PORT_BASE + 0xd0)
+#define RX_IDAF_DWORD4                  (PORT_BASE + 0xd4)
+#define RXOP_CHECK_CFG_H                (PORT_BASE + 0xfc)
+#define DONE_RECEIVED_TIME              (PORT_BASE + 0x12c)
+#define CON_CFG_DRIVER                  (PORT_BASE + 0x130)
+#define PHY_CONFIG2                     (PORT_BASE + 0x1a8)
+#define PHY_CONFIG2_FORCE_TXDEEMPH_OFF  3
+#define PHY_CONFIG2_FORCE_TXDEEMPH_MSK  (0x1 << PHY_CONFIG2_FORCE_TXDEEMPH_OFF)
+#define CHL_INT_COAL_EN                 (PORT_BASE + 0x1d0)
+#define CHL_INT0                        (PORT_BASE + 0x1b0)
+#define CHL_INT0_PHYCTRL_NOTRDY         BIT0
+#define CHL_INT1                        (PORT_BASE + 0x1b4)
+#define CHL_INT2                        (PORT_BASE + 0x1b8)
+#define CHL_INT2_SL_PHY_ENA             BIT6
+#define CHL_INT0_MSK                    (PORT_BASE + 0x1bc)
+#define CHL_INT0_MSK_PHYCTRL_NOTRDY     BIT0
+#define CHL_INT1_MSK                    (PORT_BASE + 0x1c0)
+#define CHL_INT2_MSK                    (PORT_BASE + 0x1c4)
+#define DMA_TX_STATUS                   (PORT_BASE + 0x2d0)
+#define DMA_TX_STATUS_BUSY              BIT0
+#define DMA_RX_STATUS                   (PORT_BASE + 0x2e8)
+#define DMA_RX_STATUS_BUSY              BIT0
+
+#define QUEUE_CNT                       32
+#define QUEUE_SLOTS                     256
+#define SLOT_ENTRIES                    8192
+#define PHY_CNT                         8
+#define MAX_ITCT_ENTRIES                1
+
+// Completion header
+#define CMPLT_HDR_IPTT_OFF              0
+#define CMPLT_HDR_IPTT_MSK              (0xffff << CMPLT_HDR_IPTT_OFF)
+
+#define BIT(x)                          (1 << x)
+
+// HW dma structures
+// Delivery queue header
+// dw0
+#define CMD_HDR_RESP_REPORT_OFF     5
+#define CMD_HDR_RESP_REPORT_MSK     0x20
+#define CMD_HDR_TLR_CTRL_OFF        6
+#define CMD_HDR_TLR_CTRL_MSK        0xc0
+#define CMD_HDR_PORT_OFF            17
+#define CMD_HDR_PORT_MSK            0xe0000
+#define CMD_HDR_PRIORITY_OFF        27
+#define CMD_HDR_PRIORITY_MSK        0x8000000
+#define CMD_HDR_MODE_OFF            28
+#define CMD_HDR_MODE_MSK            0x10000000
+#define CMD_HDR_CMD_OFF             29
+#define CMD_HDR_CMD_MSK             0xe0000000
+// dw1
+#define CMD_HDR_VERIFY_DTL_OFF      10
+#define CMD_HDR_VERIFY_DTL_MSK      0x400
+#define CMD_HDR_SSP_FRAME_TYPE_OFF  13
+#define CMD_HDR_SSP_FRAME_TYPE_MSK  0xe000
+#define CMD_HDR_DEVICE_ID_OFF       16
+#define CMD_HDR_DEVICE_ID_MSK       0xffff0000
+// dw2
+#define CMD_HDR_CFL_OFF             0
+#define CMD_HDR_CFL_MSK             0x1ff
+#define CMD_HDR_MRFL_OFF            15
+#define CMD_HDR_MRFL_MSK            0xff8000
+#define CMD_HDR_FIRST_BURST_OFF     25
+#define CMD_HDR_FIRST_BURST_MSK     0x2000000
+// dw3
+#define CMD_HDR_IPTT_OFF            0
+#define CMD_HDR_IPTT_MSK            0xffff
+// dw6
+#define CMD_HDR_DATA_SGL_LEN_OFF    16
+#define CMD_HDR_DATA_SGL_LEN_MSK    0xffff0000
+
+// Completion header
+#define CMPLT_HDR_IPTT_OFF          0
+#define CMPLT_HDR_IPTT_MSK          (0xffff << CMPLT_HDR_IPTT_OFF)
+#define CMPLT_HDR_CMD_CMPLT_MSK     BIT17
+#define CMPLT_HDR_ERR_RCRD_XFRD_MSK BIT18
+#define CMPLT_HDR_RSPNS_XFRD_MSK    BIT19
+#define CMPLT_HDR_IO_CFG_ERR_MSK    BIT27
+
+#define SENSE_DATA_PRES             26
+
+#define SGE_LIMIT 0x10000
+#define upper_32_bits(n) ((UINT32)(((n) >> 16) >> 16))
+#define lower_32_bits(n) ((UINT32)(n))
+#define MAX_TARGET_ID 4
+
+// Generic HW DMA host memory structures
+struct hisi_sas_cmd_hdr {
+    UINT32 dw0;
+    UINT32 dw1;
+    UINT32 dw2;
+    UINT32 transfer_tags;
+    UINT32 data_transfer_len;
+    UINT32 first_burst_num;
+    UINT32 sg_len;
+    UINT32 dw7;
+    UINT64 cmd_table_addr;
+    UINT64 sts_buffer_addr;
+    UINT64 prd_table_addr;
+    UINT64 dif_prd_table_addr;
+};
+
+struct hisi_sas_complete_hdr {
+    UINT32 data;
+};
+
+struct hisi_sas_iost {
+    UINT64 qw0;
+    UINT64 qw1;
+    UINT64 qw2;
+    UINT64 qw3;
+};
+
+struct hisi_sas_itct {
+    UINT64 qw0;
+    UINT64 sas_addr;
+    UINT64 qw2;
+    UINT64 qw3;
+    UINT64 qw4;
+    UINT64 qw_sata_ncq0_3;
+    UINT64 qw_sata_ncq7_4;
+    UINT64 qw_sata_ncq11_8;
+    UINT64 qw_sata_ncq15_12;
+    UINT64 qw_sata_ncq19_16;
+    UINT64 qw_sata_ncq23_20;
+    UINT64 qw_sata_ncq27_24;
+    UINT64 qw_sata_ncq31_28;
+    UINT64 qw_non_ncq_iptt;
+    UINT64 qw_rsvd0;
+    UINT64 qw_rsvd1;
+};
+
+struct hisi_sas_breakpoint {
+    UINT8 data[128];
+};
+
+struct hisi_sas_sge {
+    UINT64 addr;
+    UINT32 page_ctrl_0;
+    UINT32 page_ctrl_1;
+    UINT32 data_len;
+    UINT32 data_off;
+};
+
+struct hisi_sas_sge_page {
+    struct hisi_sas_sge sg[512];
+};
+
+struct hisi_sas_cmd {
+    UINT8 cmd[128];
+};
+
+struct hisi_sas_sts {
+UINT32 status[260];
+};
+
+struct hisi_sas_slot {
+    BOOLEAN used;
+};
+
+struct hisi_hba {
+    struct hisi_sas_cmd_hdr      *cmd_hdr[QUEUE_CNT];
+    struct hisi_sas_complete_hdr *complete_hdr[QUEUE_CNT];
+    struct hisi_sas_sge_page     *sge[QUEUE_CNT];
+    struct hisi_sas_sts          *status_buf[QUEUE_CNT];
+    struct hisi_sas_cmd          *command_table[QUEUE_CNT];
+    struct hisi_sas_iost         *iost;
+    struct hisi_sas_itct         *itct;
+    struct hisi_sas_breakpoint   *breakpoint;
+    struct hisi_sas_slot         *slots;
+    UINT32 base;
+    int queue;
+    int port_id;
+    UINT32 LatestTargetId;
+    UINT64 LatestLun;
+};
+
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH                  Vendor;
+  UINT64                              PhysBase;
+  EFI_DEVICE_PATH_PROTOCOL            End;
+} SAS_V1_TRANSPORT_DEVICE_PATH;
+#pragma pack ()
+
+typedef struct {
+    UINT32 Signature;
+    EFI_EXT_SCSI_PASS_THRU_MODE     ExtScsiPassThruMode;
+    EFI_EXT_SCSI_PASS_THRU_PROTOCOL ExtScsiPassThru;
+    SAS_V1_TRANSPORT_DEVICE_PATH    *DevicePath;
+    struct hisi_hba *hba;
+    EFI_EVENT TimerEvent;
+} SAS_V1_INFO;
+
+#define SAS_DEVICE_SIGNATURE SIGNATURE_32 ('S','A','S','0')
+#define SAS_FROM_PASS_THRU(a) CR (a, SAS_V1_INFO, ExtScsiPassThru, SAS_DEVICE_SIGNATURE)
+
+STATIC EFI_STATUS prepare_cmd (
+  struct hisi_hba *hba,
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
+  )
+{
+  struct hisi_sas_slot *slot;
+  struct hisi_sas_cmd_hdr *hdr;
+  struct hisi_sas_sge_page *sge;
+  struct hisi_sas_sts *sts;
+  struct hisi_sas_cmd *cmd;
+  EFI_SCSI_SENSE_DATA *SensePtr = Packet->SenseData;
+  VOID   *Buffer = NULL;
+  UINTN BufferSize = 0;
+  int queue = hba->queue;
+  UINT32 r, w = 0, slot_idx = 0;
+  UINT32 base = hba->base;
+  UINT8 *p;
+  EFI_PHYSICAL_ADDRESS  BufferAddress;
+  EFI_STATUS            Status = EFI_SUCCESS;
+  VOID                  *BufferMap = NULL;
+  DMA_MAP_OPERATION DmaOperation = MapOperationBusMasterCommonBuffer;
+
+  while (1) {
+    w = READ_REG32(base, DLVRY_Q_0_WR_PTR + (queue * 0x14));
+    r = READ_REG32(base, DLVRY_Q_0_RD_PTR + (queue * 0x14));
+    slot_idx = queue * QUEUE_SLOTS + w;
+    slot = &hba->slots[slot_idx];
+    if (slot->used || (r == (w+1) % QUEUE_SLOTS)) {
+      queue = (queue + 1) % QUEUE_CNT;
+      if (queue == hba->queue) {
+        DEBUG ((EFI_D_ERROR, "could not find free slot\n"));
+        return EFI_NOT_READY;
+      }
+      continue;
+    }
+    break;
+  }
+
+  hdr = &hba->cmd_hdr[queue][w];
+  cmd = &hba->command_table[queue][w];
+  sts = &hba->status_buf[queue][w];
+  sge = &hba->sge[queue][w];
+
+  ZeroMem (cmd, sizeof (struct hisi_sas_cmd));
+  ZeroMem (sts, sizeof (struct hisi_sas_sts));
+  if (SensePtr)
+    ZeroMem (SensePtr, sizeof (EFI_SCSI_SENSE_DATA));
+
+  slot->used = TRUE;
+  hba->queue = (queue + 1) % QUEUE_CNT;
+
+  // Only consider ssp
+  hdr->dw0 = (1 << CMD_HDR_RESP_REPORT_OFF) |
+       (0x2 << CMD_HDR_TLR_CTRL_OFF) |
+       (hba->port_id << CMD_HDR_PORT_OFF) |
+       (1 << CMD_HDR_MODE_OFF) |
+       (1 << CMD_HDR_CMD_OFF);
+  hdr->dw1 = 1 << CMD_HDR_VERIFY_DTL_OFF;
+  hdr->dw1 |= 0 << CMD_HDR_DEVICE_ID_OFF;
+  hdr->dw2 = 0x83000d;
+  hdr->transfer_tags = slot_idx << CMD_HDR_IPTT_OFF;
+
+  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+    Buffer = Packet->InDataBuffer;
+    BufferSize = Packet->InTransferLength;
+    if (Buffer) {
+      hdr->dw1 |= 1 << CMD_HDR_SSP_FRAME_TYPE_OFF;
+      DmaOperation = MapOperationBusMasterWrite;
+    }
+  } else if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE) {
+    Buffer = Packet->OutDataBuffer;
+    BufferSize = Packet->OutTransferLength;
+    if (Buffer) {
+      DmaOperation = MapOperationBusMasterRead;
+      hdr->dw1 |= 2 << CMD_HDR_SSP_FRAME_TYPE_OFF;
+    }
+  } else {
+    hdr->dw1 |= 0 << CMD_HDR_SSP_FRAME_TYPE_OFF;
+  }
+
+  hdr->data_transfer_len = BufferSize;
+  hdr->cmd_table_addr = (UINT64)cmd;
+  hdr->sts_buffer_addr = (UINT64)sts;
+
+  CopyMem (&cmd->cmd[36], Packet->Cdb, Packet->CdbLength);
+
+  if (Buffer != NULL) {
+    struct hisi_sas_sge *sg;
+    UINT32 remain, len, pos = 0, i = 0;
+
+    Status = DmaMap (DmaOperation, Buffer, &BufferSize, &BufferAddress, &BufferMap);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    remain = len = BufferSize;
+
+    while (remain) {
+      if (len > SGE_LIMIT)
+        len = SGE_LIMIT;
+      sg = &sge->sg[i];
+      sg->addr = (UINT64)(BufferAddress + pos);
+      sg->page_ctrl_0 = sg->page_ctrl_1 = 0;
+      sg->data_len = len;
+      sg->data_off = 0;
+      remain -= len;
+      pos += len;
+      len = remain;
+      i++;
+    }
+
+    hdr->prd_table_addr = (UINT64)sge;
+    hdr->sg_len = i << CMD_HDR_DATA_SGL_LEN_OFF;
+  }
+
+  // Ensure descriptor effective before start dma
+  MemoryFence();
+
+  // Start dma
+  WRITE_REG32(base, DLVRY_Q_0_WR_PTR + queue * 0x14, ++w % QUEUE_SLOTS);
+
+  // Wait for dma complete
+  while (slot->used) {
+    if (READ_REG32(base, OQ_INT_SRC) & BIT(queue)) {
+      struct hisi_sas_complete_hdr *complete_hdr;
+      UINT32 data, rd;
+      rd = READ_REG32(base, COMPL_Q_0_RD_PTR + (0x14 * queue));
+
+      complete_hdr = &hba->complete_hdr[queue][rd];
+      data = complete_hdr->data;
+
+      // Check whether dma transfer error
+      if ((data & CMPLT_HDR_ERR_RCRD_XFRD_MSK) &&
+        !(data & CMPLT_HDR_RSPNS_XFRD_MSK)) {
+        DEBUG ((EFI_D_VERBOSE, "sas retry data=0x%x\n", data));
+        DEBUG ((EFI_D_VERBOSE, "sts[0]=0x%x\n", sts->status[0]));
+        DEBUG ((EFI_D_VERBOSE, "sts[1]=0x%x\n", sts->status[1]));
+        DEBUG ((EFI_D_VERBOSE, "sts[2]=0x%x\n", sts->status[2]));
+        Status = EFI_NOT_READY;
+        // wait 1 second and retry, some disk need long time to be ready
+        // and ScsiDisk treat retry over 3 times as error
+        MicroSecondDelay(1000000);
+      }
+       // Update read point
+       WRITE_REG32(base, COMPL_Q_0_RD_PTR + (0x14 * queue), w);
+       // Clear int
+       WRITE_REG32(base, OQ_INT_SRC, BIT(queue));
+       slot->used = FALSE;
+       break;
+    }
+    // Wait for status change in polling
+    NanoSecondDelay (100);
+  }
+
+  if (BufferMap)
+       DmaUnmap (BufferMap);
+
+  p = (UINT8 *)&sts->status[0];
+  if (p[SENSE_DATA_PRES]) {
+    // Disk not ready normal return for ScsiDiskTestUnitReady do next try
+    SensePtr->Sense_Key = EFI_SCSI_SK_NOT_READY;
+    SensePtr->Addnl_Sense_Code = EFI_SCSI_ASC_NOT_READY;
+    SensePtr->Addnl_Sense_Code_Qualifier = EFI_SCSI_ASCQ_IN_PROGRESS;
+    // wait 1 second for disk spin up, refer drivers/scsi/sd.c
+    MicroSecondDelay(1000000);
+  }
+  return Status;
+}
+
+STATIC VOID hisi_sas_v1_init(struct hisi_hba *hba, PLATFORM_SAS_PROTOCOL *plat)
+{
+  int i, j;
+  UINT32 val, base = hba->base;
+
+  // Reset
+  for (i = 0; i < PHY_CNT; i++) {
+    UINT32 phy_ctrl = PHY_READ_REG32(base, PHY_CTRL, i);
+
+    phy_ctrl |= PHY_CTRL_RESET;
+    PHY_WRITE_REG32(base, PHY_CTRL, i, phy_ctrl);
+  }
+  // spec says safe to wait 50us after reset
+  MicroSecondDelay(50);
+
+  // Ensure DMA tx & rx idle
+  for (i = 0; i < PHY_CNT; i++) {
+    UINT32 dma_tx_status, dma_rx_status;
+
+    for (j = 0; j < 100; j++) {
+      dma_tx_status = PHY_READ_REG32(base, DMA_TX_STATUS, i);
+      dma_rx_status = PHY_READ_REG32(base, DMA_RX_STATUS, i);
+
+      if (!(dma_tx_status & DMA_TX_STATUS_BUSY) &&
+        !(dma_rx_status & DMA_RX_STATUS_BUSY))
+        break;
+
+        // Wait for status change in polling
+        NanoSecondDelay (100);
+    }
+  }
+
+  // Ensure axi bus idle
+  for (j = 0; j < 100; j++) {
+    UINT32 axi_status = READ_REG32(base, AXI_CFG);
+    if (axi_status == 0)
+      break;
+
+    // Wait for status change in polling
+    NanoSecondDelay (100);
+  }
+
+  plat->Init(plat);
+
+  WRITE_REG32(base, DLVRY_QUEUE_ENABLE, 0xffffffff);
+  WRITE_REG32(base, HGC_TRANS_TASK_CNT_LIMIT, 0x11);
+  WRITE_REG32(base, DEVICE_MSG_WORK_MODE, 0x1);
+  WRITE_REG32(base, HGC_SAS_TXFAIL_RETRY_CTRL, 0x1ff);
+  WRITE_REG32(base, HGC_ERR_STAT_EN, 0x401);
+  WRITE_REG32(base, CFG_1US_TIMER_TRSH, 0x64);
+  WRITE_REG32(base, HGC_GET_ITV_TIME, 0x1);
+  WRITE_REG32(base, I_T_NEXUS_LOSS_TIME, 0x64);
+  WRITE_REG32(base, BUS_INACTIVE_LIMIT_TIME, 0x2710);
+  WRITE_REG32(base, REJECT_TO_OPEN_LIMIT_TIME, 0x1);
+  WRITE_REG32(base, CFG_AGING_TIME, 0x7a12);
+  WRITE_REG32(base, HGC_DFX_CFG2, 0x9c40);
+  WRITE_REG32(base, FIS_LIST_BADDR_L, 0x2);
+  WRITE_REG32(base, INT_COAL_EN, 0xc);
+  WRITE_REG32(base, OQ_INT_COAL_TIME, 0x186a0);
+  WRITE_REG32(base, OQ_INT_COAL_CNT, 1);
+  WRITE_REG32(base, ENT_INT_COAL_TIME, 0x1);
+  WRITE_REG32(base, ENT_INT_COAL_CNT, 0x1);
+  WRITE_REG32(base, OQ_INT_SRC, 0xffffffff);
+  WRITE_REG32(base, ENT_INT_SRC1, 0xffffffff);
+  WRITE_REG32(base, ENT_INT_SRC_MSK1, 0);
+  WRITE_REG32(base, ENT_INT_SRC2, 0xffffffff);
+  WRITE_REG32(base, ENT_INT_SRC_MSK2, 0);
+  WRITE_REG32(base, SAS_ECC_INTR_MSK, 0);
+  WRITE_REG32(base, AXI_AHB_CLK_CFG, 0x2);
+  WRITE_REG32(base, CFG_SAS_CONFIG, 0x22000000);
+
+  for (i = 0; i < PHY_CNT; i++) {
+    PHY_WRITE_REG32(base, PROG_PHY_LINK_RATE, i, 0x88a);
+    PHY_WRITE_REG32(base, PHY_CONFIG2, i, 0x7c080);
+    PHY_WRITE_REG32(base, PHY_RATE_NEGO, i, 0x415ee00);
+    PHY_WRITE_REG32(base, PHY_PCN, i, 0x80a80000);
+    PHY_WRITE_REG32(base, SL_TOUT_CFG, i, 0x7d7d7d7d);
+    PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 0x0);
+    PHY_WRITE_REG32(base, RXOP_CHECK_CFG_H, i, 0x1000);
+    PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 0);
+    PHY_WRITE_REG32(base, CON_CFG_DRIVER, i, 0x13f0a);
+    PHY_WRITE_REG32(base, CHL_INT_COAL_EN, i, 3);
+    PHY_WRITE_REG32(base, DONE_RECEIVED_TIME, i, 8);
+  }
+
+  for (i = 0; i < QUEUE_CNT; i++) {
+    WRITE_REG32(base, DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14), upper_32_bits((UINT64)(hba->cmd_hdr[i])));
+    WRITE_REG32(base, DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14), lower_32_bits((UINT64)(hba->cmd_hdr[i])));
+    WRITE_REG32(base, DLVRY_Q_0_DEPTH + (i * 0x14), QUEUE_SLOTS);
+
+    WRITE_REG32(base, COMPL_Q_0_BASE_ADDR_HI + (i * 0x14), upper_32_bits((UINT64)(hba->complete_hdr[i])));
+    WRITE_REG32(base, COMPL_Q_0_BASE_ADDR_LO + (i * 0x14), lower_32_bits((UINT64)(hba->complete_hdr[i])));
+    WRITE_REG32(base, COMPL_Q_0_DEPTH + (i * 0x14), QUEUE_SLOTS);
+  }
+
+  WRITE_REG32(base, ITCT_BASE_ADDR_LO, lower_32_bits((UINT64)(hba->itct)));
+  WRITE_REG32(base, ITCT_BASE_ADDR_HI, upper_32_bits((UINT64)(hba->itct)));
+
+  WRITE_REG32(base, IOST_BASE_ADDR_LO, lower_32_bits((UINT64)(hba->iost)));
+  WRITE_REG32(base, IOST_BASE_ADDR_HI, upper_32_bits((UINT64)(hba->iost)));
+
+  WRITE_REG32(base, BROKEN_MSG_ADDR_LO, lower_32_bits((UINT64)(hba->breakpoint)));
+  WRITE_REG32(base, BROKEN_MSG_ADDR_HI, upper_32_bits((UINT64)(hba->breakpoint)));
+
+  for (i = 0; i < PHY_CNT; i++) {
+    // Clear interrupt status
+    val = PHY_READ_REG32(base, CHL_INT0, i);
+    PHY_WRITE_REG32(base, CHL_INT0, i, val);
+    val = PHY_READ_REG32(base, CHL_INT1, i);
+    PHY_WRITE_REG32(base, CHL_INT1, i, val);
+    val = PHY_READ_REG32(base, CHL_INT2, i);
+    PHY_WRITE_REG32(base, CHL_INT2, i, val);
+
+    // Bypass chip bug mask abnormal intr
+    PHY_WRITE_REG32(base, CHL_INT0_MSK, i, 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY);
+  }
+
+  // Init phy
+  for (i = 0; i < PHY_CNT; i++) {
+    PHY_WRITE_REG32(base, TX_ID_DWORD0, i, 0x10010e00);
+    PHY_WRITE_REG32(base, TX_ID_DWORD1, i, 0x16);
+    PHY_WRITE_REG32(base, TX_ID_DWORD2, i, 0x20880150);
+    PHY_WRITE_REG32(base, TX_ID_DWORD3, i, 0x16);
+    PHY_WRITE_REG32(base, TX_ID_DWORD4, i, 0x20880150);
+    PHY_WRITE_REG32(base, TX_ID_DWORD5, i, 0x0);
+
+    val = PHY_READ_REG32(base, PHY_CFG, i);
+    val &= ~PHY_CFG_DC_OPT_MSK;
+    val |= 1 << PHY_CFG_DC_OPT_OFF;
+    PHY_WRITE_REG32(base, PHY_CFG, i, val);
+
+    val = PHY_READ_REG32(base, PHY_CONFIG2, i);
+    val &= ~PHY_CONFIG2_FORCE_TXDEEMPH_MSK;
+    PHY_WRITE_REG32(base, PHY_CONFIG2, i, val);
+
+    val = PHY_READ_REG32(base, PHY_CFG, i);
+    val |= PHY_CFG_ENA_MSK;
+    PHY_WRITE_REG32(base, PHY_CFG, i, val);
+  }
+}
+
+STATIC VOID sas_init(SAS_V1_INFO *SasV1Info, PLATFORM_SAS_PROTOCOL *plat)
+{
+  struct hisi_hba *hba = SasV1Info->hba;
+  int i, s;
+
+  for (i = 0; i < QUEUE_CNT; i++) {
+    s = sizeof(struct hisi_sas_cmd_hdr) * QUEUE_SLOTS;
+    DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->cmd_hdr[i]);
+    ASSERT (hba->cmd_hdr[i] != NULL);
+    ZeroMem (hba->cmd_hdr[i], s);
+
+    s = sizeof(struct hisi_sas_complete_hdr) * QUEUE_SLOTS;
+    DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->complete_hdr[i]);
+    ASSERT (hba->complete_hdr[i] != NULL);
+    ZeroMem (hba->complete_hdr[i], s);
+
+    s = sizeof(struct hisi_sas_sts) * QUEUE_SLOTS;
+    DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->status_buf[i]);
+    ASSERT (hba->status_buf[i] != NULL);
+    ZeroMem (hba->status_buf[i], s);
+
+    s = sizeof(struct hisi_sas_cmd) * QUEUE_SLOTS;
+    DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->command_table[i]);
+    ASSERT (hba->command_table[i] != NULL);
+    ZeroMem (hba->command_table[i], s);
+
+    s = sizeof(struct hisi_sas_sge_page) * QUEUE_SLOTS;
+    DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->sge[i]);
+    ASSERT (hba->sge[i] != NULL);
+    ZeroMem (hba->sge[i], s);
+  }
+
+  s = SLOT_ENTRIES * sizeof(struct hisi_sas_iost);
+  DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->iost);
+  ASSERT (hba->iost != NULL);
+  ZeroMem (hba->iost, s);
+
+  s = SLOT_ENTRIES * sizeof(struct hisi_sas_breakpoint);
+  DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->breakpoint);
+  ASSERT (hba->breakpoint != NULL);
+  ZeroMem (hba->breakpoint, s);
+
+  s = MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
+  DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (s), (VOID *)&hba->itct);
+  ASSERT (hba->itct != NULL);
+  ZeroMem (hba->itct, s);
+
+  hba->slots = AllocateZeroPool (SLOT_ENTRIES * sizeof(struct hisi_sas_slot));
+  ASSERT (hba->slots != NULL);
+
+  hisi_sas_v1_init(hba, plat);
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruFunction (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
+  IN UINT8                                              *Target,
+  IN UINT64                                             Lun,
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
+  IN EFI_EVENT                                          Event OPTIONAL
+  )
+{
+  SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This);
+  struct hisi_hba *hba = SasV1Info->hba;
+
+  return prepare_cmd(hba, Packet);
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruGetNextTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target,
+  IN OUT UINT64                          *Lun
+  )
+{
+  SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This);
+  struct hisi_hba *hba = SasV1Info->hba;
+  UINT8 ScsiId[TARGET_MAX_BYTES];
+  UINT8 TargetId;
+
+  if (*Target == NULL || Lun == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
+
+  TargetId = (*Target)[0];
+
+  if (TargetId == MAX_TARGET_ID) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) {
+    SetMem (*Target, TARGET_MAX_BYTES,0);
+  } else {
+    (*Target)[0] = (UINT8) (hba->LatestTargetId + 1);
+  }
+
+  *Lun = 0;
+
+  //
+  // Update the LatestTargetId.
+  //
+  hba->LatestTargetId  = (*Target)[0];
+  hba->LatestLun       = *Lun;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruBuildDevicePath (
+  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN     UINT8                              *Target,
+  IN     UINT64                             Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
+  )
+{
+  SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This);
+
+  *DevicePath  = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)(SasV1Info->DevicePath));
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruGetTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL           *DevicePath,
+  OUT UINT8                              **Target,
+  OUT UINT64                             *Lun
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruResetChannel (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruResetTarget (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN UINT8                              *Target,
+  IN UINT64                             Lun
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+SasV1ExtScsiPassThruGetNextTarget (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+STATIC EFI_EXT_SCSI_PASS_THRU_PROTOCOL SasV1ExtScsiPassThruProtocolTemplate = {
+  NULL,
+  SasV1ExtScsiPassThruFunction,
+  SasV1ExtScsiPassThruGetNextTargetLun,
+  SasV1ExtScsiPassThruBuildDevicePath,
+  SasV1ExtScsiPassThruGetTargetLun,
+  SasV1ExtScsiPassThruResetChannel,
+  SasV1ExtScsiPassThruResetTarget,
+  SasV1ExtScsiPassThruGetNextTarget
+};
+
+EFI_STATUS
+EFIAPI
+SasDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  PLATFORM_SAS_PROTOCOL *plat;
+  EFI_STATUS Status;
+
+  Status = gBS->OpenProtocol (
+                Controller,
+                &gPlatformSasProtocolGuid,
+                (VOID **) &plat,
+                This->DriverBindingHandle,
+                Controller,
+                EFI_OPEN_PROTOCOL_BY_DRIVER
+                );
+  if (Status == EFI_ALREADY_STARTED) {
+    return EFI_SUCCESS;
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Close the Sas Host used to perform the supported test
+  //
+  gBS->CloseProtocol (
+      Controller,
+      &gPlatformSasProtocolGuid,
+      This->DriverBindingHandle,
+      Controller
+      );
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SasDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS Status;
+  PLATFORM_SAS_PROTOCOL *plat;
+  SAS_V1_INFO *SasV1Info = NULL;
+  SAS_V1_TRANSPORT_DEVICE_PATH  *DevicePath;
+  UINT32 val, base;
+  int i, phy_id = 0;
+  struct hisi_sas_itct *itct;
+  struct hisi_hba *hba;
+
+  Status = gBS->OpenProtocol (
+                Controller,
+                &gPlatformSasProtocolGuid,
+                (VOID **) &plat,
+                This->DriverBindingHandle,
+                Controller,
+                EFI_OPEN_PROTOCOL_BY_DRIVER
+                );
+
+  if (EFI_ERROR (Status)) {
+    if (Status == EFI_ALREADY_STARTED) {
+      return EFI_SUCCESS;
+    }
+    return Status;
+  }
+
+  SasV1Info = AllocateZeroPool (sizeof (SAS_V1_INFO));
+  ASSERT (SasV1Info);
+  SasV1Info->Signature = SAS_DEVICE_SIGNATURE;
+
+  SasV1Info->hba = AllocateZeroPool (sizeof(struct hisi_hba));
+  ASSERT (SasV1Info->hba);
+  hba = SasV1Info->hba;
+  base = hba->base = plat->BaseAddr;
+
+  sas_init(SasV1Info, plat);
+
+  // Wait for sas controller phyup happen
+  MicroSecondDelay(100000);
+
+  for (i = 0; i < PHY_CNT; i++) {
+    val = PHY_READ_REG32(base, CHL_INT2, i);
+
+    if (val & CHL_INT2_SL_PHY_ENA) {
+      phy_id = i;
+    }
+  }
+
+  itct = &hba->itct[0]; //device_id = 0
+
+  hba->port_id = (READ_REG32(base, PHY_PORT_NUM_MA) >> (4 * phy_id)) & 0xf;
+  // Setup itct
+  itct->qw0 = 0x355;
+  itct->sas_addr = PHY_READ_REG32(base, RX_IDAF_DWORD3, phy_id);
+  itct->sas_addr = itct->sas_addr << 32 | PHY_READ_REG32(base, RX_IDAF_DWORD4, phy_id);
+  itct->qw2 = 0;
+
+  // Clear phyup
+  PHY_WRITE_REG32(base, CHL_INT2, phy_id, CHL_INT2_SL_PHY_ENA);
+  val = PHY_READ_REG32(base, CHL_INT0, phy_id);
+  val &= ~CHL_INT0_PHYCTRL_NOTRDY;
+  PHY_WRITE_REG32(base, CHL_INT0, phy_id, val);
+  PHY_WRITE_REG32(base, CHL_INT0_MSK, phy_id, 0x3ce3ee);
+
+  // Need notify
+  val = PHY_READ_REG32(base, SL_CONTROL, phy_id);
+  val |= SL_CONTROL_NOTIFY_EN;
+  PHY_WRITE_REG32(base, SL_CONTROL, phy_id, val);
+  // wait 100ms required for notify takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+  MicroSecondDelay(100000);
+  val = PHY_READ_REG32(base, SL_CONTROL, phy_id);
+  val &= ~SL_CONTROL_NOTIFY_EN;
+  PHY_WRITE_REG32(base, SL_CONTROL, phy_id, val);
+
+  CopyMem (&SasV1Info->ExtScsiPassThru, &SasV1ExtScsiPassThruProtocolTemplate, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL));
+  SasV1Info->ExtScsiPassThruMode.AdapterId = 2;
+  SasV1Info->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
+  SasV1Info->ExtScsiPassThruMode.IoAlign  = 64; //cache line align
+  SasV1Info->ExtScsiPassThru.Mode = &SasV1Info->ExtScsiPassThruMode;
+
+  DevicePath = (SAS_V1_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_VENDOR_DP,
+                                               sizeof (SAS_V1_TRANSPORT_DEVICE_PATH));
+  ASSERT (DevicePath != NULL);
+  SasV1Info->DevicePath = DevicePath;
+
+  CopyMem (&DevicePath->Vendor.Guid, &gPlatformSasProtocolGuid, sizeof (EFI_GUID));
+  DevicePath->PhysBase = base;
+  SetDevicePathNodeLength (&DevicePath->Vendor,
+                           sizeof (*DevicePath) - sizeof (DevicePath->End));
+  SetDevicePathEndNode (&DevicePath->End);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                &Controller,
+                &gEfiDevicePathProtocolGuid, DevicePath,
+                &gEfiExtScsiPassThruProtocolGuid, &SasV1Info->ExtScsiPassThru,
+                NULL);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SasDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  )
+{
+  SAS_V1_INFO *SasV1Info;
+  EFI_STATUS Status;
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsi;
+  int i, s;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiExtScsiPassThruProtocolGuid,
+                  (VOID **) &ExtScsi,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SasV1Info = SAS_FROM_PASS_THRU(ExtScsi);
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                Controller,
+                &gEfiDevicePathProtocolGuid,
+                SasV1Info->DevicePath,
+                &gEfiExtScsiPassThruProtocolGuid,
+                &SasV1Info->ExtScsiPassThru,
+                NULL);
+  if (!EFI_ERROR (Status)) {
+    gBS->CloseProtocol (
+           Controller,
+           &gPlatformSasProtocolGuid,
+           This->DriverBindingHandle,
+           Controller
+           );
+
+    gBS->CloseEvent (SasV1Info->TimerEvent);
+
+    for (i = 0; i < QUEUE_CNT; i++) {
+      s = sizeof(struct hisi_sas_cmd_hdr) * QUEUE_SLOTS;
+      DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->cmd_hdr[i]);
+      s = sizeof(struct hisi_sas_complete_hdr) * QUEUE_SLOTS;
+      DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->complete_hdr[i]);
+      s = sizeof(struct hisi_sas_sts) * QUEUE_SLOTS;
+      DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->status_buf[i]);
+      s = sizeof(struct hisi_sas_cmd) * QUEUE_SLOTS;
+      DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->command_table[i]);
+      s = sizeof(struct hisi_sas_sge_page) * QUEUE_SLOTS;
+      DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->sge[i]);
+    }
+
+    s = SLOT_ENTRIES * sizeof(struct hisi_sas_iost);
+    DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->iost);
+    s = SLOT_ENTRIES * sizeof(struct hisi_sas_breakpoint);
+    DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->breakpoint);
+    s = MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
+    DmaFreeBuffer(EFI_SIZE_TO_PAGES (s), (VOID *)SasV1Info->hba->itct);
+
+    FreePool (SasV1Info->hba->slots);
+    FreePool (SasV1Info->hba);
+    FreePool (SasV1Info);
+    return EFI_SUCCESS;
+  }
+  return Status;
+}
+
+EFI_DRIVER_BINDING_PROTOCOL gSasDriverBinding = {
+  SasDriverBindingSupported,
+  SasDriverBindingStart,
+  SasDriverBindingStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+EFI_STATUS
+SasV1Initialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gSasDriverBinding,
+           ImageHandle,
+           NULL,
+           NULL
+           );
+}

+ 46 - 0
Silicon/Hisilicon/Drivers/SasV1Dxe/SasV1Dxe.inf

@@ -0,0 +1,46 @@
+#/** @file
+#
+#  Copyright (c) 2016 Linaro Ltd.
+#  Copyright (c) 2016 Hisilicon Limited.
+#  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                      = SasV1Dxe
+  FILE_GUID                      = 2b235921-8405-4219-a461-972a3a60969c
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = SasV1Initialize
+
+
+[Sources.common]
+  SasV1Dxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  DmaLib
+  IoLib
+  MemoryAllocationLib
+  PcdLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiLib
+  UncachedMemoryAllocationLib
+
+[Protocols]
+  gEfiExtScsiPassThruProtocolGuid
+  gPlatformSasProtocolGuid

+ 205 - 0
Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c

@@ -0,0 +1,205 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 "AddSmbiosType9.h"
+
+extern SMBIOS_TABLE_TYPE9 gPcieSlotInfo[];
+extern UINT8 OemGetPcieSlotNumber ();
+
+REPORT_PCIEDIDVID2BMC  PcieDeviceToReport_2P[PCIEDEVICE_REPORT_MAX] = {
+      {67,0,0,0},
+      {225,0,0,3},
+      {0xFFFF,0xFFFF,0xFFFF,0xFFFF},
+      {0xFFFF,0xFFFF,0xFFFF,0xFFFF}
+};
+VOID
+EFIAPI
+UpdateSmbiosType9Info(
+  IN OUT SMBIOS_TABLE_TYPE9             *Type9Record
+)
+{
+    EFI_STATUS                         Status;
+    UINTN                              HandleIndex;
+    EFI_HANDLE                        *HandleBuffer;
+    UINTN                              HandleCount;
+    EFI_PCI_IO_PROTOCOL               *PciIo;
+    UINTN                              SegmentNumber;
+    UINTN                              BusNumber;
+    UINTN                              DeviceNumber;
+    UINTN                              FunctionNumber;
+    UINTN                              Index;
+    REPORT_PCIEDIDVID2BMC              ReportPcieDidVid[PCIEDEVICE_REPORT_MAX];
+    if(OemIsMpBoot()){
+        (VOID)CopyMem((VOID *)ReportPcieDidVid,(VOID *)PcieDeviceToReport_2P,sizeof(PcieDeviceToReport_2P));
+    } else {
+        (VOID)CopyMem((VOID *)ReportPcieDidVid,(VOID *)PcieDeviceToReport,sizeof(PcieDeviceToReport));
+    }
+    Status = gBS->LocateHandleBuffer (
+                                      ByProtocol,
+                                      &gEfiPciIoProtocolGuid,
+                                      NULL,
+                                      &HandleCount,
+                                      &HandleBuffer
+                                      );
+    if(EFI_ERROR(Status)) {
+        DEBUG((EFI_D_ERROR, " Locate gEfiPciIoProtocol Failed.\n"));
+        gBS->FreePool ((VOID *)HandleBuffer);
+        return;
+    }
+    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+        Status = gBS->HandleProtocol (
+                                        HandleBuffer[HandleIndex],
+                                        &gEfiPciIoProtocolGuid,
+                                        (VOID **)&PciIo
+                                        );
+        if (EFI_ERROR (Status)) {
+            DEBUG((EFI_D_ERROR, "[%a]:[%dL] Status : %r\n", __FUNCTION__, __LINE__, Status));
+            continue;
+        }
+        (VOID)PciIo->GetLocation(PciIo, &SegmentNumber, &BusNumber, &DeviceNumber, &FunctionNumber);
+        for(Index = 0; Index < sizeof(ReportPcieDidVid) / sizeof(REPORT_PCIEDIDVID2BMC); Index++){
+            if (Type9Record->SlotID == ReportPcieDidVid[Index].Slot + 1) {
+                if((BusNumber == ReportPcieDidVid[Index].Bus) && (DeviceNumber == ReportPcieDidVid[Index].Device)) {
+                    DEBUG((EFI_D_ERROR,"PCIe device plot in slot Seg %d  bdf %d %d %d\r\n",SegmentNumber,BusNumber,DeviceNumber,FunctionNumber));
+                    Type9Record->SegmentGroupNum   = SegmentNumber;
+                    Type9Record->BusNum            = BusNumber;
+                    Type9Record->DevFuncNum        = (DeviceNumber << 3) | FunctionNumber;
+                    Type9Record->CurrentUsage      = SlotUsageInUse;
+                    break;
+                }
+            }
+        }
+    }
+    gBS->FreePool ((VOID *)HandleBuffer);
+    return;
+}
+EFI_STATUS
+EFIAPI
+AddSmbiosType9Entry (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+    EFI_STATUS                          Status;
+    EFI_SMBIOS_TYPE                     SmbiosType;
+    EFI_SMBIOS_HANDLE                   SmbiosHandle;
+    EFI_SMBIOS_PROTOCOL                 *Smbios;
+    EFI_SMBIOS_TABLE_HEADER             *Record;
+    SMBIOS_TABLE_TYPE9                  *Type9Record;
+    SMBIOS_TABLE_TYPE9                  *SmbiosRecord = NULL;
+    CHAR8                              *OptionalStrStart;
+
+    UINT8                               SmbiosAddType9Number;
+    UINT8                               Index;
+
+    CHAR16                              *SlotDesignation = NULL;
+    UINTN                               SlotDesignationStrLen;
+
+    Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **) &Smbios
+                  );
+    if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+        return Status;
+    }
+
+    do {
+        SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+        SmbiosType = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
+        Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &Record, NULL);
+        if (!EFI_ERROR(Status)) {
+            Status = Smbios->Remove (Smbios, SmbiosHandle);
+            if (EFI_ERROR(Status)) {
+                DEBUG((EFI_D_ERROR, "[%a]:[%dL] Remove System Slot Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+                break;
+            }
+        }
+    } while (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED);
+
+    SmbiosAddType9Number = OemGetPcieSlotNumber();
+
+    for (Index = 0; Index < SmbiosAddType9Number; Index++)
+    {
+        if (gPcieSlotInfo[Index].Hdr.Type != EFI_SMBIOS_TYPE_SYSTEM_SLOTS)
+        {
+            continue;
+        }
+
+        Type9Record = &gPcieSlotInfo[Index];
+
+        UpdateSmbiosType9Info (Type9Record);
+        SlotDesignation = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+        if (NULL == SlotDesignation)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            DEBUG((EFI_D_ERROR, "[%a]:[%dL] AllocateZeroPool Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+
+            goto Exit;
+        }
+
+        SlotDesignationStrLen = UnicodeSPrint (SlotDesignation, SMBIOS_STRING_MAX_LENGTH - 1, L"PCIE Slot%d", Type9Record->SlotID);
+
+        //
+        // Two zeros following the last string.
+        //
+        SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1);
+        if(NULL == SmbiosRecord)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            DEBUG((EFI_D_ERROR, "[%a]:[%dL] AllocateZeroPool Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+
+            goto Exit;
+        }
+
+        (VOID)CopyMem(SmbiosRecord, Type9Record, sizeof (SMBIOS_TABLE_TYPE9));
+
+        SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
+
+        OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+        UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
+
+        //
+        // Now we have got the full smbios record, call smbios protocol to add this record.
+        //
+        SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+        Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord);
+        if(EFI_ERROR(Status))
+        {
+            DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type09 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+            goto Exit;
+        }
+
+        FreePool(SmbiosRecord);
+        FreePool(SlotDesignation);
+    }
+
+    return EFI_SUCCESS;
+
+Exit:
+    if(SmbiosRecord != NULL)
+    {
+        FreePool(SmbiosRecord);
+    }
+
+    if(SlotDesignation != NULL)
+    {
+        FreePool(SlotDesignation);
+    }
+
+    return Status;
+}
+

+ 36 - 0
Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.h

@@ -0,0 +1,36 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 _ADD_SMBIOS_TYPE9_H_
+#define _ADD_SMBIOS_TYPE9_H_
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/OemMiscLib.h>
+
+#endif

+ 50 - 0
Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.inf

@@ -0,0 +1,50 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = AddSmbiosType9
+  FILE_GUID                      = 7AE6F104-66DF-48EF-B5A3-5050BF4908F0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AddSmbiosType9Entry
+
+[Sources]
+  AddSmbiosType9.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  MemoryAllocationLib
+  DebugLib
+  UefiLib
+  UefiDriverEntryPoint
+  OemMiscLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid
+  gEfiPciIoProtocolGuid
+
+[Guids]
+
+[Pcd]
+
+[Depex]
+  gEfiSmbiosProtocolGuid AND
+  gEfiPciIoProtocolGuid

+ 762 - 0
Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.c

@@ -0,0 +1,762 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 "MemorySubClass.h"
+
+EFI_SMBIOS_PROTOCOL             *mSmbios = NULL;
+EFI_HII_HANDLE                  mHiiHandle;
+
+UINT8                           mMaxSkt;
+UINT8                           mMaxCh;
+
+VOID
+SmbiosGetManufacturer (
+  IN  UINT8           MfgIdLSB,
+  IN  UINT8           MfgIdMSB,
+  OUT CHAR16          *Manufacturer
+)
+{
+    UINT32                  Index = 0;
+
+    (VOID)StrCpyS(Manufacturer, SMBIOS_STRING_MAX_LENGTH - 1, L"Unknown");
+    while (JEP106[Index].MfgIdLSB != 0xFF && JEP106[Index].MfgIdMSB != 0xFF )
+    {
+        if (JEP106[Index].MfgIdLSB == MfgIdLSB && JEP106[Index].MfgIdMSB == MfgIdMSB)
+        {
+            (VOID)StrCpyS (Manufacturer, SMBIOS_STRING_MAX_LENGTH - 1, JEP106[Index].Name);
+            break;
+        }
+        Index++;
+    }
+}
+
+VOID
+SmbiosGetPartNumber (
+  IN pGBL_DATA          pGblData,
+  IN UINT8              Skt,
+  IN UINT8              Ch,
+  IN UINT8              Dimm,
+  OUT CHAR16             *PartNumber
+  )
+{
+    CHAR16                        StringBuffer2[SMBIOS_STRING_MAX_LENGTH];
+    UINT32                        Index2;
+
+    (VOID)StrCpyS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, L"");
+    if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
+    {
+        for (Index2 = 0; Index2 < SPD_MODULE_PART; Index2++)
+        {
+            UnicodeSPrint (StringBuffer2, SMBIOS_STRING_MAX_LENGTH - 1, L"%c", pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdModPart[Index2]);
+            (VOID)StrCatS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, StringBuffer2);
+        }
+    }
+    else
+    {
+        for (Index2 = 0; Index2 < SPD_MODULE_PART_DDR4; Index2++)
+        {
+            UnicodeSPrint (StringBuffer2, SMBIOS_STRING_MAX_LENGTH - 1, L"%c", pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdModPartDDR4[Index2]);
+            (VOID)StrCatS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, StringBuffer2);
+        }
+    }
+
+    return;
+}
+
+VOID
+SmbiosGetSerialNumber (
+  IN pGBL_DATA          pGblData,
+  IN UINT8              Skt,
+  IN UINT8              Ch,
+  IN UINT8              Dimm,
+  OUT CHAR16            *SerialNumber
+  )
+{
+    UINT32              Temp;
+
+    Temp = SwapBytes32 (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdSerialNum);
+
+    UnicodeSPrint(SerialNumber, SMBIOS_STRING_MAX_LENGTH, L"0x%08x", Temp);
+
+    return;
+}
+
+BOOLEAN
+IsDimmPresent (
+  IN  pGBL_DATA          pGblData,
+  IN  UINT8              Skt,
+  IN  UINT8              Ch,
+  IN  UINT8              Dimm
+)
+{
+    if (pGblData->Channel[Skt][Ch].Status == FALSE ||
+          pGblData->Channel[Skt][Ch].Dimm[Dimm].Status == FALSE)
+    {
+        return FALSE;
+    }
+    else
+    {
+        return TRUE;
+    }
+}
+
+UINT8
+SmbiosGetMemoryType (
+  IN  pGBL_DATA          pGblData,
+  IN  UINT8              Skt,
+  IN  UINT8              Ch,
+  IN  UINT8              Dimm
+)
+{
+    UINT8 MemoryType;
+
+    if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
+    {
+        return MemoryTypeUnknown;
+    }
+
+    if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
+    {
+        MemoryType = MemoryTypeDdr3;
+    }
+    else if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR4)
+    {
+        MemoryType = MemoryTypeDdr4;
+    }
+    else
+    {
+        MemoryType = MemoryTypeUnknown;
+    }
+
+    return MemoryType;
+}
+
+VOID
+SmbiosGetTypeDetail (
+  IN  pGBL_DATA             pGblData,
+  IN  UINT8                 Skt,
+  IN  UINT8                 Ch,
+  IN  UINT8                 Dimm,
+  IN  OUT MEMORY_DEVICE_TYPE_DETAIL *TypeDetail
+)
+{
+    if (NULL == TypeDetail)
+    {
+        return;
+    }
+
+    if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
+    {
+        TypeDetail->Unknown = 1;
+        return;
+    }
+
+    switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].ModuleType)
+    {
+        case SPD_UDIMM:
+          TypeDetail->Unbuffered = 1;
+          break;
+
+        case SPD_LRDIMM:
+          TypeDetail->LrDimm = 1;
+          break;
+
+        case SPD_RDIMM:
+          TypeDetail->Registered = 1;
+          break;
+
+        default:
+          TypeDetail->Unknown = 1;
+          break;
+    }
+}
+
+VOID
+SmbiosGetDimmVoltageInfo (
+  IN     pGBL_DATA             pGblData,
+  IN     UINT8                 Skt,
+  IN     UINT8                 Ch,
+  IN     UINT8                 Dimm,
+  IN OUT SMBIOS_TABLE_TYPE17   *Type17Record
+
+)
+{
+    if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
+    {
+        return;
+    }
+
+    if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
+    {
+        Type17Record->MinimumVoltage                = 1250;
+        Type17Record->MaximumVoltage                = 1500;
+
+        switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdVdd)
+        {
+            case SPD_VDD_150:
+              Type17Record->ConfiguredVoltage = 1500;
+              break;
+
+            case SPD_VDD_135:
+              Type17Record->ConfiguredVoltage = 1350;
+              break;
+
+            case SPD_VDD_125:
+              Type17Record->ConfiguredVoltage = 1250;
+              break;
+
+            default:
+              break;
+        }
+    }
+    else if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR4)
+    {
+        Type17Record->MinimumVoltage                = 1200;
+        Type17Record->MaximumVoltage                = 2000;
+        switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdVdd)
+        {
+            case SPD_VDD_120:
+              Type17Record->ConfiguredVoltage = 1200;
+              break;
+
+            default:
+              break;
+        }
+    }
+}
+
+VOID
+SmbiosGetMemoryDevicesNumber (
+  IN OUT UINT16 *NumberOfDevices
+)
+{
+    UINT8       Skt, Ch, Dimm;
+
+    for(Skt = 0; Skt < mMaxSkt; Skt++)
+    {
+        for(Ch = 0; Ch < mMaxCh; Ch++)
+        {
+            for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
+            {
+                (*NumberOfDevices)++;
+            }
+        }
+    }
+}
+
+UINT8
+SmbiosGetPartitionWidth (
+)
+{
+
+    UINT8       Skt, Ch, Dimm;
+    UINT8       PartitionWidth = 0;
+
+    for(Skt = 0; Skt < mMaxSkt; Skt++)
+    {
+        for(Ch = 0; Ch < mMaxCh; Ch++)
+        {
+            for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
+            {
+                PartitionWidth++;
+            }
+        }
+    }
+
+    return PartitionWidth;
+}
+
+EFI_STATUS
+SmbiosAddType16Table (
+  IN  pGBL_DATA          pGblData,
+  OUT EFI_SMBIOS_HANDLE  *MemArraySmbiosHandle
+  )
+{
+    EFI_STATUS                      Status;
+    UINT64                          MemoryCapacity;
+    SMBIOS_TABLE_TYPE16             *Type16Record;
+
+    UINT16                          NumberOfMemoryDevices = 0;
+
+    SmbiosGetMemoryDevicesNumber (&NumberOfMemoryDevices);
+
+    MemoryCapacity = (UINT64) LShiftU64 (NumberOfMemoryDevices * MAX_DIMM_SIZE, 20); // GB to KB.
+
+    //
+    // Type 16 SMBIOS Record
+    //
+    Type16Record = AllocateZeroPool(sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
+    if (NULL == Type16Record)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    Type16Record->Hdr.Type                          = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
+    Type16Record->Hdr.Length                        = sizeof (SMBIOS_TABLE_TYPE16);
+    Type16Record->Hdr.Handle                        = 0x0;
+    Type16Record->Location                          = MemoryArrayLocationSystemBoard;
+    Type16Record->Use                               = MemoryArrayUseSystemMemory;
+    Type16Record->MemoryErrorInformationHandle      = 0xFFFE;
+    Type16Record->NumberOfMemoryDevices             = NumberOfMemoryDevices;
+
+    if(pGblData->EccEn)
+    {
+        Type16Record->MemoryErrorCorrection         = MemoryErrorCorrectionSingleBitEcc;
+    }
+    else
+    {
+        Type16Record->MemoryErrorCorrection         = MemoryErrorCorrectionNone;
+    }
+
+    if (MemoryCapacity >= 0x80000000)
+    {
+        Type16Record->MaximumCapacity = 0x80000000;   // in KB;
+        Type16Record->ExtendedMaximumCapacity = MemoryCapacity << 10;  // Extended Max capacity should be stored in bytes.
+    }
+    else
+    {
+        Type16Record->MaximumCapacity = (UINT32)MemoryCapacity;  // Max capacity should be stored in kilo bytes.
+        Type16Record->ExtendedMaximumCapacity = 0;
+    }
+
+    *MemArraySmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = mSmbios->Add (mSmbios, NULL, MemArraySmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type16Record);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type16 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+    }
+
+    FreePool(Type16Record);
+    return Status;
+}
+
+EFI_STATUS
+SmbiosAddType19Table (
+  IN pGBL_DATA          pGblData,
+  IN EFI_SMBIOS_HANDLE  MemArraySmbiosHandle
+  )
+{
+    EFI_STATUS                      Status;
+    UINT32                          MemInfoTotalMem;
+    UINT64                          TotalMemorySize;
+    EFI_SMBIOS_HANDLE               MemArrayMappedAddrSmbiosHandle;
+    SMBIOS_TABLE_TYPE19             *Type19Record;
+
+    MemInfoTotalMem = pGblData->MemSize;  // In MB
+
+    if (MemInfoTotalMem == 0)
+    {
+        return EFI_NOT_FOUND;
+    }
+
+    TotalMemorySize = (UINT64) LShiftU64 (MemInfoTotalMem, 10);  // MB to KB.
+
+    //
+    // Type 19 SMBIOS Record
+    //
+    Type19Record = AllocateZeroPool(sizeof(SMBIOS_TABLE_TYPE19) + 1 + 1);
+    if (NULL == Type19Record)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    Type19Record->Hdr.Type                          = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
+    Type19Record->Hdr.Length                        = sizeof(SMBIOS_TABLE_TYPE19);
+    Type19Record->Hdr.Handle                        = 0x0;
+    Type19Record->StartingAddress                   = 0x0;
+    Type19Record->EndingAddress                     = (UINT32) (TotalMemorySize - 1); // in KB;
+    Type19Record->MemoryArrayHandle                 = MemArraySmbiosHandle;
+    Type19Record->PartitionWidth                    = SmbiosGetPartitionWidth ();
+    Type19Record->ExtendedStartingAddress           = 0x0;
+    Type19Record->ExtendedEndingAddress             = 0x0;
+
+    MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = mSmbios->Add (mSmbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type19Record);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type19 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+    }
+
+    FreePool(Type19Record);
+    return Status;
+}
+
+
+EFI_STATUS
+SmbiosAddType17Table (
+  IN pGBL_DATA          pGblData,
+  IN UINT8              Skt,
+  IN UINT8              Ch,
+  IN UINT8              Dimm,
+  IN EFI_SMBIOS_HANDLE  MemArraySmbiosHandle
+  )
+{
+    EFI_STATUS                      Status;
+    SMBIOS_TABLE_TYPE17             *Type17Record;
+    EFI_SMBIOS_HANDLE               MemDevSmbiosHandle;
+    UINTN                           TableSize;
+
+    UINTN                           StringBufferSize;
+    EFI_STRING                      StringBuffer;
+    UINT16                          MemInfoMemFreq;
+    UINT16                          MemoryTotalWidth;
+    UINT16                          MemoryDataWidth;
+    UINT16                          MemoryDeviceSize;
+    UINT16                          MemorySpeed;
+    UINT8                           Attributes;
+    UINT32                          MemoryDeviceExtendSize;
+    UINT16                          CfgMemorySpeed;
+
+    CHAR8                           *OptionalStrStart;
+    UINTN                           DeviceLocatorStrLen;
+    UINTN                           BankLocatorStrLen;
+    UINTN                           ManufactureStrLen;
+    UINTN                           SerialNumberStrLen;
+    UINTN                           AssertTagStrLen;
+    UINTN                           PartNumberStrLen;
+    EFI_STRING                      DeviceLocatorStr;
+    EFI_STRING                      BankLocatorStr;
+    EFI_STRING                      ManufactureStr;
+    EFI_STRING                      SerialNumberStr;
+    EFI_STRING                      AssertTagStr;
+    EFI_STRING                      PartNumberStr;
+    EFI_STRING_ID                   DeviceLocator;
+
+    Type17Record        = NULL;
+    DeviceLocatorStr    = NULL;
+    BankLocatorStr      = NULL;
+    ManufactureStr      = NULL;
+    SerialNumberStr     = NULL;
+    AssertTagStr        = NULL;
+    PartNumberStr       = NULL;
+
+    MemoryTotalWidth    = 0;
+    MemoryDataWidth     = 0;
+    MemoryDeviceSize    = 0;
+    MemoryDeviceExtendSize = 0;
+    MemorySpeed         = 0;
+    Attributes          = 0;
+    CfgMemorySpeed      = 0;
+
+    //
+    // Allocate Buffers
+    //
+    StringBufferSize = (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH;
+    StringBuffer = AllocateZeroPool (StringBufferSize);
+    if(NULL == StringBuffer)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+
+    //
+    // Manufacture
+    //
+    ManufactureStr = AllocateZeroPool (StringBufferSize);
+    if(NULL == ManufactureStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_BUF;
+    }
+    UnicodeSPrint(ManufactureStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
+
+    //
+    // SerialNumber
+    //
+    SerialNumberStr = AllocateZeroPool (StringBufferSize);
+    if(NULL == SerialNumberStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_MAN;
+    }
+    UnicodeSPrint(SerialNumberStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
+
+    //
+    // AssetTag
+    //
+    AssertTagStr = AllocateZeroPool (StringBufferSize);
+    if(NULL == AssertTagStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_SN;
+    }
+    UnicodeSPrint(AssertTagStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
+
+    //
+    // PartNumber
+    //
+    PartNumberStr = AllocateZeroPool (StringBufferSize);
+    if(NULL == PartNumberStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_AST;
+    }
+    UnicodeSPrint(PartNumberStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
+
+
+    if(IsDimmPresent(pGblData, Skt, Ch, Dimm))
+    {
+        MemoryDataWidth = pGblData->Channel[Skt][Ch].Dimm[Dimm].PrimaryBusWidth;
+        MemoryTotalWidth = MemoryDataWidth + pGblData->Channel[Skt][Ch].Dimm[Dimm].ExtensionBusWidth;
+
+        MemoryDeviceSize = pGblData->Channel[Skt][Ch].Dimm[Dimm].DimmSize;  //in MB
+        MemoryDeviceExtendSize = 0;
+
+        if (MemoryDeviceSize >= 0x7fff)
+        {
+            MemoryDeviceExtendSize = MemoryDeviceSize;  // in MB
+            MemoryDeviceSize = 0x7fff;                    // max value
+        }
+
+        MemInfoMemFreq = pGblData->Freq;
+        MemorySpeed = pGblData->Channel[Skt][Ch].Dimm[Dimm].DimmSpeed;
+        Attributes = pGblData->Channel[Skt][Ch].Dimm[Dimm].RankNum;
+        CfgMemorySpeed = MemInfoMemFreq;
+
+        //
+        // Manufacturer
+        //
+        SmbiosGetManufacturer (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdMMfgId & 0xFF,
+                                        pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdMMfgId >> 8,
+                                        ManufactureStr
+                                        );
+
+        //
+        // SerialNumber
+        //
+        SmbiosGetSerialNumber(pGblData, Skt, Ch, Dimm, SerialNumberStr);
+
+        //
+        // AssetTag
+        //
+        UnicodeSPrint(AssertTagStr, SMBIOS_STRING_MAX_LENGTH - 1, L"Unknown");
+
+        //
+        // PartNumber
+        //
+        SmbiosGetPartNumber(pGblData, Skt, Ch, Dimm, PartNumberStr);
+    }
+
+    //
+    // DeviceLocator
+    //
+    DeviceLocatorStr = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+    if(NULL == DeviceLocatorStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_PN;
+    }
+    DeviceLocator = gDimmToDevLocator[Skt][Ch][Dimm];
+    if (DeviceLocator != 0xFFFF)
+    {
+        UnicodeSPrint(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"DIMM%x%x%x ", Skt, Ch, Dimm);
+        StringBuffer = HiiGetPackageString (&gEfiCallerIdGuid, DeviceLocator, NULL);
+        (VOID)StrCatS(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, StringBuffer);
+    }
+    else
+    {
+    UnicodeSPrint(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"DIMM%x%x%x", Skt, Ch, Dimm);
+    }
+    DeviceLocatorStrLen = StrLen (DeviceLocatorStr);
+
+    //
+    // BankLocator
+    //
+    BankLocatorStr = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+    if(NULL == BankLocatorStr)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_STR_DEV;
+    }
+    UnicodeSPrint(BankLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"SOCKET %x CHANNEL %x DIMM %x", Skt, Ch, Dimm);
+    BankLocatorStrLen = StrLen (BankLocatorStr);
+
+    ManufactureStrLen = StrLen (ManufactureStr);
+    SerialNumberStrLen = StrLen (SerialNumberStr);
+    AssertTagStrLen = StrLen (AssertTagStr);
+    PartNumberStrLen = StrLen (PartNumberStr);
+
+    //
+    // Report Type 17 SMBIOS Record
+    //
+    TableSize = sizeof(SMBIOS_TABLE_TYPE17) + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1 + AssertTagStrLen + 1 + PartNumberStrLen + 1 + 1;
+    Type17Record = AllocateZeroPool (TableSize);
+    if(NULL == Type17Record)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto FREE_BL;
+    }
+
+    Type17Record->Hdr.Type                      = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
+    Type17Record->Hdr.Length                    = sizeof (SMBIOS_TABLE_TYPE17);
+    Type17Record->Hdr.Handle                    = 0;
+    Type17Record->MemoryArrayHandle             = MemArraySmbiosHandle;
+    Type17Record->MemoryErrorInformationHandle  = 0xFFFE;
+    Type17Record->TotalWidth                    = MemoryTotalWidth;
+    Type17Record->DataWidth                     = MemoryDataWidth;
+    Type17Record->Size                          = MemoryDeviceSize;           // in MB
+    Type17Record->FormFactor                    = MemoryFormFactorDimm;
+    Type17Record->DeviceLocator                 = 1;
+    Type17Record->BankLocator                   = 2;
+    Type17Record->MemoryType                    = SmbiosGetMemoryType (pGblData, Skt, Ch, Dimm);
+
+    Type17Record->TypeDetail.Synchronous    = 1;
+
+    SmbiosGetTypeDetail (pGblData, Skt, Ch, Dimm, &(Type17Record->TypeDetail));
+
+    Type17Record->Speed                         = MemorySpeed; // in MHZ
+    Type17Record->Manufacturer                  = 3;
+    Type17Record->SerialNumber                  = 4;
+    Type17Record->AssetTag                      = 5;
+    Type17Record->PartNumber                    = 6;
+    Type17Record->Attributes                    = Attributes;
+    Type17Record->ExtendedSize                  = MemoryDeviceExtendSize;
+    Type17Record->ConfiguredMemoryClockSpeed    = CfgMemorySpeed;
+    //
+    // Add for smbios 2.8.0
+    //
+    SmbiosGetDimmVoltageInfo (pGblData, Skt, Ch, Dimm, Type17Record);
+
+    OptionalStrStart = (CHAR8 *) (Type17Record + 1);
+    UnicodeStrToAsciiStr (DeviceLocatorStr, OptionalStrStart);
+    UnicodeStrToAsciiStr (BankLocatorStr, OptionalStrStart + DeviceLocatorStrLen + 1);
+    UnicodeStrToAsciiStr (ManufactureStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1);
+    UnicodeStrToAsciiStr (SerialNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1);
+    UnicodeStrToAsciiStr (AssertTagStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1);
+    UnicodeStrToAsciiStr (PartNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1 + AssertTagStrLen + 1);
+
+    MemDevSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = mSmbios->Add (mSmbios, NULL, &MemDevSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type17Record);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type17 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+    }
+
+    FreePool (Type17Record);
+
+FREE_BL:
+    FreePool (BankLocatorStr);
+
+FREE_STR_DEV:
+    FreePool (DeviceLocatorStr);
+
+FREE_STR_PN:
+    FreePool (PartNumberStr);
+
+FREE_STR_AST:
+    FreePool (AssertTagStr);
+
+FREE_STR_SN:
+    FreePool (SerialNumberStr);
+
+FREE_STR_MAN:
+    FreePool (ManufactureStr);
+
+FREE_STR_BUF:
+    FreePool (StringBuffer);
+
+    return Status;
+}
+
+
+/**
+  Standard EFI driver point.  This driver locates the MemoryConfigurationData Variable,
+  if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+MemorySubClassEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+    EFI_STATUS                      Status;
+    EFI_SMBIOS_PROTOCOL             *Smbios;
+    EFI_HOB_GUID_TYPE               *GuidHob;
+    pGBL_DATA                       pGblData;
+    EFI_SMBIOS_HANDLE               MemArraySmbiosHandle;
+    UINT8                           Skt, Ch, Dimm;
+
+    GuidHob = GetFirstGuidHob(&gHisiEfiMemoryMapGuid);
+    if(NULL == GuidHob)
+    {
+        DEBUG((EFI_D_ERROR, "Could not get MemoryMap Guid hob.  %r\n"));
+        return EFI_NOT_FOUND;
+    }
+    pGblData = (pGBL_DATA) GET_GUID_HOB_DATA(GuidHob);
+
+    //
+    // Locate dependent protocols
+    //
+    Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
+        return Status;
+    }
+    mSmbios = Smbios;
+
+    //
+    // Add our default strings to the HII database. They will be modified later.
+    //
+    mHiiHandle = OemGetPackages();
+    if(NULL == mHiiHandle)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    mMaxSkt  = OemGetSocketNumber();
+    mMaxCh   = OemGetDdrChannel();
+    // Get DIMM slot number on Socket 0 Channel 0
+    // TODO: Assume all channels have same slot number
+
+    Status = SmbiosAddType16Table (pGblData, &MemArraySmbiosHandle);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "Smbios Add Type16 Table Failed.  %r\n", Status));
+        return Status;
+    }
+
+    Status = SmbiosAddType19Table (pGblData, MemArraySmbiosHandle);
+    if(EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "Smbios Add Type19 Table Failed.  %r\n", Status));
+        return Status;
+    }
+
+    for(Skt = 0; Skt < mMaxSkt; Skt++)
+    {
+        for(Ch = 0; Ch < mMaxCh; Ch++)
+        {
+            for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
+            {
+                Status = SmbiosAddType17Table (pGblData, Skt, Ch, Dimm, MemArraySmbiosHandle);
+                if(EFI_ERROR(Status))
+                {
+                    DEBUG((EFI_D_ERROR, "Smbios Add Type17 Table Failed.  %r\n", Status));
+                }
+            }
+        }
+    }
+
+    return Status;
+}

+ 79 - 0
Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.h

@@ -0,0 +1,79 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 _MEMORY_SUBCLASS_DRIVER_H
+#define _MEMORY_SUBCLASS_DRIVER_H
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+
+#include <Library/HwMemInitLib.h>
+#include <Guid/DebugMask.h>
+#include <Guid/MemoryMapData.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/OemMiscLib.h>
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+
+extern UINT8 MemorySubClassStrings[];
+
+#define MAX_DIMM_SIZE       32  // In GB
+
+struct SPD_JEDEC_MANUFACTURER
+{
+    UINT8  MfgIdLSB;
+    UINT8  MfgIdMSB;
+    CHAR16 *Name;
+};
+
+struct SPD_JEDEC_MANUFACTURER JEP106[] = {
+    {    0, 0x10, L"NEC"},
+    {    0, 0x2c, L"Micron"},
+    {    0, 0x3d, L"Tektronix"},
+    {    0, 0x97, L"TI"},
+    {    0, 0xad, L"Hynix"},
+    {    0, 0xb3, L"IDT"},
+    {    0, 0xc1, L"Infineon"},
+    {    0, 0xce, L"Samsung"},
+    {    1, 0x94, L"Smart"},
+    {    1, 0x98, L"Kingston"},
+    {    2, 0xc8, L"Agilent"},
+    {    2, 0xfe, L"Elpida"},
+    {    3, 0x0b, L"Nanya"},
+    {    4, 0x43, L"Ramaxel"},
+    {    4, 0xb3, L"Inphi"},
+    {    5, 0x51, L"Qimonda"},
+    {    5, 0x57, L"AENEON"},
+    { 0xFF, 0xFF, L""}
+};
+
+
+
+#endif

+ 59 - 0
Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf

@@ -0,0 +1,59 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = MemorySubClass
+  FILE_GUID                      = 62194F1A-5A0D-4B33-9EF0-7D05C6CB923A
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MemorySubClassEntryPoint
+
+[Sources]
+  MemorySubClassStrings.uni
+  MemorySubClass.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  HobLib
+  HiiLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  PrintLib
+  PlatformSysCtrlLib
+  PcdLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+
+[Guids]
+   gHisiEfiMemoryMapGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
+
+

+ 30 - 0
Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassStrings.uni

@@ -0,0 +1,30 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+// Copyright (c) 2015, 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.
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Begin English Language Strings
+//
+
+#string STR_MEMORY_SUBCLASS_UNKNOWN    #language en-US  "Unknown"
+
+//
+// End English Language Strings
+//
+

+ 728 - 0
Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c

@@ -0,0 +1,728 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 "ProcessorSubClass.h"
+
+#include <FrameworkDxe.h>
+
+EFI_HII_HANDLE                  mHiiHandle;
+
+EFI_SMBIOS_PROTOCOL             *mSmbios;
+
+SMBIOS_TABLE_TYPE7   mSmbiosCacheTable[] = {
+    //L1 Instruction Cache
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
+            sizeof(SMBIOS_TABLE_TYPE7),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //SocketDesignation
+        0,                                              //CacheConfiguration
+        0,                                              //MaximumCacheSize
+        48,                                             //InstalledSize
+        {                                               //SupportedSRAMType
+            0
+        },
+        {                                               //CurrentSRAMType
+            0
+        },
+        0,                                              //CacheSpeed
+        CacheErrorParity,                               //ErrorCorrectionType
+        CacheTypeInstruction,                           //SystemCacheType
+        CacheAssociativity8Way                          //Associativity
+    },
+
+    //L1 Data Cache
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
+            sizeof(SMBIOS_TABLE_TYPE7),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //SocketDesignation
+        0,                                              //CacheConfiguration
+        0,                                              //MaximumCacheSize
+        32,                                              //InstalledSize
+        {                                               //SupportedSRAMType
+            0
+        },
+        {                                               //CurrentSRAMType
+            0
+        },
+        0,                                              //CacheSpeed
+        CacheErrorSingleBit,                            //ErrorCorrectionType
+        CacheTypeData,                                  //SystemCacheType
+        CacheAssociativity8Way                          //Associativity
+    },
+
+    //L2 Cache
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
+            sizeof(SMBIOS_TABLE_TYPE7),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //SocketDesignation
+        0,                                              //CacheConfiguration
+        0,                                              //MaximumCacheSize
+        4096,                                           //InstalledSize
+        {                                               //SupportedSRAMType
+            0
+        },
+        {                                               //CurrentSRAMType
+            0
+        },
+        0,                                              //CacheSpeed
+        CacheErrorSingleBit,                            //ErrorCorrectionType
+        CacheTypeUnified,                               //SystemCacheType
+        CacheAssociativity8Way                          //Associativity
+    },
+
+    //L3 Cache
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
+            sizeof(SMBIOS_TABLE_TYPE7),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //SocketDesignation
+        0,                                              //CacheConfiguration
+        0,                                              //MaximumCacheSize
+        16384,                                          //InstalledSize
+        {                                               //SupportedSRAMType
+            0
+        },
+        {                                               //CurrentSRAMType
+            0
+        },
+        0,                                              //CacheSpeed
+        CacheErrorSingleBit,                            //ErrorCorrectionType
+        CacheTypeUnified,                               //SystemCacheType
+        CacheAssociativity16Way                         //Associativity
+    }
+};
+
+SMBIOS_TABLE_TYPE4   mSmbiosProcessorTable[] = {
+    //CPU0
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+            sizeof(SMBIOS_TABLE_TYPE4),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //Socket
+        CentralProcessor,                               //ProcessorType
+        ProcessorFamilyOther,                           //ProcessorFamily
+        2,                                              //ProcessorManufacture
+        {                                               //ProcessorId
+            {                                               //Signature
+                0
+            },
+            {                                               //FeatureFlags
+                0
+            }
+        },
+        3,                                              //ProcessorVersion
+        {                                               //Voltage
+            0
+        },
+        EXTERNAL_CLOCK,                                 //ExternalClock
+        CPU_MAX_SPEED,                                  //MaxSpeed
+        0,                                              //CurrentSpeed
+        0,                                              //Status
+        ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+        0xFFFF,                                         //L1CacheHandle
+        0xFFFF,                                         //L2CacheHandle
+        0xFFFF,                                         //L3CacheHandle
+        4,                                              //SerialNumber
+        5,                                              //AssetTag
+        6,                                              //PartNumber
+
+        0,                                              //CoreCount
+        0,                                              //EnabledCoreCount
+        0,                                              //ThreadCount
+        0,                                              //ProcessorCharacteristics
+
+        ProcessorFamilyARM,                             //ProcessorFamily2
+
+        0,                                              //CoreCount2
+        0,                                              //EnabledCoreCount2
+        0                                               //ThreadCount2
+    },
+
+    //CPU1
+    {
+        {                                               //Header
+            EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+            sizeof(SMBIOS_TABLE_TYPE4),                     //Length
+            0                                               //Handle
+        },
+        1,                                              //Socket
+        CentralProcessor,                               //ProcessorType
+        ProcessorFamilyOther,                           //ProcessorFamily
+        2,                                              //ProcessorManufacture
+        {                                               //ProcessorId
+            {                                               //Signature
+                0
+            },
+            {                                               //FeatureFlags
+                0
+            }
+        },
+        3,                                              //ProcessorVersion
+        {                                               //Voltage
+            0
+        },
+        EXTERNAL_CLOCK,                                 //ExternalClock
+        CPU_MAX_SPEED,                                  //MaxSpeed
+        0,                                              //CurrentSpeed
+        0,                                              //Status
+        ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+        0xFFFF,                                         //L1CacheHandle
+        0xFFFF,                                         //L2CacheHandle
+        0xFFFF,                                         //L3CacheHandle
+        4,                                              //SerialNumber
+        5,                                              //AssetTag
+        6,                                              //PartNumber
+
+        0,                                              //CoreCount
+        0,                                              //EnabledCoreCount
+        0,                                              //ThreadCount
+        0,                                              //ProcessorCharacteristics
+
+        ProcessorFamilyARM,                             //ProcessorFamily2
+
+        0,                                              //CoreCount2
+        0,                                              //EnabledCoreCount2
+        0                                               //ThreadCount2
+    }
+};
+
+
+UINT16
+GetCpuFrequency (
+  IN  UINT8 ProcessorNumber
+)
+{
+    return (UINT16)(PlatformGetCpuFreq(ProcessorNumber)/1000/1000);
+}
+
+UINTN
+GetCacheSocketStr (
+  IN  UINT8     CacheLevel,
+  OUT CHAR16    *CacheSocketStr
+  )
+{
+    UINTN CacheSocketStrLen;
+
+    if(CacheLevel == CPU_CACHE_L1_Instruction)
+    {
+        CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Instruction Cache", CacheLevel + 1);
+    }
+    else if(CacheLevel == CPU_CACHE_L1_Data)
+    {
+        CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Data Cache", CacheLevel);
+    }
+    else
+    {
+        CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Cache", CacheLevel);
+    }
+
+    return CacheSocketStrLen;
+}
+
+VOID
+UpdateSmbiosCacheTable (
+  IN UINT8  CacheLevel
+  )
+{
+    UINT16                      CoreCount;
+    UINT32                      TotalSize;
+    UINT32                      CacheSize;
+    UINT16                      MaximumCacheSize;
+    UINT16                      InstalledSize;
+    CACHE_CONFIGURATION         CacheConfig;
+    CACHE_SRAM_TYPE_DATA        CacheSramType = {0};
+
+    CoreCount = 16;     // Default value is 16 Core
+
+    //
+    // Set Cache Configuration
+    //
+    CacheConfig.Bits.Socketed                = 0;    // Not Socketed
+    CacheConfig.Bits.Reserved1               = 0;    //
+    CacheConfig.Bits.Location                = 0;    // Internal
+    CacheConfig.Bits.Enable                  = 1;    // Enabled
+    CacheConfig.Bits.Reserved2               = 0;
+    if(CacheLevel == CPU_CACHE_L1_Instruction || CacheLevel == CPU_CACHE_L1_Data)
+    {
+        CacheConfig.Bits.Level               = 0;
+        CacheConfig.Bits.OperationalMode     = 1;        // Write Back
+    }
+    else
+    {
+        CacheConfig.Bits.Level               = CacheLevel - 1;
+        CacheConfig.Bits.OperationalMode     = 2;        // Varies with Memory Address
+    }
+
+    mSmbiosCacheTable[CacheLevel].CacheConfiguration = CacheConfig.Data;
+
+    //
+    // Set Cache Size
+    //
+    CacheSize = mSmbiosCacheTable[CacheLevel].InstalledSize;
+    if (PACKAGE_16CORE != PlatformGetPackageType())  // 32 Core
+    {
+        CoreCount = CoreCount * 2;
+
+        if (CacheLevel > 1)
+        {
+            CacheSize = CacheSize * 2;
+        }
+    }
+
+    if(CacheLevel <= 1)
+    {
+        TotalSize = CacheSize * CoreCount;
+    }
+    else
+    {
+        TotalSize = CacheSize;
+    }
+
+    if((TotalSize >> 15) == 0)  // 1K granularity
+    {
+        MaximumCacheSize   = (UINT16)TotalSize;
+        InstalledSize      = (UINT16)TotalSize;
+    }
+    else    // 64K granularity
+    {
+        MaximumCacheSize   = (UINT16)(TotalSize >> 6);
+        InstalledSize      = (UINT16)(TotalSize >> 6);
+
+        // Set BIT15 to 1
+        MaximumCacheSize   |= BIT15;
+        InstalledSize      |= BIT15;
+    }
+
+    mSmbiosCacheTable[CacheLevel].MaximumCacheSize = MaximumCacheSize;
+    mSmbiosCacheTable[CacheLevel].InstalledSize = InstalledSize;
+
+    //
+    // Set SRAM Type
+    //
+    CacheSramType.Synchronous = 1;
+    (VOID)CopyMem(&mSmbiosCacheTable[CacheLevel].SupportedSRAMType, &CacheSramType, sizeof(CACHE_SRAM_TYPE_DATA));
+    (VOID)CopyMem(&mSmbiosCacheTable[CacheLevel].CurrentSRAMType, &CacheSramType, sizeof(CACHE_SRAM_TYPE_DATA));
+}
+
+/**
+  Add Type 7 SMBIOS Record for Cache Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+  @param[out]   L1CacheHandle       Pointer to the handle of the L1 Cache SMBIOS record.
+  @param[out]   L2CacheHandle       Pointer to the handle of the L2 Cache SMBIOS record.
+  @param[out]   L3CacheHandle       Pointer to the handle of the L3 Cache SMBIOS record.
+
+**/
+EFI_STATUS
+AddSmbiosCacheTypeTable (
+  IN UINTN                  ProcessorNumber,
+  OUT EFI_SMBIOS_HANDLE     *L1CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L2CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L3CacheHandle
+  )
+{
+    EFI_STATUS                  Status;
+    SMBIOS_TABLE_TYPE7          *Type7Record;
+    EFI_SMBIOS_HANDLE           SmbiosHandle;
+    UINTN                       TableSize;
+    UINT8                       CacheLevel;
+    CHAR8                       *OptionalStrStart;
+    EFI_STRING                  CacheSocketStr;
+    UINTN                       CacheSocketStrLen;
+    UINTN                       StringBufferSize;
+
+    Status = EFI_SUCCESS;
+
+    //
+    // Get Cache information
+    //
+    for(CacheLevel = 0; CacheLevel < MAX_CACHE_LEVEL; CacheLevel++)
+    {
+        Type7Record = NULL;
+
+        if(mSmbiosCacheTable[CacheLevel].InstalledSize == 0)
+        {
+            continue;
+        }
+
+        //
+        // Update Cache information
+        //
+        if (mSmbiosCacheTable[CacheLevel].MaximumCacheSize == 0)
+        {
+            UpdateSmbiosCacheTable (CacheLevel);
+        }
+
+        StringBufferSize = sizeof(CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+        CacheSocketStr = AllocateZeroPool(StringBufferSize);
+        if (CacheSocketStr == NULL)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            goto Exit;
+        }
+
+        CacheSocketStrLen = GetCacheSocketStr (CacheLevel, CacheSocketStr);
+
+        TableSize = sizeof(SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
+        Type7Record = AllocateZeroPool (TableSize);
+        if (Type7Record == NULL)
+        {
+            Status = EFI_OUT_OF_RESOURCES;
+            goto Exit;
+        }
+
+        (VOID)CopyMem(Type7Record, &mSmbiosCacheTable[CacheLevel], sizeof (SMBIOS_TABLE_TYPE7));
+
+        OptionalStrStart = (CHAR8 *) (Type7Record + 1);
+        UnicodeStrToAsciiStr (CacheSocketStr, OptionalStrStart);
+
+        SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+        Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type7Record);
+        if (EFI_ERROR (Status))
+        {
+            goto Exit;
+        }
+
+        // Config L1/L2/L3 Cache Handle
+        switch(CacheLevel)
+        {
+            case CPU_CACHE_L1_Instruction:
+            case CPU_CACHE_L1_Data:
+                *L1CacheHandle = SmbiosHandle;
+                break;
+            case CPU_CACHE_L2:
+                *L2CacheHandle = SmbiosHandle;
+                break;
+            case CPU_CACHE_L3:
+                *L3CacheHandle = SmbiosHandle;
+                break;
+            default :
+                break;
+        }
+Exit:
+        if(Type7Record != NULL)
+        {
+            FreePool (Type7Record);
+        }
+        if(CacheSocketStr != NULL)
+        {
+            FreePool (CacheSocketStr);
+            CacheSocketStr = NULL;
+        }
+    }
+
+    return Status;
+}
+
+/**
+  Add Type 4 SMBIOS Record for Processor Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+
+**/
+EFI_STATUS
+AddSmbiosProcessorTypeTable (
+  IN UINTN                  ProcessorNumber
+  )
+{
+    EFI_STATUS                  Status;
+    SMBIOS_TABLE_TYPE4          *Type4Record;
+    EFI_SMBIOS_HANDLE           SmbiosHandle;
+    EFI_SMBIOS_HANDLE           L1CacheHandle;
+    EFI_SMBIOS_HANDLE           L2CacheHandle;
+    EFI_SMBIOS_HANDLE           L3CacheHandle;
+
+    CHAR8                       *OptionalStrStart;
+    EFI_STRING_ID               ProcessorManu;
+    EFI_STRING_ID               ProcessorVersion;
+    EFI_STRING_ID               SerialNumber;
+    EFI_STRING_ID               AssetTag;
+    EFI_STRING_ID               PartNumber;
+    EFI_STRING                  ProcessorSocketStr;
+    EFI_STRING                  ProcessorManuStr;
+    EFI_STRING                  ProcessorVersionStr;
+    EFI_STRING                  SerialNumberStr;
+    EFI_STRING                  AssetTagStr;
+    EFI_STRING                  PartNumberStr;
+    UINTN                       ProcessorSocketStrLen;
+    UINTN                       ProcessorManuStrLen;
+    UINTN                       ProcessorVersionStrLen;
+    UINTN                       SerialNumberStrLen;
+    UINTN                       AssetTagStrLen;
+    UINTN                       PartNumberStrLen;
+    UINTN                       StringBufferSize;
+    UINTN                       TotalSize;
+
+    UINT8                       Voltage;
+    UINT16                      CoreCount;
+    UINT16                      CoreEnabled;
+    UINT16                      ThreadCount;
+    UINT16                      CurrentSpeed;
+    PROCESSOR_STATUS_DATA       ProcessorStatus = {{0}};
+    PROCESSOR_CHARACTERISTICS_DATA  ProcessorCharacteristics = {{0}};
+
+    CHAR16                      *CpuVersion;
+    STRING_REF                  TokenToUpdate;
+
+    UINT64                      *ProcessorId;
+    Type4Record         = NULL;
+    ProcessorManuStr    = NULL;
+    ProcessorVersionStr = NULL;
+    SerialNumberStr     = NULL;
+    AssetTagStr         = NULL;
+    PartNumberStr       = NULL;
+
+    if(OemIsSocketPresent(ProcessorNumber))  //CPU is present
+    {
+        Voltage         = BIT7 | 9;          // 0.9V
+
+        Status = AddSmbiosCacheTypeTable (ProcessorNumber, &L1CacheHandle, &L2CacheHandle, &L3CacheHandle);
+        if(EFI_ERROR(Status))
+        {
+            return Status;
+        }
+
+        CurrentSpeed        = GetCpuFrequency(ProcessorNumber);
+
+        CoreCount       = PlatformGetCoreCount();
+        CoreEnabled     = CoreCount;
+        ThreadCount     = CoreCount;
+
+        CpuVersion = (CHAR16 *) PcdGetPtr (PcdCPUInfo);
+        if (StrLen(CpuVersion) > 0)
+        {
+            TokenToUpdate = STRING_TOKEN (STR_PROCESSOR_VERSION);
+            HiiSetString (mHiiHandle, TokenToUpdate, CpuVersion, NULL);
+        }
+
+        ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
+        ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_VERSION);
+        SerialNumber        = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
+        AssetTag            = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
+        PartNumber          = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
+
+        // Processor Status
+        ProcessorStatus.Bits.CpuStatus           = 1;        // CPU Enabled
+        ProcessorStatus.Bits.Reserved1           = 0;
+        ProcessorStatus.Bits.SocketPopulated     = 1;        // CPU Socket Populated
+        ProcessorStatus.Bits.Reserved2           = 0;
+
+        // Processor Characteristics
+        ProcessorCharacteristics.Bits.Reserved       = 0;
+        ProcessorCharacteristics.Bits.Capable64Bit   = 1;        // 64-bit Capable
+        ProcessorCharacteristics.Bits.Unknown        = 0;
+        ProcessorCharacteristics.Bits.EnhancedVirtualization     = 1;
+        ProcessorCharacteristics.Bits.HardwareThread = 0;
+        ProcessorCharacteristics.Bits.MultiCore      = 1;
+        ProcessorCharacteristics.Bits.ExecuteProtection          = 1;
+        ProcessorCharacteristics.Bits.PowerPerformanceControl    = 1;
+        ProcessorCharacteristics.Bits.Reserved2      = 0;
+    }
+    else
+    {
+        Voltage             = 0;
+        CurrentSpeed        = 0;
+        CoreCount           = 0;
+        CoreEnabled         = 0;
+        ThreadCount         = 0;
+        L1CacheHandle       = 0xFFFF;
+        L2CacheHandle       = 0xFFFF;
+        L3CacheHandle       = 0xFFFF;
+
+        ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+        ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+        SerialNumber        = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+        AssetTag            = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+        PartNumber          = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+    }
+
+    // Processor Socket Designation
+    StringBufferSize = sizeof(CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+    ProcessorSocketStr = AllocateZeroPool(StringBufferSize);
+    if (ProcessorSocketStr == NULL)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+    }
+
+    ProcessorSocketStrLen = UnicodeSPrint (ProcessorSocketStr, StringBufferSize, L"CPU%02d", ProcessorNumber + 1);
+
+    // Processor Manufacture
+    ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
+    ProcessorManuStrLen = StrLen (ProcessorManuStr);
+
+    // Processor Version
+    ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
+    ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
+
+    // Serial Number
+    SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
+    SerialNumberStrLen = StrLen (SerialNumberStr);
+
+    // Asset Tag
+    AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
+    AssetTagStrLen = StrLen (AssetTagStr);
+
+    // Part Number
+    PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
+    PartNumberStrLen = StrLen (PartNumberStr);
+
+    TotalSize = sizeof (SMBIOS_TABLE_TYPE4) + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1 + PartNumberStrLen + 1 + 1;
+    Type4Record = AllocateZeroPool (TotalSize);
+    if (Type4Record == NULL)
+    {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+    }
+
+    (VOID)CopyMem(Type4Record, &mSmbiosProcessorTable[ProcessorNumber], sizeof (SMBIOS_TABLE_TYPE4));
+
+    *(UINT8 *) &Type4Record->Voltage        = Voltage;
+    Type4Record->CurrentSpeed               = CurrentSpeed;
+    Type4Record->Status                     = ProcessorStatus.Data;
+    Type4Record->L1CacheHandle              = L1CacheHandle;
+    Type4Record->L2CacheHandle              = L2CacheHandle;
+    Type4Record->L3CacheHandle              = L3CacheHandle;
+    Type4Record->CoreCount                  = CoreCount;
+    Type4Record->EnabledCoreCount           = CoreEnabled;
+    Type4Record->ThreadCount                = ThreadCount;
+    Type4Record->ProcessorCharacteristics   = ProcessorCharacteristics.Data;
+
+    Type4Record->ExternalClock              = (UINT16)(ArmReadCntFrq() / 1000 / 1000);
+    ProcessorId = (UINT64 *)&(Type4Record->ProcessorId);
+    *ProcessorId = ArmReadMidr();
+
+    OptionalStrStart = (CHAR8 *) (Type4Record + 1);
+    UnicodeStrToAsciiStr (ProcessorSocketStr, OptionalStrStart);
+    UnicodeStrToAsciiStr (ProcessorManuStr, OptionalStrStart + ProcessorSocketStrLen + 1);
+    UnicodeStrToAsciiStr (ProcessorVersionStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1);
+    UnicodeStrToAsciiStr (SerialNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1);
+    UnicodeStrToAsciiStr (AssetTagStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1);
+    UnicodeStrToAsciiStr (PartNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1);
+
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type4Record);
+    if (EFI_ERROR (Status))
+    {
+        DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+    }
+    FreePool (Type4Record);
+
+Exit:
+    if(ProcessorSocketStr != NULL)
+    {
+        FreePool (ProcessorSocketStr);
+    }
+    if(ProcessorManuStr != NULL)
+    {
+        FreePool (ProcessorManuStr);
+    }
+    if(ProcessorVersionStr != NULL)
+    {
+        FreePool (ProcessorVersionStr);
+    }
+    if(SerialNumberStr != NULL)
+    {
+        FreePool (SerialNumberStr);
+    }
+    if(AssetTagStr != NULL)
+    {
+        FreePool (AssetTagStr);
+    }
+    if(PartNumberStr != NULL)
+    {
+        FreePool (PartNumberStr);
+    }
+
+    return Status;
+}
+
+/**
+  Standard EFI driver point.  This driver locates the ProcessorConfigurationData Variable,
+  if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+ProcessorSubClassEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+    EFI_STATUS                      Status;
+    UINT32                          SocketIndex;
+
+    //
+    // Locate dependent protocols
+    //
+    Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
+        return Status;
+    }
+
+    //
+    // Add our default strings to the HII database. They will be modified later.
+    //
+    mHiiHandle = HiiAddPackages (
+                &gEfiCallerIdGuid,
+                NULL,
+                ProcessorSubClassStrings,
+                NULL,
+                NULL
+                );
+    if (mHiiHandle == NULL)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    //
+    // Add SMBIOS tables for populated sockets.
+    //
+    for (SocketIndex = 0; SocketIndex < MAX_SOCKET; SocketIndex++)
+    {
+        if((SocketIndex == 1) && !OemIsMpBoot())
+        {
+            break;
+        }
+        Status = AddSmbiosProcessorTypeTable (SocketIndex);
+        if(EFI_ERROR(Status))
+        {
+            DEBUG((EFI_D_ERROR, "Add Processor Type Table Failed!  %r.\n", Status));
+            return Status;
+        }
+    }
+
+    return Status;
+}

+ 108 - 0
Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h

@@ -0,0 +1,108 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, 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 _PROCESSOR_SUBCLASS_DRIVER_H
+#define _PROCESSOR_SUBCLASS_DRIVER_H
+
+#include <Uefi.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <PlatformArch.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/ArmLib.h>
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+
+extern UINT8 ProcessorSubClassStrings[];
+
+#define CPU_CACHE_L1_Instruction        0
+#define CPU_CACHE_L1_Data               1
+#define CPU_CACHE_L2                    2
+#define CPU_CACHE_L3                    3
+#define MAX_CACHE_LEVEL                 4
+
+#define EXTERNAL_CLOCK                  50     //50 MHz
+#define CPU_MAX_SPEED                   2100   //2.1G
+
+//
+// Cache Info
+//
+typedef struct {
+  UINT16                    InstalledSize;    //In KB
+  CACHE_TYPE_DATA           SystemCacheType;
+  CACHE_ASSOCIATIVITY_DATA  Associativity;
+} CACHE_INFO;
+
+//
+// Cache Configuration
+//
+typedef union {
+  struct {
+    UINT16    Level           :3;
+    UINT16    Socketed        :1;
+    UINT16    Reserved1       :1;
+    UINT16    Location        :2;
+    UINT16    Enable          :1;
+    UINT16    OperationalMode :2;
+    UINT16    Reserved2       :6;
+  } Bits;
+  UINT16 Data;
+}CACHE_CONFIGURATION;
+
+//
+// Processor Status
+//
+typedef union {
+  struct {
+    UINT8 CpuStatus       :3; // Indicates the status of the processor.
+    UINT8 Reserved1       :3; // Reserved for future use. Should be set to zero.
+    UINT8 SocketPopulated :1; // Indicates if the processor socket is populated or not.
+    UINT8 Reserved2       :1; // Reserved for future use. Should be set to zero.
+  } Bits;
+  UINT8 Data;
+}PROCESSOR_STATUS_DATA;
+
+//
+// Processor Characteristics
+//
+typedef union {
+  struct {
+    UINT16 Reserved                 :1;
+    UINT16 Unknown                  :1;
+    UINT16 Capable64Bit             :1;
+    UINT16 MultiCore                :1;
+    UINT16 HardwareThread           :1;
+    UINT16 ExecuteProtection        :1;
+    UINT16 EnhancedVirtualization   :1;
+    UINT16 PowerPerformanceControl  :1;
+    UINT16 Reserved2                :8;
+  } Bits;
+  UINT16 Data;
+} PROCESSOR_CHARACTERISTICS_DATA;
+
+#endif

+ 64 - 0
Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf

@@ -0,0 +1,64 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, 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                      = ProcessorSubClass
+  FILE_GUID                      = 9B25B1EA-0FD4-455D-A450-AD640C8A9C1B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ProcessorSubClassEntryPoint
+
+[Sources]
+  ProcessorSubClassStrings.uni
+  ProcessorSubClass.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  IoLib
+  HiiLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  PrintLib
+  PcdLib
+
+  PlatformSysCtrlLib
+  OemMiscLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gHisiTokenSpaceGuid.PcdCPUInfo
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
+
+[Guids]
+
+
+[Depex]
+  gEfiSmbiosProtocolGuid
+
+

+ 32 - 0
Silicon/Hisilicon/Drivers/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni

@@ -0,0 +1,32 @@
+///// @file
+//
+//  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+//  Copyright (c) 2015, 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.
+//
+/////
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Processor Information
+//
+#string STR_PROCESSOR_SOCKET_DESIGNATION    #language en-US  "Hisilicon PhosphorV660 Processor"
+#string STR_PROCESSOR_MANUFACTURE           #language en-US  "Hisilicon"
+#string STR_PROCESSOR_VERSION               #language en-US  "Hi1610ES"
+#string STR_PROCESSOR_SERIAL_NUMBER         #language en-US  "To be filled by O.E.M."
+#string STR_PROCESSOR_ASSET_TAG             #language en-US  "To be filled by O.E.M."
+#string STR_PROCESSOR_PART_NUMBER           #language en-US  "To be filled by O.E.M."
+#string STR_PROCESSOR_UNKNOWN               #language en-US  "Unknown"
+
+
+

+ 226 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMisc.h

@@ -0,0 +1,226 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+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.
+
+Module Name:
+
+  SmbiosMisc.h
+
+Abstract:
+
+  Header file for the SmbiosMisc Driver.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#ifndef _SMBIOS_MISC_DRIVER_H
+#define _SMBIOS_MISC_DRIVER_H
+
+#include <FrameworkDxe.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/DebugMask.h>
+
+#include <Library/PrintLib.h>
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+  IN  VOID                 *RecordData,
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+
+//
+// Data table entry definition.
+//
+typedef struct {
+  //
+  // intermediat input data for SMBIOS record
+  //
+  VOID                              *RecordData;
+  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function;
+
+
+//
+// Data Table entries
+//
+
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+  & NAME1 ## Data, \
+    NAME2 ## Function \
+}
+
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+  NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+  EFI_STATUS EFIAPI NAME2 ## Function( \
+  IN  VOID                  *RecordData, \
+  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
+  )
+
+//
+// Data Table Array Entries
+//
+extern EFI_HII_HANDLE               mHiiHandle;
+
+typedef struct _EFI_TYPE11_OEM_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefOemDefineString;
+} EFI_TYPE11_OEM_STRING;
+
+typedef struct _EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefType12SystemConfigurationOptionsString;
+} EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING;
+
+typedef struct _EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING{
+  UINT8                               *LanguageSignature;
+  EFI_STRING_ID                       InstallableLanguageLongString;
+  EFI_STRING_ID                       InstallableLanguageAbbreviateString;
+} EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING;
+
+typedef struct _EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY{
+  UINT8           RefType;
+  UINT8           RefOffset;
+  EFI_STRING_ID   RefString;
+  UINT8           Value;
+} EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY;
+
+typedef enum {
+  STRING,
+  DATA,
+} OEM_DEFINE_TYPE;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          Token;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_STRING;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          DataAddress;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_DATA;
+
+typedef union {
+  OEM_DEFINE_INFO_STRING         DefineString;
+  OEM_DEFINE_INFO_DATA           DefineData;
+} EFI_OEM_DEFINE_ARRAY;
+
+typedef struct _DMI_STRING_STRUCTURE {
+  UINT8                                 Type;
+  UINT8                                 Offset;
+  UINT8                                 Valid;
+  UINT16                                Length;
+  UINT8                                 String[1]; // Variable length field
+} DMI_STRING_STRUCTURE;
+
+typedef struct {
+  UINT8                                 Type;           // The SMBIOS structure type
+  UINT8                                 FixedOffset;    // The offset of the string reference
+                                                        // within the structure's fixed data.
+} DMI_UPDATABLE_STRING;
+
+EFI_STATUS
+FindString (
+  IN UINT8                              Type,
+  IN UINT8                              Offset,
+  IN EFI_STRING_ID                      TokenToUpdate
+);
+
+EFI_STATUS
+FindUuid (
+  EFI_GUID                    *Uuid
+);
+
+EFI_STATUS
+StringToBiosVeriosn (
+  IN  EFI_STRING_ID                     BiosVersionToken,
+  OUT UINT8                             *MajorVersion,
+  OUT UINT8                             *MinorVersion
+);
+
+
+/**
+ Logs SMBIOS record.
+
+ @param [in]   Buffer         Pointer to the data buffer.
+ @param [in]   SmbiosHandle   Pointer for retrieve handle.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  );
+
+/**
+ Get Link Type Handle.
+
+ @param [in]   SmbiosType     Get this Type from SMBIOS table
+ @param [out]  HandleArray    Pointer to Hadndler array with has been free by caller
+ @param [out]  HandleCount    Pointer to Hadndler Counter
+
+**/
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  );
+
+typedef enum {
+    ProductNameType01,
+    SerialNumType01,
+    UuidType01,
+    SystemManufacturerType01,
+    AssertTagType02,
+    SrNumType02,
+    BoardManufacturerType02,
+    AssetTagType03,
+    SrNumType03,
+    VersionType03,
+    ChassisTypeType03 ,
+    ManufacturerType03,
+} GET_INFO_BMC_OFFSET;
+
+VOID UpdateSmbiosInfo (IN EFI_HII_HANDLE mHiiHandle, IN EFI_STRING_ID TokenToUpdate, IN UINT8 Offset);
+EFI_STATUS GetUuidType1 (IN OUT EFI_GUID *Uuid);
+EFI_STATUS IpmiGetChassisType (IN OUT UINT8 *Type);
+#endif

+ 58 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c

@@ -0,0 +1,58 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+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.
+
+Module Name:
+
+  SmbiosMiscDataTable.c
+
+Abstract:
+
+  This file provide OEM to config SMBIOS Misc Type.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE0,  MiscBiosVendor, MiscBiosVendor)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE1,  MiscSystemManufacturer, MiscSystemManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE3,  MiscChassisManufacturer, MiscChassisManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE2,  MiscBaseBoardManufacturer, MiscBaseBoardManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE32, MiscBootInformation, MiscBootInformation)
+  MISC_SMBIOS_TABLE_EXTERNS(SMBIOS_TABLE_TYPE38, MiscIpmiDeviceInformation, MiscIpmiDeviceInformation)
+
+
+EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
+  // Type0
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBiosVendor, MiscBiosVendor),
+  // Type1
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemManufacturer, MiscSystemManufacturer),
+  // Type3
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscChassisManufacturer, MiscChassisManufacturer),
+  // Type2
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+  // Type13
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages),
+  // Type32
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBootInformation, MiscBootInformation),
+  // Type38
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscIpmiDeviceInformation, MiscIpmiDeviceInformation),
+};
+
+
+//
+// Number of Data Table entries.
+//
+UINTN mSmbiosMiscDataTableEntries =
+  (sizeof mSmbiosMiscDataTable) / sizeof(EFI_MISC_SMBIOS_DATA_TABLE);

+ 108 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf

@@ -0,0 +1,108 @@
+## @file
+# Component description file for SmbiosMisc instance.
+#
+# Parses the MiscSubclassDataTable and reports any generated data to the DataHub.
+#  All .uni file who tagged with "ToolCode="DUMMY"" in following file list is included by
+#  MiscSubclassDriver.uni file, the StrGather tool will expand MiscSubclassDriver.uni file
+#  and parse all .uni file.
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+# Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+#
+#  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.
+#
+#
+# Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmbiosMiscDxe
+  FILE_GUID                      = EF0C99B6-B1D3-4025-9405-BF6A560FE0E0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMiscEntryPoint
+
+[Sources]
+  SmbiosMisc.h
+  SmbiosMiscDataTable.c
+  SmbiosMiscEntryPoint.c
+  SmbiosMiscLibString.uni
+  ./Type00/MiscBiosVendorData.c
+  ./Type00/MiscBiosVendorFunction.c
+  ./Type01/MiscSystemManufacturerData.c
+  ./Type01/MiscSystemManufacturerFunction.c
+  ./Type02/MiscBaseBoardManufacturerData.c
+  ./Type02/MiscBaseBoardManufacturerFunction.c
+  ./Type03/MiscChassisManufacturerData.c
+  ./Type03/MiscChassisManufacturerFunction.c
+  ./Type13/MiscNumberOfInstallableLanguagesData.c
+  ./Type13/MiscNumberOfInstallableLanguagesFunction.c
+  ./Type32/MiscBootInformationData.c
+  ./Type32/MiscBootInformationFunction.c
+  ./Type38/MiscIpmiDeviceInformationData.c
+  ./Type38/MiscIpmiDeviceInformationFunction.c
+
+  ./Type09/MiscSystemSlotDesignationData.c
+  ./Type09/MiscSystemSlotDesignationFunction.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  HiiLib
+  MemoryAllocationLib
+  DevicePathLib
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  HobLib
+
+  IpmiCmdLib
+
+  SerdesLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdFdSize
+  gHisiTokenSpaceGuid.PcdFirmwareVendor
+  gHisiTokenSpaceGuid.PcdBiosVersionString
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
+
+  gHisiTokenSpaceGuid.PcdSystemProductName
+  gHisiTokenSpaceGuid.PcdSystemVersion
+  gHisiTokenSpaceGuid.PcdBaseBoardProductName
+  gHisiTokenSpaceGuid.PcdBaseBoardVersion
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+
+  gHisiTokenSpaceGuid.PcdBiosVersionForBmc
+
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+
+[Guids]
+  gEfiGenericVariableGuid
+  gVersionInfoHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
+
+

+ 194 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c

@@ -0,0 +1,194 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+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.
+
+Module Name:
+
+  SmbiosMiscEntryPoint.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data using SMBIOS protocol.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+#define MAX_HANDLE_COUNT  0x10
+
+EFI_HANDLE              mImageHandle;
+EFI_HII_HANDLE          mHiiHandle;
+EFI_SMBIOS_PROTOCOL     *mSmbios = NULL;
+
+//
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE   mSmbiosMiscDataTable[];
+//
+// Data Table Array Entries
+//
+extern UINTN                        mSmbiosMiscDataTableEntries;
+
+extern UINT8                        SmbiosMiscDxeStrings[];
+
+
+
+/**
+  Standard EFI driver point.  This driver parses the mSmbiosMiscDataTable
+  structure and reports any generated data using SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosMiscEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+    UINTN                Index;
+    EFI_STATUS           EfiStatus;
+    EFI_SMBIOS_PROTOCOL  *Smbios;
+
+    mImageHandle = ImageHandle;
+
+    EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+    if (EFI_ERROR(EfiStatus))
+    {
+        DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+        return EfiStatus;
+    }
+
+    mSmbios = Smbios;
+
+    mHiiHandle = HiiAddPackages (
+                   &gEfiCallerIdGuid,
+                   mImageHandle,
+                   SmbiosMiscDxeStrings,
+                   NULL
+                   );
+    if(mHiiHandle == NULL)
+    {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index)
+    {
+        //
+        // If the entry have a function pointer, just log the data.
+        //
+        if (mSmbiosMiscDataTable[Index].Function != NULL)
+        {
+            EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
+                mSmbiosMiscDataTable[Index].RecordData,
+                Smbios
+                );
+
+            if (EFI_ERROR(EfiStatus))
+            {
+                DEBUG((EFI_D_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+                return EfiStatus;
+            }
+        }
+    }
+
+    return EfiStatus;
+}
+
+
+/**
+  Logs SMBIOS record.
+
+  @param  Buffer                The data for the fixed portion of the SMBIOS record. The format of the record is
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
+                                a set of null terminated strings and a null.
+  @param  SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  )
+{
+    EFI_STATUS         Status;
+
+    *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+    Status = mSmbios->Add (
+                     mSmbios,
+                     NULL,
+                     SmbiosHandle,
+                     (EFI_SMBIOS_TABLE_HEADER *)Buffer
+                     );
+
+    return Status;
+}
+
+
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  )
+{
+    EFI_STATUS                       Status;
+    EFI_SMBIOS_HANDLE                SmbiosHandle;
+    EFI_SMBIOS_TABLE_HEADER          *LinkTypeData = NULL;
+
+    if(mSmbios == NULL)
+        return ;
+
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+    *HandleArray = AllocateZeroPool(sizeof(UINT16) * MAX_HANDLE_COUNT);
+    if (*HandleArray == NULL)
+    {
+        DEBUG ((EFI_D_INFO, "HandleArray allocate memory resource failed.\n"));
+        return;
+    }
+
+    *HandleCount = 0;
+
+    while(1)
+    {
+        Status = mSmbios->GetNext(
+                            mSmbios,
+                            &SmbiosHandle,
+                            &SmbiosType,
+                            &LinkTypeData,
+                            NULL
+                            );
+
+        if(!EFI_ERROR(Status))
+        {
+            (*HandleArray)[*HandleCount] = LinkTypeData->Handle;
+            (*HandleCount)++;
+        }
+        else
+        {
+            break;
+        }
+    }
+}
+

+ 28 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni

@@ -0,0 +1,28 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// 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.
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#include "./Type00/MiscBiosVendor.uni"
+#include "./Type01/MiscSystemManufacturer.uni"
+#include "./Type02/MiscBaseBoardManufacturer.uni"
+#include "./Type03/MiscChassisManufacturer.uni"
+#include "./Type13/MiscNumberOfInstallableLanguages.uni"
+#include "./Type09/MiscSystemSlotDesignation.uni"

+ 25 - 0
Silicon/Hisilicon/Drivers/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni

@@ -0,0 +1,25 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// 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.
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+//#string STR_MISC_BIOS_VENDOR           #language en-US  "Bios Vendor"
+#string STR_MISC_BIOS_VERSION          #language en-US  "Bios Version"
+//#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "Bios Release Date"
+
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Huawei Technologies Co., Ltd."
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "01/01/1900"

部分文件因为文件数量过多而无法显示