public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform
@ 2019-09-19  3:51 Gilbert Chen
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package Gilbert Chen
                   ` (13 more replies)
  0 siblings, 14 replies; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

"devel-riscv-v2" is a new branch created for reviewing code changes of SiFive U500 VC707 FPGA
platform EDK2 port. Compare to old "devel-riscv" branch, the patches sent to "devel-riscv-v2"
branch are made based on the most recent edk2/master. The corresponding patches of
edk2 code changes were sent to edk2 devel mail list with [edk2-staging/RISC-V-V2] in
patch message subject.

Gilbert Chen (14):
  Silicon/SiFive: Initial version of SiFive  silicon package
  Silicon/SiFive: Add library module of SiFive  RISC-V cores
  platforms/RiscV: Initial version of RISC-V  platform package
  RiscV/Include: Initial version of header files in  RISC-V platform
    package
  RiscV/Library: Initial version of libraries introduced  in RISC-V
    platform package
  RiscV/Universal: Initial version of common RISC-V  SEC module
  RiscV/SiFive: Initial version of SiFive U500  platform package
  U500Pkg/Include: Header files of SiFive U500  platform
  U500Pkg/Library: Initial version of  PlatformBootManagerLib
  U500Pkg/Library: Library instances of U500  platform library
  U500Pkg/RamFvbServiceruntimeDxe: FVB driver  for EFI variable.
  U500Pkg/TimerDxe: Platform Timer DXE driver
  U500Pkg/PlatformPei: Platform initialization PEIM
  Platforms: Readme file updates

 Maintainers.txt                                    |    9 +
 .../Library/FirmwareContextProcessorSpecificLib.h  |   40 +
 .../FirmwareContextProcessorSpecificLib.c          |   82 ++
 .../FirmwareContextProcessorSpecificLib.inf        |   33 +
 .../RealTimeClockLibNull/RealTimeClockLibNull.c    |  204 ++++
 .../RealTimeClockLibNull/RealTimeClockLibNull.inf  |   30 +
 Platform/RiscV/Readme.md                           |   89 ++
 Platform/RiscV/RiscVPlatformPkg.dec                |   72 ++
 Platform/RiscV/RiscVPlatformPkg.uni                |   15 +
 Platform/RiscV/RiscVPlatformPkgExtra.uni           |   12 +
 .../SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h    |   51 +
 Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h  |   19 +
 .../OpenSbiPlatformLib/OpenSbiPlatformLib.inf      |   47 +
 .../U500Pkg/Library/OpenSbiPlatformLib/platform.c  |  214 ++++
 .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        |  195 ++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |   58 +
 .../Library/PlatformBootManagerLib/MemoryTest.c    |  682 ++++++++++++
 .../PlatformBootManagerLib/PlatformBootManager.c   |  274 +++++
 .../PlatformBootManagerLib/PlatformBootManager.h   |  135 +++
 .../PlatformBootManagerLib.inf                     |   63 ++
 .../Library/PlatformBootManagerLib/PlatformData.c  |   49 +
 .../Library/PlatformBootManagerLib/Strings.uni     |   28 +
 .../RiscVPlatformTimerLib/RiscVPlatformTimerLib.S  |   48 +
 .../RiscVPlatformTimerLib.inf                      |   39 +
 .../U500Pkg/Library/SerialIoLib/SerialIoLib.inf    |   31 +
 .../U500Pkg/Library/SerialIoLib/SerialPortLib.c    |  241 +++++
 .../Library/SerialIoLib/U500SerialPortLib.uni      |   16 +
 Platform/RiscV/SiFive/U500Pkg/Readme.md            |   62 ++
 Platform/RiscV/SiFive/U500Pkg/U500.dec             |   34 +
 Platform/RiscV/SiFive/U500Pkg/U500.dsc             |  549 ++++++++++
 Platform/RiscV/SiFive/U500Pkg/U500.fdf             |  335 ++++++
 Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc         |   52 +
 Platform/RiscV/SiFive/U500Pkg/U500.uni             |   13 +
 Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni     |   12 +
 .../Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c         |  127 +++
 .../FvbServicesRuntimeDxe.inf                      |   81 ++
 .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c  | 1123 ++++++++++++++++++++
 .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h  |  187 ++++
 .../RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c   |  151 +++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.c        |  144 +++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.h        |   85 ++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c     |   20 +
 .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c  |  311 ++++++
 .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h  |  174 +++
 .../U500Pkg/Universal/Dxe/TimerDxe/Timer.uni       |   14 +
 .../U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf    |   48 +
 .../U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni  |   12 +
 .../SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c  |   49 +
 .../U500Pkg/Universal/Pei/PlatformPei/MemDetect.c  |   74 ++
 .../U500Pkg/Universal/Pei/PlatformPei/Platform.c   |  313 ++++++
 .../U500Pkg/Universal/Pei/PlatformPei/Platform.h   |   92 ++
 .../Universal/Pei/PlatformPei/PlatformPei.inf      |   75 ++
 Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc     |   78 ++
 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S    |  438 ++++++++
 Platform/RiscV/Universal/Sec/SecMain.c             |  524 +++++++++
 Platform/RiscV/Universal/Sec/SecMain.h             |   57 +
 Platform/RiscV/Universal/Sec/SecMain.inf           |   75 ++
 Readme.md                                          |   11 +
 .../E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c    |  242 +++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |   51 +
 Silicon/SiFive/Include/Library/SiFiveE51.h         |   60 ++
 Silicon/SiFive/Include/Library/SiFiveU54.h         |   60 ++
 .../SiFive/Include/Library/SiFiveU54MCCoreplex.h   |   55 +
 Silicon/SiFive/SiFive.dec                          |   39 +
 .../U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c    |  294 +++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |   51 +
 .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        |  185 ++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |   50 +
 68 files changed, 9183 insertions(+)
 create mode 100644 Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
 create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
 create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
 create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
 create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
 create mode 100644 Platform/RiscV/Readme.md
 create mode 100644 Platform/RiscV/RiscVPlatformPkg.dec
 create mode 100644 Platform/RiscV/RiscVPlatformPkg.uni
 create mode 100644 Platform/RiscV/RiscVPlatformPkgExtra.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Readme.md
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dec
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dsc
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
 create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
 create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveE51.h
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54.h
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
 create mode 100644 Silicon/SiFive/SiFive.dec
 create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf

-- 
2.12.0.windows.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-01  0:41   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores Gilbert Chen
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Add SiFive silicon EDK2 metafile and header files of
 SiFive RISC-V cores.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 Silicon/SiFive/Include/Library/SiFiveE51.h         | 60 ++++++++++++++++++++++
 Silicon/SiFive/Include/Library/SiFiveU54.h         | 60 ++++++++++++++++++++++
 .../SiFive/Include/Library/SiFiveU54MCCoreplex.h   | 55 ++++++++++++++++++++
 Silicon/SiFive/SiFive.dec                          | 39 ++++++++++++++
 4 files changed, 214 insertions(+)
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveE51.h
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54.h
 create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
 create mode 100644 Silicon/SiFive/SiFive.dec

diff --git a/Silicon/SiFive/Include/Library/SiFiveE51.h b/Silicon/SiFive/Include/Library/SiFiveE51.h
new file mode 100644
index 00000000..5faea5c7
--- /dev/null
+++ b/Silicon/SiFive/Include/Library/SiFiveE51.h
@@ -0,0 +1,60 @@
+/** @file
+  SiFive E51 Core library definitions.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SIFIVE_E51_CORE_H_
+#define _SIFIVE_E51_CORE_H_
+
+#include <PiPei.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+
+/**
+  Function to build core specific information HOB.
+
+  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
+                                 could be the same as CoreGuid if one processor has
+                                 only one core.
+  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
+  @param  HartId                 Hart ID of this core.
+  @param  IsBootHart             TRUE means this is the boot HART.
+  @param  GuidHobData            Pointer to receive RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateE51CoreProcessorSpecificDataHob (
+  IN EFI_GUID  *ParentProcessorGuid,
+  IN UINTN     ParentProcessorUid,
+  IN UINTN     HartId,
+  IN BOOLEAN   IsBootHart,
+  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobData
+  );
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateE51ProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  );
+
+#endif
diff --git a/Silicon/SiFive/Include/Library/SiFiveU54.h b/Silicon/SiFive/Include/Library/SiFiveU54.h
new file mode 100644
index 00000000..2e3a1c75
--- /dev/null
+++ b/Silicon/SiFive/Include/Library/SiFiveU54.h
@@ -0,0 +1,60 @@
+/** @file
+  SiFive U54 Core library definitions.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SIFIVE_U54_CORE_H_
+#define _SIFIVE_U54_CORE_H_
+
+#include <PiPei.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+
+/**
+  Function to build core specific information HOB.
+
+  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
+                                 could be the same as CoreGuid if one processor has
+                                 only one core.
+  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
+  @param  HartId                 Hart ID of this core.
+  @param  IsBootHart             TRUE means this is the boot HART.
+  @param  GuidHobdata            Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54CoreProcessorSpecificDataHob (
+  IN EFI_GUID  *ParentProcessorGuid,
+  IN UINTN     ParentProcessorUid,
+  IN UINTN     HartId,
+  IN BOOLEAN   IsBootHart,
+  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobdata
+  );
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54ProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  );
+
+#endif
diff --git a/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h b/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
new file mode 100644
index 00000000..3d23b34c
--- /dev/null
+++ b/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
@@ -0,0 +1,55 @@
+/** @file
+  SiFive U54 Coreplex library definitions.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SIFIVE_U54MC_COREPLEX_CORE_H_
+#define _SIFIVE_U54MC_COREPLEX_CORE_H_
+
+#include <PiPei.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+
+#define SIFIVE_U54MC_COREPLEX_E51_HART_ID     0
+#define SIFIVE_U54MC_COREPLEX_U54_0_HART_ID   1
+#define SIFIVE_U54MC_COREPLEX_U54_1_HART_ID   2
+#define SIFIVE_U54MC_COREPLEX_U54_2_HART_ID   3
+#define SIFIVE_U54MC_COREPLEX_U54_3_HART_ID   4
+
+/**
+  Build up U54MC coreplex processor core-specific information.
+
+  @param  UniqueId      U54MC unique ID.
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54MCCoreplexProcessorSpecificDataHob (
+  IN UINTN UniqueId
+  );
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54MCProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  );
+#endif
diff --git a/Silicon/SiFive/SiFive.dec b/Silicon/SiFive/SiFive.dec
new file mode 100644
index 00000000..7aca3e75
--- /dev/null
+++ b/Silicon/SiFive/SiFive.dec
@@ -0,0 +1,39 @@
+## @file
+#  SiFive silicon package definitions
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = SiFiveSiliconPkg
+  PACKAGE_GUID                   = 576912B2-7077-4B78-A934-4C133FEB20BB
+  PACKAGE_VERSION                = 1.0
+
+[Includes]
+  Include                        # Root include for the package
+
+[LibraryClasses]
+
+[Guids]
+  gEfiSiFiveSiliconSpaceGuid  = {0x5F3E9E15, 0x8FFC, 0x4F53, { 0x8E, 0x64, 0x92, 0x0B, 0xA5, 0x39, 0x81, 0xB0 }}
+
+[Protocols]
+
+[PcdsFixedAtBuild]
+  # E51 Core GUID
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid |{0xD4, 0x69, 0x54, 0x87, 0x96, 0x96, 0x48, 0x7F, 0x9F, 0x57, 0xB6, 0xF1, 0xDE, 0x7D, 0x97, 0x42}|VOID*|0x00001000
+  # U54 Core GUID
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid |{0x64, 0x70, 0xF6, 0x90, 0x11, 0x59, 0x47, 0xF1, 0xB8, 0xD5, 0xCF, 0x89, 0x10, 0xC5, 0x30, 0x20}|VOID*|0x00001001
+  # U54 MC Coreplex GUID
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54MCCoreplexGuid |{0x67, 0xBF, 0x15, 0xD9, 0x7E, 0x4F, 0x48, 0x27, 0x87, 0x19, 0x79, 0x0B, 0xA6, 0x22, 0x7C, 0xBE}|VOID*|0x00001002
+  # U5 MC Coreplex GUID
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid |{0x06, 0x38, 0x9F, 0x33, 0xF9, 0xDB, 0x43, 0x13, 0x9A, 0x9B, 0x1C, 0x68, 0xD6, 0x04, 0xEA, 0xFF}|VOID*|0x00001003
+
+[PcdsDynamic, PcdsDynamicEx]
+
+[PcdsFeatureFlag]
+
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-01 21:14   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package Gilbert Chen
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Initial version of SiFive RISC-V core libraries. Library of each core
 creates processor core SMBIOS data hob for building SMBIOS
 records in DXE phase.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 242 +++++++++++++++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
 .../U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 294 +++++++++++++++++++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
 .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 185 +++++++++++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  50 ++++
 6 files changed, 873 insertions(+)
 create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf

diff --git a/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
new file mode 100644
index 00000000..b7140b53
--- /dev/null
+++ b/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
@@ -0,0 +1,242 @@
+/**@file
+  Build up platform processor information.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ResourcePublicationLib.h>
+
+#include <SmbiosProcessorSpecificData.h>
+
+#include <RiscV.h>
+#include <ProcessorSpecificDataHob.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi.h>
+#include <sbi/SbiFirmwareContext.h>
+#include <Library/FirmwareContextProcessorSpecificLib.h>
+
+/**
+  Function to build core specific information HOB. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type44.
+
+  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
+                                 could be the same as CoreGuid if one processor has
+                                 only one core.
+  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
+  @param  HartId                 Hart ID of this core.
+  @param  IsBootHart             TRUE means this is the boot HART.
+  @param  GuidHobData            Pointer to receive   EFI_HOB_GUID_TYPE.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateE51CoreProcessorSpecificDataHob (
+  IN EFI_GUID  *ParentProcessorGuid,
+  IN UINTN     ParentProcessorUid,
+  IN UINTN     HartId,
+  IN BOOLEAN   IsBootHart,
+  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobData
+  )
+{
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *CoreGuidHob;
+  EFI_GUID *ProcessorSpecDataHobGuid;
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB ProcessorSpecDataHob;
+  struct sbi_scratch *ThisHartSbiScratch;
+  struct sbi_platform *ThisHartSbiPlatform;
+  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext;
+  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__));
+
+  if (GuidHobData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ThisHartSbiScratch = sbi_hart_id_to_scratch (sbi_scratch_thishart_ptr(), (UINT32)HartId);
+  DEBUG ((DEBUG_INFO, "    SBI Scratch is at 0x%x.\n", ThisHartSbiScratch));
+  ThisHartSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(ThisHartSbiScratch);
+  DEBUG ((DEBUG_INFO, "    SBI platform is at 0x%x.\n", ThisHartSbiPlatform));
+  FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisHartSbiPlatform->firmware_context;
+  DEBUG ((DEBUG_INFO, "    Firmware Context is at 0x%x.\n", FirmwareContext));
+  FirmwareContextHartSpecific = FirmwareContext->HartSpecific[HartId];
+  DEBUG ((DEBUG_INFO, "    Firmware Context Hart specific is at 0x%x.\n", FirmwareContextHartSpecific));
+
+  //
+  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+  //
+  CommonFirmwareContextHartSpecificInfo (
+      FirmwareContextHartSpecific,
+      ParentProcessorGuid,
+      ParentProcessorUid,
+      (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid),
+      HartId,
+      IsBootHart,
+      &ProcessorSpecDataHob
+      );
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L     = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_H     = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_H = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.HartXlen                 = RegisterLen64;
+  ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen          = RegisterLen64;
+  ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen       = RegisterUnsupported;
+  ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen             = RegisterLen64;
+
+  DEBUG ((DEBUG_INFO, "        *HartId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.HartId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *Is Boot Hart? = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.BootHartId));
+  DEBUG ((DEBUG_INFO, "        *PrivilegeModeSupported = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.PrivilegeModeSupported));
+  DEBUG ((DEBUG_INFO, "        *MModeExcepDelegation = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MModeInterruptDelegation = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *HartXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.HartXlen ));
+  DEBUG ((DEBUG_INFO, "        *MachineModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen));
+  DEBUG ((DEBUG_INFO, "        *SupervisorModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen));
+  DEBUG ((DEBUG_INFO, "        *UserModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen));
+  DEBUG ((DEBUG_INFO, "        *InstSetSupported = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.InstSetSupported));
+  DEBUG ((DEBUG_INFO, "        *MachineVendorId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineVendorId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MachineArchId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineArchId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MachineImplId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineImplId.Value64_L));
+
+  //
+  // Build GUID HOB for E51 core, this is for SMBIOS type 44
+  //
+  ProcessorSpecDataHobGuid = PcdGetPtr (PcdProcessorSpecificDataGuidHobGuid);
+  CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID *)&ProcessorSpecDataHob, sizeof (RISC_V_PROCESSOR_SPECIFIC_DATA_HOB));
+  if (CoreGuidHob == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core.\n"));
+    ASSERT (FALSE);
+  }
+  *GuidHobData = CoreGuidHob;
+  return EFI_SUCCESS;
+}
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateE51ProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  )
+{
+  EFI_GUID *GuidPtr;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L1InstCacheDataHob;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L1InstCacheDataHobPtr;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
+
+  if (SmbiosHobPtr == NULL) {
+      return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Build up SMBIOS type 7 L1 instruction cache record.
+  //
+  ZeroMem((VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid));
+  L1InstCacheDataHob.ProcessorUid = ProcessorUid;
+  L1InstCacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L1InstCacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L1InstCacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L1InstCacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeInstruction;
+  L1InstCacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L1InstCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L1InstCacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core L1 instruction cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 4 record.
+  //
+  ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid));
+  ProcessorDataHob.ProcessorUid = ProcessorUid;
+  ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture = TO_BE_FILLED_BY_VENDOR;
+  SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
+  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1;
+  ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = 0xffff;
+  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
+  ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
+  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  if (ProcessorDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  SmbiosDataHob.Processor = ProcessorDataHobPtr;
+  SmbiosDataHob.L1InstCache = L1InstCacheDataHobPtr;
+  SmbiosDataHob.L1DataCache = NULL;
+  SmbiosDataHob.L2Cache = NULL;
+  SmbiosDataHob.L3Cache = NULL;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
+  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  if (SmbiosDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+  *SmbiosHobPtr = SmbiosDataHobPtr;
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
new file mode 100644
index 00000000..003ad5ae
--- /dev/null
+++ b/Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
@@ -0,0 +1,51 @@
+## @file
+#  Library instance to create core information HOB
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconSiFiveE51CoreInfoLib
+  FILE_GUID                      = 80A59B85-1245-4309-AC58-2CFA4199B46C
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconSiFiveE51CoreInfoLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV
+#
+
+[Sources]
+ CoreInfoHob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Silicon/SiFive/SiFive.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+  FirmwareContextProcessorSpecificLib
+
+[Guids]
+
+[Ppis]
+
+[FixedPcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSpecificDataGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid
+
diff --git a/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
new file mode 100644
index 00000000..295e020a
--- /dev/null
+++ b/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
@@ -0,0 +1,294 @@
+/**@file
+  Build up platform processor information.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <SmbiosProcessorSpecificData.h>
+
+#include <RiscV.h>
+#include <ProcessorSpecificDataHob.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi.h>
+#include <sbi/SbiFirmwareContext.h>
+#include <Library/FirmwareContextProcessorSpecificLib.h>
+
+/**
+  Function to build core specific information HOB.
+
+  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
+                                 could be the same as CoreGuid if one processor has
+                                 only one core.
+  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
+  @param  HartId                 Hart ID of this core.
+  @param  IsBootHart             TRUE means this is the boot HART.
+  @param  GuidHobdata            Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54CoreProcessorSpecificDataHob (
+  IN EFI_GUID  *ParentProcessorGuid,
+  IN UINTN     ParentProcessorUid,
+  IN UINTN     HartId,
+  IN BOOLEAN   IsBootHart,
+  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobdata
+  )
+{
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *CoreGuidHob;
+  EFI_GUID *ProcessorSpecDataHobGuid;
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB ProcessorSpecDataHob;
+  struct sbi_scratch *ThisHartSbiScratch;
+  struct sbi_platform *ThisHartSbiPlatform;
+  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext;
+  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__));
+
+  if (GuidHobdata == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ThisHartSbiScratch = sbi_hart_id_to_scratch (sbi_scratch_thishart_ptr(), (UINT32)HartId);
+  DEBUG ((DEBUG_INFO, "    SBI Scratch is at 0x%x.\n", ThisHartSbiScratch));
+  ThisHartSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(ThisHartSbiScratch);
+  DEBUG ((DEBUG_INFO, "    SBI platform is at 0x%x.\n", ThisHartSbiPlatform));
+  FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisHartSbiPlatform->firmware_context;
+  DEBUG ((DEBUG_INFO, "    Firmware Context is at 0x%x.\n", FirmwareContext));
+  FirmwareContextHartSpecific = FirmwareContext->HartSpecific[HartId];
+  DEBUG ((DEBUG_INFO, "    Firmware Context Hart specific is at 0x%x.\n", FirmwareContextHartSpecific));
+
+  //
+  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+  //
+  CommonFirmwareContextHartSpecificInfo (
+      FirmwareContextHartSpecific,
+      ParentProcessorGuid,
+      ParentProcessorUid,
+      (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid),
+      HartId,
+      IsBootHart,
+      &ProcessorSpecDataHob
+      );
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L     = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_H     = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_H = TO_BE_FILLED;
+  ProcessorSpecDataHob.ProcessorSpecificData.HartXlen                 = RegisterLen64;
+  ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen          = RegisterLen64;
+  ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen       = RegisterUnsupported;
+  ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen             = RegisterLen64;
+
+  DEBUG ((DEBUG_INFO, "        *HartId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.HartId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *Is Boot Hart? = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.BootHartId));
+  DEBUG ((DEBUG_INFO, "        *PrivilegeModeSupported = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.PrivilegeModeSupported));
+  DEBUG ((DEBUG_INFO, "        *MModeExcepDelegation = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MModeInterruptDelegation = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *HartXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.HartXlen ));
+  DEBUG ((DEBUG_INFO, "        *MachineModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen));
+  DEBUG ((DEBUG_INFO, "        *SupervisorModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen));
+  DEBUG ((DEBUG_INFO, "        *UserModeXlen = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen));
+  DEBUG ((DEBUG_INFO, "        *InstSetSupported = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.InstSetSupported));
+  DEBUG ((DEBUG_INFO, "        *MachineVendorId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineVendorId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MachineArchId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineArchId.Value64_L));
+  DEBUG ((DEBUG_INFO, "        *MachineImplId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineImplId.Value64_L));
+
+  //
+  // Build GUID HOB for U54 core.
+  //
+  ProcessorSpecDataHobGuid = PcdGetPtr (PcdProcessorSpecificDataGuidHobGuid);
+  CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID *)&ProcessorSpecDataHob, sizeof (RISC_V_PROCESSOR_SPECIFIC_DATA_HOB));
+  if (CoreGuidHob == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core.\n"));
+    ASSERT (FALSE);
+  }
+  *GuidHobdata = CoreGuidHob;
+  return EFI_SUCCESS;
+}
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54ProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  )
+{
+  EFI_GUID *GuidPtr;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L1InstCacheDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L1DataCacheDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L1InstCacheDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L1DataCacheDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
+
+  if (SmbiosHobPtr == NULL) {
+      return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Build up SMBIOS type 7 L1 instruction cache record.
+  //
+  ZeroMem((VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid));
+  L1InstCacheDataHob.ProcessorUid = ProcessorUid;
+  L1InstCacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L1InstCacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L1InstCacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L1InstCacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L1InstCacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeInstruction;
+  L1InstCacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L1InstCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L1InstCacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 instruction cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 7 L1 data cache record.
+  //
+  ZeroMem((VOID *)&L1DataCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  CopyGuid (&L1DataCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid));
+  L1DataCacheDataHob.ProcessorUid = ProcessorUid;
+  L1DataCacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L1DataCacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L1DataCacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L1DataCacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L1DataCacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L1DataCacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L1DataCacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L1DataCacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L1DataCacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeData;
+  L1DataCacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L1DataCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L1DataCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L1DataCacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 data cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 7 L2 cache record.
+  //
+  ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  CopyGuid (&L2CacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid));
+  L2CacheDataHob.ProcessorUid = ProcessorUid;
+  L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified;
+  L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L2CacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 4 record.
+  //
+  ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid));
+  ProcessorDataHob.ProcessorUid = ProcessorUid;
+  ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture = TO_BE_FILLED_BY_VENDOR;
+  SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
+  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1;
+  ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
+  ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount = 1;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
+  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  if (ProcessorDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  SmbiosDataHob.Processor = ProcessorDataHobPtr;
+  SmbiosDataHob.L1InstCache = L1InstCacheDataHobPtr;
+  SmbiosDataHob.L1DataCache = L1DataCacheDataHobPtr;
+  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
+  SmbiosDataHob.L3Cache = NULL;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
+  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  if (SmbiosDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+  *SmbiosHobPtr = SmbiosDataHobPtr;
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
new file mode 100644
index 00000000..8efee93b
--- /dev/null
+++ b/Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
@@ -0,0 +1,51 @@
+## @file
+#  Library instance to create core information HOB
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconSiFiveU54CoreInfoLib
+  FILE_GUID                      = 483DE090-267E-4278-A0A1-15D9836780EA
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconSiFiveU54CoreInfoLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV
+#
+
+[Sources]
+ CoreInfoHob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+  Silicon/SiFive/SiFive.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+  FirmwareContextProcessorSpecificLib
+
+[Guids]
+
+[Ppis]
+
+[FixedPcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSpecificDataGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid
+
diff --git a/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
new file mode 100644
index 00000000..e14b5977
--- /dev/null
+++ b/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
@@ -0,0 +1,185 @@
+/**@file
+  Build up platform processor information.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/SiFiveU54MCCoreplex.h>
+#include <Library/SiFiveE51.h>
+#include <Library/SiFiveU54.h>
+
+/**
+  Build up processor-specific HOB for U54MC Coreplex
+
+  @param  UniqueId      Unique ID of this U54MC Coreplex processor
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54MCCoreplexProcessorSpecificDataHob (
+  IN UINTN UniqueId
+  )
+{
+  EFI_STATUS Status;
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ThisGuidHobData;
+  EFI_GUID *ParentProcessorGuid;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__));
+
+  ParentProcessorGuid = PcdGetPtr (PcdSiFiveU54MCCoreplexGuid);
+  Status = CreateE51CoreProcessorSpecificDataHob (ParentProcessorGuid, UniqueId, SIFIVE_U54MC_COREPLEX_E51_HART_ID, FALSE, &ThisGuidHobData);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Faile to build E51 core information HOB for U54 Coreplex.\n", __FUNCTION__));
+    return Status;
+  }
+  Status = CreateU54CoreProcessorSpecificDataHob (ParentProcessorGuid, UniqueId, SIFIVE_U54_COREPLEX_U54MC_0_HART_ID, TRUE, &ThisGuidHobData);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Faile to build U54 core information HOB for U54 Coreplex.\n", __FUNCTION__));
+    return Status;
+  }
+  Status = CreateU54CoreProcessorSpecificDataHob (ParentProcessorGuid, UniqueId, SIFIVE_U54_COREPLEX_U54MC_1_HART_ID, FALSE, &ThisGuidHobData);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Faile to build U54 core information HOB for U54 Coreplex.\n", __FUNCTION__));
+    return Status;
+  }
+  Status = CreateU54CoreProcessorSpecificDataHob (ParentProcessorGuid, UniqueId, SIFIVE_U54_COREPLEX_U54MC_2_HART_ID, FALSE, &ThisGuidHobData);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Faile to build U54 core information HOB for U54 Coreplex.\n", __FUNCTION__));
+    return Status;
+  }
+  Status = CreateU54CoreProcessorSpecificDataHob (ParentProcessorGuid, UniqueId, SIFIVE_U54_COREPLEX_U54MC_3_HART_ID, FALSE, &ThisGuidHobData);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Faile to build U54 core information HOB for U54 Coreplex.\n", __FUNCTION__));
+    return Status;
+  }
+  return Status;
+}
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU54MCProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  )
+{
+  EFI_GUID *GuidPtr;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
+
+  if (SmbiosHobPtr == NULL) {
+      return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Build up SMBIOS type 7 L2 cache record.
+  //
+  ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU54MCCoreplexGuid));
+  L2CacheDataHob.ProcessorUid = ProcessorUid;
+  L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified;
+  L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L2CacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 MC Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 4 record.
+  //
+  ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU54MCCoreplexGuid));
+  ProcessorDataHob.ProcessorUid = ProcessorUid;
+  ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture = TO_BE_FILLED_BY_VENDOR;
+  SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
+  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1;
+  ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
+  ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount = 5;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = 5;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount = 5;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
+  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  if (ProcessorDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 MC Coreplex RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  SmbiosDataHob.Processor = ProcessorDataHobPtr;
+  SmbiosDataHob.L1InstCache = NULL;
+  SmbiosDataHob.L1DataCache = NULL;
+  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
+  SmbiosDataHob.L3Cache = NULL;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
+  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  if (SmbiosDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54MC Coreplex RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+  *SmbiosHobPtr = SmbiosDataHobPtr;
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
new file mode 100644
index 00000000..a5714a20
--- /dev/null
+++ b/Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
@@ -0,0 +1,50 @@
+## @file
+#  Library instance to create core information HOB
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconSiFiveU54MCCoreplexInfoLib
+  FILE_GUID                      = 483DE090-267E-4278-A0A1-15D9836780EA
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconSiFiveU54MCCoreplexInfoLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV
+#
+
+[Sources]
+ CoreInfoHob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Silicon/SiFive/SiFive.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+  SiliconSiFiveE51CoreInfoLib
+  SiliconSiFiveU54CoreInfoLib
+
+[Guids]
+
+[Ppis]
+
+[FixedPcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54MCCoreplexGuid
+
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package Gilbert Chen
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02  9:07   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in " Gilbert Chen
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Initial version of RISC-V platform package which provides the common
 libraries, drivers, PCD and etc. for RISC-V platform development.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 Platform/RiscV/Readme.md                 | 89 ++++++++++++++++++++++++++++++++
 Platform/RiscV/RiscVPlatformPkg.dec      | 72 ++++++++++++++++++++++++++
 Platform/RiscV/RiscVPlatformPkg.uni      | 15 ++++++
 Platform/RiscV/RiscVPlatformPkgExtra.uni | 12 +++++
 4 files changed, 188 insertions(+)
 create mode 100644 Platform/RiscV/Readme.md
 create mode 100644 Platform/RiscV/RiscVPlatformPkg.dec
 create mode 100644 Platform/RiscV/RiscVPlatformPkg.uni
 create mode 100644 Platform/RiscV/RiscVPlatformPkgExtra.uni

diff --git a/Platform/RiscV/Readme.md b/Platform/RiscV/Readme.md
new file mode 100644
index 00000000..277782e3
--- /dev/null
+++ b/Platform/RiscV/Readme.md
@@ -0,0 +1,89 @@
+# Introduction
+
+## EDK2 RISC-V Platform Package
+RISC-V platform package provides the generic and common modules for RISC-V platforms. RISC-V platform package could include RiscPlatformPkg.dec to use the common drivers, libraries, definitions, PCDs and etc. for the platform development.
+
+## EDK2 RISC-V Platforms
+RISC-V platform is created and maintained by RISC-V platform vendors. The directory of RISC-V platform should be created under Platform/RiscV. Vendor should create the folder under Platform/RiscV and name it using vendor name, under the vendor folder is the platform folder named by platform model name, code name or etc. (e.g. Platform/RiscV/SiFive/U500Pkg)
+
+## Build EDK2 RISC-V Platforms
+RISC-V platform package should provide EDK2 metafiles under RISC-V platform package folder (Platform/RiscV/{Vendor}/{Platform}). Build RISC-V platform package against edk2 and follow the build guidence mentioned in Readme.md under below link.<br>
+https://github.com/tianocore/edk2-platforms<br>
+
+### Download the sources ###
+```
+git clone https://github.com/tianocore/edk2-staging.git
+# Checkout RISC-V-V2 branch
+git clone https://github.com/tianocore/edk2-platforms.git
+# Checkout devel-riscv-v2 branch
+git clone https://github.com/tianocore/edk2-non-osi.git
+```
+
+### Requirements
+Build EDK2 RISC-V platform requires GCC RISC-V toolchain. Refer to https://github.com/riscv/riscv-gnu-toolchain for the details.
+The commit ID 64879b24 is verified to build RISC-V EDK2 platform and boot to EFI SHELL successfully.
+
+### EDK2 project
+Currently, the EDK2 RISC-V platform can only build with edk2 project in **edk2-staging/RISC-V-V2** branch. The build architecture whcih is supported and verified so far is "RISCV64". The verified RISC-V toolchain is https://github.com/riscv/riscv-gnu-toolchain @64879b24, toolchain tag is "GCCRISCV" declared in tools_def.txt<br>
+
+### Linux Build Instructions
+You can build the RISC-V platform using below script, <br>
+`build -a RISCV64 -p Platform/{Vendor}/{Platform}/{Platform}.dsc -t GCCRISCV`
+
+Or modify target.txt to set up your build parameters.
+
+## RISC-V Platform PCD settings
+### EDK2 Firmware Volume Settings
+EDK2 Firmware volume related PCDs which declared in platform FDF file.
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdRiscVSecFvBase| The base address of SEC Firmware Volume|
+|PcdRiscVSecFvSize| The size of SEC Firmware Volume|
+|PcdRiscVPeiFvBase| The base address of SEC Firmware Volume|
+|PcdRiscVPeiFvSize| The size of SEC Firmware Volume|
+|PcdRiscVDxeFvBase| The base address of SEC Firmware Volume|
+|PcdRiscVDxeFvSize| The size of SEC Firmware Volume|
+
+### EDK2 EFI Variable Region Settings
+The PCD settings regard to EFI Variable
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdVariableFdBaseAddress| The EFI variable firmware device base address|
+|PcdVariableFdSize| The EFI variable firmware device size|
+|PcdVariableFdBlockSize| The block size of EFI variable firmware device|
+|PcdPlatformFlashNvStorageVariableBase| EFI variable base address within firmware device|
+|PcdPlatformFlashNvStorageFtwWorkingBase| The base address of EFI variable fault tolerance worksapce (FTW) within firmware device|
+|PcdPlatformFlashNvStorageFtwSpareBase| The base address of EFI variable spare FTW within firmware device|
+
+### RISC-V Physical Memory Protection (PMP) Region Settings
+Below PCDs could be set in platform FDF file.
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdFwStartAddress| The starting address of firmware region to protected by PMP|
+|PcdFwEndAddress| The ending address of firmware region to protected by PMP|
+
+### RISC-V Processor HART Settings
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdHartCount| Number of RISC-V HARTs, the value is processor-implementation specific|
+|PcdBootHartId| The ID of RISC-V HART to execute main fimrware code and boot system to OS|
+
+### RISC-V OpenSBI Settings
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdScratchRamBase| The base address of OpenSBI scratch buffer for all RISC-V HARTs|
+|PcdScratchRamSize| The total size of OpenSBI scratch buffer for all RISC-V HARTs|
+|PcdOpenSbiStackSize| The size of initial stack of each RISC-V HART for booting system use OpenSBI|
+|PcdTemporaryRamBase| The base address of temporary memory for PEI phase|
+|PcdTemporaryRamSize| The temporary memory size for PEI phase|
+
+## Supported Operating Systems
+Only support to boot to EFI Shell so far
+
+## Known Issues and Limitations
+Only RISC-V RV64 is verified
diff --git a/Platform/RiscV/RiscVPlatformPkg.dec b/Platform/RiscV/RiscVPlatformPkg.dec
new file mode 100644
index 00000000..3ce16bfc
--- /dev/null
+++ b/Platform/RiscV/RiscVPlatformPkg.dec
@@ -0,0 +1,72 @@
+## @file  RiscVPlatformPkg.dec
+# This Package provides UEFI RISC-V platform modules and libraries.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = RiscPlatformPkg
+  PACKAGE_UNI_FILE               = RiscPlatformPkg.uni
+  PACKAGE_GUID                   = 6A67AF99-4592-40F8-B6BE-62BCA10DA1EC
+  PACKAGE_VERSION                = 1.0
+
+[Includes]
+  Include
+
+[LibraryClasses]
+
+[LibraryClasses.RISCV32, LibraryClasses.RISCV64]
+
+[Guids]
+  gUefiRiscVPlatformPkgTokenSpaceGuid  = {0x6A67AF99, 0x4592, 0x40F8, { 0xB6, 0xBE, 0x62, 0xBC, 0xA1, 0x0D, 0xA1, 0xEC}}
+
+[PcdsFixedAtBuild]
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|0x0|UINT32|0x00001000
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize|0x0|UINT32|0x00001001
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|0x0|UINT32|0x00001002
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize|0x0|UINT32|0x00001003
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|0x0|UINT32|0x00001004
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize|0x0|UINT32|0x00001005
+
+#
+# Definition of EFI Variable region
+#
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress|0|UINT32|0x00001010
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize|0|UINT32|0x00001011
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize|0|UINT32|0x00001012
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase|0|UINT32|0x00001013
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase|0|UINT32|0x00001014
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|0|UINT32|0x00001015
+#
+# Firmware region which is protected by PMP.
+#
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwBlockSize|0|UINT32|0x00001020
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress|0|UINT32|0x00001021
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress|0|UINT32|0x00001022
+#
+# Definition of RISC-V Hart
+#
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount|0|UINT32|0x00001023
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId|0|UINT32|0x00001024
+#
+# Definitions for OpenSbi
+#
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase|0|UINT32|0x00001025
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize|0|UINT32|0x00001026
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize|0|UINT32|0x00001027
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase|0|UINT32|0x00001028
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize|0|UINT32|0x00001029
+
+[PcdsPatchableInModule]
+
+[PcdsFeatureFlag]
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable|FALSE|BOOLEAN|0x00001006
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  RiscVPlatformPkgExtra.uni
diff --git a/Platform/RiscV/RiscVPlatformPkg.uni b/Platform/RiscV/RiscVPlatformPkg.uni
new file mode 100644
index 00000000..deb91fa1
--- /dev/null
+++ b/Platform/RiscV/RiscVPlatformPkg.uni
@@ -0,0 +1,15 @@
+// /** @file
+// RISC-V Package Localized Strings and Content.
+//
+// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_PACKAGE_ABSTRACT            #language en-US "Provides UEFI compatible RISC-V platform modules and libraries"
+
+#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package provides UEFI compatible RISC-V platform modules and libraries."
+
+
diff --git a/Platform/RiscV/RiscVPlatformPkgExtra.uni b/Platform/RiscV/RiscVPlatformPkgExtra.uni
new file mode 100644
index 00000000..98d81aed
--- /dev/null
+++ b/Platform/RiscV/RiscVPlatformPkgExtra.uni
@@ -0,0 +1,12 @@
+// /** @file
+// RISC-V Package Localized Strings and Content.
+//
+// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_PACKAGE_NAME
+#language en-US
+"RiscV platform package"
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in RISC-V platform package
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (2 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 16:46   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced " Gilbert Chen
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

FirmwareContextProcessorSpecificLib.h
- The difinitions of Firmware Context EDK2 implementaion based on
 RISC-V OpenSBI.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../Library/FirmwareContextProcessorSpecificLib.h  | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h

diff --git a/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h b/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
new file mode 100644
index 00000000..772a0783
--- /dev/null
+++ b/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
@@ -0,0 +1,40 @@
+/** @file
+  Firmware Context Processor-specific common library
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _FIRMWARE_CONTEXT_PROCESSOR_SPECIFIC_LIB_H_
+#define _FIRMWARE_CONTEXT_PROCESSOR_SPECIFIC_LIB_H_
+
+#include <PiPei.h>
+
+/**
+  Build up common firmware context processor-specific information
+
+  @param  FirmwareContextHartSpecific  Pointer to EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
+  @param  ParentProcessorGuid          Pointer to GUID of Processor which contains this core
+  @param  ParentProcessorUid           Unique ID of pysical processor which owns this core.
+  @param  CoreGuid                     Pointer to GUID of core
+  @param  HartId                       Hart ID of this core.
+  @param  IsBootHart                   This is boot hart or not
+  @param  ProcessorSpecDataHob         Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+CommonFirmwareContextHartSpecificInfo (
+  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific,
+  EFI_GUID  *ParentProcessorGuid,
+  UINTN     ParentProcessorUid,
+  EFI_GUID  *CoreGuid,
+  UINTN     HartId,
+  BOOLEAN   IsBootHart,
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob
+  );
+
+#endif
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced in RISC-V platform package
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (3 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in " Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 17:04   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module Gilbert Chen
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

FirmwareContextProcessorSpecificLib
- Common library to consume EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
 and build up processor specific data HOB.

RealTimClockLibNull
- NULL instance of Real Time Clock library.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../FirmwareContextProcessorSpecificLib.c          |  82 +++++++++
 .../FirmwareContextProcessorSpecificLib.inf        |  33 ++++
 .../RealTimeClockLibNull/RealTimeClockLibNull.c    | 204 +++++++++++++++++++++
 .../RealTimeClockLibNull/RealTimeClockLibNull.inf  |  30 +++
 4 files changed, 349 insertions(+)
 create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
 create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
 create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
 create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf

diff --git a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
new file mode 100644
index 00000000..4d4c51dc
--- /dev/null
+++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
@@ -0,0 +1,82 @@
+/**@file
+  Common library to build upfirmware context processor-specific information
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <RiscV.h>
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi.h>
+#include <sbi/SbiFirmwareContext.h>
+
+/**
+  Build up common firmware context processor-specific information
+
+  @param  FirmwareContextHartSpecific  Pointer to EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
+  @param  ParentProcessorGuid          Pointer to GUID of Processor which contains this core
+  @param  ParentProcessorUid           Unique ID of pysical processor which owns this core.
+  @param  CoreGuid                     Pointer to GUID of core
+  @param  HartId                       Hart ID of this core.
+  @param  IsBootHart                   This is boot hart or not
+  @param  ProcessorSpecDataHob         Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+CommonFirmwareContextHartSpecificInfo (
+  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific,
+  EFI_GUID  *ParentProcessorGuid,
+  UINTN     ParentProcessorUid,
+  EFI_GUID  *CoreGuid,
+  UINTN     HartId,
+  BOOLEAN   IsBootHart,
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob
+  )
+{
+  //
+  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
+  //
+  CopyGuid (&ProcessorSpecDataHob->ParentPrcessorGuid, ParentProcessorGuid);
+  ProcessorSpecDataHob->ParentProcessorUid = ParentProcessorUid;
+  CopyGuid (&ProcessorSpecDataHob->CoreGuid, CoreGuid);
+  ProcessorSpecDataHob->Context = NULL;
+  ProcessorSpecDataHob->ProcessorSpecificData.Revision         = SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA_REVISION;
+  ProcessorSpecDataHob->ProcessorSpecificData.Length           = sizeof (SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA);
+  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_L = (UINT64)HartId;
+  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_H = 0;
+  ProcessorSpecDataHob->ProcessorSpecificData.BootHartId       = (UINT8)IsBootHart;
+  ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported = FirmwareContextHartSpecific->IsaExtensionSupported;
+  ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported   = SMBIOS_RISC_V_PSD_MACHINE_MODE_SUPPORTED;
+  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported & RISC_V_ISA_SUPERVISOR_MODE_IMPLEMENTED) != 0) {
+    ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported |= SMBIOS_RISC_V_PSD_SUPERVISOR_MODE_SUPPORTED;
+  }
+  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported & RISC_V_ISA_USER_MODE_IMPLEMENTED) != 0) {
+    ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported |= SMBIOS_RISC_V_PSD_USER_MODE_SUPPORTED;
+  }
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineVendorId.Value64_L = FirmwareContextHartSpecific->MachineVendorId.Value64_L;
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineVendorId.Value64_H = FirmwareContextHartSpecific->MachineVendorId.Value64_H;
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineArchId.Value64_L = FirmwareContextHartSpecific->MachineArchId.Value64_L;
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineArchId.Value64_H = FirmwareContextHartSpecific->MachineArchId.Value64_H;
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineImplId.Value64_L = FirmwareContextHartSpecific->MachineImplId.Value64_L;
+  ProcessorSpecDataHob->ProcessorSpecificData.MachineImplId.Value64_H = FirmwareContextHartSpecific->MachineImplId.Value64_H;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
new file mode 100644
index 00000000..ff841c3e
--- /dev/null
+++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
@@ -0,0 +1,33 @@
+#/** @file
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FirmwareContextProcessorSpecificLib
+  FILE_GUID                      = 8BEC9FD7-C554-403A-94F1-0EBBFD81A242
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FirmwareContextProcessorSpecificLib
+
+[Sources.common]
+  FirmwareContextProcessorSpecificLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Silicon/SiFive/SiFive.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+
+[Pcd]
+
diff --git a/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c b/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
new file mode 100644
index 00000000..904e7e7b
--- /dev/null
+++ b/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
@@ -0,0 +1,204 @@
+/** @file
+  EFI RealTimeClock NULL library
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+// Use EfiAtRuntime to check stage
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/RealTimeClock.h>
+
+
+/**
+  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;
+
+  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;
+
+
+  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((DEBUG_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;
+}
diff --git a/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf b/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
new file mode 100644
index 00000000..21b2e435
--- /dev/null
+++ b/Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RealTimeClockLibNull
+  FILE_GUID                      = BFC3E25A-8AD0-4201-8A75-F00DE7964370
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RealTimeClockLib
+
+[Sources.common]
+  RealTimeClockLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiLib
+  DebugLib
+# Use EFiAtRuntime to check stage
+  UefiRuntimeLib
+
+[Pcd]
+
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (4 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced " Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 19:43   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package Gilbert Chen
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Common RISC-V SEC module for RISC-V platforms.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438 ++++++++++++++++++++
 Platform/RiscV/Universal/Sec/SecMain.c          | 524 ++++++++++++++++++++++++
 Platform/RiscV/Universal/Sec/SecMain.h          |  57 +++
 Platform/RiscV/Universal/Sec/SecMain.inf        |  75 ++++
 4 files changed, 1094 insertions(+)
 create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
 create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf

diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
new file mode 100644
index 00000000..18b54b84
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *   Anup Patel <anup.patel@wdc.com>
+ *
+ */
+
+#include <Base.h>
+#include <RiscV.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_trap.h>
+
+#include <SecMain.h>
+#include <sbi/SbiFirmwareContext.h>
+
+.text
+.align 3
+.global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  /*
+   * Jump to warm-boot if this is not the selected core booting,
+   */
+  csrr a6, CSR_MHARTID
+  li a5, FixedPcdGet32 (PcdBootHartId)
+  bne a6, a5, _wait_for_boot_hart
+
+  // light LED on
+  li a5, 0x54002000
+  li a4, 0xff
+  sw a4, 0x08(a5)
+  li a4, 0x11
+  sw a4, 0x0c(a5)
+
+  li ra, 0
+  call _reset_regs
+
+  /* Preload HART details
+   * s7 -> HART Count
+   * s8 -> HART Stack Size
+   */
+  li s7, FixedPcdGet32 (PcdHartCount)
+  li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
+
+  /* Setup scratch space for all the HARTs*/
+  li  tp, FixedPcdGet32 (PcdScratchRamBase)
+  mul a5, s7, s8
+  add tp, tp, a5
+  /* Keep a copy of tp */
+  add t3, tp, zero
+  /* Counter */
+  li t2, 1
+  /* hartid 0 is mandated by ISA */
+  li t1, 0
+_scratch_init:
+  add tp, t3, zero
+  mul a5, s8, t1
+  sub tp, tp, a5
+  li a5, SBI_SCRATCH_SIZE
+  sub tp, tp, a5
+
+  /* Initialize scratch space */
+  li  a4, FixedPcdGet32 (PcdFwStartAddress)
+  li  a5, FixedPcdGet32 (PcdFwEndAddress)
+  sub a5, a5, a4
+  sd a4, SBI_SCRATCH_FW_START_OFFSET(tp)
+  sd a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)
+  /* Note: fw_next_arg1() uses a0, a1, and ra */
+  call fw_next_arg1
+  sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
+  /* Note: fw_next_addr() uses a0, a1, and ra */
+  call fw_next_addr
+  sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)
+  li a4, PRV_S
+  sd a4, SBI_SCRATCH_NEXT_MODE_OFFSET(tp)
+  la a4, _start_warm
+  sd a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
+  la a4, platform
+  sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
+  la a4, _hartid_to_scratch
+  sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
+  sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)
+#ifdef FW_OPTIONS
+  li a4, FW_OPTIONS
+  sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp)
+#else
+  sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp)
+#endif
+  add t1, t1, t2
+  blt t1, s7, _scratch_init
+
+  /* Fill-out temporary memory with 55aa*/
+  li a4, FixedPcdGet32 (PcdTemporaryRamBase)
+  li a5, FixedPcdGet32 (PcdTemporaryRamSize)
+  add a5, a4, a5
+1:
+  li a3, 0x5AA55AA55AA55AA5
+  sd a3, (a4)
+  add a4, a4, __SIZEOF_POINTER__
+  blt a4, a5, 1b
+
+  /* Update boot hart flag */
+  la a4, _boot_hart_done
+  li a5, 1
+  sd a5, (a4)
+
+  /* Wait for boot hart */
+_wait_for_boot_hart:
+  la a4, _boot_hart_done
+  ld a5, (a4)
+  /* Reduce the bus traffic so that boot hart may proceed faster */
+  nop
+  nop
+  nop
+  beqz a5, _wait_for_boot_hart
+
+_start_warm:
+  li ra, 0
+  call _reset_regs
+
+  /* Disable and clear all interrupts */
+  csrw CSR_MIE, zero
+  csrw CSR_MIP, zero
+
+  li s7, FixedPcdGet32 (PcdHartCount)
+  li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
+
+  /* HART ID should be within expected limit */
+  csrr s6, CSR_MHARTID
+  bge s6, s7, _start_hang
+
+  /* find the scratch space for this hart */
+  li tp, FixedPcdGet32 (PcdScratchRamBase)
+  mul a5, s7, s8
+  add tp, tp, a5
+  mul a5, s8, s6
+  sub tp, tp, a5
+  li a5, SBI_SCRATCH_SIZE
+  sub tp, tp, a5
+
+  /* update the mscratch */
+  csrw CSR_MSCRATCH, tp
+
+  /*make room for Hart specific Firmware Context*/
+  li a5, FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
+  sub tp, tp, a5
+
+  /* Setup stack */
+  add sp, tp, zero
+
+  /* Setup stack for the Hart executing EFI to top of temporary ram*/
+  csrr a6, CSR_MHARTID
+  li a5, FixedPcdGet32 (PcdBootHartId)
+  bne a6, a5, 1f
+
+  li a4, FixedPcdGet32(PcdTemporaryRamBase)
+  li a5, FixedPcdGet32(PcdTemporaryRamSize)
+  add sp, a4, a5
+  1:
+
+  /* Setup trap handler */
+  la a4, _trap_handler
+  csrw CSR_MTVEC, a4
+  /* Make sure that mtvec is updated */
+  1:
+  csrr a5, CSR_MTVEC
+  bne a4, a5, 1b
+
+  /* Call library constructors before jup to SEC core */
+  call ProcessLibraryConstructorList
+
+  /* jump to SEC Core C */
+  csrr a0, CSR_MHARTID
+  csrr a1, CSR_MSCRATCH
+  call SecCoreStartUpWithStack
+
+  /* We do not expect to reach here hence just hang */
+  j _start_hang
+
+  .align 3
+  .section .data, "aw"
+_boot_hart_done:
+  RISCV_PTR 0
+
+  .align 3
+  .section .entry, "ax", %progbits
+  .globl _hartid_to_scratch
+_hartid_to_scratch:
+  add sp, sp, -(3 * __SIZEOF_POINTER__)
+  sd s0, (sp)
+  sd s1, (__SIZEOF_POINTER__)(sp)
+  sd s2, (__SIZEOF_POINTER__ * 2)(sp)
+  /*
+   * a0 -> HART ID (passed by caller)
+   * s0 -> HART Stack Size
+   * s1 -> HART Stack End
+   * s2 -> Temporary
+   */
+  la s2, platform
+#if __riscv_xlen == 64
+  lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
+  lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
+#else
+  lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
+  lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
+#endif
+  mul s2, s2, s0
+  li s1, FixedPcdGet32 (PcdScratchRamBase)
+  add s1, s1, s2
+  mul s2, s0, a0
+  sub s1, s1, s2
+  li s2, SBI_SCRATCH_SIZE
+  sub a0, s1, s2
+  ld s0, (sp)
+  ld s1, (__SIZEOF_POINTER__)(sp)
+  ld s2, (__SIZEOF_POINTER__ * 2)(sp)
+  add sp, sp, (3 * __SIZEOF_POINTER__)
+  ret
+
+  .align 3
+  .section .entry, "ax", %progbits
+  .globl _start_hang
+_start_hang:
+  wfi
+  j _start_hang
+
+  .align 3
+  .section .entry, "ax", %progbits
+  .globl _trap_handler
+_trap_handler:
+  /* Swap TP and MSCRATCH */
+  csrrw tp, CSR_MSCRATCH, tp
+
+  /* Save T0 in scratch space */
+  sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+
+  /* Check which mode we came from */
+  csrr t0, CSR_MSTATUS
+  srl t0, t0, MSTATUS_MPP_SHIFT
+  and t0, t0, PRV_M
+  xori t0, t0, PRV_M
+  beq t0, zero, _trap_handler_m_mode
+
+  /* We came from S-mode or U-mode */
+_trap_handler_s_mode:
+  /* Set T0 to original SP */
+  add t0, sp, zero
+
+  /* Setup exception stack */
+  add sp, tp, -(SBI_TRAP_REGS_SIZE)
+
+  /* Jump to code common for all modes */
+  j _trap_handler_all_mode
+
+  /* We came from M-mode */
+_trap_handler_m_mode:
+  /* Set T0 to original SP */
+  add t0, sp, zero
+
+  /* Re-use current SP as exception stack */
+  add sp, sp, -(SBI_TRAP_REGS_SIZE)
+
+_trap_handler_all_mode:
+  /* Save original SP (from T0) on stack */
+  sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
+
+  /* Restore T0 from scratch space */
+  ld t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+
+  /* Save T0 on stack */
+  sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+  /* Swap TP and MSCRATCH */
+  csrrw tp, CSR_MSCRATCH, tp
+
+  /* Save MEPC and MSTATUS CSRs */
+  csrr t0, CSR_MEPC
+  sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
+  csrr t0, CSR_MSTATUS
+  sd t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
+
+  /* Save all general regisers except SP and T0 */
+  sd zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
+  sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+  sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+  sd tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+  sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+  sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+  sd s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+  sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+  sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+  sd a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+  sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+  sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+  sd a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+  sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+  sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+  sd a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+  sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+  sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+  sd s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+  sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+  sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+  sd s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+  sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+  sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+  sd s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+  sd s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+  sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+  sd t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+  sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+  sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+  /* Call C routine */
+  add a0, sp, zero
+  csrr a1, CSR_MSCRATCH
+  call sbi_trap_handler
+
+  /* Restore all general regisers except SP and T0 */
+  ld ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+  ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+  ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+  ld t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+  ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+  ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+  ld s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+  ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+  ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+  ld a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+  ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+  ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+  ld a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+  ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+  ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+  ld s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+  ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+  ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+  ld s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+  ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+  ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+  ld s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+  ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+  ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+  ld s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+  ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+  ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+  ld t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+  ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+  /* Restore MEPC and MSTATUS CSRs */
+  ld t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
+  csrw CSR_MEPC, t0
+  ld t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
+  csrw CSR_MSTATUS, t0
+
+  /* Restore T0 */
+  ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+  /* Restore SP */
+  ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
+
+  mret
+
+  .align 3
+  .section .entry, "ax", %progbits
+  .globl _reset_regs
+_reset_regs:
+
+  /* flush the instruction cache */
+  fence.i
+  /* Reset all registers except ra, a0,a1 */
+  li sp, 0
+  li gp, 0
+  li tp, 0
+  li t0, 0
+  li t1, 0
+  li t2, 0
+  li s0, 0
+  li s1, 0
+  li a2, 0
+  li a3, 0
+  li a4, 0
+  li a5, 0
+  li a6, 0
+  li a7, 0
+  li s2, 0
+  li s3, 0
+  li s4, 0
+  li s5, 0
+  li s6, 0
+  li s7, 0
+  li s8, 0
+  li s9, 0
+  li s10, 0
+  li s11, 0
+  li t3, 0
+  li t4, 0
+  li t5, 0
+  li t6, 0
+  csrw CSR_MSCRATCH, 0
+  ret
+
+    .align 3
+    .section .entry, "ax", %progbits
+    .global fw_prev_arg1
+fw_prev_arg1:
+    /* We return previous arg1 in 'a0' */
+    add a0, zero, zero
+    ret
+
+    .align 3
+    .section .entry, "ax", %progbits
+    .global fw_next_arg1
+fw_next_arg1:
+    /* We return next arg1 in 'a0' */
+    li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
+    ret
+
+    .align 3
+    .section .entry, "ax", %progbits
+    .global fw_next_addr
+fw_next_addr:
+    /* We return next address in 'a0' */
+    la a0, _jump_addr
+    ld a0, (a0)
+    ret
+
+  .align 3
+ .section .entry, "ax", %progbits
+_jump_addr:
+ RISCV_PTR SecCoreStartUpWithStack
diff --git a/Platform/RiscV/Universal/Sec/SecMain.c b/Platform/RiscV/Universal/Sec/SecMain.c
new file mode 100644
index 00000000..40b351ca
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.c
@@ -0,0 +1,524 @@
+/** @file
+  RISC-V SEC phase module.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecMain.h"
+#include <Library/SerialPortLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi.h>
+#include <sbi/sbi_init.h>
+#include <sbi/SbiFirmwareContext.h>
+
+int HartsIn = 0;
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+  TemporaryRamMigration
+};
+
+EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
+  TemporaryRamDone
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gEfiTemporaryRamSupportPpiGuid,
+    &mTemporaryRamSupportPpi
+  },
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiTemporaryRamDonePpiGuid,
+    &mTemporaryRamDonePpi
+  },
+};
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  The Instance parameter indicates which instance of the section
+  type to return. (0 is first instance, 1 is second...)
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[in]   Instance        The section instance number
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  IN  UINTN                            Instance,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfSections;
+  EFI_COMMON_SECTION_HEADER   *Section;
+  EFI_PHYSICAL_ADDRESS        EndOfSection;
+
+  //
+  // Loop through the FFS file sections within the PEI Core FFS file
+  //
+  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+  EndOfSections = EndOfSection + SizeOfSections;
+  for (;;) {
+    if (EndOfSection == EndOfSections) {
+      break;
+    }
+    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+    if (CurrentAddress >= EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+    Size = SECTION_SIZE (Section);
+    if (Size < sizeof (*Section)) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    EndOfSection = CurrentAddress + Size;
+    if (EndOfSection > EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the requested section type
+    //
+    if (Section->Type == SectionType) {
+      if (Instance == 0) {
+        *FoundSection = Section;
+        return EFI_SUCCESS;
+      } else {
+        Instance--;
+      }
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  return FindFfsSectionInstance (
+           Sections,
+           SizeOfSections,
+           SectionType,
+           0,
+           FoundSection
+           );
+}
+
+/**
+  Locates a FFS file with the specified file type and a section
+  within that file with the specified section type.
+
+  @param[in]   Fv            The firmware volume to search
+  @param[in]   FileType      The file type to locate
+  @param[in]   SectionType   The section type to locate
+  @param[out]  FoundSection  The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  IN  EFI_FV_FILETYPE                  FileType,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+
+  if (Fv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+  //
+  // Loop through the FFS files in the Boot Firmware Volume
+  //
+  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    Size = *(UINT32*) File->Size & 0xffffff;
+    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the request file type
+    //
+    if (File->Type != FileType) {
+      continue;
+    }
+
+    Status = FindFfsSectionInSections (
+               (VOID*) (File + 1),
+               (UINTN) EndOfFile - (UINTN) (File + 1),
+               SectionType,
+               FoundSection
+               );
+    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+      return Status;
+    }
+  }
+}
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in]  Fv                 The firmware volume to search
+  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_COMMON_SECTION_HEADER   *Section;
+
+  Status = FindFfsFileAndSection (
+             Fv,
+             EFI_FV_FILETYPE_PEI_CORE,
+             EFI_SECTION_PE32,
+             &Section
+             );
+  if (EFI_ERROR (Status)) {
+    Status = FindFfsFileAndSection (
+               Fv,
+               EFI_FV_FILETYPE_PEI_CORE,
+               EFI_SECTION_TE,
+               &Section
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
+      return Status;
+    }
+  }
+  DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
+  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+  return EFI_SUCCESS;
+}
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in,out]  Fv                 The firmware volume to search
+  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
+     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  *PeiCoreImageBase = 0;
+
+  DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));
+  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/*
+  Find and return Pei Core entry point.
+
+  It also find SEC and PEI Core file debug inforamtion. It will report them if
+  remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
+  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
+
+  DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));
+
+  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+  //
+  // Find PEI Core entry point
+  //
+  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+  if (EFI_ERROR(Status)) {
+    *PeiCoreEntryPoint = 0;
+  }
+  DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n", *PeiCoreEntryPoint));
+
+  return;
+}
+/*
+  Print out the content of firmware context.
+
+**/
+VOID
+DebutPrintFirmwareContext (
+    EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
+    )
+{
+  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at 0x%x\n", FirmwareContext));
+  DEBUG ((DEBUG_INFO, "           PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable));
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  )
+{
+  VOID      *OldHeap;
+  VOID      *NewHeap;
+  VOID      *OldStack;
+  VOID      *NewStack;
+  struct sbi_platform *ThisSbiPlatform;
+
+  DEBUG ((DEBUG_INFO,
+    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+    TemporaryMemoryBase,
+    PermanentMemoryBase,
+    (UINT64)CopySize
+    ));
+
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+  CopyMem (NewHeap, OldHeap, CopySize >> 1);   // Migrate Heap
+  CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
+
+  //
+  // Reset firmware context pointer
+  //
+  ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+  ThisSbiPlatform->firmware_context += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+  //
+  // Relocate PEI Service **
+  //
+  ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is relocated to 0x%x\n", ThisSbiPlatform->firmware_context));
+  DebutPrintFirmwareContext ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context);
+
+  register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack);
+  asm volatile ("add sp, sp, a0"::"r"(a0):);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI TemporaryRamDone (VOID)
+{
+  DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
+  return EFI_SUCCESS;
+}
+
+#if 1
+#define GPIO_CTRL_ADDR  0x54002000
+#define GPIO_OUTPUT_VAL 0x0C
+static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
+#define REG32(p, i)   ((p)[(i)>>2])
+#endif
+
+static VOID EFIAPI PeiCore(VOID)
+{
+  EFI_SEC_PEI_HAND_OFF        SecCoreData;
+  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
+  EFI_FIRMWARE_VOLUME_HEADER *BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32(PcdRiscVPeiFvBase);
+  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
+  struct sbi_platform *ThisSbiPlatform;
+  UINT32 HartId;
+
+  REG32(gpio, GPIO_OUTPUT_VAL) = 0x88;
+  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+
+  SecCoreData.DataSize               = sizeof(EFI_SEC_PEI_HAND_OFF);
+  SecCoreData.BootFirmwareVolumeBase = BootFv;
+  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+  SecCoreData.TemporaryRamBase       = (VOID*)(UINT64) FixedPcdGet32(PcdTemporaryRamBase);
+  SecCoreData.TemporaryRamSize       = (UINTN)  FixedPcdGet32(PcdTemporaryRamSize);
+  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
+  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >> 1;
+  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >> 1);
+  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
+
+  //
+  // Print out scratch address of each hart
+  //
+  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI scratch address for each hart:\n"));
+  for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
+    DEBUG ((DEBUG_INFO, "          Hart %d: 0x%x\n", HartId, sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));
+  }
+
+  //
+  // Set up OpepSBI firmware context poitner on boot hart OpenSbi scratch. Firmware context residents in stack and will be
+  // switched to memory when temporary ram migration.
+  //
+  ZeroMem ((VOID *)&FirmwareContext, sizeof (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
+  ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+  if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
+      DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version 0x%x is newer than OpenSBI version 0x%x.\n"
+                           "There maybe be some backward compatable issues.\n",
+             ThisSbiPlatform->opensbi_version,
+             OPENSBI_VERSION
+             ));
+      ASSERT(FALSE);
+  }
+  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address: 0x%x\nFirmware Context is located at 0x%x\n",
+             ThisSbiPlatform,
+             &FirmwareContext
+             ));
+  ThisSbiPlatform->firmware_context = (unsigned long)&FirmwareContext;
+  //
+  // Set firmware context Hart-specific pointer
+  //
+  for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
+    FirmwareContext.HartSpecific [HartId] = \
+      (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
+    DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n",
+             HartId,
+             FirmwareContext.HartSpecific [HartId]
+             ));
+  }
+
+  //
+  // Transfer the control to the PEI core
+  //
+  (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+}
+/**
+  This function initilizes hart specific information and SBI.
+  For the boot hart, it boots system through PEI core and initial SBI in the DXE IPL.
+  For others, it goes to initial SBI and halt.
+
+  the lay out of memory region for each hart is as below delineates,
+
+                                               _                                        ____
+  |----Scratch ends                             |                                           |
+  |                                             | sizeof (sbi_scratch)                      |
+  |                                            _|                                           |
+  |----Scratch buffer start s                  <----- *scratch                              |
+  |----Firmware Context Hart-specific ends     _                                            |
+  |                                             |                                           |
+  |                                             | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE       |
+  |                                             |                                           |  PcdOpenSbiStackSize
+  |                                            _|                                           |
+  |----Firmware Context Hart-specific starts   <----- **HartFirmwareContext                 |
+  |----Hart stack top                          _                                            |
+  |                                             |                                           |
+  |                                             |                                           |
+  |                                             |  Stack                                    |
+  |                                             |                                           |
+  |                                            _|                                       ____|
+  |----Hart stack bottom
+
+**/
+VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct sbi_scratch *scratch)
+{
+  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext;
+
+  //
+  // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
+  //
+  HartFirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
+  HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
+  HartFirmwareContext->MachineVendorId.Value64_L = RiscVReadMVendorId ();
+  HartFirmwareContext->MachineVendorId.Value64_H = 0;
+  HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId ();
+  HartFirmwareContext->MachineArchId.Value64_H = 0;
+  HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
+  HartFirmwareContext->MachineImplId.Value64_H = 0;
+
+#if 0
+  while (HartsIn != hartid);
+  DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context Hart-specific for HART ID:%d\n", hartid));
+  DEBUG ((DEBUG_INFO, "           Scratch at address: 0x%x\n", scratch));
+  DEBUG ((DEBUG_INFO, "           Firmware Context Hart-specific at address: 0x%x\n", HartFirmwareContext));
+  DEBUG ((DEBUG_INFO, "           stack pointer at address: 0x%x\n", stack_point));
+  DEBUG ((DEBUG_INFO, "                    MISA: 0x%x\n", HartFirmwareContext->IsaExtensionSupported));
+  DEBUG ((DEBUG_INFO, "                    MVENDORID: 0x%x\n", HartFirmwareContext->MachineVendorId.Value64_L));
+  DEBUG ((DEBUG_INFO, "                    MARCHID: 0x%x\n", HartFirmwareContext->MachineArchId.Value64_L));
+  DEBUG ((DEBUG_INFO, "                    MIMPID: 0x%x\n\n", HartFirmwareContext->MachineImplId.Value64_L));
+  HartsIn ++;
+  for (;;);
+#endif
+
+  if (hartid == FixedPcdGet32(PcdBootHartId)) {
+    PeiCore();
+  }
+  sbi_init(scratch);
+}
diff --git a/Platform/RiscV/Universal/Sec/SecMain.h b/Platform/RiscV/Universal/Sec/SecMain.h
new file mode 100644
index 00000000..e7565f5e
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.h
@@ -0,0 +1,57 @@
+/** @file
+  RISC-V SEC phase module definitions..
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SECMAIN_H_
+#define _SECMAIN_H_
+
+#include <PiPei.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/HobLib.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <Library/RiscVCpuLib.h>
+
+VOID
+SecMachineModeTrapHandler (
+  IN VOID
+  );
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+  IN VOID                     *Context
+  );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamDone (
+  VOID
+  );
+
+#endif // _SECMAIN_H_
diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf b/Platform/RiscV/Universal/Sec/SecMain.inf
new file mode 100644
index 00000000..c408fc8d
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.inf
@@ -0,0 +1,75 @@
+## @file
+#  RISC-V SEC module.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecMain
+  FILE_GUID                      = df1ccef6-f301-4a63-9661-fc6030dcc880
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64 EBC
+#
+
+[Sources]
+  SecMain.c
+
+[Sources.RISCV64]
+  Riscv64/SecEntry.s
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  PcdLib
+  DebugAgentLib
+  IoLib
+  PeCoffLib
+  PeCoffGetEntryPointLib
+  PeCoffExtraActionLib
+  ExtractGuidedSectionLib
+  RiscVCpuLib
+  PrintLib
+  SerialPortLib
+  RiscVOpensbiLib
+  OpenSbiPlatformLib # This is required library which
+                     # provides platform level opensbi
+                     # functions.
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+  gEfiTemporaryRamDonePpiGuid    # PPI ALWAYS_PRODUCED
+
+[Guids]
+  gUefiRiscVMachineContextGuid
+
+[FixedPcd]
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
+
+[Pcd]
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (5 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 20:16   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform Gilbert Chen
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

The initial version of SiFive U500 platform package.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 Platform/RiscV/SiFive/U500Pkg/Readme.md        |  62 +++
 Platform/RiscV/SiFive/U500Pkg/U500.dec         |  34 ++
 Platform/RiscV/SiFive/U500Pkg/U500.dsc         | 549 +++++++++++++++++++++++++
 Platform/RiscV/SiFive/U500Pkg/U500.fdf         | 335 +++++++++++++++
 Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc     |  52 +++
 Platform/RiscV/SiFive/U500Pkg/U500.uni         |  13 +
 Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni |  12 +
 Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc |  78 ++++
 8 files changed, 1135 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Readme.md
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dec
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dsc
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc

diff --git a/Platform/RiscV/SiFive/U500Pkg/Readme.md b/Platform/RiscV/SiFive/U500Pkg/Readme.md
new file mode 100644
index 00000000..71fa62a1
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Readme.md
@@ -0,0 +1,62 @@
+# Introduction
+
+## U500 Platform Package
+This is a sample RISC-V EDK2 platform package used agaist SiFive Freedom U500 VC707 FPGA Dev Kit, please refer to "SiFive Freedom U500 VC707 FPGA Getting Started Guide" on https://www.sifive.com/documentation. This package is built with below common packages, <br>
+- **RiscVPlatformPkg**, edk2-platform/Platform/RiscV
+- **RiscVPkg**, edk2 master branch (Currently is in edk2-staging/RISC-V branch)
+<br>
+This package provides librareis and modules which are SiFive U500 platform implementation-specific and incorporate with common RISC-V packages mentioned above.
+
+## Download the sources
+```
+git clone https://github.com/tianocore/edk2-staging.git
+# Checkout RISC-V-V2 branch
+git clone https://github.com/tianocore/edk2-platforms.git
+# Checkout devel-riscv-v2 branch
+git clone https://github.com/tianocore/edk2-non-osi.git
+```
+
+## Platform Owners
+Chang, Abner <abner.chang@hpe.com><br>
+Chen, Gilbert <gilbert.chen@hpe.com>
+
+## Platform Status
+Currently the binary built from U500Pkg can boot SiFive Freedom U500 VC707 FPGA to EFI shell with console in/out enabled.
+
+## Linux Build Instructions
+You can build the RISC-V platform using below script, <br>
+`build -a RISCV64 -p Platform/RiscV/SiFive/U500Pkg/U500.dsc -t GCCRISCV`
+
+## Supported Operating Systems
+Only support to boot to EFI Shell so far
+
+## Known Issues and Limitations
+Only RISC-V RV64 is verified on this platform.
+
+## Related Materials
+- [RISC-V OpenSbi](https://github.com/riscv/opensbi)<br>
+- [SiFive U500 VC707 FPGA Getting Started Guide](https://sifive.cdn.prismic.io/sifive%2Fc248fabc-5e44-4412-b1c3-6bb6aac73a2c_sifive-u500-vc707-gettingstarted-v0.2.pdf)<br>
+- [SiFive RISC-V Core Document](https://www.sifive.com/documentation)
+
+## U500 Platform Libraries and Drivers
+### OpneSbiPlatformLib
+In order to reduce the dependencies with RISC-V OpenSBI project (https://github.com/riscv/opensbi) and less burdens to EDK2 build process, the implementation of RISC-V EDK2 platform is leverage platform source code from OpenSBI code tree. The "platform.c" under OpenSbiPlatformLib  is cloned from RISC-V OpenSBI code tree (in EDK2 RiscVPkg) and built based on EDK2 build environment.
+
+### PeiCoreInfoHobLib
+This is the library to create RISC-V core characteristics for building up RISC-V related SMBIOS records to support the unified boot loader and OS image. This library leverage the silicon libraries provided in Silicon/SiFive.
+
+### RiscVPlatformTimerLib
+This is U500 platform timer library which has the platform-specific timer implementation.
+
+### PlatformPei
+This is the platform-implementation specific library which is executed in early PEI phase for platform initialization.
+
+### TimerDxe
+This is U500 platform timer DXE driver whcih has the platform-specific timer implementation.
+
+## U500 Platform PCD settings
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdNumberofU5Cores| Number of U5 core enabled on U500 platform|
+|PcdE5MCSupported| Indicates whether or not the Monitor Core (E5) is supported on U500 platform|
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.dec b/Platform/RiscV/SiFive/U500Pkg/U500.dec
new file mode 100644
index 00000000..4ecca89b
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500.dec
@@ -0,0 +1,34 @@
+## @file  U500.dec
+# This Package provides SiFive U500 modules and libraries.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = U500
+  PACKAGE_UNI_FILE               = U500.uni
+  PACKAGE_GUID                   = D11E9DB9-5940-4642-979D-2114342140D2
+  PACKAGE_VERSION                = 1.0
+
+[Includes]
+  Include
+
+[LibraryClasses]
+
+
+[Guids]
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid  = {0xDFD87009, 0x27A1, 0x41DD, { 0x84, 0xB1, 0x35, 0xB4, 0xB9, 0x0D, 0x17, 0x63 }}
+
+[PcdsFixedAtBuild]
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores|0x8|UINT32|0x00001000
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported|TRUE|BOOLEAN|0x00001001
+
+[PcdsPatchableInModule]
+
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  U500PkgExtra.uni
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.dsc b/Platform/RiscV/SiFive/U500Pkg/U500.dsc
new file mode 100644
index 00000000..edcd951a
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500.dsc
@@ -0,0 +1,549 @@
+## @file
+#  RISC-V EFI on SiFive VC707 (U500) RISC-V platform
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = U500
+  PLATFORM_GUID                  = 0955581C-2A6A-48F7-8690-9D275AE884F8
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/U500Pkg
+  SUPPORTED_ARCHITECTURES        = RISCV64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/RiscV/SiFive/U500Pkg/U500.fdf
+
+  #
+  # Enable below options may cause build error or may not work on
+  # the initial version of RISC-V package
+  # Defines for default states.  These can be changed on the command line.
+  # -D FLAG=VALUE
+  #
+  DEFINE SECURE_BOOT_ENABLE      = FALSE
+  DEFINE DEBUG_ON_SERIAL_PORT    = TRUE
+
+  #
+  # Network definition
+  #
+  DEFINE NETWORK_SNP_ENABLE       = FALSE
+  DEFINE NETWORK_IP6_ENABLE       = FALSE
+  DEFINE NETWORK_TLS_ENABLE       = FALSE
+  DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
+  DEFINE NETWORK_ISCSI_ENABLE     = FALSE
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  GCC:*_*_RISCV64_GENFW_FLAGS    = --keepexceptiontable
+!endif
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SerialPortLib|Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+
+# RISC-V Platform Library
+  RealTimeClockLib|Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
+
+# RISC-V Core Library
+  RiscVOpensbiLib|RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
+!endif
+
+# ACPI not supported yet.
+  #S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+
+[LibraryClasses.common]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+  RiscVCpuLib|RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
+  RiscVPlatformTimerLib|Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
+  CpuExceptionHandlerLib|RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
+
+[LibraryClasses.common.SEC]
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+
+#
+# OpenSBi Platform Library
+#
+  OpenSbiPlatformLib|Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  FirmwareContextProcessorSpecificLib|Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
+  RiscVPlatformDxeIplLib|RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
+
+#
+# RISC-V core libraries
+#
+  SiliconSiFiveE51CoreInfoLib|Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
+  SiliconSiFiveU54CoreInfoLib|Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
+  SiliconSiFiveU5MCCoreplexInfoLib|Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  #CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  #PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
+  #CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.DXE_SMM_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+
+[LibraryClasses.common.SMM_CORE]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+[PcdsFixedAtBuild]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+!endif
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+  #gUefiPayloadPkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+!endif
+
+  #
+  # F2 for UI APP
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
+
+  # Set video resolution for text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+
+  #
+  # SEC Phase modules
+  #
+  Platform/RiscV/Universal/Sec/SecMain.inf
+
+  #
+  # PEI Phase modules
+  #
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+    NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  #
+  # DXE Phase modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg//Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
+   <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+  }
+!else
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+
+  #
+  # EBC not supported on RISC-V yet
+  #
+  #MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/Metronome/Metronome.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf {
+    <LibraryClasses>
+      ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
+  }
+
+  #
+  # RISC-V Platform module
+  #
+  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
+  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+  #
+  # RISC-V Core module
+  #
+  RiscVPkg/Universal/CpuDxe/CpuDxe.inf
+  RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
+
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+  }
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+
+# No graphic console supported yet.
+#  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+#    <LibraryClasses>
+#      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+#  }
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+  #
+  # ACPI Support
+  # Not support on RISC-V yet
+  #
+  #MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  #MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+
+  #
+  # Network Support
+  #
+  !include NetworkPkg/Network.dsc.inc
+
+  #
+  # Usb Support
+  #
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.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/UsbMassStorageDxe/UsbMassStorageDxe.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
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+      SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+  MdeModulePkg/Application/UiApp/UiApp.inf
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.fdf b/Platform/RiscV/SiFive/U500Pkg/U500.fdf
new file mode 100644
index 00000000..5ca84be3
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500.fdf
@@ -0,0 +1,335 @@
+# @file
+#  Flash definition file on SiFive VC707 (U500) RISC-V platform
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+
+!include U500.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.U500]
+BaseAddress   = $(FW_BASE_ADDRESS)
+Size          = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(FW_BLOCKS)
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize
+FV = SECFV
+
+$(PEIFV_OFFSET)|$(PEIFV_SIZE)
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
+FV = PEIFV
+
+$(FVMAIN_OFFSET)|$(FVMAIN_SIZE)
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize
+FV = FVMAIN_COMPACT
+
+!include VarStore.fdf.inc
+
+################################################################################
+
+[FV.SECFV]
+BlockSize          = 0x1000
+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
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF Platform/RiscV/Universal/Sec/SecMain.inf
+
+################################################################################
+[FV.PEIFV]
+BlockSize          = 0x10000
+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/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+}
+
+#
+#  PEI Phase modules
+#
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+# RISC-V Platform PEI Driver
+INF  Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
+
+################################################################################
+
+[FV.DXEFV]
+BlockSize          = 0x10000
+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 DXE {
+  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+}
+
+#
+# DXE Phase modules
+#
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf
+
+# RISC-V Platform Drivers
+INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+# RISC-V Core Drivers
+INF  RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
+INF  RiscVPkg/Universal/CpuDxe/CpuDxe.inf
+INF  RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
+
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+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/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+!ifndef $(SOURCE_DEBUG_ENABLE)
+INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+!endif
+
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+#
+# ACPI is not supported yet on RISC-V package.
+#
+#INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+#INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+#INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
+
+#INF  RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+
+#
+# Network modules
+#
+!if $(E1000_ENABLE)
+  FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
+    SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI
+  }
+!endif
+
+!include NetworkPkg/Network.fdf.inc
+
+#
+# Usb Support
+#
+INF  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.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/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+INF  MdeModulePkg/Application/UiApp/UiApp.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
+FvNameGuid         = 27A72E80-3118-4c0c-8673-AA5B4EFA9613
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+     #
+     # These firmware volumes will have files placed in them uncompressed,
+     # and then both firmware volumes will be compressed in a single
+     # compression operation in order to achieve better overall compression.
+     #
+     SECTION FV_IMAGE = DXEFV
+   }
+ }
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32     PE32   Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32     PE32   Align=4K         $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align = 4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32  Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32   Align=4K   |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32     PE32   Align=4K   $(INF_OUTPUT)/$(MODULE_NAME).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  Align=4K  |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc b/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
new file mode 100644
index 00000000..ac24b5b0
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
@@ -0,0 +1,52 @@
+## @file
+#  Definitions of Flash definition file on SiFive VC707 (U500) RISC-V platform
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+DEFINE BLOCK_SIZE        = 0x1000
+
+DEFINE FW_BASE_ADDRESS   = 0x80000000
+DEFINE FW_SIZE           = 0x00800000
+DEFINE FW_BLOCKS         = 0x800
+
+#
+# 0x000000-0x7DFFFF code
+# 0x7E0000-0x800000 variables
+#
+DEFINE CODE_BASE_ADDRESS = 0x80000000
+DEFINE CODE_SIZE         = 0x007E0000
+DEFINE CODE_BLOCKS       = 0x7E0
+DEFINE VARS_BLOCKS       = 0x20
+
+DEFINE SECFV_OFFSET      = 0x00000000
+DEFINE SECFV_SIZE        = 0x00020000
+DEFINE PEIFV_OFFSET      = 0x00020000
+DEFINE PEIFV_SIZE        = 0x00060000
+DEFINE SCRATCH_OFFSET    = 0x00080000
+DEFINE SCRATCH_SIZE      = 0x00010000
+DEFINE FVMAIN_OFFSET     = 0x00100000 # Must be power of 2 for PMP setting
+DEFINE FVMAIN_SIZE       = 0x0018C000
+DEFINE VARS_OFFSET       = 0x007E0000
+DEFINE VARS_SIZE         = 0x00020000
+
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress = $(FW_BASE_ADDRESS) + $(VARS_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize        = $(VARS_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize   = $(BLOCK_SIZE)
+
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress = $(CODE_BASE_ADDRESS)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress = $(CODE_BASE_ADDRESS) + $(SECFV_SIZE) + $(PEIFV_SIZE) + $(SCRATCH_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize = 8192
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase = $(CODE_BASE_ADDRESS) + $(SCRATCH_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize = $(SCRATCH_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase = $(CODE_BASE_ADDRESS) + $(FW_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize = 0x10000
+
+
+SET gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz = 1000000
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount = 4               # Total cores on U500 platform
+SET gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores = 4     # Total U5 cores enabled on U500 platform
+SET gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported = False   # Enable optional E51 MC core?
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId = 0              # Boot hart ID
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.uni b/Platform/RiscV/SiFive/U500Pkg/U500.uni
new file mode 100644
index 00000000..7ac1096f
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500.uni
@@ -0,0 +1,13 @@
+// /** @file
+// SiFive U500 Package Localized Strings and Content.
+//
+// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_PACKAGE_ABSTRACT            #language en-US "Provides SiFIve RISC-V U500 platform modules and libraries"
+
+#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package SiFIve RISC-V U500 platform modules and libraries."
diff --git a/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni b/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
new file mode 100644
index 00000000..6b68fb43
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
@@ -0,0 +1,12 @@
+// /** @file
+// SiFive U500 Package Localized Strings and Content.
+//
+// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_PACKAGE_NAME
+#language en-US
+"SiFive U500 package"
diff --git a/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc b/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
new file mode 100644
index 00000000..c287bb43
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
@@ -0,0 +1,78 @@
+## @file
+#  FDF include file with Layout Regions that define an empty variable store.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (C) 2014, Red Hat, Inc.
+#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+$(VARS_OFFSET)|0x00007000
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#
+# NV_VARIABLE_STORE
+#
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
+  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  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, 0x39, 0xF1, 0x00, 0x00, 0x00, 0x02,
+  # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  # Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  # Signature: gEfiAuthenticatedVariableGuid =
+  #   { 0xaaf32c78, 0x947b, 0x439a,
+  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+  # Signature: gEfiVariableGuid =
+  #   { 0xddcf3616, 0x3275, 0x4164,
+  #     { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+  # Size: 0x7000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x6fb8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0x6F, 0x00, 0x00,
+  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x007e7000|0x00001000
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#
+#NV_FTW_WROK
+#
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64
+  0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x007e8000|0x00018000
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#
+#NV_FTW_SPARE
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (6 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 21:00   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib Gilbert Chen
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

The initial header file commit for SiFive U5-MC Coreplex and U500 Core
 Local interrupt definitions.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h    | 51 ++++++++++++++++++++++
 Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h  | 19 ++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h

diff --git a/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h b/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
new file mode 100644
index 00000000..9968159c
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
@@ -0,0 +1,51 @@
+/** @file
+  SiFive U54 Coreplex library definitions.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SIFIVE_U5MC_COREPLEX_H_
+#define _SIFIVE_U5MC_COREPLEX_H_
+
+#include <PiPei.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+
+#define SIFIVE_U5MC_COREPLEX_MC_HART_ID     0
+
+/**
+  Build up U5MC coreplex processor core-specific information.
+
+  @param  UniqueId      U5MC unique ID.
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU5MCCoreplexProcessorSpecificDataHob (
+  IN UINTN UniqueId
+  );
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid        Unique ID of pysical processor which owns this core.
+  @param  SmbiosDataHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                              maintained in this structure is only valid before memory is discovered.
+                              Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU5MCProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosDataHobPtr
+  );
+#endif
diff --git a/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h b/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
new file mode 100644
index 00000000..a8c9ae15
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
@@ -0,0 +1,19 @@
+/** @file
+  RISC-V Timer Architectural definition for U500 platform.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _U500_H_
+#define _U500_H_
+
+#define CLINT_REG_MTIME     0x0200BFF8
+#define CLINT_REG_MTIMECMP0 0x02004000
+#define CLINT_REG_MTIMECMP1 0x02004008
+#define CLINT_REG_MTIMECMP2 0x02004010
+#define CLINT_REG_MTIMECMP3 0x02004018
+#define CLINT_REG_MTIMECMP4 0x02004020
+
+#endif
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (7 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-02 22:02   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library Gilbert Chen
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

SiFive RISC-V U500 Platform Boot Manager library.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../Library/PlatformBootManagerLib/MemoryTest.c    | 682 +++++++++++++++++++++
 .../PlatformBootManagerLib/PlatformBootManager.c   | 274 +++++++++
 .../PlatformBootManagerLib/PlatformBootManager.h   | 135 ++++
 .../PlatformBootManagerLib.inf                     |  63 ++
 .../Library/PlatformBootManagerLib/PlatformData.c  |  49 ++
 .../Library/PlatformBootManagerLib/Strings.uni     |  28 +
 6 files changed, 1231 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni

diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
new file mode 100644
index 00000000..8c6d89e9
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
@@ -0,0 +1,682 @@
+/** @file
+  Perform the RISC-V platform memory test
+
+Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+EFI_HII_HANDLE gStringPackHandle = NULL;
+EFI_GUID       mPlatformBootManagerStringPackGuid = {
+  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, 0x88 }
+  };
+// extern UINT8  BdsDxeStrings[];
+
+//
+// BDS Platform Functions
+//
+/**
+
+  Show progress bar with title above it. It only works in Graphics mode.
+
+  @param TitleForeground Foreground color for Title.
+  @param TitleBackground Background color for Title.
+  @param Title           Title above progress bar.
+  @param ProgressColor   Progress bar color.
+  @param Progress        Progress (0-100)
+  @param PreviousValue   The previous value of the progress.
+
+  @retval  EFI_STATUS       Success update the progress bar
+
+**/
+EFI_STATUS
+PlatformBootManagerShowProgress (
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+  IN CHAR16                        *Title,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+  IN UINTN                         Progress,
+  IN UINTN                         PreviousValue
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
+  EFI_UGA_DRAW_PROTOCOL          *UgaDraw;
+  UINT32                         SizeOfX;
+  UINT32                         SizeOfY;
+  UINT32                         ColorDepth;
+  UINT32                         RefreshRate;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
+  UINTN                          BlockHeight;
+  UINTN                          BlockWidth;
+  UINTN                          BlockNum;
+  UINTN                          PosX;
+  UINTN                          PosY;
+  UINTN                          Index;
+
+  if (Progress > 100) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  UgaDraw = NULL;
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &GraphicsOutput
+                  );
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    GraphicsOutput = NULL;
+
+    Status = gBS->HandleProtocol (
+                    gST->ConsoleOutHandle,
+                    &gEfiUgaDrawProtocolGuid,
+                    (VOID **) &UgaDraw
+                    );
+  }
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SizeOfX = 0;
+  SizeOfY = 0;
+  if (GraphicsOutput != NULL) {
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+  } else if (UgaDraw != NULL) {
+    Status = UgaDraw->GetMode (
+                        UgaDraw,
+                        &SizeOfX,
+                        &SizeOfY,
+                        &ColorDepth,
+                        &RefreshRate
+                        );
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  BlockWidth  = SizeOfX / 100;
+  BlockHeight = SizeOfY / 50;
+
+  BlockNum    = Progress;
+
+  PosX        = 0;
+  PosY        = SizeOfY * 48 / 50;
+
+  if (BlockNum == 0) {
+    //
+    // Clear progress area
+    //
+    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          &Color,
+                          EfiBltVideoFill,
+                          0,
+                          0,
+                          0,
+                          PosY - EFI_GLYPH_HEIGHT - 1,
+                          SizeOfX,
+                          SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
+                          SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = UgaDraw->Blt (
+                          UgaDraw,
+                          (EFI_UGA_PIXEL *) &Color,
+                          EfiUgaVideoFill,
+                          0,
+                          0,
+                          0,
+                          PosY - EFI_GLYPH_HEIGHT - 1,
+                          SizeOfX,
+                          SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
+                          SizeOfX * sizeof (EFI_UGA_PIXEL)
+                          );
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  //
+  // Show progress by drawing blocks
+  //
+  for (Index = PreviousValue; Index < BlockNum; Index++) {
+    PosX = Index * BlockWidth;
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          &ProgressColor,
+                          EfiBltVideoFill,
+                          0,
+                          0,
+                          PosX,
+                          PosY,
+                          BlockWidth - 1,
+                          BlockHeight,
+                          (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = UgaDraw->Blt (
+                          UgaDraw,
+                          (EFI_UGA_PIXEL *) &ProgressColor,
+                          EfiUgaVideoFill,
+                          0,
+                          0,
+                          PosX,
+                          PosY,
+                          BlockWidth - 1,
+                          BlockHeight,
+                          (BlockWidth) * sizeof (EFI_UGA_PIXEL)
+                          );
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  PrintXY (
+    (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
+    PosY - EFI_GLYPH_HEIGHT - 1,
+    &TitleForeground,
+    &TitleBackground,
+    Title
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Perform the memory test base on the memory test intensive level,
+  and update the memory resource.
+
+  @param  Level         The memory test intensive level.
+
+  @retval EFI_STATUS    Success test all the system memory and update
+                        the memory resource
+
+**/
+EFI_STATUS
+PlatformBootManagerMemoryTest (
+  IN EXTENDMEM_COVERAGE_LEVEL Level
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_STATUS                        KeyStatus;
+  EFI_STATUS                        InitStatus;
+  EFI_STATUS                        ReturnStatus;
+  BOOLEAN                           RequireSoftECCInit;
+  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;
+  UINT64                            TestedMemorySize;
+  UINT64                            TotalMemorySize;
+  UINTN                             TestPercent;
+  UINT64                            PreviousValue;
+  BOOLEAN                           ErrorOut;
+  BOOLEAN                           TestAbort;
+  EFI_INPUT_KEY                     Key;
+  CHAR16                            StrPercent[80];
+  CHAR16                            *StrTotalMemory;
+  CHAR16                            *Pos;
+  CHAR16                            *TmpStr;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Foreground;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Background;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Color;
+  UINT32                            TempData;
+  UINTN                             StrTotalMemorySize;
+
+  ReturnStatus = EFI_SUCCESS;
+  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
+
+  StrTotalMemorySize = 128;
+  Pos = AllocateZeroPool (StrTotalMemorySize);
+  ASSERT (Pos != NULL);
+
+  if (gStringPackHandle == NULL) {
+    gStringPackHandle = HiiAddPackages (
+                           &mPlatformBootManagerStringPackGuid,
+                           gImageHandle,
+                           PlatformBootManagerLibStrings,
+                           NULL
+                           );
+    ASSERT (gStringPackHandle != NULL);
+  }
+
+  StrTotalMemory    = Pos;
+
+  TestedMemorySize  = 0;
+  TotalMemorySize   = 0;
+  PreviousValue     = 0;
+  ErrorOut          = FALSE;
+  TestAbort         = FALSE;
+
+  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+
+  RequireSoftECCInit = FALSE;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGenericMemTestProtocolGuid,
+                  NULL,
+                  (VOID **) &GenMemoryTest
+                  );
+  if (EFI_ERROR (Status)) {
+    FreePool (Pos);
+    return EFI_SUCCESS;
+  }
+
+  InitStatus = GenMemoryTest->MemoryTestInit (
+                                GenMemoryTest,
+                                Level,
+                                &RequireSoftECCInit
+                                );
+  if (InitStatus == EFI_NO_MEDIA) {
+    //
+    // The PEI codes also have the relevant memory test code to check the memory,
+    // it can select to test some range of the memory or all of them. If PEI code
+    // checks all the memory, this BDS memory test will has no not-test memory to
+    // do the test, and then the status of EFI_NO_MEDIA will be returned by
+    // "MemoryTestInit". So it does not need to test memory again, just return.
+    //
+    FreePool (Pos);
+    return EFI_SUCCESS;
+  }
+
+  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+    TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST), NULL);
+
+    if (TmpStr != NULL) {
+      PrintXY (10, 10, NULL, NULL, TmpStr);
+      FreePool (TmpStr);
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "Enter memory test.\n"));
+  }
+  do {
+    Status = GenMemoryTest->PerformMemoryTest (
+                              GenMemoryTest,
+                              &TestedMemorySize,
+                              &TotalMemorySize,
+                              &ErrorOut,
+                              TestAbort
+                              );
+    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
+      TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SYSTEM_MEM_ERROR), NULL);
+      if (TmpStr != NULL) {
+        PrintXY (10, 10, NULL, NULL, TmpStr);
+        FreePool (TmpStr);
+      }
+
+      ASSERT (0);
+    }
+
+    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+      TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
+      TestPercent = (UINTN) DivU64x32 (
+                              DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
+                              TempData
+                              );
+      if (TestPercent != PreviousValue) {
+        UnicodeValueToString (StrPercent, 0, TestPercent, 0);
+        TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEMORY_TEST_PERCENT), NULL);
+        if (TmpStr != NULL) {
+          //
+          // TmpStr size is 64, StrPercent is reserved to 16.
+          //
+          StrnCatS (
+            StrPercent,
+            sizeof (StrPercent) / sizeof (CHAR16),
+            TmpStr,
+            sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) - 1
+            );
+          PrintXY (10, 10, NULL, NULL, StrPercent);
+          FreePool (TmpStr);
+        }
+
+        TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
+        if (TmpStr != NULL) {
+          PlatformBootManagerShowProgress (
+            Foreground,
+            Background,
+            TmpStr,
+            Color,
+            TestPercent,
+            (UINTN) PreviousValue
+            );
+          FreePool (TmpStr);
+        }
+      }
+
+      PreviousValue = TestPercent;
+    } else {
+      DEBUG ((DEBUG_INFO, "Perform memory test (ESC to skip).\n"));
+    }
+
+    if (!PcdGetBool (PcdConInConnectOnDemand)) {
+      KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+      if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
+        if (!RequireSoftECCInit) {
+          if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+            TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
+            if (TmpStr != NULL) {
+              PlatformBootManagerShowProgress (
+                Foreground,
+                Background,
+                TmpStr,
+                Color,
+                100,
+                (UINTN) PreviousValue
+                );
+              FreePool (TmpStr);
+            }
+
+            PrintXY (10, 10, NULL, NULL, L"100");
+          }
+          Status = GenMemoryTest->Finished (GenMemoryTest);
+          goto Done;
+        }
+
+        TestAbort = TRUE;
+      }
+    }
+  } while (Status != EFI_NOT_FOUND);
+
+  Status = GenMemoryTest->Finished (GenMemoryTest);
+
+Done:
+  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+    UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
+    if (StrTotalMemory[0] == L',') {
+      StrTotalMemory++;
+      StrTotalMemorySize -= sizeof (CHAR16);
+    }
+
+    TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEM_TEST_COMPLETED), NULL);
+    if (TmpStr != NULL) {
+      StrnCatS (
+        StrTotalMemory,
+        StrTotalMemorySize / sizeof (CHAR16),
+        TmpStr,
+        StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) - 1
+        );
+      FreePool (TmpStr);
+    }
+
+    PrintXY (10, 10, NULL, NULL, StrTotalMemory);
+    PlatformBootManagerShowProgress (
+      Foreground,
+      Background,
+      StrTotalMemory,
+      Color,
+      100,
+      (UINTN) PreviousValue
+      );
+
+  } else {
+    DEBUG ((DEBUG_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize));
+  }
+
+  FreePool (Pos);
+  return ReturnStatus;
+}
+
+/**
+  Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+  buffer is passed in it will be used if it is big enough.
+
+  @param  BmpImage      Pointer to BMP file
+  @param  BmpImageSize  Number of bytes in BmpImage
+  @param  GopBlt        Buffer containing GOP version of BmpImage.
+  @param  GopBltSize    Size of GopBlt in bytes.
+  @param  PixelHeight   Height of GopBlt/BmpImage in pixels
+  @param  PixelWidth    Width of GopBlt/BmpImage in pixels
+
+  @retval EFI_SUCCESS           GopBlt and GopBltSize are returned.
+  @retval EFI_UNSUPPORTED       BmpImage is not a valid *.BMP image
+  @retval EFI_BUFFER_TOO_SMALL  The passed in GopBlt buffer is not big enough.
+                                GopBltSize will contain the required size.
+  @retval EFI_OUT_OF_RESOURCES  No enough buffer to allocate.
+
+**/
+EFI_STATUS
+PlatformBootManagerConvertBmpToGopBlt (
+  IN     VOID      *BmpImage,
+  IN     UINTN     BmpImageSize,
+  IN OUT VOID      **GopBlt,
+  IN OUT UINTN     *GopBltSize,
+     OUT UINTN     *PixelHeight,
+     OUT UINTN     *PixelWidth
+  )
+{
+  UINT8                         *Image;
+  UINT8                         *ImageHeader;
+  BMP_IMAGE_HEADER              *BmpHeader;
+  BMP_COLOR_MAP                 *BmpColorMap;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+  UINT64                        BltBufferSize;
+  UINTN                         Index;
+  UINTN                         Height;
+  UINTN                         Width;
+  UINTN                         ImageIndex;
+  UINT32                        DataSizePerLine;
+  BOOLEAN                       IsAllocated;
+  UINT32                        ColorMapNum;
+
+  if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+    DEBUG ((DEBUG_INFO, "BMP_IMAGE_HEADER) > BmpImageSize.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+    DEBUG ((DEBUG_INFO, "(BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M').\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Doesn't support compress.
+  //
+  if (BmpHeader->CompressionType != 0) {
+    DEBUG ((DEBUG_INFO, "It's compressed! We dont support.\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Only support BITMAPINFOHEADER format.
+  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+  //
+  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
+    DEBUG ((DEBUG_INFO, "Only support BITMAPINFOHEADER.\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // The data size in each line must be 4 byte alignment.
+  //
+  DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+  if (BltBufferSize > (UINT32) ~0) {
+    DEBUG ((DEBUG_INFO, "The data size in each line must be 4 byte alignment.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((BmpHeader->Size != BmpImageSize) ||
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||
+      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * DataSizePerLine)) {
+    DEBUG ((DEBUG_INFO, "BmpHeader->Size problem.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Calculate Color Map offset in the image.
+  //
+  Image       = BmpImage;
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+    DEBUG ((DEBUG_INFO, "BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+    switch (BmpHeader->BitPerPixel) {
+      case 1:
+        ColorMapNum = 2;
+        break;
+      case 4:
+        ColorMapNum = 16;
+        break;
+      case 8:
+        ColorMapNum = 256;
+        break;
+      default:
+        ColorMapNum = 0;
+        break;
+      }
+    //
+    // BMP file may has padding data between the bmp header section and the bmp data section.
+    //
+    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {
+      DEBUG ((DEBUG_INFO, "(BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum)\n"));
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Calculate graphics image data address in the image
+  //
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+  ImageHeader   = Image;
+
+  //
+  // Calculate the BltBuffer needed size.
+  //
+  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+  //
+  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+  //
+  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    return EFI_UNSUPPORTED;
+  }
+  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+  IsAllocated   = FALSE;
+  if (*GopBlt == NULL) {
+    //
+    // GopBlt is not allocated by caller.
+    //
+    *GopBltSize = (UINTN) BltBufferSize;
+    *GopBlt     = AllocatePool (*GopBltSize);
+    IsAllocated = TRUE;
+    if (*GopBlt == NULL) {
+      DEBUG ((DEBUG_INFO, "EFI_OUT_OF_RESOURCES\n"));
+      return EFI_OUT_OF_RESOURCES;
+    }
+  } else {
+    //
+    // GopBlt has been allocated by caller.
+    //
+    if (*GopBltSize < (UINTN) BltBufferSize) {
+      *GopBltSize = (UINTN) BltBufferSize;
+      DEBUG ((DEBUG_INFO, "EEFI_BUFFER_TOO_SMALL\n"));
+      return EFI_BUFFER_TOO_SMALL;
+    }
+  }
+
+  *PixelWidth   = BmpHeader->PixelWidth;
+  *PixelHeight  = BmpHeader->PixelHeight;
+
+  //
+  // Convert image from BMP to Blt buffer format
+  //
+  BltBuffer = *GopBlt;
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+      switch (BmpHeader->BitPerPixel) {
+      case 1:
+        //
+        // Convert 1-bit (2 colors) BMP to 24-bit color
+        //
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+          Blt++;
+          Width++;
+        }
+
+        Blt--;
+        Width--;
+        break;
+
+      case 4:
+        //
+        // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+        //
+        Index       = (*Image) >> 4;
+        Blt->Red    = BmpColorMap[Index].Red;
+        Blt->Green  = BmpColorMap[Index].Green;
+        Blt->Blue   = BmpColorMap[Index].Blue;
+        if (Width < (BmpHeader->PixelWidth - 1)) {
+          Blt++;
+          Width++;
+          Index       = (*Image) & 0x0f;
+          Blt->Red    = BmpColorMap[Index].Red;
+          Blt->Green  = BmpColorMap[Index].Green;
+          Blt->Blue   = BmpColorMap[Index].Blue;
+        }
+        break;
+
+      case 8:
+        //
+        // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+        //
+        Blt->Red    = BmpColorMap[*Image].Red;
+        Blt->Green  = BmpColorMap[*Image].Green;
+        Blt->Blue   = BmpColorMap[*Image].Blue;
+        break;
+
+      case 24:
+        //
+        // It is 24-bit BMP.
+        //
+        Blt->Blue   = *Image++;
+        Blt->Green  = *Image++;
+        Blt->Red    = *Image;
+        break;
+
+      default:
+        //
+        // Other bit format BMP is not supported.
+        //
+        if (IsAllocated) {
+          FreePool (*GopBlt);
+          *GopBlt = NULL;
+        }
+        DEBUG ((DEBUG_INFO, "Other bit format BMP is not supported.\n"));
+        return EFI_UNSUPPORTED;
+        break;
+      };
+
+    }
+
+    ImageIndex = (UINTN) (Image - ImageHeader);
+    if ((ImageIndex % 4) != 0) {
+      //
+      // Bmp Image starts each row on a 32-bit boundary!
+      //
+      Image = Image + (4 - (ImageIndex % 4));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
new file mode 100644
index 00000000..9ef85089
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
@@ -0,0 +1,274 @@
+/** @file
+  This file include all platform action which can be customized
+  by IBV/OEM.
+
+Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+
+EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1}};
+
+/**
+  Perform the platform diagnostic, such like test memory. OEM/IBV also
+  can customize this function to support specific platform diagnostic.
+
+  @param MemoryTestLevel  The memory test intensive level
+  @param QuietBoot        Indicate if need to enable the quiet boot
+
+**/
+VOID
+PlatformBootManagerDiagnostics (
+  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
+  IN BOOLEAN                     QuietBoot
+  )
+{
+  EFI_STATUS                     Status;
+
+  //
+  // Here we can decide if we need to show
+  // the diagnostics screen
+  // Notes: this quiet boot code should be remove
+  // from the graphic lib
+  //
+  if (QuietBoot) {
+
+    //
+    // Perform system diagnostic
+    //
+    Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
+    return;
+  }
+
+  //
+  // Perform system diagnostic
+  //
+  Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
+}
+
+/**
+  Return the index of the load option in the load option array.
+
+  The function consider two load options are equal when the
+  OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+  @param Key    Pointer to the load option to be found.
+  @param Array  Pointer to the array of load options to be found.
+  @param Count  Number of entries in the Array.
+
+  @retval -1          Key wasn't found in the Array.
+  @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+  IN UINTN                              Count
+  )
+{
+  UINTN                             Index;
+
+  for (Index = 0; Index < Count; Index++) {
+    if ((Key->OptionType == Array[Index].OptionType) &&
+        (Key->Attributes == Array[Index].Attributes) &&
+        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+      return (INTN) Index;
+    }
+  }
+
+  return -1;
+}
+
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID                         *FileGuid,
+  CHAR16                           *Description,
+  UINT32                           Attributes
+  )
+{
+  EFI_STATUS                        Status;
+  UINTN                             OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
+  UINTN                             BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+
+  Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = AppendDevicePathNode (
+                 DevicePathFromHandle (LoadedImage->DeviceHandle),
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                 );
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  if (!EFI_ERROR (Status)) {
+    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+    if (OptionIndex == -1) {
+      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
+      ASSERT_EFI_ERROR (Status);
+    }
+    EfiBootManagerFreeLoadOption (&NewOption);
+    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+  }
+}
+
+/**
+  Do the platform specific action before the console is connected.
+
+  Such as:
+    Update console variable;
+    Register new Driver#### or Boot####;
+    Signal ReadyToLock event.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  UINTN                        Index;
+  EFI_STATUS                   Status;
+  EFI_INPUT_KEY                Enter;
+  EFI_INPUT_KEY                F2;
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+  //
+  // Update the console variables.
+  //
+  for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
+    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+      Status = EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+      Status = EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+      Status = EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
+    }
+  }
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  //
+  // Map F2 to Boot Manager Menu
+  //
+  F2.ScanCode    = SCAN_F2;
+  F2.UnicodeChar = CHAR_NULL;
+  EfiBootManagerGetBootManagerMenu (&BootOption);
+  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
+  //
+  // Register UEFI Shell
+  //
+  PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
+}
+
+/**
+  Do the platform specific action after the console is connected.
+
+  Such as:
+    Dynamically switch output mode;
+    Signal console ready platform customized event;
+    Run diagnostics like memory testing;
+    Connect certain devices;
+    Dispatch aditional option roms.
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Black;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  White;
+
+  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
+  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
+
+  EfiBootManagerConnectAll ();
+  EfiBootManagerRefreshAllBootOption ();
+
+  PlatformBootManagerDiagnostics (QUICK, TRUE);
+
+  PrintXY (10, 10, &White, &Black, L"F2    to enter Boot Manager Menu.                                            ");
+  PrintXY (10, 30, &White, &Black, L"Enter to boot directly.");
+}
+
+/**
+  This function is called each second during the boot manager waits the timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16          TimeoutRemain
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
+  UINT16                        Timeout;
+
+  Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
+  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
+
+  PlatformBootManagerShowProgress (
+    White,
+    Black,
+    L"Start boot option",
+    White,
+    (Timeout - TimeoutRemain) * 100 / Timeout,
+    0
+    );
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  return;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
new file mode 100644
index 00000000..20d66758
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
@@ -0,0 +1,135 @@
+/**@file
+   Head file for BDS Platform specific code
+
+Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_BOOT_MANAGER_H_
+#define _PLATFORM_BOOT_MANAGER_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/BootLogo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DxeServicesLib.h>
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
+
+#define gEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE,\
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\
+    END_DEVICE_PATH_LENGTH,\
+    0\
+  }
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN  BIT1
+#define STD_ERROR   BIT2
+
+//D3987D4B-971A-435F-8CAF-4967EB627241
+#define EFI_SERIAL_DXE_GUID \
+  { 0xD3987D4B, 0x971A, 0x435F, { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } }
+
+typedef struct {
+  VENDOR_DEVICE_PATH        Guid;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} SERIAL_CONSOLE_DEVICE_PATH;
+
+/**
+  Use SystemTable Conout to stop video based Simple Text Out consoles from going
+  to the video device. Put up LogoFile on every video device that is a console.
+
+  @param[in]  LogoFile   File name of logo to display on the center of the screen.
+
+  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo displayed.
+  @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+PlatformBootManagerEnableQuietBoot (
+  IN  EFI_GUID  *LogoFile
+  );
+
+/**
+  Use SystemTable Conout to turn on video based Simple Text Out consoles. The
+  Simple Text Out screens will now be synced up with all non video output devices
+
+  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
+
+**/
+EFI_STATUS
+PlatformBootManagerDisableQuietBoot (
+  VOID
+  );
+
+/**
+  Perform the memory test base on the memory test intensive level,
+  and update the memory resource.
+
+  @param  Level         The memory test intensive level.
+
+  @retval EFI_STATUS    Success test all the system memory and update
+                        the memory resource
+
+**/
+EFI_STATUS
+PlatformBootManagerMemoryTest (
+  IN EXTENDMEM_COVERAGE_LEVEL Level
+  );
+
+/**
+
+  Show progress bar with title above it. It only works in Graphics mode.
+
+
+  @param TitleForeground Foreground color for Title.
+  @param TitleBackground Background color for Title.
+  @param Title           Title above progress bar.
+  @param ProgressColor   Progress bar color.
+  @param Progress        Progress (0-100)
+  @param PreviousValue   The previous value of the progress.
+
+  @retval  EFI_STATUS       Success update the progress bar
+
+**/
+EFI_STATUS
+PlatformBootManagerShowProgress (
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+  IN CHAR16                        *Title,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+  IN UINTN                         Progress,
+  IN UINTN                         PreviousValue
+  );
+
+#endif // _PLATFORM_BOOT_MANAGER_H
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 00000000..92c31db4
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,63 @@
+## @file
+#  Include all platform action which can be customized by IBV/OEM.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBootManagerLib
+  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV
+#
+
+[Sources]
+  PlatformData.c
+  PlatformBootManager.c
+  PlatformBootManager.h
+  MemoryTest.c
+  Strings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  UefiBootManagerLib
+  PcdLib
+  DxeServicesLib
+  MemoryAllocationLib
+  DevicePathLib
+  HiiLib
+  PrintLib
+
+[Guids]
+
+[Protocols]
+  gEfiGenericMemTestProtocolGuid  ## CONSUMES
+  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
+  gEfiUgaDrawProtocolGuid         ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 00000000..3208051e
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -0,0 +1,49 @@
+/**@file
+  Defined the platform specific device path which will be filled to
+  ConIn/ConOut variables.
+
+Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+//
+// Platform specific serial device path
+//
+SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },
+    EFI_SERIAL_DXE_GUID  // Use the driver's GUID
+  },
+  {
+    { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} },
+    0,                  // Reserved
+    115200,             // BaudRate
+    8,                  // DataBits
+    1,                  // Parity
+    1                   // StopBits
+  },
+  {
+    { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
+};
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *) &gSerialConsoleDevicePath0,
+    CONSOLE_OUT | CONSOLE_IN
+  },
+  {
+    NULL,
+    0
+  }
+};
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
new file mode 100644
index 00000000..73bf5d51
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
@@ -0,0 +1,28 @@
+///** @file
+//
+//    String definitions for PlatformBootManagerLib.
+//
+//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//**/
+
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+#string STR_PERFORM_MEM_TEST           #language en-US  "Perform memory test (ESC to skip)"
+                                       #language fr-FR  "Exécute l'examen de mémoire (ESC pour sauter)"
+#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the system memory tested OK"
+                                       #language fr-FR  "% de la mémoire de système essayée D'ACCORD"
+#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC key to skip memory test"
+                                       #language fr-FR  "Appuie sur ESC sauter examen de mémoire"
+#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of system memory tested OK\r\n"
+                                       #language fr-FR  "octets dela mémoire de système essayée D'ACCORD\r\n"
+#string STR_SYSTEM_MEM_ERROR           #language en-US  "System encounters memory errors"
+                                       #language fr-FR  "le Système rencontre les erreurs de mémoire"
+#string STR_START_BOOT_OPTION          #language en-US  "Start boot option"
+                                       #language fr-FR  "l'option de botte de Début"
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (8 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-03 16:32   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable Gilbert Chen
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

OpneSbiPlatformLib
- In order to reduce the dependencies with RISC-V OpenSBI project
(https://github.com/riscv/opensbi) and less burdens to EDK2 build
 process, the implementation of RISC-V EDK2 platform is leverage
 platform source code from OpenSBI code tree. The "platform.c"
 under OpenSbiPlatformLib is cloned from RISC-V OpenSBI code tree
 (in EDK2 RiscVPkg) and built based on EDK2 build environment.

PeiCoreInfoHobLib
- This is the library to create RISC-V core characteristics for building
 up RISC-V related SMBIOS records to support the unified boot loader
 and OS image.

- RiscVPlatformTimerLib
This is U500 platform timer library which has the platform-specific
 timer implementation.

- SerialPortLib
U500 serial port platform library

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../OpenSbiPlatformLib/OpenSbiPlatformLib.inf      |  47 ++++
 .../U500Pkg/Library/OpenSbiPlatformLib/platform.c  | 214 ++++++++++++++++++
 .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 195 +++++++++++++++++
 .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  58 +++++
 .../RiscVPlatformTimerLib/RiscVPlatformTimerLib.S  |  48 ++++
 .../RiscVPlatformTimerLib.inf                      |  39 ++++
 .../U500Pkg/Library/SerialIoLib/SerialIoLib.inf    |  31 +++
 .../U500Pkg/Library/SerialIoLib/SerialPortLib.c    | 241 +++++++++++++++++++++
 .../Library/SerialIoLib/U500SerialPortLib.uni      |  16 ++
 9 files changed, 889 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni

diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
new file mode 100644
index 00000000..473386d2
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
@@ -0,0 +1,47 @@
+## @file
+#  RISC-V OpenSbi Platform Library
+#  This is the the required library which provides platform
+#  level opensbi functions follow RISC-V opensbi implementation.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OpenSbiPlatformLib
+  FILE_GUID                      = 9424ED54-EBDA-4FB5-8FF6-8291B07BB151
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OpenSbiPlatformLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64 EBC
+#
+
+[Sources]
+  platform.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  PcdLib
+  DebugAgentLib
+  RiscVCpuLib
+  PrintLib
+
+[FixedPcd]
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
new file mode 100644
index 00000000..4dca75f2
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
@@ -0,0 +1,214 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *   Atish Patra <atish.patra@wdc.com>
+ */
+
+#include <libfdt.h>
+#include <fdt.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/riscv_io.h>
+#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/serial/sifive-uart.h>
+#include <sbi_utils/sys/clint.h>
+
+
+#define U500_HART_COUNT         FixedPcdGet32(PcdHartCount)
+#define U500_HART_STACK_SIZE   FixedPcdGet32(PcdOpenSbiStackSize)
+#define U500_BOOT_HART_ID       FixedPcdGet32(PcdBootHartId)
+
+#define U500_SYS_CLK         100000000
+
+#define U500_CLINT_ADDR         0x2000000
+
+#define U500_PLIC_ADDR            0xc000000
+#define U500_PLIC_NUM_SOURCES      0x35
+#define U500_PLIC_NUM_PRIORITIES   7
+
+#define U500_UART_ADDR            0x54000000
+
+#define U500_UART_BAUDRATE         115200
+
+/**
+ * The U500 SoC has 8 HARTs but HART ID 0 doesn't have S mode.
+ * HARTs 1 is selected as boot HART
+ */
+#ifndef U500_ENABLED_HART_MASK
+#define U500_ENABLED_HART_MASK   (1 << U500_BOOT_HART_ID)
+#endif
+
+#define U500_HARTID_DISABLED   ~(U500_ENABLED_HART_MASK)
+
+/* PRCI clock related macros */
+//TODO: Do we need a separate driver for this ?
+#define U500_PRCI_BASE_ADDR         0x10000000
+#define U500_PRCI_CLKMUXSTATUSREG   0x002C
+#define U500_PRCI_CLKMUX_STATUS_TLCLKSEL   (0x1 << 1)
+
+static void U500_modify_dt(void *fdt)
+{
+   u32 i, size;
+   int chosen_offset, err;
+   int cpu_offset;
+   char cpu_node[32] = "";
+   const char *mmu_type;
+
+   for (i = 0; i < U500_HART_COUNT; i++) {
+      sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
+      cpu_offset = fdt_path_offset(fdt, cpu_node);
+      mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
+      if (mmu_type && (!strcmp(mmu_type, "riscv,sv39") ||
+          !strcmp(mmu_type,"riscv,sv48")))
+         continue;
+      else
+         fdt_setprop_string(fdt, cpu_offset, "status", "masked");
+      memset(cpu_node, 0, sizeof(cpu_node));
+   }
+   size = fdt_totalsize(fdt);
+   err = fdt_open_into(fdt, fdt, size + 256);
+   if (err < 0)
+      sbi_printf("Device Tree can't be expanded to accmodate new node");
+
+   chosen_offset = fdt_path_offset(fdt, "/chosen");
+   fdt_setprop_string(fdt, chosen_offset, "stdout-path",
+            "/soc/serial@10010000:115200");
+
+   plic_fdt_fixup(fdt, "riscv,plic0");
+}
+
+static int U500_final_init(bool cold_boot)
+{
+   void *fdt;
+
+   if (!cold_boot)
+      return 0;
+
+   fdt = sbi_scratch_thishart_arg1_ptr();
+   U500_modify_dt(fdt);
+
+   return 0;
+}
+
+static u32 U500_pmp_region_count(u32 hartid)
+{
+   return 1;
+}
+
+static int U500_pmp_region_info(u32 hartid, u32 index,
+             ulong *prot, ulong *addr, ulong *log2size)
+{
+   int ret = 0;
+
+   switch (index) {
+   case 0:
+      *prot = PMP_R | PMP_W | PMP_X;
+      *addr = 0;
+      *log2size = __riscv_xlen;
+      break;
+   default:
+      ret = -1;
+      break;
+   };
+
+   return ret;
+}
+
+static int U500_console_init(void)
+{
+   unsigned long peri_in_freq;
+
+   peri_in_freq = U500_SYS_CLK/2;
+   return sifive_uart_init(U500_UART_ADDR, peri_in_freq, U500_UART_BAUDRATE);
+}
+
+static int U500_irqchip_init(bool cold_boot)
+{
+   int rc;
+   u32 hartid = sbi_current_hartid();
+
+   if (cold_boot) {
+      rc = plic_cold_irqchip_init(U500_PLIC_ADDR,
+                   U500_PLIC_NUM_SOURCES,
+                   U500_HART_COUNT);
+      if (rc)
+         return rc;
+   }
+
+   return plic_warm_irqchip_init(hartid,
+         (hartid) ? (2 * hartid - 1) : 0,
+         (hartid) ? (2 * hartid) : -1);
+}
+
+static int U500_ipi_init(bool cold_boot)
+{
+   int rc;
+
+   if (cold_boot) {
+      rc = clint_cold_ipi_init(U500_CLINT_ADDR,
+                U500_HART_COUNT);
+      if (rc)
+         return rc;
+
+   }
+
+   return clint_warm_ipi_init();
+}
+
+static int U500_timer_init(bool cold_boot)
+{
+   int rc;
+
+   if (cold_boot) {
+      rc = clint_cold_timer_init(U500_CLINT_ADDR,
+                  U500_HART_COUNT);
+      if (rc)
+         return rc;
+   }
+
+   return clint_warm_timer_init();
+}
+
+static int U500_system_down(u32 type)
+{
+   /* For now nothing to do. */
+   return 0;
+}
+
+const struct sbi_platform_operations platform_ops = {
+   .pmp_region_count = U500_pmp_region_count,
+   .pmp_region_info = U500_pmp_region_info,
+   .final_init = U500_final_init,
+   .console_putc = sifive_uart_putc,
+   .console_getc = sifive_uart_getc,
+   .console_init = U500_console_init,
+   .irqchip_init = U500_irqchip_init,
+   .ipi_send = clint_ipi_send,
+   .ipi_sync = clint_ipi_sync,
+   .ipi_clear = clint_ipi_clear,
+   .ipi_init = U500_ipi_init,
+   .timer_value = clint_timer_value,
+   .timer_event_stop = clint_timer_event_stop,
+   .timer_event_start = clint_timer_event_start,
+   .timer_init = U500_timer_init,
+   .system_reboot = U500_system_down,
+   .system_shutdown = U500_system_down
+};
+
+const struct sbi_platform platform = {
+   .opensbi_version   = OPENSBI_VERSION,                  // The OpenSBI version this platform table is built bassed on.
+   .platform_version   = SBI_PLATFORM_VERSION(0x0001, 0x0000),   // SBI Platform version 1.0
+   .name               = "SiFive Freedom U500",
+   .features      = SBI_PLATFORM_DEFAULT_FEATURES,
+   .hart_count      = U500_HART_COUNT,
+   .hart_stack_size   = U500_HART_STACK_SIZE,
+   .disabled_hart_mask   = U500_HARTID_DISABLED,
+   .platform_ops_addr   = (unsigned long)&platform_ops
+};
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
new file mode 100644
index 00000000..bfb97351
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
@@ -0,0 +1,195 @@
+/**@file
+  Build up platform processor information.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+#include <SiFiveU5MCCoreplex.h>
+#include <Library/SiFiveE51.h>
+#include <Library/SiFiveU54.h>
+
+/**
+  Build up processor-specific HOB for U5MC Coreplex
+
+  @param  UniqueId      Unique ID of this U5MC Coreplex processor
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU5MCCoreplexProcessorSpecificDataHob (
+  IN UINTN UniqueId
+  )
+{
+  EFI_STATUS Status;
+  UINT32 HartIdNumber;
+  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *GuidHobData;
+  EFI_GUID *ParentCoreGuid;
+  BOOLEAN MCSupport;
+
+  DEBUG ((DEBUG_INFO, "Building U5 Coreplex processor information HOB\n"));
+
+  HartIdNumber = 0;
+  ParentCoreGuid = PcdGetPtr(PcdSiFiveU5MCCoreplexGuid);
+  MCSupport = PcdGetBool (PcdE5MCSupported);
+  if (MCSupport == TRUE) {
+    Status = CreateE51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, FALSE, &GuidHobData);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
+      ASSERT (FALSE);
+    }
+    HartIdNumber ++;
+    DEBUG ((DEBUG_INFO, "Support E5 Monitor core on U500 platform, HOB at address 0x%x\n", GuidHobData));
+  }
+  for (; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) + (UINT32)MCSupport); HartIdNumber ++) {
+    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32 (PcdBootHartId))? TRUE: FALSE, &GuidHobData);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
+      ASSERT (FALSE);
+    }
+    DEBUG ((DEBUG_INFO, "Support U5 application core on U500 platform, HOB Data at address 0x%x\n", GuidHobData));
+  }
+  DEBUG ((DEBUG_INFO, "Support %d U5 application cores on U500 platform\n", HartIdNumber - (UINT32)MCSupport));
+
+  if (HartIdNumber != FixedPcdGet32 (PcdHartCount)) {
+    DEBUG ((DEBUG_ERROR, "Improper core settings...\n"));
+    DEBUG ((DEBUG_ERROR, "    PcdHartCount\n"));
+    DEBUG ((DEBUG_ERROR, "    PcdNumberofU5Cores\n"));
+    DEBUG ((DEBUG_ERROR, "    PcdE5MCSupported\n\n"));
+    ASSERT (FALSE);
+  }
+  return Status;
+}
+
+/**
+  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
+  this information and build SMBIOS Type4 and Type7 record.
+
+  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
+                          maintained in this structure is only valid before memory is discovered.
+                          Access to those pointers after memory is installed will cause unexpected issues.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateU5MCProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
+  )
+{
+  EFI_GUID *GuidPtr;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
+  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
+
+  if (SmbiosHobPtr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Build up SMBIOS type 7 L2 cache record.
+  //
+  ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid));
+  L2CacheDataHob.ProcessorUid = ProcessorUid;
+  L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
+      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
+      RISC_V_CACHE_CONFIGURATION_ENABLED | \
+      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
+  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
+  L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
+  L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified;
+  L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
+  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
+  if (L2CacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Build up SMBIOS type 4 record.
+  //
+  ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid));
+  ProcessorDataHob.ProcessorUid = ProcessorUid;
+  ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture = TO_BE_FILLED_BY_VENDOR;
+  SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
+  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1;
+  ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
+  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
+  ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE;
+  ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);
+  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable
+  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64;
+  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
+  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
+  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
+  if (ProcessorDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+
+  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  SmbiosDataHob.Processor = ProcessorDataHobPtr;
+  SmbiosDataHob.L1InstCache = NULL;
+  SmbiosDataHob.L1DataCache = NULL;
+  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
+  SmbiosDataHob.L3Cache = NULL;
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
+  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
+  if (SmbiosDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
+    ASSERT (FALSE);
+  }
+  *SmbiosHobPtr = SmbiosDataHobPtr;
+  DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
new file mode 100644
index 00000000..915021f9
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
@@ -0,0 +1,58 @@
+## @file
+#  Library instance to create core information HOB
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconSiFiveU5MCCoreplexInfoLib
+  FILE_GUID                      = 4E397A71-5164-4E69-9884-70CBE2740AAB
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconSiFiveU5MCCoreplexInfoLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV
+#
+
+[Sources]
+ CoreInfoHob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+  Platform/RiscV/SiFive/U500Pkg/U500.dec
+  Silicon/SiFive/SiFive.dec
+  RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+  SiliconSiFiveE51CoreInfoLib
+  SiliconSiFiveU54CoreInfoLib
+
+[Guids]
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid
+
+[Ppis]
+
+[FixedPcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid
+  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
new file mode 100644
index 00000000..bb4aafb9
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+//
+// SiFive U500 Timer CSR functions.
+//
+// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//------------------------------------------------------------------------------
+#include <Base.h>
+#include <RiscV.h>
+#include <U500Clint.h>
+
+.data
+
+.text
+.align 3
+
+.global ASM_PFX(RiscVReadMachineTimer)
+.global ASM_PFX(RiscVSetMachineTimerCmp)
+.global ASM_PFX(RiscVReadMachineTimerCmp)
+
+//
+// Read machine timer CSR.
+// @retval a0 : 64-bit machine timer.
+//
+ASM_PFX (RiscVReadMachineTimer):
+    li t1, CLINT_REG_MTIME
+    ld a0, (t1)
+    ret
+
+//
+// Set machine timer compare CSR.
+// @param a0 : UINT64
+//
+ASM_PFX (RiscVSetMachineTimerCmp):
+    li t1, CLINT_REG_MTIMECMP0
+    sd a0, (t1)
+    ret
+
+//
+// Read machine timer compare CSR.
+// @param a0 : UINT64
+//
+ASM_PFX (RiscVReadMachineTimerCmp):
+    li t1, CLINT_REG_MTIMECMP0
+    ld a0, (t1)
+    ret
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
new file mode 100644
index 00000000..62771b68
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
@@ -0,0 +1,39 @@
+## @file
+# RISC-V CPU lib to override timer mechanism for U500 platform.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RiscVPlatformTimerLib
+  FILE_GUID                      = AFA75BBD-DE9D-4E77-BD88-1EA401BE931D
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RiscVPlatformTimerLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV32 RISCV64
+#
+
+[Sources]
+
+[Sources.RISCV32]
+  RiscVPlatformTimerLib.s
+
+[Sources.RISCV64]
+  RiscVPlatformTimerLib.s
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/SiFive/U500Pkg/U500.dec
+
+
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
new file mode 100644
index 00000000..85af1fbd
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
@@ -0,0 +1,31 @@
+## @file
+#   Library instance for SerialIo library class
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = U500SerialPortLib
+  MODULE_UNI_FILE                = U500SerialPortLib.uni
+  FILE_GUID                      = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  RiscVOpensbiLib
+
+[Sources]
+  SerialPortLib.c
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
new file mode 100644
index 00000000..e51bf9c1
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
@@ -0,0 +1,241 @@
+/** @file
+  UART Serial Port library functions
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/SerialPortLib.h>
+#include <sbi_utils/serial/sifive-uart.h>
+
+#define REG32(p, i) ((p)[(i) >> 2])
+
+//---------------------------------------------
+// UART Register Offsets
+//---------------------------------------------
+
+#define UART_REG_IP     0x14
+  #define UART_IP_RXWM 0x02
+
+//---------------------------------------------
+// UART Settings
+//---------------------------------------------
+
+#define U500_UART_ADDR      0x54000000
+#define U500_UART_BAUDRATE  115200
+#define U500_SYS_CLK        100000000
+
+/**
+  Initialize the serial device hardware.
+
+  If no initialization is required, then return RETURN_SUCCESS.
+  If the serial device was successfuly initialized, then return RETURN_SUCCESS.
+  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
+
+  @retval RETURN_SUCCESS        The serial device was initialized.
+  @retval RETURN_DEVICE_ERROR   The serail device could not be initialized.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  if (sifive_uart_init (U500_UART_ADDR, U500_SYS_CLK/2, U500_UART_BAUDRATE) != 0) {
+      return EFI_DEVICE_ERROR;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data from buffer to serial device.
+
+  Writes NumberOfBytes data bytes from Buffer to the serial device.
+  The number of bytes actually written to the serial device is returned.
+  If the return value is less than NumberOfBytes, then the write operation failed.
+
+  If Buffer is NULL, then ASSERT().
+
+  If NumberOfBytes is zero, then return 0.
+
+  @param  Buffer           Pointer to the data buffer to be written.
+  @param  NumberOfBytes    Number of bytes to written to the serial device.
+
+  @retval 0                NumberOfBytes is 0.
+  @retval >0               The number of bytes written to the serial device.
+                           If this value is less than NumberOfBytes, then the write operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+  UINTN i;
+
+  if (Buffer == NULL) {
+    return 0;
+  }
+
+  for(i=0; i < NumberOfBytes; i++) {
+    sifive_uart_putc (Buffer[i]);
+  }
+
+  return i;
+}
+
+
+/**
+  Reads data from a serial device into a buffer.
+
+  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.
+  @param  NumberOfBytes    Number of bytes to read from the serial device.
+
+  @retval 0                NumberOfBytes is 0.
+  @retval >0               The number of bytes read from the serial device.
+                           If this value is less than NumberOfBytes, then the read operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+  )
+{
+  UINTN i;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  for(i=0; i < NumberOfBytes; i++) {
+    Buffer[i] = (UINT8)sifive_uart_getc ();
+  }
+
+  return i;
+}
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+
+  Polls aserial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  static volatile UINT32 * const uart = (void *)(U500_UART_ADDR);
+  UINT32 ip;
+
+  ip = REG32(uart, UART_REG_IP);
+  if(ip & UART_IP_RXWM) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+/**
+  Sets the control bits on a serial device.
+
+  @param Control                Sets the bits of Control that are settable.
+
+  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32 Control
+  )
+{
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Retrieve the status of the control bits on a serial device.
+
+  @param Control                A pointer to return the current control signals from the serial device.
+
+  @retval RETURN_SUCCESS        The control bits were read from the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32 *Control
+  )
+{
+  *Control = 0;
+  return RETURN_SUCCESS;
+}
+
+/**
+  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+  data bits, and stop bits on a serial device.
+
+  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
+                            device's default interface speed.
+                            On output, the value actually set.
+  @param ReveiveFifoDepth   The requested depth of the FIFO on the receive side of the
+                            serial interface. A ReceiveFifoDepth value of 0 will use
+                            the device's default FIFO depth.
+                            On output, the value actually set.
+  @param Timeout            The requested time out for a single character in microseconds.
+                            This timeout applies to both the transmit and receive side of the
+                            interface. A Timeout value of 0 will use the device's default time
+                            out value.
+                            On output, the value actually set.
+  @param Parity             The type of parity to use on this serial device. A Parity value of
+                            DefaultParity will use the device's default parity value.
+                            On output, the value actually set.
+  @param DataBits           The number of data bits to use on the serial device. A DataBits
+                            vaule of 0 will use the device's default data bit setting.
+                            On output, the value actually set.
+  @param StopBits           The number of stop bits to use on this serial device. A StopBits
+                            value of DefaultStopBits will use the device's default number of
+                            stop bits.
+                            On output, the value actually set.
+
+  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
+  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
+  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
+  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN OUT UINT64             *BaudRate,
+  IN OUT UINT32             *ReceiveFifoDepth,
+  IN OUT UINT32             *Timeout,
+  IN OUT EFI_PARITY_TYPE    *Parity,
+  IN OUT UINT8              *DataBits,
+  IN OUT EFI_STOP_BITS_TYPE *StopBits
+  )
+{
+  return RETURN_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
new file mode 100644
index 00000000..49163bd8
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Library instance for SerialIo library class
+//
+// Library instance for SerialIO library class.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Library instance for SerialIO library class"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Library instance for SerialIO library class."
+
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable.
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (9 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-03 16:58   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver Gilbert Chen
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Firmware Volume Block driver instance for ram based EFI variable on U500
 platform.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c         |  127 +++
 .../FvbServicesRuntimeDxe.inf                      |   81 ++
 .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c  | 1123 ++++++++++++++++++++
 .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h  |  187 ++++
 .../RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c   |  151 +++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.c        |  144 +++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.h        |   85 ++
 .../Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c     |   20 +
 8 files changed, 1918 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c

diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
new file mode 100644
index 00000000..1ade0d14
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
@@ -0,0 +1,127 @@
+/**@file
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:
+
+    FvbInfo.c
+
+  Abstract:
+
+    Defines data structure that is the volume header found.These data is intent
+    to decouple FVB driver with FV header.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <Pi/PiFirmwareVolume.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Guid/SystemNvDataGuid.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+typedef struct {
+  UINT64                      FvLength;
+  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
+  //
+  // EFI_FV_BLOCK_MAP_ENTRY    ExtraBlockMap[n];//n=0
+  //
+  EFI_FV_BLOCK_MAP_ENTRY      End[1];
+} EFI_FVB_MEDIA_INFO;
+
+EFI_FVB_MEDIA_INFO  mPlatformFvbMediaInfo[] = {
+  //
+  // Systen NvStorage FVB
+  //
+  {
+    FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+    FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+    FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
+    {
+      {
+        0,
+      },  // ZeroVector[16]
+      EFI_SYSTEM_NV_DATA_FV_GUID,
+      FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+      FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+      FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
+      EFI_FVH_SIGNATURE,
+      EFI_FVB2_MEMORY_MAPPED |
+        EFI_FVB2_READ_ENABLED_CAP |
+        EFI_FVB2_READ_STATUS |
+        EFI_FVB2_WRITE_ENABLED_CAP |
+        EFI_FVB2_WRITE_STATUS |
+        EFI_FVB2_ERASE_POLARITY |
+        EFI_FVB2_ALIGNMENT_16,
+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+      0,  // CheckSum
+      0,  // ExtHeaderOffset
+      {
+        0,
+      },  // Reserved[1]
+      2,  // Revision
+      {
+        {
+          (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+           FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+           FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)) /
+          FixedPcdGet32 (PcdVariableFdBlockSize),
+          FixedPcdGet32 (PcdVariableFdBlockSize),
+        }
+      } // BlockMap[1]
+    },
+    {
+      {
+        0,
+        0
+      }
+    }  // End[1]
+  }
+};
+
+EFI_STATUS
+GetFvbInfo (
+  IN  UINT64                        FvLength,
+  OUT EFI_FIRMWARE_VOLUME_HEADER    **FvbInfo
+  )
+{
+  STATIC BOOLEAN Checksummed = FALSE;
+  UINTN Index;
+
+  if (!Checksummed) {
+    for (Index = 0;
+         Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO);
+         Index += 1) {
+      UINT16 Checksum;
+      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0;
+      Checksum = CalculateCheckSum16 (
+                   (UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo,
+                   mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength
+                   );
+      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum;
+    }
+    Checksummed = TRUE;
+  }
+
+  for (Index = 0;
+       Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO);
+       Index += 1) {
+    if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
+      *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
new file mode 100644
index 00000000..1e8aa592
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
@@ -0,0 +1,81 @@
+## @file
+#  Component description file for RAM Flash Fimware Volume Block DXE driver
+#  module.
+#
+#  This DXE runtime driver implements and produces the Fimware Volue Block
+#  Protocol for a RAM flash device.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FvbServicesRuntimeDxe
+  FILE_GUID                      = B04036D3-4C60-43D6-9850-0FCC090FF054
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FvbInitialize
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FvbInfo.c
+  FwBlockService.c
+  FwBlockServiceDxe.c
+  RamFlash.c
+  RamFlashDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid   # ALWAYS_CONSUMED
+  # gEfiEventVirtualAddressChangeGuid # Create Event: EVENT_GROUP_GUID
+
+[Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid           # PROTOCOL SOMETIMES_PRODUCED
+  gEfiDevicePathProtocolGuid                    # PROTOCOL SOMETIMES_PRODUCED
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+
+[Depex]
+  TRUE
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
new file mode 100644
index 00000000..8b89d2e0
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
@@ -0,0 +1,1123 @@
+/**@file
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:
+
+    FWBlockService.c
+
+  Abstract:
+
+  Revision History
+
+**/
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "FwBlockService.h"
+#include "RamFlash.h"
+
+#define EFI_FVB2_STATUS \
+          (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+ESAL_FWB_GLOBAL         *mFvbModuleGlobal;
+
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_MEMMAP_DP,
+      {
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+      }
+    },
+    EfiMemoryMappedIO,
+    (EFI_PHYSICAL_ADDRESS) 0,
+    (EFI_PHYSICAL_ADDRESS) 0,
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
+  {
+    {
+      MEDIA_DEVICE_PATH,
+      MEDIA_PIWG_FW_VOL_DP,
+      {
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+      }
+    },
+    { 0 }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+  FVB_DEVICE_SIGNATURE,
+  NULL,
+  0,
+  {
+    FvbProtocolGetAttributes,
+    FvbProtocolSetAttributes,
+    FvbProtocolGetPhysicalAddress,
+    FvbProtocolGetBlockSize,
+    FvbProtocolRead,
+    FvbProtocolWrite,
+    FvbProtocolEraseBlocks,
+    NULL
+  }
+};
+
+
+EFI_STATUS
+GetFvbInstance (
+  IN  UINTN                               Instance,
+  IN  ESAL_FWB_GLOBAL                     *Global,
+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance
+  )
+/*++
+
+  Routine Description:
+    Retrieves the physical address of a memory mapped FV
+
+  Arguments:
+    Instance              - The FV instance whose base address is going to be
+                            returned
+    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                            instance data
+    FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+    EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhRecord;
+
+  *FwhInstance = NULL;
+  if (Instance >= Global->NumFv) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Find the right instance of the FVB private data
+  //
+  FwhRecord = Global->FvInstance;
+  while (Instance > 0) {
+    FwhRecord = (EFI_FW_VOL_INSTANCE *)
+      (
+        (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +
+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+      );
+    Instance--;
+  }
+
+  *FwhInstance = FwhRecord;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+  IN UINTN                                Instance,
+  OUT EFI_PHYSICAL_ADDRESS                *Address,
+  IN ESAL_FWB_GLOBAL                      *Global
+  )
+/*++
+
+  Routine Description:
+    Retrieves the physical address of a memory mapped FV
+
+  Arguments:
+    Instance              - The FV instance whose base address is going to be
+                            returned
+    Address               - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
+                            that on successful return, contains the base
+                            address of the firmware volume.
+    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                            instance data
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+    EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_STATUS          Status;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);
+  ASSERT_EFI_ERROR (Status);
+  *Address = FwhInstance->FvBase;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+  IN UINTN                                Instance,
+  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global
+  )
+/*++
+
+  Routine Description:
+    Retrieves attributes, insures positive polarity of attribute bits, returns
+    resulting attributes in output parameter
+
+  Arguments:
+    Instance              - The FV instance whose attributes is going to be
+                            returned
+    Attributes            - Output buffer which contains attributes
+    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                            instance data
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+    EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_STATUS          Status;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);
+  ASSERT_EFI_ERROR (Status);
+  *Attributes = FwhInstance->VolumeHeader.Attributes;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                               Instance,
+  IN  EFI_LBA                             Lba,
+  OUT UINTN                               *LbaAddress,
+  OUT UINTN                               *LbaLength,
+  OUT UINTN                               *NumOfBlocks,
+  IN  ESAL_FWB_GLOBAL                     *Global
+  )
+/*++
+
+  Routine Description:
+    Retrieves the starting address of an LBA in an FV
+
+  Arguments:
+    Instance              - The FV instance which the Lba belongs to
+    Lba                   - The logical block address
+    LbaAddress            - On output, contains the physical starting address
+                            of the Lba
+    LbaLength             - On output, contains the length of the block
+    NumOfBlocks           - A 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
+    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                            instance data
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+    EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  UINT32                  NumBlocks;
+  UINT32                  BlockLength;
+  UINTN                   Offset;
+  EFI_LBA                 StartLba;
+  EFI_LBA                 NextLba;
+  EFI_FW_VOL_INSTANCE     *FwhInstance;
+  EFI_FV_BLOCK_MAP_ENTRY  *BlockMap;
+  EFI_STATUS              Status;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);
+  ASSERT_EFI_ERROR (Status);
+
+  StartLba  = 0;
+  Offset    = 0;
+  BlockMap  = &(FwhInstance->VolumeHeader.BlockMap[0]);
+
+  //
+  // Parse the blockmap of the FV to find which map entry the Lba belongs to
+  //
+  while (TRUE) {
+    NumBlocks   = BlockMap->NumBlocks;
+    BlockLength = BlockMap->Length;
+
+    if (NumBlocks == 0 || BlockLength == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    NextLba = StartLba + NumBlocks;
+
+    //
+    // The map entry found
+    //
+    if (Lba >= StartLba && Lba < NextLba) {
+      Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);
+      if (LbaAddress != NULL) {
+        *LbaAddress = FwhInstance->FvBase + Offset;
+      }
+
+      if (LbaLength != NULL) {
+        *LbaLength = BlockLength;
+      }
+
+      if (NumOfBlocks != NULL) {
+        *NumOfBlocks = (UINTN) (NextLba - Lba);
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    StartLba  = NextLba;
+    Offset    = Offset + NumBlocks * BlockLength;
+    BlockMap++;
+  }
+}
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                                  Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2               *Attributes,
+  IN ESAL_FWB_GLOBAL                        *Global
+  )
+/*++
+
+  Routine Description:
+    Modifies the current settings of the firmware volume according to the
+    input parameter, and returns the new setting of the volume
+
+  Arguments:
+    Instance              - The FV instance whose attributes is going to be
+                            modified
+    Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
+                            containing the desired firmware volume settings.
+                            On successful return, it contains the new settings
+                            of the firmware volume
+    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                            instance data
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+    EFI_ACCESS_DENIED     - The volume setting is locked and cannot be modified
+    EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
+                            in conflict with the capabilities as declared in
+                            the firmware volume header
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE   *FwhInstance;
+  EFI_FVB_ATTRIBUTES_2  OldAttributes;
+  EFI_FVB_ATTRIBUTES_2  *AttribPtr;
+  UINT32                Capabilities;
+  UINT32                OldStatus;
+  UINT32                NewStatus;
+  EFI_STATUS            Status;
+  EFI_FVB_ATTRIBUTES_2  UnchangedAttributes;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);
+  ASSERT_EFI_ERROR (Status);
+
+  AttribPtr     =
+    (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
+  OldAttributes = *AttribPtr;
+  Capabilities  = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \
+                                   EFI_FVB2_READ_ENABLED_CAP | \
+                                   EFI_FVB2_WRITE_DISABLED_CAP | \
+                                   EFI_FVB2_WRITE_ENABLED_CAP | \
+                                   EFI_FVB2_LOCK_CAP \
+                                   );
+  OldStatus     = OldAttributes & EFI_FVB2_STATUS;
+  NewStatus     = *Attributes & EFI_FVB2_STATUS;
+
+  UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP  | \
+                        EFI_FVB2_READ_ENABLED_CAP   | \
+                        EFI_FVB2_WRITE_DISABLED_CAP | \
+                        EFI_FVB2_WRITE_ENABLED_CAP  | \
+                        EFI_FVB2_LOCK_CAP           | \
+                        EFI_FVB2_STICKY_WRITE       | \
+                        EFI_FVB2_MEMORY_MAPPED      | \
+                        EFI_FVB2_ERASE_POLARITY     | \
+                        EFI_FVB2_READ_LOCK_CAP      | \
+                        EFI_FVB2_WRITE_LOCK_CAP     | \
+                        EFI_FVB2_ALIGNMENT;
+
+  //
+  // Some attributes of FV is read only can *not* be set
+  //
+  if ((OldAttributes & UnchangedAttributes) ^
+      (*Attributes & UnchangedAttributes)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // If firmware volume is locked, no status bit can be updated
+  //
+  if (OldAttributes & EFI_FVB2_LOCK_STATUS) {
+    if (OldStatus ^ NewStatus) {
+      return EFI_ACCESS_DENIED;
+    }
+  }
+  //
+  // Test read disable
+  //
+  if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+    if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // Test read enable
+  //
+  if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_READ_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // Test write disable
+  //
+  if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+    if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // Test write enable
+  //
+  if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // Test lock
+  //
+  if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+  *AttribPtr  = (*AttribPtr) | NewStatus;
+  *Attributes = *AttribPtr;
+
+  return EFI_SUCCESS;
+}
+
+//
+// FVB protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_PHYSICAL_ADDRESS                        *Address
+  )
+/*++
+
+  Routine Description:
+
+    Retrieves the physical address of the device.
+
+  Arguments:
+
+    This                  - Calling context
+    Address               - Output buffer containing the address.
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetPhysicalAddress (FvbDevice->Instance, Address,
+           mFvbModuleGlobal);
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN CONST EFI_LBA                                     Lba,
+  OUT UINTN                                       *BlockSize,
+  OUT UINTN                                       *NumOfBlocks
+  )
+/*++
+
+  Routine Description:
+    Retrieve the size of a logical block
+
+  Arguments:
+    This                  - Calling context
+    Lba                   - Indicates which block to return the size for.
+    BlockSize             - A pointer to a caller allocated UINTN in which
+                            the size of the block is returned
+    NumOfBlocks           - a 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
+
+  Returns:
+    EFI_SUCCESS           - The firmware volume was read successfully and
+                            contents are in Buffer
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetLbaAddress (
+          FvbDevice->Instance,
+          Lba,
+          NULL,
+          BlockSize,
+          NumOfBlocks,
+          mFvbModuleGlobal
+          );
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_FVB_ATTRIBUTES_2                              *Attributes
+  )
+/*++
+
+  Routine Description:
+      Retrieves Volume attributes.  No polarity translations are done.
+
+  Arguments:
+      This                - Calling context
+      Attributes          - output buffer which contains attributes
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes,
+           mFvbModuleGlobal);
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2                           *Attributes
+  )
+/*++
+
+  Routine Description:
+    Sets Volume attributes. No polarity translations are done.
+
+  Arguments:
+    This                  - Calling context
+    Attributes            - output buffer which contains attributes
+
+  Returns:
+    EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes,
+           mFvbModuleGlobal);
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  )
+/*++
+
+  Routine Description:
+
+    The EraseBlock() function erases one or more blocks as denoted by the
+    variable argument list. The entire parameter list of blocks must be
+    verified prior to 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 EraseBlock() function must
+    return EFI_INVALID_PARAMETER without modifying the contents of the firmware
+    volume.
+
+  Arguments:
+    This                  - Calling context
+    ...                   - Starting LBA followed by Number of Lba to erase.
+                            a -1 to terminate the list.
+
+  Returns:
+    EFI_SUCCESS           - The erase request was successfully completed
+    EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                            could not be written. Firmware device may have been
+                            partially erased
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+  EFI_FW_VOL_INSTANCE     *FwhInstance;
+  UINTN                   NumOfBlocks;
+  VA_LIST                 args;
+  EFI_LBA                 StartingLba;
+  UINTN                   NumOfLba;
+  EFI_STATUS              Status;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal,
+                &FwhInstance);
+  ASSERT_EFI_ERROR (Status);
+
+  NumOfBlocks = FwhInstance->NumOfBlocks;
+
+  VA_START (args, This);
+
+  do {
+    StartingLba = VA_ARG (args, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+      break;
+    }
+
+    NumOfLba = VA_ARG (args, UINT32);
+
+    //
+    // Check input parameters
+    //
+    if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) {
+      VA_END (args);
+      return EFI_INVALID_PARAMETER;
+    }
+  } while (1);
+
+  VA_END (args);
+
+  VA_START (args, This);
+  do {
+    StartingLba = VA_ARG (args, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+      break;
+    }
+
+    NumOfLba = VA_ARG (args, UINT32);
+
+    while (NumOfLba > 0) {
+      Status = RamFlashEraseBlock (StartingLba);
+      if (EFI_ERROR (Status)) {
+        VA_END (args);
+        return Status;
+      }
+
+      StartingLba++;
+      NumOfLba--;
+    }
+
+  } while (1);
+
+  VA_END (args);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN       EFI_LBA                                      Lba,
+  IN       UINTN                                        Offset,
+  IN OUT   UINTN                                    *NumBytes,
+  IN       UINT8                                        *Buffer
+  )
+/*++
+
+  Routine Description:
+
+    Writes data beginning at Lba:Offset from FV. The write terminates either
+    when *NumBytes of data have been written, or when a block boundary is
+    reached.  *NumBytes is updated to reflect the actual number of bytes
+    written. The write opertion does not include erase. This routine will
+    attempt to write only the specified bytes. If the writes do not stick,
+    it will return an error.
+
+  Arguments:
+    This                  - Calling context
+    Lba                   - Block in which to begin write
+    Offset                - Offset in the block at which to begin write
+    NumBytes              - On input, indicates the requested write size. On
+                            output, indicates the actual number of bytes
+                            written
+    Buffer                - Buffer containing source data for the write.
+
+  Returns:
+    EFI_SUCCESS           - The firmware volume was written successfully
+    EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,
+                            NumBytes contains the total number of bytes
+                            actually written
+    EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                            could not be written
+    EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+  return RamFlashWrite ((EFI_LBA)Lba, (UINTN)Offset, NumBytes,
+           (UINT8 *)Buffer);
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN CONST EFI_LBA                                      Lba,
+  IN CONST UINTN                                        Offset,
+  IN OUT UINTN                                    *NumBytes,
+  IN UINT8                                        *Buffer
+  )
+/*++
+
+  Routine Description:
+
+    Reads data beginning at Lba:Offset from FV. The Read terminates either
+    when *NumBytes of data have been read, or when a block boundary is
+    reached.  *NumBytes is updated to reflect the actual number of bytes
+    written. The write opertion does not include erase. This routine will
+    attempt to write only the specified bytes. If the writes do not stick,
+    it will return an error.
+
+  Arguments:
+    This                  - Calling context
+    Lba                   - Block in which to begin Read
+    Offset                - Offset in the block at which to begin Read
+    NumBytes              - On input, indicates the requested write size. On
+                            output, indicates the actual number of bytes Read
+    Buffer                - Buffer containing source data for the Read.
+
+  Returns:
+    EFI_SUCCESS           - The firmware volume was read successfully and
+                            contents are in Buffer
+    EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,
+                            NumBytes contains the total number of bytes
+                            returned in Buffer
+    EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state
+    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                            could not be read
+    EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+  return RamFlashRead ((EFI_LBA)Lba, (UINTN)Offset, NumBytes,
+           (UINT8 *)Buffer);
+}
+
+EFI_STATUS
+ValidateFvHeader (
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
+  )
+/*++
+
+  Routine Description:
+    Check the integrity of firmware volume header
+
+  Arguments:
+    FwVolHeader           - A pointer to a firmware volume header
+
+  Returns:
+    EFI_SUCCESS           - The firmware volume is consistent
+    EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an
+                            FV
+
+--*/
+{
+  UINT16 Checksum;
+
+  //
+  // 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 == ((UINTN) -1)) ||
+      ((FwVolHeader->HeaderLength & 0x01) != 0)
+      ) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Verify the header checksum
+  //
+
+  Checksum = CalculateSum16 ((UINT16 *) FwVolHeader,
+               FwVolHeader->HeaderLength);
+  if (Checksum != 0) {
+    UINT16 Expected;
+
+    Expected =
+      (UINT16) (((UINTN) FwVolHeader->Checksum + 0x10000 - Checksum) & 0xffff);
+
+    DEBUG ((DEBUG_INFO, "FV@%p Checksum is 0x%x, expected 0x%x\n",
+            FwVolHeader, FwVolHeader->Checksum, Expected));
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MarkMemoryRangeForRuntimeAccess (
+  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  UINTN                               Length
+  )
+{
+  EFI_STATUS                          Status;
+
+  //
+  // Mark flash region as runtime memory
+  //
+  Status = gDS->RemoveMemorySpace (
+                  BaseAddress,
+                  Length
+                  );
+
+  Status = gDS->AddMemorySpace (
+                  EfiGcdMemoryTypeSystemMemory,
+                  BaseAddress,
+                  Length,
+                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->AllocatePages (
+                  AllocateAddress,
+                  EfiRuntimeServicesData,
+                  EFI_SIZE_TO_PAGES (Length),
+                  &BaseAddress
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+InitializeVariableFvHeader (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_FIRMWARE_VOLUME_HEADER          *GoodFwVolHeader;
+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
+  UINTN                               Length;
+  UINTN                               WriteLength;
+  UINTN                               BlockSize;
+
+  FwVolHeader =
+    (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
+      PcdGet32 (PcdPlatformFlashNvStorageVariableBase);
+
+  Length =
+    (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+     FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+     FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize));
+
+  BlockSize = PcdGet32 (PcdVariableFdBlockSize);
+
+  Status      = ValidateFvHeader (FwVolHeader);
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "ValidateFvHeader() return ok\n"));
+    if (FwVolHeader->FvLength != Length ||
+        FwVolHeader->BlockMap[0].Length != BlockSize) {
+      Status = EFI_VOLUME_CORRUPTED;
+     DEBUG ((DEBUG_INFO, "FwVolHeader->FvLength(%x) != Length(%x) || FwVolHeader->BlockMap[0].Length(%x) != BlockSize(%x)\n", FwVolHeader->FvLength, Length, FwVolHeader->BlockMap[0].Length, BlockSize));
+    }
+  }
+  else {
+    DEBUG ((DEBUG_INFO, "ValidateFvHeader() return failed\n"));
+  }
+  if (EFI_ERROR (Status)) {
+    UINTN   Offset;
+    UINTN   Start;
+
+    DEBUG ((DEBUG_INFO,
+      "Variable FV header is not valid. It will be reinitialized.\n"));
+
+    //
+    // Get FvbInfo to provide in FwhInstance.
+    //
+    Status = GetFvbInfo (Length, &GoodFwVolHeader);
+    ASSERT (!EFI_ERROR (Status));
+
+    Start = (UINTN)(UINT8*) FwVolHeader - PcdGet32 (PcdVariableFdBaseAddress);
+    ASSERT (Start % BlockSize == 0 && Length % BlockSize == 0);
+    ASSERT (GoodFwVolHeader->HeaderLength <= BlockSize);
+
+    //
+    // Erase all the blocks
+    //
+    for (Offset = Start; Offset < Start + Length; Offset += BlockSize) {
+      Status = RamFlashEraseBlock (Offset / BlockSize);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    //
+    // Write good FV header
+    //
+    WriteLength = GoodFwVolHeader->HeaderLength;
+    Status = RamFlashWrite (
+               Start / BlockSize,
+               0,
+               &WriteLength,
+               (UINT8 *) GoodFwVolHeader);
+    ASSERT_EFI_ERROR (Status);
+    ASSERT (WriteLength == GoodFwVolHeader->HeaderLength);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+  Routine Description:
+    This function does common initialization for FVB services
+
+  Arguments:
+
+  Returns:
+
+--*/
+{
+  EFI_STATUS                          Status;
+  EFI_FW_VOL_INSTANCE                 *FwhInstance;
+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
+  UINT32                              BufferSize;
+  EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;
+  EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;
+  UINT32                              MaxLbaSize;
+  EFI_PHYSICAL_ADDRESS                BaseAddress;
+  UINTN                               Length;
+  UINTN                               NumOfBlocks;
+
+  if (EFI_ERROR (RamFlashInitialize ())) {
+    //
+    // Return an error so image will be unloaded
+    //
+    DEBUG ((DEBUG_INFO,
+      "RAM flash was not detected. Writable FVB is not being installed.\n"));
+    return EFI_WRITE_PROTECTED;
+  }
+
+  //
+  // Allocate runtime services data for global variable, which contains
+  // the private data of all firmware volume block instances
+  //
+  mFvbModuleGlobal = AllocateRuntimePool (sizeof (ESAL_FWB_GLOBAL));
+  ASSERT (mFvbModuleGlobal != NULL);
+
+  BaseAddress = (UINTN) PcdGet32 (PcdVariableFdBaseAddress);
+  Length = PcdGet32 (PcdVariableFdSize);
+  DEBUG ((DEBUG_INFO, "FvbInitialize(): BaseAddress: 0x%lx Length:0x%x\n", BaseAddress, Length));
+  Status = InitializeVariableFvHeader ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO,
+      "RAM Flash: Unable to initialize variable FV header\n"));
+    return EFI_WRITE_PROTECTED;
+  }
+
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
+  Status      = ValidateFvHeader (FwVolHeader);
+  if (EFI_ERROR (Status)) {
+    //
+    // Get FvbInfo
+    //
+    DEBUG ((DEBUG_INFO, "FvbInitialize(): ValidateFvHeader() return error(%r)\n", Status));
+
+    Status = GetFvbInfo (Length, &FwVolHeader);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "FvbInitialize(): GetFvbInfo (Length, &FwVolHeader) return error(%r)\n", Status));
+      return EFI_WRITE_PROTECTED;
+    }
+  }
+
+  BufferSize = (sizeof (EFI_FW_VOL_INSTANCE) +
+                FwVolHeader->HeaderLength -
+                sizeof (EFI_FIRMWARE_VOLUME_HEADER)
+                );
+  mFvbModuleGlobal->FvInstance = AllocateRuntimePool (BufferSize);
+  ASSERT (mFvbModuleGlobal->FvInstance != NULL);
+
+  FwhInstance = mFvbModuleGlobal->FvInstance;
+
+  mFvbModuleGlobal->NumFv                   = 0;
+  MaxLbaSize = 0;
+
+  FwVolHeader =
+    (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
+      PcdGet32 (PcdPlatformFlashNvStorageVariableBase);
+
+  FwhInstance->FvBase = (UINTN) BaseAddress;
+
+  CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader,
+    FwVolHeader->HeaderLength);
+  FwVolHeader = &(FwhInstance->VolumeHeader);
+
+  NumOfBlocks = 0;
+
+  for (PtrBlockMapEntry = FwVolHeader->BlockMap;
+       PtrBlockMapEntry->NumBlocks != 0;
+       PtrBlockMapEntry++) {
+    //
+    // Get the maximum size of a block.
+    //
+    if (MaxLbaSize < PtrBlockMapEntry->Length) {
+      MaxLbaSize = PtrBlockMapEntry->Length;
+    }
+
+    NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
+  }
+
+  //
+  // The total number of blocks in the FV.
+  //
+  FwhInstance->NumOfBlocks = NumOfBlocks;
+
+  //
+  // Add a FVB Protocol Instance
+  //
+  FvbDevice = AllocateRuntimePool (sizeof (EFI_FW_VOL_BLOCK_DEVICE));
+  ASSERT (FvbDevice != NULL);
+
+  CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));
+
+  FvbDevice->Instance = mFvbModuleGlobal->NumFv;
+  mFvbModuleGlobal->NumFv++;
+
+  //
+  // Set up the devicepath
+  //
+  if (FwVolHeader->ExtHeaderOffset == 0) {
+    FV_MEMMAP_DEVICE_PATH *FvMemmapDevicePath;
+
+    //
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
+    //
+    FvMemmapDevicePath = AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH),
+                           &mFvMemmapDevicePathTemplate);
+    FvMemmapDevicePath->MemMapDevPath.StartingAddress = BaseAddress;
+    FvMemmapDevicePath->MemMapDevPath.EndingAddress   =
+      BaseAddress + FwVolHeader->FvLength - 1;
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvMemmapDevicePath;
+  } else {
+    FV_PIWG_DEVICE_PATH *FvPiwgDevicePath;
+
+    FvPiwgDevicePath = AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH),
+                         &mFvPIWGDevicePathTemplate);
+    CopyGuid (
+      &FvPiwgDevicePath->FvDevPath.FvName,
+      (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
+      );
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvPiwgDevicePath;
+  }
+
+  //
+  // Module type specific hook.
+  //
+  InstallProtocolInterfaces (FvbDevice);
+
+  MarkMemoryRangeForRuntimeAccess (BaseAddress, Length);
+
+  //
+  // Set several PCD values to point to flash
+  //
+  PcdSet64 (
+    PcdFlashNvStorageVariableBase64,
+    (UINTN) PcdGet32 (PcdPlatformFlashNvStorageVariableBase)
+    );
+  PcdSet32 (
+    PcdFlashNvStorageFtwWorkingBase,
+    PcdGet32 (PcdPlatformFlashNvStorageFtwWorkingBase)
+    );
+  PcdSet32 (
+    PcdFlashNvStorageFtwSpareBase,
+    PcdGet32 (PcdPlatformFlashNvStorageFtwSpareBase)
+    );
+
+  FwhInstance = (EFI_FW_VOL_INSTANCE *)
+    (
+      (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
+      (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+    );
+
+  //
+  // Module type specific hook.
+  //
+  InstallVirtualAddressChangeHandler ();
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
new file mode 100644
index 00000000..a1aeb2c3
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
@@ -0,0 +1,187 @@
+/**@file
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:
+
+    FwBlockService.h
+
+  Abstract:
+
+    Firmware volume block driver for Intel Firmware Hub (FWH) device
+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H_
+#define _FW_BLOCK_SERVICE_H_
+
+typedef struct {
+  UINTN                       FvBase;
+  UINTN                       NumOfBlocks;
+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+  UINT32              NumFv;
+  EFI_FW_VOL_INSTANCE *FvInstance;
+} ESAL_FWB_GLOBAL;
+
+extern ESAL_FWB_GLOBAL *mFvbModuleGlobal;
+
+//
+// Fvb Protocol instance data
+//
+#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \
+                                  FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \
+                                         FvbExtension, FVB_DEVICE_SIGNATURE)
+
+#define FVB_DEVICE_SIGNATURE            SIGNATURE_32 ('F', 'V', 'B', 'N')
+
+typedef struct {
+  MEDIA_FW_VOL_DEVICE_PATH  FvDevPath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
+} FV_PIWG_DEVICE_PATH;
+
+typedef struct {
+  MEMMAP_DEVICE_PATH          MemMapDevPath;
+  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+typedef struct {
+  UINTN                               Signature;
+  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
+  UINTN                               Instance;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+EFI_STATUS
+GetFvbInfo (
+  IN  UINT64                            FvLength,
+  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo
+  );
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                                Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global
+  );
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+  IN UINTN                                Instance,
+  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global
+  );
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+  IN UINTN                                Instance,
+  OUT EFI_PHYSICAL_ADDRESS                *Address,
+  IN ESAL_FWB_GLOBAL                      *Global
+  );
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+
+VOID
+EFIAPI
+FvbClassAddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  );
+
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                               Instance,
+  IN  EFI_LBA                             Lba,
+  OUT UINTN                               *LbaAddress,
+  OUT UINTN                               *LbaLength,
+  OUT UINTN                               *NumOfBlocks,
+  IN  ESAL_FWB_GLOBAL                     *Global
+  );
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_FVB_ATTRIBUTES_2                              *Attributes
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2                           *Attributes
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_PHYSICAL_ADDRESS                        *Address
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN CONST EFI_LBA                                     Lba,
+  OUT UINTN                                       *BlockSize,
+  OUT UINTN                                       *NumOfBlocks
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN CONST EFI_LBA                                      Lba,
+  IN CONST UINTN                                        Offset,
+  IN OUT UINTN                                    *NumBytes,
+  IN UINT8                                        *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN       EFI_LBA                                      Lba,
+  IN       UINTN                                        Offset,
+  IN OUT   UINTN                                        *NumBytes,
+  IN       UINT8                                        *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  );
+
+//
+// The following functions have different implementations dependent on the
+// module type chosen for building this driver.
+//
+VOID
+InstallProtocolInterfaces (
+  IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice
+  );
+
+VOID
+InstallVirtualAddressChangeHandler (
+  VOID
+  );
+#endif
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
new file mode 100644
index 00000000..46112365
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
@@ -0,0 +1,151 @@
+/**@file
+  Functions related to the Firmware Volume Block service whose
+  implementation is specific to the runtime DXE driver build.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (C) 2015, Red Hat, Inc.
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/EventGroup.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#include "FwBlockService.h"
+#include "RamFlash.h"
+
+VOID
+InstallProtocolInterfaces (
+  IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_HANDLE                         FwbHandle;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
+
+  //
+  // Find a handle with a matching device path that has supports FW Block
+  // protocol
+  //
+  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid,
+                  &FvbDevice->DevicePath, &FwbHandle);
+  if (EFI_ERROR (Status)) {
+    //
+    // LocateDevicePath fails so install a new interface and device path
+    //
+    FwbHandle = NULL;
+    DEBUG ((DEBUG_INFO, "Installing RAM FVB\n"));
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &FwbHandle,
+                    &gEfiFirmwareVolumeBlockProtocolGuid,
+                    &FvbDevice->FwVolBlockInstance,
+                    &gEfiDevicePathProtocolGuid,
+                    FvbDevice->DevicePath,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
+    //
+    // Device already exists, so reinstall the FVB protocol
+    //
+    Status = gBS->HandleProtocol (
+                    FwbHandle,
+                    &gEfiFirmwareVolumeBlockProtocolGuid,
+                    (VOID**)&OldFwbInterface
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    DEBUG ((DEBUG_INFO, "Reinstalling FVB for Ram flash region\n"));
+    Status = gBS->ReinstallProtocolInterface (
+                    FwbHandle,
+                    &gEfiFirmwareVolumeBlockProtocolGuid,
+                    OldFwbInterface,
+                    &FvbDevice->FwVolBlockInstance
+                    );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    //
+    // There was a FVB protocol on an End Device Path node
+    //
+    ASSERT (FALSE);
+  }
+}
+
+
+STATIC
+VOID
+EFIAPI
+FvbVirtualAddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+/*++
+
+  Routine Description:
+
+    Fixup internal data so that EFI and SAL can be call in virtual mode.
+    Call the passed in Child Notify event and convert the mFvbModuleGlobal
+    date items to there virtual address.
+
+  Arguments:
+
+    (Standard EFI notify event - EFI_EVENT_NOTIFY)
+
+  Returns:
+
+    None
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  UINTN               Index;
+
+  FwhInstance = mFvbModuleGlobal->FvInstance;
+  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance);
+
+  //
+  // Convert the base address of all the instances
+  //
+  Index       = 0;
+  while (Index < mFvbModuleGlobal->NumFv) {
+    EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase);
+    FwhInstance = (EFI_FW_VOL_INSTANCE *)
+      (
+        (UINTN) ((UINT8 *) FwhInstance) +
+        FwhInstance->VolumeHeader.HeaderLength +
+        (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+      );
+    Index++;
+  }
+
+  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);
+  RamFlashConvertPointers ();
+}
+
+
+VOID
+InstallVirtualAddressChangeHandler (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  VirtualAddressChangeEvent;
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  FvbVirtualAddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &VirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
new file mode 100644
index 00000000..6c3e613a
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
@@ -0,0 +1,144 @@
+/** @file
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include "RamFlash.h"
+
+UINT8 *mFlashBase;
+
+STATIC UINTN       mFdBlockSize = 0;
+STATIC UINTN       mFdBlockCount = 0;
+
+STATIC
+volatile UINT8*
+RamFlashPtr (
+  IN        EFI_LBA                             Lba,
+  IN        UINTN                               Offset
+  )
+{
+  return mFlashBase + ((UINTN)Lba * mFdBlockSize) + Offset;
+}
+
+/**
+  Read from Ram Flash
+
+  @param[in] Lba      The starting logical block index to read from.
+  @param[in] Offset   Offset into the block at which to begin reading.
+  @param[in] NumBytes On input, indicates the requested read size. On
+                      output, indicates the actual number of bytes read
+  @param[in] Buffer   Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+RamFlashRead (
+  IN        EFI_LBA                              Lba,
+  IN        UINTN                                Offset,
+  IN        UINTN                                *NumBytes,
+  IN        UINT8                                *Buffer
+  )
+{
+  UINT8  *Ptr;
+
+  //
+  // Only write to the first 64k. We don't bother saving the FTW Spare
+  // block into the flash memory.
+  //
+  if (Lba >= mFdBlockCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Get flash address
+  //
+  Ptr = (UINT8*) RamFlashPtr (Lba, Offset);
+
+  CopyMem (Buffer, Ptr, *NumBytes);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Write to Ram Flash
+
+  @param[in] Lba      The starting logical block index to write to.
+  @param[in] Offset   Offset into the block at which to begin writing.
+  @param[in] NumBytes On input, indicates the requested write size. On
+                      output, indicates the actual number of bytes written
+  @param[in] Buffer   Pointer to the data to write.
+
+**/
+EFI_STATUS
+RamFlashWrite (
+  IN        EFI_LBA                             Lba,
+  IN        UINTN                               Offset,
+  IN        UINTN                               *NumBytes,
+  IN        UINT8                               *Buffer
+  )
+{
+  volatile UINT8  *Ptr;
+  UINTN           Loop;
+
+  //
+  // Only write to the first 64k. We don't bother saving the FTW Spare
+  // block into the flash memory.
+  //
+  if (Lba >= mFdBlockCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Program flash
+  //
+  Ptr = RamFlashPtr (Lba, Offset);
+  for (Loop = 0; Loop < *NumBytes; Loop++) {
+    *Ptr = Buffer[Loop];
+    Ptr++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Erase a Ram Flash block
+
+  @param Lba    The logical block index to erase.
+
+**/
+EFI_STATUS
+RamFlashEraseBlock (
+  IN   EFI_LBA      Lba
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Initializes Ram flash memory support
+
+  @retval EFI_WRITE_PROTECTED   The Ram flash device is not present.
+  @retval EFI_SUCCESS           The Ram flash device is supported.
+
+**/
+EFI_STATUS
+RamFlashInitialize (
+  VOID
+  )
+{
+  mFlashBase = (UINT8*)(UINTN) PcdGet32 (PcdVariableFdBaseAddress);
+  mFdBlockSize = PcdGet32 (PcdVariableFdBlockSize);
+  ASSERT(PcdGet32 (PcdVariableFdSize) % mFdBlockSize == 0);
+  mFdBlockCount = PcdGet32 (PcdVariableFdSize) / mFdBlockSize;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
new file mode 100644
index 00000000..008c795e
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
@@ -0,0 +1,85 @@
+/** @file
+  Ram flash device for EFI variable
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _RAM_FLASH_H_
+#define _RAM_FLASH_H_
+
+#include <Protocol/FirmwareVolumeBlock.h>
+
+extern UINT8 *mFlashBase;
+
+/**
+  Read from Ram Flash
+
+  @param[in] Lba      The starting logical block index to read from.
+  @param[in] Offset   Offset into the block at which to begin reading.
+  @param[in] NumBytes On input, indicates the requested read size. On
+                      output, indicates the actual number of bytes read
+  @param[in] Buffer   Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+RamFlashRead (
+  IN        EFI_LBA                              Lba,
+  IN        UINTN                                Offset,
+  IN        UINTN                                *NumBytes,
+  IN        UINT8                                *Buffer
+  );
+
+
+/**
+  Write to Ram Flash
+
+  @param[in] Lba      The starting logical block index to write to.
+  @param[in] Offset   Offset into the block at which to begin writing.
+  @param[in] NumBytes On input, indicates the requested write size. On
+                      output, indicates the actual number of bytes written
+  @param[in] Buffer   Pointer to the data to write.
+
+**/
+EFI_STATUS
+RamFlashWrite (
+  IN        EFI_LBA                              Lba,
+  IN        UINTN                                Offset,
+  IN        UINTN                                *NumBytes,
+  IN        UINT8                                *Buffer
+  );
+
+
+/**
+  Erase a Ram Flash block
+
+  @param Lba    The logical block index to erase.
+
+**/
+EFI_STATUS
+RamFlashEraseBlock (
+  IN   EFI_LBA      Lba
+  );
+
+
+/**
+  Initializes Ram flash memory support
+
+  @retval EFI_WRITE_PROTECTED   The Ram flash device is not present.
+  @retval EFI_SUCCESS           The Ram flash device is supported.
+
+**/
+EFI_STATUS
+RamFlashInitialize (
+  VOID
+  );
+
+
+VOID
+RamFlashConvertPointers (
+  VOID
+  );
+
+#endif
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
new file mode 100644
index 00000000..a9d48637
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
@@ -0,0 +1,20 @@
+/** @file
+  Ram flash device for EFI variable
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiRuntimeLib.h>
+
+#include "RamFlash.h"
+
+VOID
+RamFlashConvertPointers (
+  VOID
+  )
+{
+  EfiConvertPointer (0x0, (VOID **) &mFlashBase);
+}
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (10 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-03 17:30   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM Gilbert Chen
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates Gilbert Chen
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Timer DXE driver for U500 platform based U500 platform implementation
 specifc timer registers.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c  | 311 +++++++++++++++++++++
 .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h  | 174 ++++++++++++
 .../U500Pkg/Universal/Dxe/TimerDxe/Timer.uni       |  14 +
 .../U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf    |  48 ++++
 .../U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni  |  12 +
 5 files changed, 559 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni

diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
new file mode 100644
index 00000000..5cb42943
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
@@ -0,0 +1,311 @@
+/** @file
+  RISC-V Timer Architectural Protocol for U500 platform.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Timer.h"
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi.h>
+#include <sbi/riscv_io.h>
+#include <sbi/riscv_atomic.h>
+
+#define CLINT_REG_MTIME     0x0200BFF8
+#define CLINT_REG_MTIMECMP0 0x02004000
+#define CLINT_REG_MTIMECMP1 0x02004008
+#define CLINT_REG_MTIMECMP2 0x02004010
+#define CLINT_REG_MTIMECMP3 0x02004018
+#define CLINT_REG_MTIMECMP4 0x02004020
+
+static volatile void * const p_mtime = (void *)CLINT_REG_MTIME;
+#define MTIME          (*p_mtime)
+#define MTIMECMP(i)    (p_mtimecmp[i])
+
+//
+// The handle onto which the Timer Architectural Protocol will be installed
+//
+EFI_HANDLE                mTimerHandle = NULL;
+
+//
+// The Timer Architectural Protocol that this driver produces
+//
+EFI_TIMER_ARCH_PROTOCOL   mTimer = {
+  TimerDriverRegisterHandler,
+  TimerDriverSetTimerPeriod,
+  TimerDriverGetTimerPeriod,
+  TimerDriverGenerateSoftInterrupt
+};
+
+//
+// Pointer to the CPU Architectural Protocol instance
+//
+EFI_CPU_ARCH_PROTOCOL     *mCpu;
+
+//
+// The notification function to call on every timer interrupt.
+// A bug in the compiler prevents us from initializing this here.
+//
+EFI_TIMER_NOTIFY mTimerNotifyFunction;
+
+//
+// The current period of the timer interrupt
+//
+volatile UINT64 mTimerPeriod = 0;
+
+
+/**
+  8254 Timer #0 Interrupt Handler.
+
+  @param InterruptType    The type of interrupt that occured
+  @param SystemContext    A pointer to the system context when the interrupt occured
+**/
+
+VOID
+EFIAPI
+TimerInterruptHandler (
+  IN EFI_EXCEPTION_TYPE   InterruptType,
+  IN EFI_SYSTEM_CONTEXT   SystemContext
+  )
+{
+  EFI_TPL OriginalTPL;
+  UINT64 RiscvTimer;
+
+  csr_clear(CSR_SIE, MIP_STIP); // enable timer int
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  if (mTimerPeriod == 0) {
+    gBS->RestoreTPL (OriginalTPL);
+    mCpu->DisableInterrupt(mCpu);
+    return;
+  }
+  if (mTimerNotifyFunction != NULL) {
+    mTimerNotifyFunction (mTimerPeriod);
+  }
+  gBS->RestoreTPL (OriginalTPL);
+
+
+  RiscvTimer = readq_relaxed(p_mtime);
+  sbi_set_timer(RiscvTimer += mTimerPeriod);
+  csr_set(CSR_SIE, MIP_STIP); // enable timer int
+
+}
+
+/**
+
+  This function registers the handler NotifyFunction so it is called every time
+  the timer interrupt fires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
+  returned.  If the CPU does not support registering a timer interrupt handler,
+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+  is returned.
+
+  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction   The function to call when a timer interrupt fires.  This
+                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
+                          register a handler for the timer interrupt, so it can know
+                          how much time has passed.  This information is used to
+                          signal timer based events.  NULL will unregister the handler.
+
+  @retval        EFI_SUCCESS            The timer handler was registered.
+  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
+  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
+                                        registered.
+  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
+                                        previously registered.
+  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", NotifyFunction));
+  mTimerNotifyFunction = NotifyFunction;
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  UINT64 RiscvTimer;
+
+  DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));
+
+  if (TimerPeriod == 0) {
+    mTimerPeriod = 0;
+    mCpu->DisableInterrupt(mCpu);
+    csr_clear(CSR_SIE, MIP_STIP); // disable timer int
+    return EFI_SUCCESS;
+  }
+
+  mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us
+
+  mCpu->EnableInterrupt(mCpu);
+  csr_set(CSR_SIE, MIP_STIP); // enable timer int
+
+  RiscvTimer = readq_relaxed(p_mtime);
+  sbi_set_timer(RiscvTimer + mTimerPeriod);
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
+                         0 is returned, then the timer is currently disabled.
+
+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+{
+  *TimerPeriod = mTimerPeriod;
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+
+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the Timer Architectural Protocol driver
+
+  @param ImageHandle     ImageHandle of the loaded driver
+  @param SystemTable     Pointer to the System Table
+
+  @retval EFI_SUCCESS            Timer Architectural Protocol created
+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initialize the pointer to our notify function.
+  //
+  mTimerNotifyFunction = NULL;
+
+  //
+  // Make sure the Timer Architectural Protocol is not already installed in the system
+  //
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
+
+  //
+  // Find the CPU architectural protocol.
+  //
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Force the timer to be disabled
+  //
+  Status = TimerDriverSetTimerPeriod (&mTimer, 0);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install interrupt handler for RISC-V Timer.
+  //
+  Status = mCpu->RegisterInterruptHandler (mCpu, EXCEPT_RISCV_TIMER_INT, TimerInterruptHandler);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Force the timer to be enabled at its default period
+  //
+  Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the Timer Architectural Protocol onto a new handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mTimerHandle,
+                  &gEfiTimerArchProtocolGuid, &mTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
new file mode 100644
index 00000000..3bfc415d
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
@@ -0,0 +1,174 @@
+/** @file
+  RISC-V Timer Architectural Protocol definitions for U500 platform,
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/Timer.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/RiscVCpuLib.h>
+
+//
+// RISC-V use 100us timer.
+// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units
+//
+#define DEFAULT_TIMER_TICK_DURATION 100000
+
+extern VOID RiscvSetTimerPeriod (UINT32 TimerPeriod);
+
+//
+// Function Prototypes
+//
+/**
+  Initialize the Timer Architectural Protocol driver
+
+  @param ImageHandle     ImageHandle of the loaded driver
+  @param SystemTable     Pointer to the System Table
+
+  @retval EFI_SUCCESS            Timer Architectural Protocol created
+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+;
+
+/**
+
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
+                         0 is returned, then the timer is currently disabled.
+
+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+;
+
+/**
+
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+
+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+;
+
+#endif
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
new file mode 100644
index 00000000..38302244
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
@@ -0,0 +1,14 @@
+// /** @file
+//
+// RISC-V Timer Arch protocol strings.
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "RISC-V timer driver that provides Timer Arch protocol"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "RISC-V timer driver that provides Timer Arch protocol."
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
new file mode 100644
index 00000000..f8af6889
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
@@ -0,0 +1,48 @@
+## @file
+# RISC-V Timer Arch protocol module for U500 platform
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Timer
+  MODULE_UNI_FILE                = Timer.uni
+  FILE_GUID                      = 3F75D495-23FF-46B6-9D19-0DECC8A4EA91
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TimerDriverInitialize
+
+[Packages]
+  MdePkg/MdePkg.dec
+  RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  BaseLib
+  DebugLib
+  UefiDriverEntryPoint
+  IoLib
+  RiscVCpuLib
+  RiscVOpensbiLib
+
+[Sources]
+  Timer.h
+  Timer.c
+
+[Protocols]
+  gEfiCpuArchProtocolGuid       ## CONSUMES
+  gEfiTimerArchProtocolGuid     ## PRODUCES
+
+[Pcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz
+
+[Depex]
+  gEfiCpuArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  TimerExtra.uni
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
new file mode 100644
index 00000000..cf25ff14
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
@@ -0,0 +1,12 @@
+// /** @file
+// Timer Localized Strings and Content
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"RISC-V Timer DXE Driver"
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (11 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-03 17:38   ` [edk2-devel] " Leif Lindholm
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates Gilbert Chen
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

This is the platform-implementation specific library which is executed
 in early PEI phase for platform initialization.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c  |  49 ++++
 .../U500Pkg/Universal/Pei/PlatformPei/MemDetect.c  |  74 +++++
 .../U500Pkg/Universal/Pei/PlatformPei/Platform.c   | 313 +++++++++++++++++++++
 .../U500Pkg/Universal/Pei/PlatformPei/Platform.h   |  92 ++++++
 .../Universal/Pei/PlatformPei/PlatformPei.inf      |  75 +++++
 5 files changed, 603 insertions(+)
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf

diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
new file mode 100644
index 00000000..74e4d433
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
@@ -0,0 +1,49 @@
+/** @file
+  Build FV related hobs for platform.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiPei.h"
+#include "Platform.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+/**
+  Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
+  and DXE know about them.
+
+  @retval EFI_SUCCESS   Platform PEI FVs were initialized successfully.
+
+**/
+EFI_STATUS
+PeiFvInitialization (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n"));
+  //
+  // Let DXE know about the DXE FV
+  //
+  BuildFvHob (PcdGet32 (PcdRiscVDxeFvBase), PcdGet32 (PcdRiscVDxeFvSize));
+  DEBUG ((DEBUG_INFO, "Platform builds DXE FV at %x, size %x.\n", PcdGet32 (PcdRiscVDxeFvBase), PcdGet32 (PcdRiscVDxeFvSize)));
+
+  //
+  // Let PEI know about the DXE FV so it can find the DXE Core
+  //
+  PeiServicesInstallFvInfoPpi (
+    NULL,
+    (VOID *)(UINTN) PcdGet32 (PcdRiscVDxeFvBase),
+    PcdGet32 (PcdRiscVDxeFvSize),
+    NULL,
+    NULL
+    );
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
new file mode 100644
index 00000000..dc99f2e0
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
@@ -0,0 +1,74 @@
+/**@file
+  Memory Detection for Virtual Machines.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+
+#include "Platform.h"
+
+
+/**
+  Publish PEI core memory
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+PublishPeiMemory (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        MemoryBase;
+  UINT64                      MemorySize;
+
+  MemoryBase = 0x80000000UL + 0x1000000UL;
+  MemorySize = 0x40000000UL - 0x1000000UL; //1GB - 16MB
+
+  DEBUG((DEBUG_INFO, "%a: MemoryBase:0x%x MemorySize:%d\n", __FUNCTION__, MemoryBase, MemorySize));
+
+  //
+  // Publish this memory to the PEI Core
+  //
+  Status = PublishSystemMemory(MemoryBase, MemorySize);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+  VOID
+  )
+{
+  AddMemoryRangeHob(0x81000000UL, 0x81000000UL + 0x3F000000UL);
+
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
new file mode 100644
index 00000000..45356399
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
@@ -0,0 +1,313 @@
+/**@file
+  Platform PEI driver
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/MasterBootMode.h>
+#include <IndustryStandard/Pci22.h>
+
+#include <SiFiveU5MCCoreplex.h>
+
+#include "Platform.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+  { EfiACPIMemoryNVS,       0x004 },
+  { EfiACPIReclaimMemory,   0x008 },
+  { EfiReservedMemoryType,  0x004 },
+  { EfiRuntimeServicesData, 0x024 },
+  { EfiRuntimeServicesCode, 0x030 },
+  { EfiBootServicesCode,    0x180 },
+  { EfiBootServicesData,    0xF00 },
+  { EfiMaxMemoryType,       0x000 }
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiMasterBootModePpiGuid,
+    NULL
+  }
+};
+
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+BOOLEAN mS3Supported = FALSE;
+
+
+VOID
+AddIoMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+AddIoMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  )
+{
+  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  )
+{
+  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+AddUntestedMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  )
+{
+  AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+VOID
+AddPciResource (
+  VOID
+  )
+{
+  //
+  // Platform-specific
+  //
+}
+
+VOID
+MemMapInitialization (
+  VOID
+  )
+{
+  //
+  // Create Memory Type Information HOB
+  //
+  BuildGuidDataHob (
+    &gEfiMemoryTypeInformationGuid,
+    mDefaultMemoryTypeInformation,
+    sizeof(mDefaultMemoryTypeInformation)
+    );
+
+  //
+  // Add PCI IO Port space available for PCI resource allocations.
+  //
+  AddPciResource ();
+}
+
+VOID
+MiscInitialization (
+  VOID
+  )
+{
+  //
+  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
+  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
+  // S3 resume as well, so we build it unconditionally.)
+  //
+  BuildCpuHob (32, 32);
+}
+
+/**
+  Check if system retunrs from S3.
+
+  @return BOOLEAN   TRUE, system returned from S3
+                    FALSE, system is not returned from S3
+
+**/
+BOOLEAN
+CheckResumeFromS3 (
+  VOID
+  )
+{
+  //
+  //Platform implementation-specific
+  //
+  return FALSE;
+}
+
+
+VOID
+BootModeInitialization (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  if (CheckResumeFromS3 () == TRUE) {
+    DEBUG ((DEBUG_INFO, "This is wake from S3\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "This is normal boot\n"));
+  }
+  Status = PeiServicesSetBootMode (mBootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesInstallPpi (mPpiBootMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Build processor information for U54 Coreplex processor.
+
+  @return EFI_SUCCESS     Status.
+
+**/
+EFI_STATUS
+BuildCoreInformationHob (
+  VOID
+)
+{
+  EFI_STATUS Status;
+  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosHobPtr;
+
+  Status = CreateU5MCCoreplexProcessorSpecificDataHob (0);
+  if (EFI_ERROR (Status)) {
+    ASSERT(FALSE);
+  }
+  Status = CreateU5MCProcessorSmbiosDataHob(0, &SmbiosHobPtr);
+  if (EFI_ERROR (Status)) {
+    ASSERT(FALSE);
+  }
+
+  DEBUG ((DEBUG_INFO, "U5 MC Coreplex SMBIOS DATA HOB at address 0x%x\n", SmbiosHobPtr));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Perform Platform PEI initialization.
+
+  @param  FileHandle      Handle of the file being invoked.
+  @param  PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatform (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS Status;
+
+  DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
+
+  BootModeInitialization ();
+  DEBUG ((DEBUG_INFO, "Platform BOOT mode initiated.\n"));
+  PublishPeiMemory ();
+  DEBUG ((DEBUG_INFO, "PEI memory published.\n"));
+  InitializeRamRegions ();
+  DEBUG ((DEBUG_INFO, "Platform RAM regions initiated.\n"));
+
+  if (mBootMode != BOOT_ON_S3_RESUME) {
+    PeiFvInitialization ();
+    MemMapInitialization ();
+  }
+
+  MiscInitialization ();
+  Status = BuildCoreInformationHob ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to build processor informstion HOB.\n"));
+    ASSERT(FALSE);
+  }
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
new file mode 100644
index 00000000..23600203
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
@@ -0,0 +1,92 @@
+/** @file
+  Platform PEI module include file.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_PEI_H_INCLUDED_
+#define _PLATFORM_PEI_H_INCLUDED_
+
+VOID
+AddIoMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddIoMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  );
+
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  );
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddUntestedMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  );
+
+VOID
+AddressWidthInitialization (
+  VOID
+  );
+
+EFI_STATUS
+PublishPeiMemory (
+  VOID
+  );
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+  VOID
+  );
+
+VOID
+InitializeRamRegions (
+  VOID
+  );
+
+EFI_STATUS
+PeiFvInitialization (
+  VOID
+  );
+
+EFI_STATUS
+InitializeXen (
+  VOID
+  );
+
+extern EFI_BOOT_MODE mBootMode;
+
+extern BOOLEAN mS3Supported;
+
+extern UINT8 mPhysMemAddressWidth;
+
+#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
new file mode 100644
index 00000000..420b0702
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
@@ -0,0 +1,75 @@
+## @file
+#  Platform PEI driver
+#
+#  This module provides platform specific function to detect boot mode.
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformPei
+  FILE_GUID                      = 222c386d-5abc-4fb4-b124-fbb82488acf4
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializePlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC RISCV64
+#
+
+[Sources]
+  Fv.c
+  MemDetect.c
+  Platform.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  RiscVPkg/RiscVPkg.dec
+  Platform/RiscV/RiscVPlatformPkg.dec
+  Silicon/SiFive/SiFive.dec
+  Platform/RiscV/SiFive/U500Pkg/U500.dec
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  IoLib
+  PciLib
+  PeiResourcePublicationLib
+  PeiServicesLib
+  PeiServicesTablePointerLib
+  PeimEntryPoint
+  PcdLib
+  SiliconSiFiveU5MCCoreplexInfoLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize
+
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
+  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
+
+
+[Ppis]
+  gEfiPeiMasterBootModePpiGuid
+
+[Depex]
+  TRUE
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates
  2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
                   ` (12 preceding siblings ...)
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM Gilbert Chen
@ 2019-09-19  3:51 ` Gilbert Chen
  2019-10-03 17:45   ` [edk2-devel] " Leif Lindholm
  13 siblings, 1 reply; 43+ messages in thread
From: Gilbert Chen @ 2019-09-19  3:51 UTC (permalink / raw)
  To: devel

Update Readme.md and Maintainers.txt for RISV-V platforms.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 Maintainers.txt |  9 +++++++++
 Readme.md       | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index 876ae561..c494c9d5 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -108,6 +108,11 @@ R: Marcin Wojtas <mw@semihalf.com>
 Platform/SolidRun/Armada80x0McBin
 R: Marcin Wojtas <mw@semihalf.com>
 
+Platform/RiscV
+Platform/RiscV/SiFive/U500Pkg
+R: Abner Chang <abner.chang@hpe.com>
+R: Gilbert Chen <gilbert.chen@hpe.com>
+
 Silicon
 M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
 M: Leif Lindholm <leif.lindholm@linaro.org>
@@ -151,3 +156,7 @@ M: Liming Gao <liming.gao@intel.com>
 
 Silicon/Marvell
 R: Marcin Wojtas <mw@semihalf.com>
+
+Silicon/SiFive
+R: Abner Chang <abner.chang@hpe.com>
+R: Gilbert Chen <gilbert.chen@hpe.com>
diff --git a/Readme.md b/Readme.md
index 63e59f60..0395e20a 100644
--- a/Readme.md
+++ b/Readme.md
@@ -52,6 +52,7 @@ ARM                 | arm-linux-gnueabihf-
 IA32                | i?86-linux-gnu-* _or_ x86_64-linux-gnu-
 IPF                 | ia64-linux-gnu
 X64                 | x86_64-linux-gnu-
+RISCV64             | riscv64-unknown-elf-
 
 \* i386, i486, i586 or i686
 
@@ -62,6 +63,12 @@ and [arm-linux-gnueabihf](https://releases.linaro.org/components/toolchain/binar
 compiled to run on x86_64/i686 Linux and i686 Windows. Some Linux distributions
 provide their own packaged cross-toolchains.
 
+### GCC for RISC-V
+RISC-V open source community provides GCC toolchains for
+[riscv64-unknown-elf](https://github.com/riscv/riscv-gnu-toolchain)
+compiled to run on x86 Linux. The commit ID 64879b24 is verified to build RISC-V EDK2 platform and boot to EFI
+SHELL successfully.
+
 ### clang
 Clang does not require separate cross compilers, but it does need a
 target-specific binutils. These are included with any prepackaged GCC toolchain
@@ -243,6 +250,10 @@ For more information, see the
 ## Raspberry Pi
 * [Pi 3](Platform/RaspberryPi/RPi3)
 
+## RISC-V
+### SiFive
+* [Freedom U500 VC707 FPGA](Platform/RiscV/SiFive/U500Pkg)
+
 ## Socionext
 * [SynQuacer](Platform/Socionext/DeveloperBox)
 
-- 
2.12.0.windows.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package Gilbert Chen
@ 2019-10-01  0:41   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-01  0:41 UTC (permalink / raw)
  To: devel, gilbert.chen

On Thu, Sep 19, 2019 at 11:51:18AM +0800, Gilbert Chen wrote:
> Add SiFive silicon EDK2 metafile and header files of
>  SiFive RISC-V cores.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  Silicon/SiFive/Include/Library/SiFiveE51.h         | 60 ++++++++++++++++++++++
>  Silicon/SiFive/Include/Library/SiFiveU54.h         | 60 ++++++++++++++++++++++
>  .../SiFive/Include/Library/SiFiveU54MCCoreplex.h   | 55 ++++++++++++++++++++
>  Silicon/SiFive/SiFive.dec                          | 39 ++++++++++++++
>  4 files changed, 214 insertions(+)
>  create mode 100644 Silicon/SiFive/Include/Library/SiFiveE51.h
>  create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54.h
>  create mode 100644 Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
>  create mode 100644 Silicon/SiFive/SiFive.dec

Hmm, this seems a bit sideways to me.
This patch adds the headers for 3 different libraries. The subsequent
patch adds the code for those 3 different libraries.

Heck, this is an initial bootstrap of several new platforms, I would
even take all 3 libraries (with headers) as a single patch.

But there is a greater issue here which I will cover in more detail in
reply to the next patch; these are 3 near-identical libraries
fulfilling the same function given their own global header files and
each implementing their own library class.

> 
> diff --git a/Silicon/SiFive/Include/Library/SiFiveE51.h b/Silicon/SiFive/Include/Library/SiFiveE51.h
> new file mode 100644
> index 00000000..5faea5c7
> --- /dev/null
> +++ b/Silicon/SiFive/Include/Library/SiFiveE51.h
> @@ -0,0 +1,60 @@
> +/** @file
> +  SiFive E51 Core library definitions.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SIFIVE_E51_CORE_H_
> +#define _SIFIVE_E51_CORE_H_

Please drop leading _.
This applies to all header files throughout the set.
I will not point each one out.

> +
> +#include <PiPei.h>
> +
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>
> +
> +/**
> +  Function to build core specific information HOB.
> +
> +  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
> +                                 could be the same as CoreGuid if one processor has
> +                                 only one core.
> +  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
> +  @param  HartId                 Hart ID of this core.
> +  @param  IsBootHart             TRUE means this is the boot HART.
> +  @param  GuidHobData            Pointer to receive RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateE51CoreProcessorSpecificDataHob (
> +  IN EFI_GUID  *ParentProcessorGuid,
> +  IN UINTN     ParentProcessorUid,
> +  IN UINTN     HartId,
> +  IN BOOLEAN   IsBootHart,
> +  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobData
> +  );
> +
> +/**
> +  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
> +  this information and build SMBIOS Type4 and Type7 record.
> +
> +  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
> +  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> +                          maintained in this structure is only valid before memory is discovered.
> +                          Access to those pointers after memory is installed will cause unexpected issues.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateE51ProcessorSmbiosDataHob (
> +  IN UINTN     ProcessorUid,
> +  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> +  );
> +
> +#endif
> diff --git a/Silicon/SiFive/Include/Library/SiFiveU54.h b/Silicon/SiFive/Include/Library/SiFiveU54.h
> new file mode 100644
> index 00000000..2e3a1c75
> --- /dev/null
> +++ b/Silicon/SiFive/Include/Library/SiFiveU54.h
> @@ -0,0 +1,60 @@
> +/** @file
> +  SiFive U54 Core library definitions.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SIFIVE_U54_CORE_H_
> +#define _SIFIVE_U54_CORE_H_
> +
> +#include <PiPei.h>
> +
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>
> +
> +/**
> +  Function to build core specific information HOB.
> +
> +  @param  ParentProcessorGuid    Parent processor od this core. ParentProcessorGuid
> +                                 could be the same as CoreGuid if one processor has
> +                                 only one core.
> +  @param  ParentProcessorUid     Unique ID of pysical processor which owns this core.
> +  @param  HartId                 Hart ID of this core.
> +  @param  IsBootHart             TRUE means this is the boot HART.
> +  @param  GuidHobdata            Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU54CoreProcessorSpecificDataHob (
> +  IN EFI_GUID  *ParentProcessorGuid,
> +  IN UINTN     ParentProcessorUid,
> +  IN UINTN     HartId,
> +  IN BOOLEAN   IsBootHart,
> +  OUT RISC_V_PROCESSOR_SPECIFIC_DATA_HOB **GuidHobdata
> +  );
> +
> +/**
> +  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
> +  this information and build SMBIOS Type4 and Type7 record.
> +
> +  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
> +  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> +                          maintained in this structure is only valid before memory is discovered.
> +                          Access to those pointers after memory is installed will cause unexpected issues.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU54ProcessorSmbiosDataHob (
> +  IN UINTN     ProcessorUid,
> +  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> +  );
> +
> +#endif
> diff --git a/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h b/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
> new file mode 100644
> index 00000000..3d23b34c
> --- /dev/null
> +++ b/Silicon/SiFive/Include/Library/SiFiveU54MCCoreplex.h
> @@ -0,0 +1,55 @@
> +/** @file
> +  SiFive U54 Coreplex library definitions.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SIFIVE_U54MC_COREPLEX_CORE_H_
> +#define _SIFIVE_U54MC_COREPLEX_CORE_H_
> +
> +#include <PiPei.h>
> +
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>
> +
> +#define SIFIVE_U54MC_COREPLEX_E51_HART_ID     0
> +#define SIFIVE_U54MC_COREPLEX_U54_0_HART_ID   1
> +#define SIFIVE_U54MC_COREPLEX_U54_1_HART_ID   2
> +#define SIFIVE_U54MC_COREPLEX_U54_2_HART_ID   3
> +#define SIFIVE_U54MC_COREPLEX_U54_3_HART_ID   4
> +
> +/**
> +  Build up U54MC coreplex processor core-specific information.
> +
> +  @param  UniqueId      U54MC unique ID.
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU54MCCoreplexProcessorSpecificDataHob (
> +  IN UINTN UniqueId
> +  );
> +
> +/**
> +  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
> +  this information and build SMBIOS Type4 and Type7 record.
> +
> +  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
> +  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> +                          maintained in this structure is only valid before memory is discovered.
> +                          Access to those pointers after memory is installed will cause unexpected issues.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU54MCProcessorSmbiosDataHob (
> +  IN UINTN     ProcessorUid,
> +  IN RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> +  );
> +#endif
> diff --git a/Silicon/SiFive/SiFive.dec b/Silicon/SiFive/SiFive.dec
> new file mode 100644
> index 00000000..7aca3e75
> --- /dev/null
> +++ b/Silicon/SiFive/SiFive.dec
> @@ -0,0 +1,39 @@
> +## @file
> +#  SiFive silicon package definitions
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005

Please use the current specification version, unless you have need of
building with an older version of BaseTools. (In which case, use that
specification version.)

> +  PACKAGE_NAME                   = SiFiveSiliconPkg
> +  PACKAGE_GUID                   = 576912B2-7077-4B78-A934-4C133FEB20BB
> +  PACKAGE_VERSION                = 1.0
> +
> +[Includes]
> +  Include                        # Root include for the package
> +
> +[LibraryClasses]
> +
> +[Guids]
> +  gEfiSiFiveSiliconSpaceGuid  = {0x5F3E9E15, 0x8FFC, 0x4F53, { 0x8E, 0x64, 0x92, 0x0B, 0xA5, 0x39, 0x81, 0xB0 }}

TokenSpaceGuid, not just SpaceGuid.

/
    Leif

> +
> +[Protocols]
> +
> +[PcdsFixedAtBuild]
> +  # E51 Core GUID
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid |{0xD4, 0x69, 0x54, 0x87, 0x96, 0x96, 0x48, 0x7F, 0x9F, 0x57, 0xB6, 0xF1, 0xDE, 0x7D, 0x97, 0x42}|VOID*|0x00001000
> +  # U54 Core GUID
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid |{0x64, 0x70, 0xF6, 0x90, 0x11, 0x59, 0x47, 0xF1, 0xB8, 0xD5, 0xCF, 0x89, 0x10, 0xC5, 0x30, 0x20}|VOID*|0x00001001
> +  # U54 MC Coreplex GUID
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54MCCoreplexGuid |{0x67, 0xBF, 0x15, 0xD9, 0x7E, 0x4F, 0x48, 0x27, 0x87, 0x19, 0x79, 0x0B, 0xA6, 0x22, 0x7C, 0xBE}|VOID*|0x00001002
> +  # U5 MC Coreplex GUID
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid |{0x06, 0x38, 0x9F, 0x33, 0xF9, 0xDB, 0x43, 0x13, 0x9A, 0x9B, 0x1C, 0x68, 0xD6, 0x04, 0xEA, 0xFF}|VOID*|0x00001003
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> +[PcdsFeatureFlag]
> +
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores Gilbert Chen
@ 2019-10-01 21:14   ` Leif Lindholm
  2019-10-16  1:36     ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-01 21:14 UTC (permalink / raw)
  To: devel, gilbert.chen

On Thu, Sep 19, 2019 at 11:51:19AM +0800, Gilbert Chen wrote:
> Initial version of SiFive RISC-V core libraries. Library of each core
>  creates processor core SMBIOS data hob for building SMBIOS
>  records in DXE phase.

So yes, this implementation needs to change.
These should all implement the same LibraryClass.
Also, U54 appears to be a simple superset of U51.

What I would suggest is creating a
Silicon/SiFive/Library/SiFiveCoreInfoLib, which calls into a
SiFiveSoCCoreInfoLib in Silicon/SiFive/<SoC>/Library, providing the
acual SoC-specific bits.

/
    Leif

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 242 +++++++++++++++++
>  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
>  .../U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 294 +++++++++++++++++++++
>  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
>  .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 185 +++++++++++++
>  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  50 ++++
>  6 files changed, 873 insertions(+)
>  create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
>  create mode 100644 Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
>  create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
>  create mode 100644 Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
>  create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
>  create mode 100644 Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package Gilbert Chen
@ 2019-10-02  9:07   ` Leif Lindholm
  2019-10-15 15:24     ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02  9:07 UTC (permalink / raw)
  To: devel, gilbert.chen

On Thu, Sep 19, 2019 at 11:51:20AM +0800, Gilbert Chen wrote:
> Initial version of RISC-V platform package which provides the common
>  libraries, drivers, PCD and etc. for RISC-V platform development.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  Platform/RiscV/Readme.md                 | 89 ++++++++++++++++++++++++++++++++
>  Platform/RiscV/RiscVPlatformPkg.dec      | 72 ++++++++++++++++++++++++++
>  Platform/RiscV/RiscVPlatformPkg.uni      | 15 ++++++
>  Platform/RiscV/RiscVPlatformPkgExtra.uni | 12 +++++
>  4 files changed, 188 insertions(+)
>  create mode 100644 Platform/RiscV/Readme.md
>  create mode 100644 Platform/RiscV/RiscVPlatformPkg.dec
>  create mode 100644 Platform/RiscV/RiscVPlatformPkg.uni
>  create mode 100644 Platform/RiscV/RiscVPlatformPkgExtra.uni
> 
> diff --git a/Platform/RiscV/Readme.md b/Platform/RiscV/Readme.md
> new file mode 100644
> index 00000000..277782e3
> --- /dev/null
> +++ b/Platform/RiscV/Readme.md

Please also add a link to this file from the top-level Readme.md.
High up since this is intended for a branch specifically for this.

> @@ -0,0 +1,89 @@
> +# Introduction
> +
> +## EDK2 RISC-V Platform Package
> +RISC-V platform package provides the generic and common modules for RISC-V platforms. RISC-V platform package could include RiscPlatformPkg.dec to use the common drivers, libraries, definitions, PCDs and etc. for the platform development.

Please wrap lines at max 80 characters.

> +
> +## EDK2 RISC-V Platforms
> +RISC-V platform is created and maintained by RISC-V platform vendors. The directory of RISC-V platform should be created under Platform/RiscV. Vendor should create the folder under Platform/RiscV and name it using vendor name, under the vendor folder is the platform folder named by platform model name, code name or etc. (e.g. Platform/RiscV/SiFive/U500Pkg)
> +
> +## Build EDK2 RISC-V Platforms
> +RISC-V platform package should provide EDK2 metafiles under RISC-V platform package folder (Platform/RiscV/{Vendor}/{Platform}). Build RISC-V platform package against edk2 and follow the build guidence mentioned in Readme.md under below link.<br>

OK, so we reach this topic here for the first time.
We don't have a Platforms/ARM and we don't have a Platforms/X86, so I
don't want to see a Platforms/RiscV. The paths should be
Platforms/Vendor. I will comment on the patch adding the code where
the content currently there should go.

> +https://github.com/tianocore/edk2-platforms<br>
> +
> +### Download the sources ###
> +```
> +git clone https://github.com/tianocore/edk2-staging.git
> +# Checkout RISC-V-V2 branch
> +git clone https://github.com/tianocore/edk2-platforms.git
> +# Checkout devel-riscv-v2 branch
> +git clone https://github.com/tianocore/edk2-non-osi.git
> +```
> +
> +### Requirements
> +Build EDK2 RISC-V platform requires GCC RISC-V toolchain. Refer to https://github.com/riscv/riscv-gnu-toolchain for the details.

Please add all of the missing details I pointed out for the Readme.md
on the edks-staging branch.

> +The commit ID 64879b24 is verified to build RISC-V EDK2 platform and boot to EFI SHELL successfully.
> +
> +### EDK2 project
> +Currently, the EDK2 RISC-V platform can only build with edk2 project in **edk2-staging/RISC-V-V2** branch. The build architecture whcih is supported and verified so far is "RISCV64". The verified RISC-V toolchain is https://github.com/riscv/riscv-gnu-toolchain @64879b24, toolchain tag is "GCCRISCV" declared in tools_def.txt<br>

It's GCC5 now, not GCCRISCV.

> +
> +### Linux Build Instructions
> +You can build the RISC-V platform using below script, <br>
> +`build -a RISCV64 -p Platform/{Vendor}/{Platform}/{Platform}.dsc -t GCCRISCV`
> +
> +Or modify target.txt to set up your build parameters.

Which target.txt?

> +
> +## RISC-V Platform PCD settings
> +### EDK2 Firmware Volume Settings
> +EDK2 Firmware volume related PCDs which declared in platform FDF file.
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdRiscVSecFvBase| The base address of SEC Firmware Volume|
> +|PcdRiscVSecFvSize| The size of SEC Firmware Volume|
> +|PcdRiscVPeiFvBase| The base address of SEC Firmware Volume|
> +|PcdRiscVPeiFvSize| The size of SEC Firmware Volume|

PEI Firmware Volume

> +|PcdRiscVDxeFvBase| The base address of SEC Firmware Volume|
> +|PcdRiscVDxeFvSize| The size of SEC Firmware Volume|

DXE Firmware Volume

> +
> +### EDK2 EFI Variable Region Settings
> +The PCD settings regard to EFI Variable
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdVariableFdBaseAddress| The EFI variable firmware device base address|
> +|PcdVariableFdSize| The EFI variable firmware device size|
> +|PcdVariableFdBlockSize| The block size of EFI variable firmware device|
> +|PcdPlatformFlashNvStorageVariableBase| EFI variable base address within firmware device|
> +|PcdPlatformFlashNvStorageFtwWorkingBase| The base address of EFI variable fault tolerance worksapce (FTW) within firmware device|
> +|PcdPlatformFlashNvStorageFtwSpareBase| The base address of EFI variable spare FTW within firmware device|
> +
> +### RISC-V Physical Memory Protection (PMP) Region Settings
> +Below PCDs could be set in platform FDF file.
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdFwStartAddress| The starting address of firmware region to protected by PMP|
> +|PcdFwEndAddress| The ending address of firmware region to protected by PMP|
> +
> +### RISC-V Processor HART Settings
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdHartCount| Number of RISC-V HARTs, the value is processor-implementation specific|
> +|PcdBootHartId| The ID of RISC-V HART to execute main fimrware code and boot system to OS|
> +
> +### RISC-V OpenSBI Settings
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdScratchRamBase| The base address of OpenSBI scratch buffer for all RISC-V HARTs|
> +|PcdScratchRamSize| The total size of OpenSBI scratch buffer for all RISC-V HARTs|
> +|PcdOpenSbiStackSize| The size of initial stack of each RISC-V HART for booting system use OpenSBI|
> +|PcdTemporaryRamBase| The base address of temporary memory for PEI phase|
> +|PcdTemporaryRamSize| The temporary memory size for PEI phase|
> +
> +## Supported Operating Systems
> +Only support to boot to EFI Shell so far
> +
> +## Known Issues and Limitations
> +Only RISC-V RV64 is verified
> diff --git a/Platform/RiscV/RiscVPlatformPkg.dec b/Platform/RiscV/RiscVPlatformPkg.dec
> new file mode 100644
> index 00000000..3ce16bfc
> --- /dev/null
> +++ b/Platform/RiscV/RiscVPlatformPkg.dec

I think all of this content should either go into:
Silicon/SiFive/SiFive.dec
or
<edk2>/RiscVPkg/RiscVPkg.dec

/
    Leif

> @@ -0,0 +1,72 @@
> +## @file  RiscVPlatformPkg.dec
> +# This Package provides UEFI RISC-V platform modules and libraries.
> +#
> +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005
> +  PACKAGE_NAME                   = RiscPlatformPkg
> +  PACKAGE_UNI_FILE               = RiscPlatformPkg.uni
> +  PACKAGE_GUID                   = 6A67AF99-4592-40F8-B6BE-62BCA10DA1EC
> +  PACKAGE_VERSION                = 1.0
> +
> +[Includes]
> +  Include
> +
> +[LibraryClasses]
> +
> +[LibraryClasses.RISCV32, LibraryClasses.RISCV64]
> +
> +[Guids]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid  = {0x6A67AF99, 0x4592, 0x40F8, { 0xB6, 0xBE, 0x62, 0xBC, 0xA1, 0x0D, 0xA1, 0xEC}}
> +
> +[PcdsFixedAtBuild]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|0x0|UINT32|0x00001000
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize|0x0|UINT32|0x00001001
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|0x0|UINT32|0x00001002
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize|0x0|UINT32|0x00001003
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|0x0|UINT32|0x00001004
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize|0x0|UINT32|0x00001005
> +
> +#
> +# Definition of EFI Variable region
> +#
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress|0|UINT32|0x00001010
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize|0|UINT32|0x00001011
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize|0|UINT32|0x00001012
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase|0|UINT32|0x00001013
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase|0|UINT32|0x00001014
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|0|UINT32|0x00001015
> +#
> +# Firmware region which is protected by PMP.
> +#
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwBlockSize|0|UINT32|0x00001020
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress|0|UINT32|0x00001021
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress|0|UINT32|0x00001022
> +#
> +# Definition of RISC-V Hart
> +#
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount|0|UINT32|0x00001023
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId|0|UINT32|0x00001024
> +#
> +# Definitions for OpenSbi
> +#
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase|0|UINT32|0x00001025
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize|0|UINT32|0x00001026
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize|0|UINT32|0x00001027
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase|0|UINT32|0x00001028
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize|0|UINT32|0x00001029
> +
> +[PcdsPatchableInModule]
> +
> +[PcdsFeatureFlag]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable|FALSE|BOOLEAN|0x00001006
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  RiscVPlatformPkgExtra.uni
> diff --git a/Platform/RiscV/RiscVPlatformPkg.uni b/Platform/RiscV/RiscVPlatformPkg.uni
> new file mode 100644
> index 00000000..deb91fa1
> --- /dev/null
> +++ b/Platform/RiscV/RiscVPlatformPkg.uni
> @@ -0,0 +1,15 @@
> +// /** @file
> +// RISC-V Package Localized Strings and Content.
> +//
> +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_PACKAGE_ABSTRACT            #language en-US "Provides UEFI compatible RISC-V platform modules and libraries"
> +
> +#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package provides UEFI compatible RISC-V platform modules and libraries."
> +
> +
> diff --git a/Platform/RiscV/RiscVPlatformPkgExtra.uni b/Platform/RiscV/RiscVPlatformPkgExtra.uni
> new file mode 100644
> index 00000000..98d81aed
> --- /dev/null
> +++ b/Platform/RiscV/RiscVPlatformPkgExtra.uni
> @@ -0,0 +1,12 @@
> +// /** @file
> +// RISC-V Package Localized Strings and Content.
> +//
> +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_PACKAGE_NAME
> +#language en-US
> +"RiscV platform package"
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in RISC-V platform package
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in " Gilbert Chen
@ 2019-10-02 16:46   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 16:46 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:21AM +0800, Gilbert Chen wrote:
> FirmwareContextProcessorSpecificLib.h
> - The difinitions of Firmware Context EDK2 implementaion based on
>  RISC-V OpenSBI.

Typos:
difinitions ->
definitions
implementaion ->
implementation

> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../Library/FirmwareContextProcessorSpecificLib.h  | 40 ++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
>  create mode 100644 Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
> 
> diff --git a/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h b/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
> new file mode 100644
> index 00000000..772a0783
> --- /dev/null
> +++ b/Platform/RiscV/Include/Library/FirmwareContextProcessorSpecificLib.h
> @@ -0,0 +1,40 @@
> +/** @file
> +  Firmware Context Processor-specific common library
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _FIRMWARE_CONTEXT_PROCESSOR_SPECIFIC_LIB_H_
> +#define _FIRMWARE_CONTEXT_PROCESSOR_SPECIFIC_LIB_H_

Please drop leading _.

/
    Leif

> +
> +#include <PiPei.h>
> +
> +/**
> +  Build up common firmware context processor-specific information
> +
> +  @param  FirmwareContextHartSpecific  Pointer to EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> +  @param  ParentProcessorGuid          Pointer to GUID of Processor which contains this core
> +  @param  ParentProcessorUid           Unique ID of pysical processor which owns this core.
> +  @param  CoreGuid                     Pointer to GUID of core
> +  @param  HartId                       Hart ID of this core.
> +  @param  IsBootHart                   This is boot hart or not
> +  @param  ProcessorSpecDataHob         Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CommonFirmwareContextHartSpecificInfo (
> +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific,
> +  EFI_GUID  *ParentProcessorGuid,
> +  UINTN     ParentProcessorUid,
> +  EFI_GUID  *CoreGuid,
> +  UINTN     HartId,
> +  BOOLEAN   IsBootHart,
> +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob
> +  );
> +
> +#endif
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced in RISC-V platform package
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced " Gilbert Chen
@ 2019-10-02 17:04   ` Leif Lindholm
  2019-10-15 15:26     ` Abner Chang
  2019-10-18  5:23     ` Abner Chang
  0 siblings, 2 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 17:04 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:22AM +0800, Gilbert Chen wrote:
> FirmwareContextProcessorSpecificLib
> - Common library to consume EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
>  and build up processor specific data HOB.
> 
> RealTimClockLibNull
> - NULL instance of Real Time Clock library.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../FirmwareContextProcessorSpecificLib.c          |  82 +++++++++
>  .../FirmwareContextProcessorSpecificLib.inf        |  33 ++++
>  .../RealTimeClockLibNull/RealTimeClockLibNull.c    | 204 +++++++++++++++++++++
>  .../RealTimeClockLibNull/RealTimeClockLibNull.inf  |  30 +++

I think you can replace this NULL RealTimeClockLib implementation with
EmbeddedPkg/Library/VirtualRealTimeClockLib/ (which did not exist at
the time of the original port).

>  4 files changed, 349 insertions(+)
>  create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
>  create mode 100644 Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
>  create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
>  create mode 100644 Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
> 
> diff --git a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
> new file mode 100644
> index 00000000..4d4c51dc
> --- /dev/null
> +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.c
> @@ -0,0 +1,82 @@
> +/**@file
> +  Common library to build upfirmware context processor-specific information
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/BaseMemoryLib.h>

Please sort these includes alphabetically.

> +
> +#include <RiscV.h>
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>

Please sort these includes alphabetically.

> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi.h>
> +#include <sbi/SbiFirmwareContext.h>
> +
> +/**
> +  Build up common firmware context processor-specific information
> +
> +  @param  FirmwareContextHartSpecific  Pointer to EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> +  @param  ParentProcessorGuid          Pointer to GUID of Processor which contains this core
> +  @param  ParentProcessorUid           Unique ID of pysical processor which owns this core.
> +  @param  CoreGuid                     Pointer to GUID of core
> +  @param  HartId                       Hart ID of this core.
> +  @param  IsBootHart                   This is boot hart or not
> +  @param  ProcessorSpecDataHob         Pointer to RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CommonFirmwareContextHartSpecificInfo (
> +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific,
> +  EFI_GUID  *ParentProcessorGuid,
> +  UINTN     ParentProcessorUid,
> +  EFI_GUID  *CoreGuid,
> +  UINTN     HartId,
> +  BOOLEAN   IsBootHart,
> +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob

Spec is not a clear enough abbreviation, please use Specific.
Or call it something else. If you keep the name, it certainly wouldn't
hurt to use a local variable with a shorter name..

> +  )
> +{
> +  //
> +  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
> +  //
> +  CopyGuid (&ProcessorSpecDataHob->ParentPrcessorGuid, ParentProcessorGuid);
> +  ProcessorSpecDataHob->ParentProcessorUid = ParentProcessorUid;
> +  CopyGuid (&ProcessorSpecDataHob->CoreGuid, CoreGuid);
> +  ProcessorSpecDataHob->Context = NULL;
> +  ProcessorSpecDataHob->ProcessorSpecificData.Revision         = SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA_REVISION;

80 Characters is up to                                                      here ->
These lines are way too long, please wrap them.

> +  ProcessorSpecDataHob->ProcessorSpecificData.Length           = sizeof (SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA);
> +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_L = (UINT64)HartId;
> +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_H = 0;
> +  ProcessorSpecDataHob->ProcessorSpecificData.BootHartId       = (UINT8)IsBootHart;
> +  ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported = FirmwareContextHartSpecific->IsaExtensionSupported;
> +  ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported   = SMBIOS_RISC_V_PSD_MACHINE_MODE_SUPPORTED;
> +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported & RISC_V_ISA_SUPERVISOR_MODE_IMPLEMENTED) != 0) {
> +    ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported |= SMBIOS_RISC_V_PSD_SUPERVISOR_MODE_SUPPORTED;
> +  }
> +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported & RISC_V_ISA_USER_MODE_IMPLEMENTED) != 0) {
> +    ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported |= SMBIOS_RISC_V_PSD_USER_MODE_SUPPORTED;
> +  }
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineVendorId.Value64_L = FirmwareContextHartSpecific->MachineVendorId.Value64_L;
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineVendorId.Value64_H = FirmwareContextHartSpecific->MachineVendorId.Value64_H;
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineArchId.Value64_L = FirmwareContextHartSpecific->MachineArchId.Value64_L;
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineArchId.Value64_H = FirmwareContextHartSpecific->MachineArchId.Value64_H;
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineImplId.Value64_L = FirmwareContextHartSpecific->MachineImplId.Value64_L;
> +  ProcessorSpecDataHob->ProcessorSpecificData.MachineImplId.Value64_H = FirmwareContextHartSpecific->MachineImplId.Value64_H;
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
> new file mode 100644
> index 00000000..ff841c3e
> --- /dev/null
> +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
> @@ -0,0 +1,33 @@
> +#/** @file
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Can we update to a more recent specification version?

> +  BASE_NAME                      = FirmwareContextProcessorSpecificLib
> +  FILE_GUID                      = 8BEC9FD7-C554-403A-94F1-0EBBFD81A242
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = FirmwareContextProcessorSpecificLib
> +
> +[Sources.common]
> +  FirmwareContextProcessorSpecificLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec

Please sort the above alphabetically.

> +  RiscVPkg/RiscVPkg.dec
> +  Silicon/SiFive/SiFive.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  MemoryAllocationLib

Please sort the above alphabetically.

> +  PrintLib
> +
> +[Pcd]
> +

/
    Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module Gilbert Chen
@ 2019-10-02 19:43   ` Leif Lindholm
  2019-10-15 15:27     ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 19:43 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:23AM +0800, Gilbert Chen wrote:
> Common RISC-V SEC module for RISC-V platforms.

If this is common to RISC-V platforms, this really should live in
edk2/RiscVPkg.

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438 ++++++++++++++++++++
>  Platform/RiscV/Universal/Sec/SecMain.c          | 524 ++++++++++++++++++++++++
>  Platform/RiscV/Universal/Sec/SecMain.h          |  57 +++
>  Platform/RiscV/Universal/Sec/SecMain.inf        |  75 ++++
>  4 files changed, 1094 insertions(+)
>  create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
>  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
>  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
>  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
> 
> diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> new file mode 100644
> index 00000000..18b54b84
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> @@ -0,0 +1,438 @@
> +/*
> + * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All rights reserved.
> + *
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *   Anup Patel <anup.patel@wdc.com>

If Anup is the author, he should be indicated in the commit as the
Author.

If you further modify the patch, you can add a comment above your
signed-off-by: of the form
[Updated coding style issues.]
Signed-off-by: ...

> + *
> + */
> +
> +#include <Base.h>
> +#include <RiscV.h>
> +#include <sbi/riscv_asm.h>
> +#include <sbi/riscv_encoding.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi_scratch.h>
> +#include <sbi/sbi_trap.h>
> +
> +#include <SecMain.h>
> +#include <sbi/SbiFirmwareContext.h>
> +
> +.text
> +.align 3
> +.global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +  /*
> +   * Jump to warm-boot if this is not the selected core booting,
> +   */
> +  csrr a6, CSR_MHARTID
> +  li a5, FixedPcdGet32 (PcdBootHartId)
> +  bne a6, a5, _wait_for_boot_hart

We don't actually have a coding style for assembler, but I find it
really helps readability to have the arguments aligned across all
lines. Compare (for example) with OvmfPkg/Sec/X64/SecEntry.nasm.

> +
> +  // light LED on
> +  li a5, 0x54002000
> +  li a4, 0xff
> +  sw a4, 0x08(a5)
> +  li a4, 0x11
> +  sw a4, 0x0c(a5)
> +
> +  li ra, 0
> +  call _reset_regs
> +
> +  /* Preload HART details
> +   * s7 -> HART Count
> +   * s8 -> HART Stack Size
> +   */
> +  li s7, FixedPcdGet32 (PcdHartCount)
> +  li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
> +
> +  /* Setup scratch space for all the HARTs*/
> +  li  tp, FixedPcdGet32 (PcdScratchRamBase)
> +  mul a5, s7, s8
> +  add tp, tp, a5
> +  /* Keep a copy of tp */
> +  add t3, tp, zero
> +  /* Counter */
> +  li t2, 1
> +  /* hartid 0 is mandated by ISA */
> +  li t1, 0
> +_scratch_init:
> +  add tp, t3, zero
> +  mul a5, s8, t1
> +  sub tp, tp, a5
> +  li a5, SBI_SCRATCH_SIZE
> +  sub tp, tp, a5
> +
> +  /* Initialize scratch space */
> +  li  a4, FixedPcdGet32 (PcdFwStartAddress)
> +  li  a5, FixedPcdGet32 (PcdFwEndAddress)
> +  sub a5, a5, a4
> +  sd a4, SBI_SCRATCH_FW_START_OFFSET(tp)
> +  sd a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)

Can you add a blank line here?

> +  /* Note: fw_next_arg1() uses a0, a1, and ra */
> +  call fw_next_arg1
> +  sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)

Can you add a blank line here?

> +  /* Note: fw_next_addr() uses a0, a1, and ra */
> +  call fw_next_addr

Can you add a blank line here?

> +  sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)
> +  li a4, PRV_S
> +  sd a4, SBI_SCRATCH_NEXT_MODE_OFFSET(tp)
> +  la a4, _start_warm
> +  sd a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
> +  la a4, platform
> +  sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
> +  la a4, _hartid_to_scratch
> +  sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
> +  sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)

Can you add a blank line here?

> +#ifdef FW_OPTIONS
> +  li a4, FW_OPTIONS
> +  sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp)
> +#else
> +  sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp)
> +#endif

Can you add a blank line here?

> +  add t1, t1, t2
> +  blt t1, s7, _scratch_init
> +
> +  /* Fill-out temporary memory with 55aa*/
> +  li a4, FixedPcdGet32 (PcdTemporaryRamBase)
> +  li a5, FixedPcdGet32 (PcdTemporaryRamSize)
> +  add a5, a4, a5
> +1:
> +  li a3, 0x5AA55AA55AA55AA5
> +  sd a3, (a4)
> +  add a4, a4, __SIZEOF_POINTER__
> +  blt a4, a5, 1b
> +
> +  /* Update boot hart flag */
> +  la a4, _boot_hart_done
> +  li a5, 1
> +  sd a5, (a4)
> +
> +  /* Wait for boot hart */
> +_wait_for_boot_hart:
> +  la a4, _boot_hart_done
> +  ld a5, (a4)
> +  /* Reduce the bus traffic so that boot hart may proceed faster */
> +  nop
> +  nop
> +  nop
> +  beqz a5, _wait_for_boot_hart
> +
> +_start_warm:
> +  li ra, 0
> +  call _reset_regs
> +
> +  /* Disable and clear all interrupts */
> +  csrw CSR_MIE, zero
> +  csrw CSR_MIP, zero
> +
> +  li s7, FixedPcdGet32 (PcdHartCount)
> +  li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
> +
> +  /* HART ID should be within expected limit */
> +  csrr s6, CSR_MHARTID
> +  bge s6, s7, _start_hang
> +
> +  /* find the scratch space for this hart */
> +  li tp, FixedPcdGet32 (PcdScratchRamBase)
> +  mul a5, s7, s8
> +  add tp, tp, a5
> +  mul a5, s8, s6
> +  sub tp, tp, a5
> +  li a5, SBI_SCRATCH_SIZE
> +  sub tp, tp, a5
> +
> +  /* update the mscratch */
> +  csrw CSR_MSCRATCH, tp
> +
> +  /*make room for Hart specific Firmware Context*/
> +  li a5, FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> +  sub tp, tp, a5
> +
> +  /* Setup stack */
> +  add sp, tp, zero
> +
> +  /* Setup stack for the Hart executing EFI to top of temporary ram*/
> +  csrr a6, CSR_MHARTID
> +  li a5, FixedPcdGet32 (PcdBootHartId)
> +  bne a6, a5, 1f
> +
> +  li a4, FixedPcdGet32(PcdTemporaryRamBase)
> +  li a5, FixedPcdGet32(PcdTemporaryRamSize)
> +  add sp, a4, a5
> +  1:
> +
> +  /* Setup trap handler */
> +  la a4, _trap_handler
> +  csrw CSR_MTVEC, a4

Can you add a blank line here?

> +  /* Make sure that mtvec is updated */
> +  1:
> +  csrr a5, CSR_MTVEC
> +  bne a4, a5, 1b
> +
> +  /* Call library constructors before jup to SEC core */
> +  call ProcessLibraryConstructorList
> +
> +  /* jump to SEC Core C */
> +  csrr a0, CSR_MHARTID
> +  csrr a1, CSR_MSCRATCH
> +  call SecCoreStartUpWithStack
> +
> +  /* We do not expect to reach here hence just hang */
> +  j _start_hang
> +
> +  .align 3
> +  .section .data, "aw"
> +_boot_hart_done:
> +  RISCV_PTR 0
> +
> +  .align 3
> +  .section .entry, "ax", %progbits
> +  .globl _hartid_to_scratch
> +_hartid_to_scratch:
> +  add sp, sp, -(3 * __SIZEOF_POINTER__)
> +  sd s0, (sp)
> +  sd s1, (__SIZEOF_POINTER__)(sp)
> +  sd s2, (__SIZEOF_POINTER__ * 2)(sp)

Can you add a blank line here?

> +  /*
> +   * a0 -> HART ID (passed by caller)
> +   * s0 -> HART Stack Size
> +   * s1 -> HART Stack End
> +   * s2 -> Temporary
> +   */
> +  la s2, platform
> +#if __riscv_xlen == 64
> +  lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> +  lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> +#else
> +  lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> +  lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> +#endif
> +  mul s2, s2, s0
> +  li s1, FixedPcdGet32 (PcdScratchRamBase)
> +  add s1, s1, s2
> +  mul s2, s0, a0
> +  sub s1, s1, s2
> +  li s2, SBI_SCRATCH_SIZE
> +  sub a0, s1, s2
> +  ld s0, (sp)
> +  ld s1, (__SIZEOF_POINTER__)(sp)
> +  ld s2, (__SIZEOF_POINTER__ * 2)(sp)
> +  add sp, sp, (3 * __SIZEOF_POINTER__)
> +  ret
> +
> +  .align 3
> +  .section .entry, "ax", %progbits
> +  .globl _start_hang
> +_start_hang:
> +  wfi
> +  j _start_hang
> +
> +  .align 3
> +  .section .entry, "ax", %progbits
> +  .globl _trap_handler
> +_trap_handler:
> +  /* Swap TP and MSCRATCH */
> +  csrrw tp, CSR_MSCRATCH, tp
> +
> +  /* Save T0 in scratch space */
> +  sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> +
> +  /* Check which mode we came from */
> +  csrr t0, CSR_MSTATUS
> +  srl t0, t0, MSTATUS_MPP_SHIFT
> +  and t0, t0, PRV_M
> +  xori t0, t0, PRV_M
> +  beq t0, zero, _trap_handler_m_mode
> +
> +  /* We came from S-mode or U-mode */
> +_trap_handler_s_mode:
> +  /* Set T0 to original SP */
> +  add t0, sp, zero
> +
> +  /* Setup exception stack */
> +  add sp, tp, -(SBI_TRAP_REGS_SIZE)
> +
> +  /* Jump to code common for all modes */
> +  j _trap_handler_all_mode
> +
> +  /* We came from M-mode */
> +_trap_handler_m_mode:
> +  /* Set T0 to original SP */
> +  add t0, sp, zero
> +
> +  /* Re-use current SP as exception stack */
> +  add sp, sp, -(SBI_TRAP_REGS_SIZE)
> +
> +_trap_handler_all_mode:
> +  /* Save original SP (from T0) on stack */
> +  sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
> +
> +  /* Restore T0 from scratch space */
> +  ld t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> +
> +  /* Save T0 on stack */
> +  sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> +
> +  /* Swap TP and MSCRATCH */
> +  csrrw tp, CSR_MSCRATCH, tp
> +
> +  /* Save MEPC and MSTATUS CSRs */
> +  csrr t0, CSR_MEPC
> +  sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> +  csrr t0, CSR_MSTATUS
> +  sd t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> +
> +  /* Save all general regisers except SP and T0 */
> +  sd zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
> +  sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> +  sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> +  sd tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
> +  sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> +  sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> +  sd s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
> +  sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> +  sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> +  sd a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
> +  sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> +  sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> +  sd a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
> +  sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> +  sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> +  sd a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
> +  sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> +  sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> +  sd s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
> +  sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> +  sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> +  sd s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
> +  sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> +  sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> +  sd s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
> +  sd s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
> +  sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> +  sd t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> +  sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> +  sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> +
> +  /* Call C routine */
> +  add a0, sp, zero
> +  csrr a1, CSR_MSCRATCH
> +  call sbi_trap_handler
> +
> +  /* Restore all general regisers except SP and T0 */
> +  ld ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> +  ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> +  ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
> +  ld t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> +  ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> +  ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
> +  ld s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> +  ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> +  ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
> +  ld a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> +  ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> +  ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
> +  ld a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> +  ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> +  ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
> +  ld s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> +  ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> +  ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
> +  ld s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> +  ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> +  ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
> +  ld s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> +  ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> +  ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
> +  ld s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
> +  ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> +  ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> +  ld t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> +  ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> +
> +  /* Restore MEPC and MSTATUS CSRs */
> +  ld t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> +  csrw CSR_MEPC, t0
> +  ld t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> +  csrw CSR_MSTATUS, t0
> +
> +  /* Restore T0 */
> +  ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> +
> +  /* Restore SP */
> +  ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
> +
> +  mret
> +
> +  .align 3
> +  .section .entry, "ax", %progbits
> +  .globl _reset_regs
> +_reset_regs:
> +
> +  /* flush the instruction cache */
> +  fence.i
> +  /* Reset all registers except ra, a0,a1 */
> +  li sp, 0
> +  li gp, 0
> +  li tp, 0
> +  li t0, 0
> +  li t1, 0
> +  li t2, 0
> +  li s0, 0
> +  li s1, 0
> +  li a2, 0
> +  li a3, 0
> +  li a4, 0
> +  li a5, 0
> +  li a6, 0
> +  li a7, 0
> +  li s2, 0
> +  li s3, 0
> +  li s4, 0
> +  li s5, 0
> +  li s6, 0
> +  li s7, 0
> +  li s8, 0
> +  li s9, 0
> +  li s10, 0
> +  li s11, 0
> +  li t3, 0
> +  li t4, 0
> +  li t5, 0
> +  li t6, 0
> +  csrw CSR_MSCRATCH, 0
> +  ret
> +
> +    .align 3
> +    .section .entry, "ax", %progbits
> +    .global fw_prev_arg1
> +fw_prev_arg1:
> +    /* We return previous arg1 in 'a0' */
> +    add a0, zero, zero
> +    ret
> +
> +    .align 3
> +    .section .entry, "ax", %progbits
> +    .global fw_next_arg1
> +fw_next_arg1:
> +    /* We return next arg1 in 'a0' */
> +    li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
> +    ret
> +
> +    .align 3
> +    .section .entry, "ax", %progbits
> +    .global fw_next_addr
> +fw_next_addr:
> +    /* We return next address in 'a0' */
> +    la a0, _jump_addr
> +    ld a0, (a0)
> +    ret
> +
> +  .align 3
> + .section .entry, "ax", %progbits
> +_jump_addr:
> + RISCV_PTR SecCoreStartUpWithStack
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.c b/Platform/RiscV/Universal/Sec/SecMain.c
> new file mode 100644
> index 00000000..40b351ca
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.c
> @@ -0,0 +1,524 @@
> +/** @file
> +  RISC-V SEC phase module.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "SecMain.h"
> +#include <Library/SerialPortLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/DebugPrintErrorLevelLib.h>
> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi_scratch.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi.h>
> +#include <sbi/sbi_init.h>

Please sort includes alphabetically.

> +#include <sbi/SbiFirmwareContext.h>
> +
> +int HartsIn = 0;

UINTN?

> +
> +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> +  TemporaryRamMigration
> +};
> +
> +EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
> +  TemporaryRamDone
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &gEfiTemporaryRamSupportPpiGuid,
> +    &mTemporaryRamSupportPpi
> +  },
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiTemporaryRamDonePpiGuid,
> +    &mTemporaryRamDonePpi
> +  },
> +};

Can the above three variables all be made STATIC?

> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  The Instance parameter indicates which instance of the section
> +  type to return. (0 is first instance, 1 is second...)
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[in]   Instance        The section instance number
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInstance (

This is a note, not something that needs to be addressed for setting
up the -devel branch: but this function is identical to the one in
<edk2>/OvmfPkg/Sec/SecMain.c and the one in
Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
We should address this.

> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  IN  UINTN                            Instance,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfSections;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> +
> +  //
> +  // Loop through the FFS file sections within the PEI Core FFS file
> +  //
> +  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> +  EndOfSections = EndOfSection + SizeOfSections;
> +  for (;;) {
> +    if (EndOfSection == EndOfSections) {
> +      break;
> +    }
> +    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> +    if (CurrentAddress >= EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +
> +    Size = SECTION_SIZE (Section);
> +    if (Size < sizeof (*Section)) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    EndOfSection = CurrentAddress + Size;
> +    if (EndOfSection > EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the requested section type
> +    //
> +    if (Section->Type == SectionType) {
> +      if (Instance == 0) {
> +        *FoundSection = Section;
> +        return EFI_SUCCESS;
> +      } else {
> +        Instance--;
> +      }
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInSections (

The same applies to this one.

> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  return FindFfsSectionInstance (
> +           Sections,
> +           SizeOfSections,
> +           SectionType,
> +           0,
> +           FoundSection
> +           );
> +}
> +
> +/**
> +  Locates a FFS file with the specified file type and a section
> +  within that file with the specified section type.
> +
> +  @param[in]   Fv            The firmware volume to search
> +  @param[in]   FileType      The file type to locate
> +  @param[in]   SectionType   The section type to locate
> +  @param[out]  FoundSection  The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsFileAndSection (

And this one.

> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  IN  EFI_FV_FILETYPE                  FileType,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +
> +  if (Fv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> +  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> +
> +  //
> +  // Loop through the FFS files in the Boot Firmware Volume
> +  //
> +  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> +
> +    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    Size = *(UINT32*) File->Size & 0xffffff;
> +    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the request file type
> +    //
> +    if (File->Type != FileType) {
> +      continue;
> +    }
> +
> +    Status = FindFfsSectionInSections (
> +               (VOID*) (File + 1),
> +               (UINTN) EndOfFile - (UINTN) (File + 1),
> +               SectionType,
> +               FoundSection
> +               );
> +    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> +      return Status;
> +    }
> +  }
> +}
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in]  Fv                 The firmware volume to search
> +  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindPeiCoreImageBaseInFv (

And this.

> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +
> +  Status = FindFfsFileAndSection (
> +             Fv,
> +             EFI_FV_FILETYPE_PEI_CORE,
> +             EFI_SECTION_PE32,
> +             &Section
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Status = FindFfsFileAndSection (
> +               Fv,
> +               EFI_FV_FILETYPE_PEI_CORE,
> +               EFI_SECTION_TE,
> +               &Section
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
> +      return Status;
> +    }
> +  }
> +  DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
> +  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in,out]  Fv                 The firmware volume to search
> +  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +VOID
> +FindPeiCoreImageBase (
> +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
> +     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  *PeiCoreImageBase = 0;
> +
> +  DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));

This one is the same with S3 support ripped out, and the above line added.
Can you delete the message, or change it to something more human
friendly? I personally would interpret that as something that was
printed _from_ that function (and in that situation should be using %a
__FUNCTION__).

> +  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> +}
> +
> +/*
> +  Find and return Pei Core entry point.
> +
> +  It also find SEC and PEI Core file debug inforamtion. It will report them if
> +  remote debug is enabled.
> +
> +**/
> +VOID
> +FindAndReportEntryPoints (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
> +  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> +
> +  DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));

Use %a __FUNCTION__.

> +
> +  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> +  //
> +  // Find PEI Core entry point
> +  //
> +  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
> +  if (EFI_ERROR(Status)) {
> +    *PeiCoreEntryPoint = 0;
> +  }
> +  DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n", *PeiCoreEntryPoint));
> +
> +  return;
> +}
> +/*
> +  Print out the content of firmware context.
> +
> +**/
> +VOID
> +DebutPrintFirmwareContext (

Debut -> Debug?

> +    EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
> +    )
> +{
> +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at 0x%x\n", FirmwareContext));

Please drop the [OpenSBI] prefix.

> +  DEBUG ((DEBUG_INFO, "           PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable));
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  )
> +{
> +  VOID      *OldHeap;
> +  VOID      *NewHeap;
> +  VOID      *OldStack;
> +  VOID      *NewStack;
> +  struct sbi_platform *ThisSbiPlatform;
> +
> +  DEBUG ((DEBUG_INFO,
> +    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",

%a
__FUNCTION__

> +    TemporaryMemoryBase,
> +    PermanentMemoryBase,
> +    (UINT64)CopySize
> +    ));
> +
> +  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> +  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> +
> +  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> +  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> +
> +  CopyMem (NewHeap, OldHeap, CopySize >> 1);   // Migrate Heap
> +  CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
> +
> +  //
> +  // Reset firmware context pointer
> +  //
> +  ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> +  ThisSbiPlatform->firmware_context += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);

"unsigned long" is not a type that exists in UEFI.
Please use UINTN. Applies throughout.

> +  //
> +  // Relocate PEI Service **
> +  //
> +  ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);

The above line is begging for a temporary pointer for the firmware_context.

> +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is relocated to 0x%x\n", ThisSbiPlatform->firmware_context));

Please 

> +  DebutPrintFirmwareContext ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context);
> +
> +  register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack);
> +  asm volatile ("add sp, sp, a0"::"r"(a0):);

Urgh.
Is there any way this could be broken out into a separate assembler
function instead? If not, we still need to get rid of the uintptr_t:s.

> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS EFIAPI TemporaryRamDone (VOID)
> +{
> +  DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +#if 1

Just delete the #if 1?

> +#define GPIO_CTRL_ADDR  0x54002000
> +#define GPIO_OUTPUT_VAL 0x0C
> +static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
> +#define REG32(p, i)   ((p)[(i)>>2])
> +#endif

And the #endif

Moreover, please move the ADDRESS/VALUE macros to SecMain.h, and use
IoLib instead of defining your own variables and macros.

> +
> +static VOID EFIAPI PeiCore(VOID)

STATIC
Also, please follow coding style for function definition, this is
supposed to be over multiple lines.

> +{
> +  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> +  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> +  EFI_FIRMWARE_VOLUME_HEADER *BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32(PcdRiscVPeiFvBase);
> +  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
> +  struct sbi_platform *ThisSbiPlatform;
> +  UINT32 HartId;
> +
> +  REG32(gpio, GPIO_OUTPUT_VAL) = 0x88;
> +  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> +
> +  SecCoreData.DataSize               = sizeof(EFI_SEC_PEI_HAND_OFF);
> +  SecCoreData.BootFirmwareVolumeBase = BootFv;
> +  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +  SecCoreData.TemporaryRamBase       = (VOID*)(UINT64) FixedPcdGet32(PcdTemporaryRamBase);
> +  SecCoreData.TemporaryRamSize       = (UINTN)  FixedPcdGet32(PcdTemporaryRamSize);
> +  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
> +  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >> 1;
> +  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >> 1);

Please don't use UINT8 * to get away from pointer arithmetic. It
disguises what function is actually being performed.
(VOID *)((UINTN) ...) is a much preferred form where that level of
description is required.

> +  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
> +
> +  //
> +  // Print out scratch address of each hart
> +  //
> +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI scratch address for each hart:\n"));

Please drop [OpenSBI] tag.

> +  for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> +    DEBUG ((DEBUG_INFO, "          Hart %d: 0x%x\n", HartId, sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));

Please wrap long line.

> +  }
> +
> +  //
> +  // Set up OpepSBI firmware context poitner on boot hart OpenSbi scratch. Firmware context residents in stack and will be

Please wrap long line.

> +  // switched to memory when temporary ram migration.
> +  //
> +  ZeroMem ((VOID *)&FirmwareContext, sizeof (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
> +  ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> +  if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
> +      DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version 0x%x is newer than OpenSBI version 0x%x.\n"
> +                           "There maybe be some backward compatable issues.\n",

Please drop [OpenSBI] tag. Please convert the two lines to two
separate DEBUG prints.

> +             ThisSbiPlatform->opensbi_version,
> +             OPENSBI_VERSION
> +             ));
> +      ASSERT(FALSE);
> +  }
> +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address: 0x%x\nFirmware Context is located at 0x%x\n",

Please drop [OpenSBI] tag.

> +             ThisSbiPlatform,
> +             &FirmwareContext
> +             ));
> +  ThisSbiPlatform->firmware_context = (unsigned long)&FirmwareContext;

UINTN (probably best to do a global search and replace on this).

> +  //
> +  // Set firmware context Hart-specific pointer
> +  //
> +  for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> +    FirmwareContext.HartSpecific [HartId] = \
> +      (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);

Please don't use (UINT8 *) to get away from pointer arithmetic.
UINTN should work fine in this context.

Screaming out for a temporary variable.

> +    DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n",

Please drop [OpenSBI] tag.

> +             HartId,
> +             FirmwareContext.HartSpecific [HartId]
> +             ));
> +  }
> +
> +  //
> +  // Transfer the control to the PEI core
> +  //
> +  (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
> +}
> +/**
> +  This function initilizes hart specific information and SBI.
> +  For the boot hart, it boots system through PEI core and initial SBI in the DXE IPL.
> +  For others, it goes to initial SBI and halt.
> +
> +  the lay out of memory region for each hart is as below delineates,
> +
> +                                               _                                        ____
> +  |----Scratch ends                             |                                           |
> +  |                                             | sizeof (sbi_scratch)                      |
> +  |                                            _|                                           |
> +  |----Scratch buffer start s                  <----- *scratch                              |
> +  |----Firmware Context Hart-specific ends     _                                            |
> +  |                                             |                                           |
> +  |                                             | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE       |
> +  |                                             |                                           |  PcdOpenSbiStackSize
> +  |                                            _|                                           |
> +  |----Firmware Context Hart-specific starts   <----- **HartFirmwareContext                 |
> +  |----Hart stack top                          _                                            |
> +  |                                             |                                           |
> +  |                                             |                                           |
> +  |                                             |  Stack                                    |
> +  |                                             |                                           |
> +  |                                            _|                                       ____|
> +  |----Hart stack bottom
> +
> +**/
> +VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct sbi_scratch *scratch)

Split up over multiple lines.

> +{
> +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext;
> +
> +  //
> +  // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
> +  //
> +  HartFirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);

Please don't use UINT8 * to get away from pointer arithmetic.
In this context, UINTN should work just fine.

> +  HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
> +  HartFirmwareContext->MachineVendorId.Value64_L = RiscVReadMVendorId ();
> +  HartFirmwareContext->MachineVendorId.Value64_H = 0;
> +  HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId ();
> +  HartFirmwareContext->MachineArchId.Value64_H = 0;
> +  HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
> +  HartFirmwareContext->MachineImplId.Value64_H = 0;
> +
> +#if 0

Please don't leave unused code in.
If you want to keep the printouts for extreme debugging sessions,
change the loglevel to DEBUG_VERBOSE.

> +  while (HartsIn != hartid);
> +  DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context Hart-specific for HART ID:%d\n", hartid));

Please drop [OpenSBI] tag.

> +  DEBUG ((DEBUG_INFO, "           Scratch at address: 0x%x\n", scratch));
> +  DEBUG ((DEBUG_INFO, "           Firmware Context Hart-specific at address: 0x%x\n", HartFirmwareContext));
> +  DEBUG ((DEBUG_INFO, "           stack pointer at address: 0x%x\n", stack_point));
> +  DEBUG ((DEBUG_INFO, "                    MISA: 0x%x\n", HartFirmwareContext->IsaExtensionSupported));
> +  DEBUG ((DEBUG_INFO, "                    MVENDORID: 0x%x\n", HartFirmwareContext->MachineVendorId.Value64_L));
> +  DEBUG ((DEBUG_INFO, "                    MARCHID: 0x%x\n", HartFirmwareContext->MachineArchId.Value64_L));
> +  DEBUG ((DEBUG_INFO, "                    MIMPID: 0x%x\n\n", HartFirmwareContext->MachineImplId.Value64_L));
> +  HartsIn ++;
> +  for (;;);
> +#endif
> +
> +  if (hartid == FixedPcdGet32(PcdBootHartId)) {
> +    PeiCore();
> +  }
> +  sbi_init(scratch);
> +}
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.h b/Platform/RiscV/Universal/Sec/SecMain.h
> new file mode 100644
> index 00000000..e7565f5e
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.h
> @@ -0,0 +1,57 @@
> +/** @file
> +  RISC-V SEC phase module definitions..
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _SECMAIN_H_
> +#define _SECMAIN_H_

Plese drop leading _.

> +
> +#include <PiPei.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.h>
> +#include <Library/HobLib.h>
> +#include <Ppi/TemporaryRamSupport.h>
> +#include <Ppi/TemporaryRamDone.h>
> +#include <Library/RiscVCpuLib.h>

Please drop all include statements not required by this file, and add
them instead in the files that do use them.

> +
> +VOID
> +SecMachineModeTrapHandler (
> +  IN VOID
> +  );
> +
> +VOID
> +EFIAPI
> +SecStartupPhase2 (
> +  IN VOID                     *Context
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamDone (
> +  VOID
> +  );
> +
> +#endif // _SECMAIN_H_
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf b/Platform/RiscV/Universal/Sec/SecMain.inf
> new file mode 100644
> index 00000000..c408fc8d
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.inf
> @@ -0,0 +1,75 @@
> +## @file
> +#  RISC-V SEC module.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Can this be updated to a recent specification version.

> +  BASE_NAME                      = SecMain
> +  FILE_GUID                      = df1ccef6-f301-4a63-9661-fc6030dcc880
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SecMain
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV64 EBC

Pretty sure EBC is not valid here.

> +#
> +
> +[Sources]
> +  SecMain.c
> +
> +[Sources.RISCV64]
> +  Riscv64/SecEntry.s
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  PcdLib
> +  DebugAgentLib
> +  IoLib
> +  PeCoffLib
> +  PeCoffGetEntryPointLib
> +  PeCoffExtraActionLib
> +  ExtractGuidedSectionLib
> +  RiscVCpuLib
> +  PrintLib
> +  SerialPortLib
> +  RiscVOpensbiLib
> +  OpenSbiPlatformLib # This is required library which
> +                     # provides platform level opensbi
> +                     # functions.

I don't doubt it, but I can tell it's required from the fact that it
is listed. And the name itself says all of the rest. The comment is
superfluous and can be deleted.

> +
> +[Ppis]
> +  gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> +  gEfiTemporaryRamDonePpiGuid    # PPI ALWAYS_PRODUCED
> +
> +[Guids]
> +  gUefiRiscVMachineContextGuid
> +
> +[FixedPcd]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
> +
> +[Pcd]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize

Please sort the above alphabetically (
apart from where it makes sense not to - for example
PcdFwStartAddress
before
PcdFwEndAddress
makes more sense than the other way around).

/
    Leif

> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package Gilbert Chen
@ 2019-10-02 20:16   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 20:16 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:24AM +0800, Gilbert Chen wrote:
> The initial version of SiFive U500 platform package.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  Platform/RiscV/SiFive/U500Pkg/Readme.md        |  62 +++
>  Platform/RiscV/SiFive/U500Pkg/U500.dec         |  34 ++
>  Platform/RiscV/SiFive/U500Pkg/U500.dsc         | 549 +++++++++++++++++++++++++
>  Platform/RiscV/SiFive/U500Pkg/U500.fdf         | 335 +++++++++++++++
>  Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc     |  52 +++
>  Platform/RiscV/SiFive/U500Pkg/U500.uni         |  13 +
>  Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni |  12 +
>  Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc |  78 ++++
>  8 files changed, 1135 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Readme.md
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dec
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.dsc
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500.uni
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Readme.md b/Platform/RiscV/SiFive/U500Pkg/Readme.md
> new file mode 100644
> index 00000000..71fa62a1
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Readme.md

Please add a link to this file from top-level Readme.md.

> @@ -0,0 +1,62 @@
> +# Introduction
> +
> +## U500 Platform Package
> +This is a sample RISC-V EDK2 platform package used agaist SiFive Freedom U500 VC707 FPGA Dev Kit, please refer to "SiFive Freedom U500 VC707 FPGA Getting Started Guide" on https://www.sifive.com/documentation. This package is built with below common packages, <br>

Please wrap lines in file at no more than 80 characters.
No inline HTML please (search and replace all <br>.

> +- **RiscVPlatformPkg**, edk2-platform/Platform/RiscV
> +- **RiscVPkg**, edk2 master branch (Currently is in edk2-staging/RISC-V branch)
> +<br>
> +This package provides librareis and modules which are SiFive U500 platform implementation-specific and incorporate with common RISC-V packages mentioned above.
> +
> +## Download the sources
> +```
> +git clone https://github.com/tianocore/edk2-staging.git
> +# Checkout RISC-V-V2 branch
> +git clone https://github.com/tianocore/edk2-platforms.git
> +# Checkout devel-riscv-v2 branch
> +git clone https://github.com/tianocore/edk2-non-osi.git
> +```
> +
> +## Platform Owners
> +Chang, Abner <abner.chang@hpe.com><br>
> +Chen, Gilbert <gilbert.chen@hpe.com>

It is not important while it is a -devel branch, but when merged to
master, we will want an entry in Maintainers.txt instead.

> +
> +## Platform Status
> +Currently the binary built from U500Pkg can boot SiFive Freedom U500 VC707 FPGA to EFI shell with console in/out enabled.
> +
> +## Linux Build Instructions
> +You can build the RISC-V platform using below script, <br>
> +`build -a RISCV64 -p Platform/RiscV/SiFive/U500Pkg/U500.dsc -t GCCRISCV`

GCC5

> +
> +## Supported Operating Systems
> +Only support to boot to EFI Shell so far
> +
> +## Known Issues and Limitations
> +Only RISC-V RV64 is verified on this platform.
> +
> +## Related Materials
> +- [RISC-V OpenSbi](https://github.com/riscv/opensbi)<br>
> +- [SiFive U500 VC707 FPGA Getting Started Guide](https://sifive.cdn.prismic.io/sifive%2Fc248fabc-5e44-4412-b1c3-6bb6aac73a2c_sifive-u500-vc707-gettingstarted-v0.2.pdf)<br>
> +- [SiFive RISC-V Core Document](https://www.sifive.com/documentation)
> +
> +## U500 Platform Libraries and Drivers
> +### OpneSbiPlatformLib
> +In order to reduce the dependencies with RISC-V OpenSBI project (https://github.com/riscv/opensbi) and less burdens to EDK2 build process, the implementation of RISC-V EDK2 platform is leverage platform source code from OpenSBI code tree. The "platform.c" under OpenSbiPlatformLib  is cloned from RISC-V OpenSBI code tree (in EDK2 RiscVPkg) and built based on EDK2 build environment.
> +
> +### PeiCoreInfoHobLib
> +This is the library to create RISC-V core characteristics for building up RISC-V related SMBIOS records to support the unified boot loader and OS image. This library leverage the silicon libraries provided in Silicon/SiFive.
> +
> +### RiscVPlatformTimerLib
> +This is U500 platform timer library which has the platform-specific timer implementation.
> +
> +### PlatformPei
> +This is the platform-implementation specific library which is executed in early PEI phase for platform initialization.
> +
> +### TimerDxe
> +This is U500 platform timer DXE driver whcih has the platform-specific timer implementation.
> +
> +## U500 Platform PCD settings
> +
> +| **PCD name** |**Usage**|
> +|----------------|----------|
> +|PcdNumberofU5Cores| Number of U5 core enabled on U500 platform|
> +|PcdE5MCSupported| Indicates whether or not the Monitor Core (E5) is supported on U500 platform|
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.dec b/Platform/RiscV/SiFive/U500Pkg/U500.dec
> new file mode 100644
> index 00000000..4ecca89b
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500.dec
> @@ -0,0 +1,34 @@
> +## @file  U500.dec
> +# This Package provides SiFive U500 modules and libraries.
> +#
> +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005

Pleae bump specification version.

> +  PACKAGE_NAME                   = U500
> +  PACKAGE_UNI_FILE               = U500.uni
> +  PACKAGE_GUID                   = D11E9DB9-5940-4642-979D-2114342140D2
> +  PACKAGE_VERSION                = 1.0
> +
> +[Includes]
> +  Include
> +
> +[LibraryClasses]
> +
> +
> +[Guids]
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid  = {0xDFD87009, 0x27A1, 0x41DD, { 0x84, 0xB1, 0x35, 0xB4, 0xB9, 0x0D, 0x17, 0x63 }}

I would prefer ...SiFivePlatform... over ...RiscVPlattform...

> +
> +[PcdsFixedAtBuild]
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores|0x8|UINT32|0x00001000
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported|TRUE|BOOLEAN|0x00001001
> +
> +[PcdsPatchableInModule]
> +
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  U500PkgExtra.uni
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.dsc b/Platform/RiscV/SiFive/U500Pkg/U500.dsc
> new file mode 100644
> index 00000000..edcd951a
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500.dsc
> @@ -0,0 +1,549 @@
> +## @file
> +#  RISC-V EFI on SiFive VC707 (U500) RISC-V platform
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = U500
> +  PLATFORM_GUID                  = 0955581C-2A6A-48F7-8690-9D275AE884F8
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x00010005

Please bump specification version.

> +  OUTPUT_DIRECTORY               = Build/U500Pkg

We don't tend to use Pkg in the actual platform OUTPUT_DIRECTORY
names. Reusing $(PLATFORM_NAME) is usually sufficient.

> +  SUPPORTED_ARCHITECTURES        = RISCV64
> +  BUILD_TARGETS                  = DEBUG|RELEASE

Please add NOOPT target.

> +  SKUID_IDENTIFIER               = DEFAULT
> +  FLASH_DEFINITION               = Platform/RiscV/SiFive/U500Pkg/U500.fdf
> +
> +  #
> +  # Enable below options may cause build error or may not work on
> +  # the initial version of RISC-V package
> +  # Defines for default states.  These can be changed on the command line.
> +  # -D FLAG=VALUE
> +  #
> +  DEFINE SECURE_BOOT_ENABLE      = FALSE
> +  DEFINE DEBUG_ON_SERIAL_PORT    = TRUE
> +
> +  #
> +  # Network definition
> +  #
> +  DEFINE NETWORK_SNP_ENABLE       = FALSE
> +  DEFINE NETWORK_IP6_ENABLE       = FALSE
> +  DEFINE NETWORK_TLS_ENABLE       = FALSE
> +  DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
> +  DEFINE NETWORK_ISCSI_ENABLE     = FALSE
> +
> +[BuildOptions]
> +  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  GCC:*_*_RISCV64_GENFW_FLAGS    = --keepexceptiontable
> +!endif
> +
> +################################################################################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this Platform.
> +#
> +################################################################################
> +[SkuIds]
> +  0|DEFAULT
> +
> +################################################################################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +################################################################################
> +[LibraryClasses]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
> +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  SerialPortLib|Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
> +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
> +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
> +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
> +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
> +  SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +
> +# RISC-V Platform Library
> +  RealTimeClockLib|Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
> +
> +# RISC-V Core Library
> +  RiscVOpensbiLib|RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
> +  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
> +!else
> +  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
> +  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
> +!endif
> +
> +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
> +  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +!else
> +  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
> +  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
> +!endif
> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +
> +!if $(HTTP_BOOT_ENABLE) == TRUE
> +  HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
> +!endif
> +
> +# ACPI not supported yet.
> +  #S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
> +  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
> +  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> +
> +[LibraryClasses.common]
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +  RiscVCpuLib|RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
> +  RiscVPlatformTimerLib|Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
> +  CpuExceptionHandlerLib|RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
> +
> +[LibraryClasses.common.SEC]
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
> +!endif
> +
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +
> +#
> +# OpenSBi Platform Library
> +#
> +  OpenSbiPlatformLib|Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
> +
> +[LibraryClasses.common.PEI_CORE]
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesTablePointerLib|RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> +[LibraryClasses.common.PEIM]
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesTablePointerLib|RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
> +!endif
> +  FirmwareContextProcessorSpecificLib|Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
> +  RiscVPlatformDxeIplLib|RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
> +
> +#
> +# RISC-V core libraries
> +#
> +  SiliconSiFiveE51CoreInfoLib|Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> +  SiliconSiFiveU54CoreInfoLib|Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> +  SiliconSiFiveU5MCCoreplexInfoLib|Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> +
> +[LibraryClasses.common.DXE_CORE]
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
> +!endif
> +  #CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +
> +[LibraryClasses.common.DXE_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
> +!endif
> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +  PlatformBootManagerLib|Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +  #PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
> +  #CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.common.UEFI_APPLICATION]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!endif
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +
> +[LibraryClasses.common.DXE_SMM_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +
> +[LibraryClasses.common.SMM_CORE]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
> +
> +################################################################################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
> +#
> +################################################################################
> +[PcdsFeatureFlag]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
> +
> +[PcdsFixedAtBuild]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +!endif
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
> +!endif
> +
> +  #gUefiPayloadPkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
> +  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
> +  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
> +  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
> +!endif
> +
> +  #
> +  # F2 for UI APP
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
> +
> +################################################################################
> +#
> +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +################################################################################
> +
> +[PcdsDynamicDefault]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
> +
> +  # Set video resolution for text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
> +
> +################################################################################
> +#
> +# Components Section - list of all EDK II Modules needed by this Platform.
> +#
> +################################################################################
> +[Components]
> +
> +  #
> +  # SEC Phase modules
> +  #
> +  Platform/RiscV/Universal/Sec/SecMain.inf
> +
> +  #
> +  # PEI Phase modules
> +  #
> +  MdeModulePkg/Core/Pei/PeiMain.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
> +  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +    NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +  }
> +
> +  Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  #
> +  # DXE Phase modules
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg//Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +  }
> +
> +  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
> +  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
> +   <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
> +    <LibraryClasses>
> +      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> +  }
> +!else
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +!endif
> +
> +  #
> +  # EBC not supported on RISC-V yet
> +  #
> +  #MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> +
> +  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  MdeModulePkg/Universal/Metronome/Metronome.inf
> +  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> +  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf {
> +    <LibraryClasses>
> +      ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
> +  }
> +
> +  #
> +  # RISC-V Platform module
> +  #
> +  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
> +  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +
> +  #
> +  # RISC-V Core module
> +  #
> +  RiscVPkg/Universal/CpuDxe/CpuDxe.inf
> +  RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
> +  RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
> +
> +  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +  }
> +  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> +# No graphic console supported yet.
> +#  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
> +#    <LibraryClasses>
> +#      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +#  }
> +  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
> +    <LibraryClasses>
> +      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
> +  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
> +  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
> +
> +  #
> +  # SMBIOS Support
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +
> +  #
> +  # ACPI Support
> +  # Not support on RISC-V yet
> +  #
> +  #MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  #MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +
> +  #
> +  # Network Support
> +  #
> +  !include NetworkPkg/Network.dsc.inc
> +
> +  #
> +  # Usb Support
> +  #
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.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/UsbMassStorageDxe/UsbMassStorageDxe.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
> +      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
> +      ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +      SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
> +
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
> +  }
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
> +!endif
> +
> +  MdeModulePkg/Application/UiApp/UiApp.inf
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.fdf b/Platform/RiscV/SiFive/U500Pkg/U500.fdf
> new file mode 100644
> index 00000000..5ca84be3
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500.fdf
> @@ -0,0 +1,335 @@
> +# @file
> +#  Flash definition file on SiFive VC707 (U500) RISC-V platform
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +[Defines]
> +
> +!include U500.fdf.inc

Why is this kept as a separate include file?

> +
> +#
> +# Build the variable store and the firmware code as one unified flash device
> +# image.
> +#
> +[FD.U500]
> +BaseAddress   = $(FW_BASE_ADDRESS)
> +Size          = $(FW_SIZE)
> +ErasePolarity = 1
> +BlockSize     = $(BLOCK_SIZE)
> +NumBlocks     = $(FW_BLOCKS)
> +
> +$(SECFV_OFFSET)|$(SECFV_SIZE)
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize
> +FV = SECFV
> +
> +$(PEIFV_OFFSET)|$(PEIFV_SIZE)
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
> +FV = PEIFV
> +
> +$(FVMAIN_OFFSET)|$(FVMAIN_SIZE)
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize
> +FV = FVMAIN_COMPACT
> +
> +!include VarStore.fdf.inc
> +
> +################################################################################
> +
> +[FV.SECFV]
> +BlockSize          = 0x1000
> +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
> +
> +#
> +# SEC Phase modules
> +#
> +# The code in this FV handles the initial firmware startup, and
> +# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
> +#
> +INF Platform/RiscV/Universal/Sec/SecMain.inf
> +
> +################################################################################
> +[FV.PEIFV]
> +BlockSize          = 0x10000
> +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/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
> +  INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +}
> +
> +#
> +#  PEI Phase modules
> +#
> +INF  MdeModulePkg/Core/Pei/PeiMain.inf
> +INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
> +INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +
> +# RISC-V Platform PEI Driver
> +INF  Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
> +
> +################################################################################
> +
> +[FV.DXEFV]
> +BlockSize          = 0x10000
> +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 DXE {
> +  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +  INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +}
> +
> +#
> +# DXE Phase modules
> +#
> +INF  MdeModulePkg/Core/Dxe/DxeMain.inf
> +
> +INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +
> +INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +INF  MdeModulePkg/Universal/Metronome/Metronome.inf
> +
> +# RISC-V Platform Drivers
> +INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +
> +# RISC-V Core Drivers
> +INF  RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
> +INF  Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
> +INF  RiscVPkg/Universal/CpuDxe/CpuDxe.inf
> +INF  RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
> +
> +INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> +
> +INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
> +!endif
> +
> +INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +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/BdsDxe/BdsDxe.inf
> +INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
> +INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
> +
> +!ifndef $(SOURCE_DEBUG_ENABLE)
> +INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
> +!endif
> +
> +INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +
> +#
> +# ACPI is not supported yet on RISC-V package.
> +#
> +#INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +#INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +#INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
> +
> +#INF  RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf
> +
> +INF  ShellPkg/Application/Shell/Shell.inf
> +
> +#
> +# Network modules
> +#
> +!if $(E1000_ENABLE)
> +  FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
> +    SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI
> +  }
> +!endif
> +
> +!include NetworkPkg/Network.fdf.inc
> +
> +#
> +# Usb Support
> +#
> +INF  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.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/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +INF  MdeModulePkg/Application/UiApp/UiApp.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
> +FvNameGuid         = 27A72E80-3118-4c0c-8673-AA5B4EFA9613
> +
> +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
> +     #
> +     # These firmware volumes will have files placed in them uncompressed,
> +     # and then both firmware volumes will be compressed in a single
> +     # compression operation in order to achieve better overall compression.
> +     #
> +     SECTION FV_IMAGE = DXEFV
> +   }
> + }
> +
> +[Rule.Common.SEC]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> +    PE32     PE32   Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING ="$(MODULE_NAME)" Optional
> +    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEI_CORE]
> +  FILE PEI_CORE = $(NAMED_GUID) {
> +    PE32     PE32   Align=4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING ="$(MODULE_NAME)" Optional
> +    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32     PE32   Align=4K         $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI       STRING="$(MODULE_NAME)" Optional
> +     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_CORE]
> +  FILE DXE_CORE = $(NAMED_GUID) {
> +    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32   Align = 4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32  Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional      |.depex
> +    PE32      PE32   Align=4K   |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32     PE32   Align=4K   $(INF_OUTPUT)/$(MODULE_NAME).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  Align=4K  |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI               |.acpi
> +    RAW ASL                |.aml
> +  }
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc b/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
> new file mode 100644
> index 00000000..ac24b5b0
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500.fdf.inc
> @@ -0,0 +1,52 @@
> +## @file
> +#  Definitions of Flash definition file on SiFive VC707 (U500) RISC-V platform
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##

*if* this is kept as a separate file, we need to add a [Defines]
 section header here.

> +DEFINE BLOCK_SIZE        = 0x1000
> +
> +DEFINE FW_BASE_ADDRESS   = 0x80000000
> +DEFINE FW_SIZE           = 0x00800000
> +DEFINE FW_BLOCKS         = 0x800
> +
> +#
> +# 0x000000-0x7DFFFF code
> +# 0x7E0000-0x800000 variables
> +#
> +DEFINE CODE_BASE_ADDRESS = 0x80000000
> +DEFINE CODE_SIZE         = 0x007E0000
> +DEFINE CODE_BLOCKS       = 0x7E0
> +DEFINE VARS_BLOCKS       = 0x20
> +
> +DEFINE SECFV_OFFSET      = 0x00000000
> +DEFINE SECFV_SIZE        = 0x00020000
> +DEFINE PEIFV_OFFSET      = 0x00020000
> +DEFINE PEIFV_SIZE        = 0x00060000
> +DEFINE SCRATCH_OFFSET    = 0x00080000
> +DEFINE SCRATCH_SIZE      = 0x00010000
> +DEFINE FVMAIN_OFFSET     = 0x00100000 # Must be power of 2 for PMP setting
> +DEFINE FVMAIN_SIZE       = 0x0018C000
> +DEFINE VARS_OFFSET       = 0x007E0000
> +DEFINE VARS_SIZE         = 0x00020000
> +
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress = $(FW_BASE_ADDRESS) + $(VARS_OFFSET)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize        = $(VARS_SIZE)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize   = $(BLOCK_SIZE)
> +
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress = $(CODE_BASE_ADDRESS)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress = $(CODE_BASE_ADDRESS) + $(SECFV_SIZE) + $(PEIFV_SIZE) + $(SCRATCH_SIZE)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize = 8192
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase = $(CODE_BASE_ADDRESS) + $(SCRATCH_OFFSET)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize = $(SCRATCH_SIZE)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase = $(CODE_BASE_ADDRESS) + $(FW_SIZE)
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize = 0x10000
> +
> +
> +SET gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz = 1000000
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount = 4               # Total cores on U500 platform
> +SET gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores = 4     # Total U5 cores enabled on U500 platform
> +SET gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported = False   # Enable optional E51 MC core?
> +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId = 0              # Boot hart ID
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500.uni b/Platform/RiscV/SiFive/U500Pkg/U500.uni
> new file mode 100644
> index 00000000..7ac1096f
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500.uni
> @@ -0,0 +1,13 @@
> +// /** @file
> +// SiFive U500 Package Localized Strings and Content.
> +//
> +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_PACKAGE_ABSTRACT            #language en-US "Provides SiFIve RISC-V U500 platform modules and libraries"
> +
> +#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package SiFIve RISC-V U500 platform modules and libraries."
> diff --git a/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni b/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
> new file mode 100644
> index 00000000..6b68fb43
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/U500PkgExtra.uni
> @@ -0,0 +1,12 @@
> +// /** @file
> +// SiFive U500 Package Localized Strings and Content.
> +//
> +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_PACKAGE_NAME
> +#language en-US
> +"SiFive U500 package"
> diff --git a/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc b/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
> new file mode 100644
> index 00000000..c287bb43
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/VarStore.fdf.inc
> @@ -0,0 +1,78 @@
> +## @file
> +#  FDF include file with Layout Regions that define an empty variable store.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#  Copyright (C) 2014, Red Hat, Inc.
> +#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##

Again, if this is kept as a separate file, we need to add a
[FD.U500] header.

/
     Leif

> +
> +$(VARS_OFFSET)|0x00007000
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +#
> +# NV_VARIABLE_STORE
> +#
> +DATA = {
> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
> +  # ZeroVector []
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
> +  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
> +  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
> +  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, 0x39, 0xF1, 0x00, 0x00, 0x00, 0x02,
> +  # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block
> +  0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
> +  # Blockmap[1]: End
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  ## This is the VARIABLE_STORE_HEADER
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  # Signature: gEfiAuthenticatedVariableGuid =
> +  #   { 0xaaf32c78, 0x947b, 0x439a,
> +  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
> +!else
> +  # Signature: gEfiVariableGuid =
> +  #   { 0xddcf3616, 0x3275, 0x4164,
> +  #     { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
> +  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
> +  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
> +!endif
> +  # Size: 0x7000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
> +  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x6fb8
> +  # This can speed up the Variable Dispatch a bit.
> +  0xB8, 0x6F, 0x00, 0x00,
> +  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +0x007e7000|0x00001000
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +#
> +#NV_FTW_WROK
> +#
> +DATA = {
> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
> +  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
> +  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
> +  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
> +  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
> +  # WriteQueueSize: UINT64
> +  0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +0x007e8000|0x00018000
> +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +#
> +#NV_FTW_SPARE
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform Gilbert Chen
@ 2019-10-02 21:00   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 21:00 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:25AM +0800, Gilbert Chen wrote:
> The initial header file commit for SiFive U5-MC Coreplex and U500 Core
>  Local interrupt definitions.

There is a generic issue here, and not just with this patch:
It is being added *after* the U500 platform, which depends on this.
Please reorder the set so that all of the prerequisites for the
platforms come before the platform .dsc.

Also, please add these files together with the implementations of the
functions declared here.
SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h    | 51 ++++++++++++++++++++++
>  Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h  | 19 ++++++++
>  2 files changed, 70 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h b/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
> new file mode 100644
> index 00000000..9968159c
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Include/SiFiveU5MCCoreplex.h
> @@ -0,0 +1,51 @@
> +/** @file
> +  SiFive U54 Coreplex library definitions.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SIFIVE_U5MC_COREPLEX_H_
> +#define _SIFIVE_U5MC_COREPLEX_H_

Please drop leading _.

> +
> +#include <PiPei.h>
> +
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>
> +
> +#define SIFIVE_U5MC_COREPLEX_MC_HART_ID     0
> +
> +/**
> +  Build up U5MC coreplex processor core-specific information.
> +
> +  @param  UniqueId      U5MC unique ID.
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU5MCCoreplexProcessorSpecificDataHob (
> +  IN UINTN UniqueId
> +  );
> +
> +/**
> +  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
> +  this information and build SMBIOS Type4 and Type7 record.
> +
> +  @param  ProcessorUid        Unique ID of pysical processor which owns this core.
> +  @param  SmbiosDataHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> +                              maintained in this structure is only valid before memory is discovered.
> +                              Access to those pointers after memory is installed will cause unexpected issues.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU5MCProcessorSmbiosDataHob (
> +  IN UINTN     ProcessorUid,
> +  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosDataHobPtr
> +  );
> +#endif
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h b/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
> new file mode 100644
> index 00000000..a8c9ae15
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Include/U500Clint.h
> @@ -0,0 +1,19 @@
> +/** @file
> +  RISC-V Timer Architectural definition for U500 platform.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _U500_H_
> +#define _U500_H_

Please drop leading _.

/
    Leif

> +
> +#define CLINT_REG_MTIME     0x0200BFF8
> +#define CLINT_REG_MTIMECMP0 0x02004000
> +#define CLINT_REG_MTIMECMP1 0x02004008
> +#define CLINT_REG_MTIMECMP2 0x02004010
> +#define CLINT_REG_MTIMECMP3 0x02004018
> +#define CLINT_REG_MTIMECMP4 0x02004020
> +
> +#endif
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib Gilbert Chen
@ 2019-10-02 22:02   ` Leif Lindholm
  2019-10-18  6:23     ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-02 22:02 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> SiFive RISC-V U500 Platform Boot Manager library.

First of all, let me say that I think before upstreaming to master,
you ought to look into merging PlatformBootManagerLibs for all Risc-V
platforms. Like we have for *most* ARM/AARCH64 platforms with
ArmPkg/Library/PlatformBootManagerLib/.

(Longer-term we should merge them all together into a single one.)

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../Library/PlatformBootManagerLib/MemoryTest.c    | 682 +++++++++++++++++++++
>  .../PlatformBootManagerLib/PlatformBootManager.c   | 274 +++++++++
>  .../PlatformBootManagerLib/PlatformBootManager.h   | 135 ++++
>  .../PlatformBootManagerLib.inf                     |  63 ++
>  .../Library/PlatformBootManagerLib/PlatformData.c  |  49 ++
>  .../Library/PlatformBootManagerLib/Strings.uni     |  28 +
>  6 files changed, 1231 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
> new file mode 100644
> index 00000000..8c6d89e9
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c

Why build a MemoryTest into the PlatformBootManagerLib?

> @@ -0,0 +1,682 @@
> +/** @file
> +  Perform the RISC-V platform memory test
> +
> +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +EFI_HII_HANDLE gStringPackHandle = NULL;
> +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, 0x88 }
> +  };
> +// extern UINT8  BdsDxeStrings[];

No need to keep commented-out code in.

> +
> +//
> +// BDS Platform Functions
> +//
> +/**
> +
> +  Show progress bar with title above it. It only works in Graphics mode.
> +
> +  @param TitleForeground Foreground color for Title.
> +  @param TitleBackground Background color for Title.
> +  @param Title           Title above progress bar.
> +  @param ProgressColor   Progress bar color.
> +  @param Progress        Progress (0-100)
> +  @param PreviousValue   The previous value of the progress.
> +
> +  @retval  EFI_STATUS       Success update the progress bar
> +
> +**/
> +EFI_STATUS
> +PlatformBootManagerShowProgress (

I'm not a super fan of how this file integrates a custom memory test
with a direct (copy) graphical progress indicator. There are both
common memory test and common progress indicators - please use those
instead. And improve them if they are currently insufficient for your
needs.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
> new file mode 100644
> index 00000000..9ef85089
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
> @@ -0,0 +1,274 @@
> +/** @file
> +  This file include all platform action which can be customized
> +  by IBV/OEM.
> +
> +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +
> +EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1}};
> +
> +/**
> +  Perform the platform diagnostic, such like test memory. OEM/IBV also
> +  can customize this function to support specific platform diagnostic.
> +
> +  @param MemoryTestLevel  The memory test intensive level
> +  @param QuietBoot        Indicate if need to enable the quiet boot
> +
> +**/
> +VOID
> +PlatformBootManagerDiagnostics (
> +  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
> +  IN BOOLEAN                     QuietBoot
> +  )
> +{
> +  EFI_STATUS                     Status;
> +
> +  //
> +  // Here we can decide if we need to show
> +  // the diagnostics screen
> +  // Notes: this quiet boot code should be remove
> +  // from the graphic lib
> +  //
> +  if (QuietBoot) {
> +
> +    //
> +    // Perform system diagnostic
> +    //
> +    Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
> +    return;
> +  }
> +
> +  //
> +  // Perform system diagnostic
> +  //
> +  Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
> +}
> +
> +/**
> +  Return the index of the load option in the load option array.
> +
> +  The function consider two load options are equal when the
> +  OptionType, Attributes, Description, FilePath and OptionalData are equal.
> +
> +  @param Key    Pointer to the load option to be found.
> +  @param Array  Pointer to the array of load options to be found.
> +  @param Count  Number of entries in the Array.
> +
> +  @retval -1          Key wasn't found in the Array.
> +  @retval 0 ~ Count-1 The index of the Key in the Array.
> +**/
> +INTN
> +PlatformFindLoadOption (
> +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
> +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
> +  IN UINTN                              Count
> +  )
> +{
> +  UINTN                             Index;
> +
> +  for (Index = 0; Index < Count; Index++) {
> +    if ((Key->OptionType == Array[Index].OptionType) &&
> +        (Key->Attributes == Array[Index].Attributes) &&
> +        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
> +        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
> +        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
> +        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
> +      return (INTN) Index;
> +    }
> +  }
> +
> +  return -1;
> +}
> +
> +VOID
> +PlatformRegisterFvBootOption (
> +  EFI_GUID                         *FileGuid,
> +  CHAR16                           *Description,
> +  UINT32                           Attributes
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  UINTN                             OptionIndex;
> +  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
> +  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
> +  UINTN                             BootOptionCount;
> +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
> +  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
> +  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
> +
> +  Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> +  DevicePath = AppendDevicePathNode (
> +                 DevicePathFromHandle (LoadedImage->DeviceHandle),
> +                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
> +                 );
> +
> +  Status = EfiBootManagerInitializeLoadOption (
> +             &NewOption,
> +             LoadOptionNumberUnassigned,
> +             LoadOptionTypeBoot,
> +             Attributes,
> +             Description,
> +             DevicePath,
> +             NULL,
> +             0
> +             );
> +  if (!EFI_ERROR (Status)) {
> +    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
> +
> +    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
> +
> +    if (OptionIndex == -1) {
> +      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +    EfiBootManagerFreeLoadOption (&NewOption);
> +    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> +  }
> +}
> +
> +/**
> +  Do the platform specific action before the console is connected.
> +
> +  Such as:
> +    Update console variable;
> +    Register new Driver#### or Boot####;
> +    Signal ReadyToLock event.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerBeforeConsole (
> +  VOID
> +  )
> +{
> +  UINTN                        Index;
> +  EFI_STATUS                   Status;
> +  EFI_INPUT_KEY                Enter;
> +  EFI_INPUT_KEY                F2;
> +  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
> +
> +  //
> +  // Update the console variables.
> +  //
> +  for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
> +    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
> +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));

Some really long lines here, can we wrap them?

> +    }
> +
> +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
> +    }
> +
> +    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
> +    }
> +  }
> +
> +  //
> +  // Register ENTER as CONTINUE key
> +  //
> +  Enter.ScanCode    = SCAN_NULL;
> +  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> +  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> +  //
> +  // Map F2 to Boot Manager Menu
> +  //
> +  F2.ScanCode    = SCAN_F2;
> +  F2.UnicodeChar = CHAR_NULL;
> +  EfiBootManagerGetBootManagerMenu (&BootOption);
> +  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
> +  //
> +  // Register UEFI Shell
> +  //
> +  PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
> +}
> +
> +/**
> +  Do the platform specific action after the console is connected.
> +
> +  Such as:
> +    Dynamically switch output mode;
> +    Signal console ready platform customized event;
> +    Run diagnostics like memory testing;
> +    Connect certain devices;
> +    Dispatch aditional option roms.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerAfterConsole (
> +  VOID
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Black;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  White;
> +
> +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> +  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
> +
> +  EfiBootManagerConnectAll ();
> +  EfiBootManagerRefreshAllBootOption ();
> +
> +  PlatformBootManagerDiagnostics (QUICK, TRUE);
> +
> +  PrintXY (10, 10, &White, &Black, L"F2    to enter Boot Manager Menu.                                            ");
> +  PrintXY (10, 30, &White, &Black, L"Enter to boot directly.");
> +}
> +
> +/**
> +  This function is called each second during the boot manager waits the timeout.
> +
> +  @param TimeoutRemain  The remaining timeout.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerWaitCallback (
> +  UINT16          TimeoutRemain
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
> +  UINT16                        Timeout;
> +
> +  Timeout = PcdGet16 (PcdPlatformBootTimeOut);
> +
> +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> +  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
> +
> +  PlatformBootManagerShowProgress (
> +    White,
> +    Black,
> +    L"Start boot option",
> +    White,
> +    (Timeout - TimeoutRemain) * 100 / Timeout,
> +    0
> +    );
> +}
> +
> +/**
> +  The function is called when no boot option could be launched,
> +  including platform recovery options and options pointing to applications
> +  built into firmware volumes.
> +
> +  If this function returns, BDS attempts to enter an infinite loop.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerUnableToBoot (
> +  VOID
> +  )
> +{
> +  return;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
> new file mode 100644
> index 00000000..20d66758
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
> @@ -0,0 +1,135 @@
> +/**@file
> +   Head file for BDS Platform specific code
> +
> +Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _PLATFORM_BOOT_MANAGER_H_
> +#define _PLATFORM_BOOT_MANAGER_H_

Please drop leading _.

> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Bmp.h>
> +#include <Protocol/GenericMemoryTest.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/UgaDraw.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/BootLogo.h>
> +#include <Protocol/DevicePath.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/DxeServicesLib.h>

Please remove any includes not needed by this file, and add them to
the files that actually use them.

> +
> +typedef struct {
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  UINTN                     ConnectType;
> +} PLATFORM_CONSOLE_CONNECT_ENTRY;
> +
> +extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
> +
> +#define gEndEntire \
> +  { \
> +    END_DEVICE_PATH_TYPE,\
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,\
> +    END_DEVICE_PATH_LENGTH,\
> +    0\
> +  }
> +
> +#define CONSOLE_OUT BIT0
> +#define CONSOLE_IN  BIT1
> +#define STD_ERROR   BIT2
> +
> +//D3987D4B-971A-435F-8CAF-4967EB627241
> +#define EFI_SERIAL_DXE_GUID \
> +  { 0xD3987D4B, 0x971A, 0x435F, { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } }
> +
> +typedef struct {
> +  VENDOR_DEVICE_PATH        Guid;
> +  UART_DEVICE_PATH          Uart;
> +  VENDOR_DEVICE_PATH        TerminalType;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} SERIAL_CONSOLE_DEVICE_PATH;
> +
> +/**
> +  Use SystemTable Conout to stop video based Simple Text Out consoles from going
> +  to the video device. Put up LogoFile on every video device that is a console.
> +
> +  @param[in]  LogoFile   File name of logo to display on the center of the screen.
> +
> +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo displayed.
> +  @retval EFI_UNSUPPORTED Logo not found
> +
> +**/
> +EFI_STATUS
> +PlatformBootManagerEnableQuietBoot (
> +  IN  EFI_GUID  *LogoFile
> +  );
> +
> +/**
> +  Use SystemTable Conout to turn on video based Simple Text Out consoles. The
> +  Simple Text Out screens will now be synced up with all non video output devices
> +
> +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
> +
> +**/
> +EFI_STATUS
> +PlatformBootManagerDisableQuietBoot (
> +  VOID
> +  );
> +
> +/**
> +  Perform the memory test base on the memory test intensive level,
> +  and update the memory resource.
> +
> +  @param  Level         The memory test intensive level.
> +
> +  @retval EFI_STATUS    Success test all the system memory and update
> +                        the memory resource
> +
> +**/
> +EFI_STATUS
> +PlatformBootManagerMemoryTest (
> +  IN EXTENDMEM_COVERAGE_LEVEL Level
> +  );
> +
> +/**
> +
> +  Show progress bar with title above it. It only works in Graphics mode.
> +
> +
> +  @param TitleForeground Foreground color for Title.
> +  @param TitleBackground Background color for Title.
> +  @param Title           Title above progress bar.
> +  @param ProgressColor   Progress bar color.
> +  @param Progress        Progress (0-100)
> +  @param PreviousValue   The previous value of the progress.
> +
> +  @retval  EFI_STATUS       Success update the progress bar
> +
> +**/
> +EFI_STATUS
> +PlatformBootManagerShowProgress (
> +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
> +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
> +  IN CHAR16                        *Title,
> +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
> +  IN UINTN                         Progress,
> +  IN UINTN                         PreviousValue
> +  );
> +
> +#endif // _PLATFORM_BOOT_MANAGER_H
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 00000000..92c31db4
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -0,0 +1,63 @@
> +## @file
> +#  Include all platform action which can be customized by IBV/OEM.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = PlatformBootManagerLib
> +  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV
> +#
> +
> +[Sources]
> +  PlatformData.c
> +  PlatformBootManager.c
> +  PlatformBootManager.h
> +  MemoryTest.c
> +  Strings.uni
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  UefiLib
> +  UefiBootManagerLib
> +  PcdLib
> +  DxeServicesLib
> +  MemoryAllocationLib
> +  DevicePathLib
> +  HiiLib
> +  PrintLib

Please sort Sources, Packages and LibraryClasses alphabetically.

> +
> +[Guids]
> +
> +[Protocols]
> +  gEfiGenericMemTestProtocolGuid  ## CONSUMES
> +  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
> +  gEfiUgaDrawProtocolGuid         ## CONSUMES

You're hopefully not really using UGA, so please drop that.

> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable

Please sort Pcds alphabetically.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
> new file mode 100644
> index 00000000..3208051e
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
> @@ -0,0 +1,49 @@
> +/**@file
> +  Defined the platform specific device path which will be filled to
> +  ConIn/ConOut variables.
> +
> +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +//
> +// Platform specific serial device path
> +//
> +SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
> +  {
> +    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },
> +    EFI_SERIAL_DXE_GUID  // Use the driver's GUID
> +  },
> +  {
> +    { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} },
> +    0,                  // Reserved
> +    115200,             // BaudRate
> +    8,                  // DataBits
> +    1,                  // Parity
> +    1                   // StopBits
> +  },
> +  {
> +    { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },
> +    DEVICE_PATH_MESSAGING_PC_ANSI
> +  },
> +  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
> +};
> +
> +//
> +// Predefined platform default console device path
> +//
> +PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
> +  {
> +    (EFI_DEVICE_PATH_PROTOCOL *) &gSerialConsoleDevicePath0,
> +    CONSOLE_OUT | CONSOLE_IN
> +  },
> +  {
> +    NULL,
> +    0
> +  }
> +};
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
> new file mode 100644
> index 00000000..73bf5d51
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
> @@ -0,0 +1,28 @@
> +///** @file
> +//
> +//    String definitions for PlatformBootManagerLib.
> +//
> +//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> +//
> +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//**/
> +
> +/=#
> +
> +#langdef   en-US "English"
> +#langdef   fr-FR "Français"
> +
> +#string STR_PERFORM_MEM_TEST           #language en-US  "Perform memory test (ESC to skip)"
> +                                       #language fr-FR  "Exécute l'examen de mémoire (ESC pour sauter)"
> +#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the system memory tested OK"
> +                                       #language fr-FR  "% de la mémoire de système essayée D'ACCORD"
> +#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC key to skip memory test"
> +                                       #language fr-FR  "Appuie sur ESC sauter examen de mémoire"
> +#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of system memory tested OK\r\n"
> +                                       #language fr-FR  "octets dela mémoire de système essayée D'ACCORD\r\n"

if there's a space before 'bytes' you probably want one before
'octets'.

/
    Leif

> +#string STR_SYSTEM_MEM_ERROR           #language en-US  "System encounters memory errors"
> +                                       #language fr-FR  "le Système rencontre les erreurs de mémoire"
> +#string STR_START_BOOT_OPTION          #language en-US  "Start boot option"
> +                                       #language fr-FR  "l'option de botte de Début"
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library Gilbert Chen
@ 2019-10-03 16:32   ` Leif Lindholm
  2019-10-17  2:21     ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-03 16:32 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:27AM +0800, Gilbert Chen wrote:
> OpneSbiPlatformLib
> - In order to reduce the dependencies with RISC-V OpenSBI project
> (https://github.com/riscv/opensbi) and less burdens to EDK2 build
>  process, the implementation of RISC-V EDK2 platform is leverage
>  platform source code from OpenSBI code tree. The "platform.c"
>  under OpenSbiPlatformLib is cloned from RISC-V OpenSBI code tree
>  (in EDK2 RiscVPkg) and built based on EDK2 build environment.
> 
> PeiCoreInfoHobLib
> - This is the library to create RISC-V core characteristics for building
>  up RISC-V related SMBIOS records to support the unified boot loader
>  and OS image.
> 
> - RiscVPlatformTimerLib
> This is U500 platform timer library which has the platform-specific
>  timer implementation.
> 
> - SerialPortLib
> U500 serial port platform library

Please split this up into the 4 logical commits.
And add the specific header files with those commits.

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../OpenSbiPlatformLib/OpenSbiPlatformLib.inf      |  47 ++++
>  .../U500Pkg/Library/OpenSbiPlatformLib/platform.c  | 214 ++++++++++++++++++
>  .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 195 +++++++++++++++++
>  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  58 +++++
>  .../RiscVPlatformTimerLib/RiscVPlatformTimerLib.S  |  48 ++++
>  .../RiscVPlatformTimerLib.inf                      |  39 ++++
>  .../U500Pkg/Library/SerialIoLib/SerialIoLib.inf    |  31 +++
>  .../U500Pkg/Library/SerialIoLib/SerialPortLib.c    | 241 +++++++++++++++++++++
>  .../Library/SerialIoLib/U500SerialPortLib.uni      |  16 ++
>  9 files changed, 889 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
> new file mode 100644
> index 00000000..473386d2
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatformLib.inf
> @@ -0,0 +1,47 @@
> +## @file
> +#  RISC-V OpenSbi Platform Library
> +#  This is the the required library which provides platform

Please don't use the word required. (If it wasn't, why would you
include it at all?)

> +#  level opensbi functions follow RISC-V opensbi implementation.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = OpenSbiPlatformLib
> +  FILE_GUID                      = 9424ED54-EBDA-4FB5-8FF6-8291B07BB151
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = OpenSbiPlatformLib

Seeing this, I have a bit of a feeling that this Opensbi isn't being
consistently treated/named:
- In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
  class RiscVOpensbiLib.
- Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing the
  class OpenSbiPlatformLib.
- *Logically*, what we have is
  Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
  OpensbiLib which depends on the OpenSbiPlatformLib.
  - However, there is no OpenSbiPlatformLib in edk2, which is very
    unfortunate because that does not let us build edk2/RiscVPkg in
    isolation (like we can with all the other packages in edk2).

Here is my preferred solution for untangling this:
1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
   already use for Openssl, so would be my preference.
2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
   LibararyClasses. Either is fine, the former is less likely to clash
   with other imported projects in the future (but I would estimate
   this risk as *very* low to begin with).
3) Implement a (RiscV)OpensbiPlatformLibNull in edk2/RiscVPkg/Library,
   containing only what is required to build/link
   RiscVPkg/Library/(RiscV)OpensbiLib/.
   3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
   3.6) Add a depedency on OpensbiPlatformLib to
        (RiscV)OpensbiLib.inf
   3.7) Drop the dependency on OpensbiPlatformLib from
        Platform/RiscV/Universal/Sec/SecMain.inf

(That might read like a lot of work, but really it's a 5 minute job
and if we untangle this now, this won't cascade over umpteen
platforms.)

> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV64 EBC

Drop EBC.

> +#
> +
> +[Sources]
> +  platform.c

Please rename as Platform.c.

> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec

Please sort files alphabetically.

> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  PcdLib
> +  DebugAgentLib
> +  RiscVCpuLib
> +  PrintLib

Please sort LibraryClasses alphabetically.

> +
> +[FixedPcd]
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId

Please sort Pcds alphabetically.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> new file mode 100644
> index 00000000..4dca75f2
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> @@ -0,0 +1,214 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *   Atish Patra <atish.patra@wdc.com>

Please change commit Author instead.

Please point out that this is the platform-specific portion of
OpensbiLib. With that, I'm OK with it not following EDK2 coding
style. *However*, it needs to follow OpenSBI coding style, and it
currently doesn't - 3-space indentation follows nothing.

>From what I see, OpenSBI follows Linux coding style. So please update
to that, throughout this file. *if* you untabify it (8 spaces/tab)
before submission, our tools will complain less, so do consider that.

> + */
> +
> +#include <libfdt.h>
> +#include <fdt.h>
> +#include <sbi/riscv_encoding.h>
> +#include <sbi/sbi_const.h>
> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi_console.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/riscv_io.h>
> +#include <sbi_utils/irqchip/plic.h>
> +#include <sbi_utils/serial/sifive-uart.h>
> +#include <sbi_utils/sys/clint.h>
> +
> +
> +#define U500_HART_COUNT         FixedPcdGet32(PcdHartCount)
> +#define U500_HART_STACK_SIZE   FixedPcdGet32(PcdOpenSbiStackSize)
> +#define U500_BOOT_HART_ID       FixedPcdGet32(PcdBootHartId)
> +
> +#define U500_SYS_CLK         100000000
> +
> +#define U500_CLINT_ADDR         0x2000000
> +
> +#define U500_PLIC_ADDR            0xc000000
> +#define U500_PLIC_NUM_SOURCES      0x35
> +#define U500_PLIC_NUM_PRIORITIES   7
> +
> +#define U500_UART_ADDR            0x54000000
> +
> +#define U500_UART_BAUDRATE         115200
> +
> +/**
> + * The U500 SoC has 8 HARTs but HART ID 0 doesn't have S mode.
> + * HARTs 1 is selected as boot HART
> + */
> +#ifndef U500_ENABLED_HART_MASK
> +#define U500_ENABLED_HART_MASK   (1 << U500_BOOT_HART_ID)
> +#endif
> +
> +#define U500_HARTID_DISABLED   ~(U500_ENABLED_HART_MASK)
> +
> +/* PRCI clock related macros */
> +//TODO: Do we need a separate driver for this ?

Well, do we?

> +#define U500_PRCI_BASE_ADDR         0x10000000
> +#define U500_PRCI_CLKMUXSTATUSREG   0x002C
> +#define U500_PRCI_CLKMUX_STATUS_TLCLKSEL   (0x1 << 1)

Please adjust right-column alignment through the defines above.

> +
> +static void U500_modify_dt(void *fdt)
> +{
> +   u32 i, size;


> +   int chosen_offset, err;
> +   int cpu_offset;
> +   char cpu_node[32] = "";
> +   const char *mmu_type;
> +
> +   for (i = 0; i < U500_HART_COUNT; i++) {
> +      sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
> +      cpu_offset = fdt_path_offset(fdt, cpu_node);
> +      mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
> +      if (mmu_type && (!strcmp(mmu_type, "riscv,sv39") ||
> +          !strcmp(mmu_type,"riscv,sv48")))
> +         continue;
> +      else
> +         fdt_setprop_string(fdt, cpu_offset, "status", "masked");
> +      memset(cpu_node, 0, sizeof(cpu_node));
> +   }
> +   size = fdt_totalsize(fdt);
> +   err = fdt_open_into(fdt, fdt, size + 256);
> +   if (err < 0)
> +      sbi_printf("Device Tree can't be expanded to accmodate new node");
> +
> +   chosen_offset = fdt_path_offset(fdt, "/chosen");
> +   fdt_setprop_string(fdt, chosen_offset, "stdout-path",
> +            "/soc/serial@10010000:115200");
> +
> +   plic_fdt_fixup(fdt, "riscv,plic0");
> +}
> +
> +static int U500_final_init(bool cold_boot)
> +{
> +   void *fdt;
> +
> +   if (!cold_boot)
> +      return 0;
> +
> +   fdt = sbi_scratch_thishart_arg1_ptr();
> +   U500_modify_dt(fdt);
> +
> +   return 0;
> +}
> +
> +static u32 U500_pmp_region_count(u32 hartid)
> +{
> +   return 1;
> +}
> +
> +static int U500_pmp_region_info(u32 hartid, u32 index,
> +             ulong *prot, ulong *addr, ulong *log2size)
> +{
> +   int ret = 0;
> +
> +   switch (index) {
> +   case 0:
> +      *prot = PMP_R | PMP_W | PMP_X;
> +      *addr = 0;
> +      *log2size = __riscv_xlen;
> +      break;
> +   default:
> +      ret = -1;
> +      break;
> +   };
> +
> +   return ret;
> +}
> +
> +static int U500_console_init(void)
> +{
> +   unsigned long peri_in_freq;
> +
> +   peri_in_freq = U500_SYS_CLK/2;
> +   return sifive_uart_init(U500_UART_ADDR, peri_in_freq, U500_UART_BAUDRATE);
> +}
> +
> +static int U500_irqchip_init(bool cold_boot)
> +{
> +   int rc;
> +   u32 hartid = sbi_current_hartid();
> +
> +   if (cold_boot) {
> +      rc = plic_cold_irqchip_init(U500_PLIC_ADDR,
> +                   U500_PLIC_NUM_SOURCES,
> +                   U500_HART_COUNT);
> +      if (rc)
> +         return rc;
> +   }
> +
> +   return plic_warm_irqchip_init(hartid,
> +         (hartid) ? (2 * hartid - 1) : 0,
> +         (hartid) ? (2 * hartid) : -1);
> +}
> +
> +static int U500_ipi_init(bool cold_boot)
> +{
> +   int rc;
> +
> +   if (cold_boot) {
> +      rc = clint_cold_ipi_init(U500_CLINT_ADDR,
> +                U500_HART_COUNT);
> +      if (rc)
> +         return rc;
> +
> +   }
> +
> +   return clint_warm_ipi_init();
> +}
> +
> +static int U500_timer_init(bool cold_boot)
> +{
> +   int rc;
> +
> +   if (cold_boot) {
> +      rc = clint_cold_timer_init(U500_CLINT_ADDR,
> +                  U500_HART_COUNT);
> +      if (rc)
> +         return rc;
> +   }
> +
> +   return clint_warm_timer_init();
> +}
> +
> +static int U500_system_down(u32 type)
> +{
> +   /* For now nothing to do. */
> +   return 0;
> +}
> +
> +const struct sbi_platform_operations platform_ops = {
> +   .pmp_region_count = U500_pmp_region_count,
> +   .pmp_region_info = U500_pmp_region_info,
> +   .final_init = U500_final_init,
> +   .console_putc = sifive_uart_putc,
> +   .console_getc = sifive_uart_getc,
> +   .console_init = U500_console_init,
> +   .irqchip_init = U500_irqchip_init,
> +   .ipi_send = clint_ipi_send,
> +   .ipi_sync = clint_ipi_sync,
> +   .ipi_clear = clint_ipi_clear,
> +   .ipi_init = U500_ipi_init,
> +   .timer_value = clint_timer_value,
> +   .timer_event_stop = clint_timer_event_stop,
> +   .timer_event_start = clint_timer_event_start,
> +   .timer_init = U500_timer_init,
> +   .system_reboot = U500_system_down,
> +   .system_shutdown = U500_system_down
> +};
> +
> +const struct sbi_platform platform = {
> +   .opensbi_version   = OPENSBI_VERSION,                  // The OpenSBI version this platform table is built bassed on.
> +   .platform_version   = SBI_PLATFORM_VERSION(0x0001, 0x0000),   // SBI Platform version 1.0
> +   .name               = "SiFive Freedom U500",
> +   .features      = SBI_PLATFORM_DEFAULT_FEATURES,
> +   .hart_count      = U500_HART_COUNT,
> +   .hart_stack_size   = U500_HART_STACK_SIZE,
> +   .disabled_hart_mask   = U500_HARTID_DISABLED,
> +   .platform_ops_addr   = (unsigned long)&platform_ops
> +};
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> new file mode 100644
> index 00000000..bfb97351
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> @@ -0,0 +1,195 @@
> +/**@file
> +  Build up platform processor information.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#include <SmbiosProcessorSpecificData.h>
> +#include <ProcessorSpecificDataHob.h>
> +#include <SiFiveU5MCCoreplex.h>
> +#include <Library/SiFiveE51.h>
> +#include <Library/SiFiveU54.h>

Please sort includes alphabetically.

> +
> +/**
> +  Build up processor-specific HOB for U5MC Coreplex
> +
> +  @param  UniqueId      Unique ID of this U5MC Coreplex processor
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU5MCCoreplexProcessorSpecificDataHob (
> +  IN UINTN UniqueId
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32 HartIdNumber;
> +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *GuidHobData;
> +  EFI_GUID *ParentCoreGuid;
> +  BOOLEAN MCSupport;
> +
> +  DEBUG ((DEBUG_INFO, "Building U5 Coreplex processor information HOB\n"));
> +
> +  HartIdNumber = 0;
> +  ParentCoreGuid = PcdGetPtr(PcdSiFiveU5MCCoreplexGuid);
> +  MCSupport = PcdGetBool (PcdE5MCSupported);
> +  if (MCSupport == TRUE) {
> +    Status = CreateE51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, FALSE, &GuidHobData);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
> +      ASSERT (FALSE);
> +    }
> +    HartIdNumber ++;
> +    DEBUG ((DEBUG_INFO, "Support E5 Monitor core on U500 platform, HOB at address 0x%x\n", GuidHobData));

Hmm, OK, this was why you had the different LibraryClasses?
I still don't think it should be a separate libraryclass per
CPU. If possible, I would prefer MonitorCoreInfoLib and
ApplicationCoreInfoLib.

> +  }
> +  for (; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) + (UINT32)MCSupport); HartIdNumber ++) {
> +    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32 (PcdBootHartId))? TRUE: FALSE, &GuidHobData);

Nesting that ternary saves you nothing other than typing, and not much
of that. Please use a temporary variable instead:

   BOOL IsBootHart;
   IsBootHart = HartIdNumber == FixedPcdGet32 (PcdBootHartId)) ? TRUE : FALSE
   /* Also, always spaces around ? and : for ternaries. */
   /* No, don't actually include this comment. */
   Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId,
              HartIdNumber, IsBootHart, &GuidHobData);

> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
> +      ASSERT (FALSE);
> +    }
> +    DEBUG ((DEBUG_INFO, "Support U5 application core on U500 platform, HOB Data at address 0x%x\n", GuidHobData));
> +  }
> +  DEBUG ((DEBUG_INFO, "Support %d U5 application cores on U500 platform\n", HartIdNumber - (UINT32)MCSupport));

Please wrap those DEBUG lines. Not the strings, just the arguments.

> +
> +  if (HartIdNumber != FixedPcdGet32 (PcdHartCount)) {
> +    DEBUG ((DEBUG_ERROR, "Improper core settings...\n"));
> +    DEBUG ((DEBUG_ERROR, "    PcdHartCount\n"));
> +    DEBUG ((DEBUG_ERROR, "    PcdNumberofU5Cores\n"));
> +    DEBUG ((DEBUG_ERROR, "    PcdE5MCSupported\n\n"));
> +    ASSERT (FALSE);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect
> +  this information and build SMBIOS Type4 and Type7 record.
> +
> +  @param  ProcessorUid    Unique ID of pysical processor which owns this core.
> +  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> +                          maintained in this structure is only valid before memory is discovered.
> +                          Access to those pointers after memory is installed will cause unexpected issues.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateU5MCProcessorSmbiosDataHob (
> +  IN UINTN     ProcessorUid,
> +  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> +  )
> +{
> +  EFI_GUID *GuidPtr;
> +  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
> +  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
> +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
> +  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
> +  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
> +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
> +
> +  DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
> +
> +  if (SmbiosHobPtr == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Build up SMBIOS type 7 L2 cache record.
> +  //
> +  ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
> +  L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid));
> +  L2CacheDataHob.ProcessorUid = ProcessorUid;
> +  L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR;
> +  L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
> +      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
> +      RISC_V_CACHE_CONFIGURATION_ENABLED | \
> +      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
> +  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR;
> +  L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR;
> +  L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
> +  L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
> +  L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR;
> +  L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR;
> +  L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified;
> +  L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR;
> +  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid);
> +  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_DATA_HOB));

Please wrap long line.

> +  if (L2CacheDataHobPtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));

Please wrap long line. (That format string is longer than 80
characters on its own, consider shortening it.)

> +    ASSERT (FALSE);
> +  }
> +
> +  //
> +  // Build up SMBIOS type 4 record.
> +  //
> +  ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> +  ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid));
> +  ProcessorDataHob.ProcessorUid = ProcessorUid;
> +  ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor;
> +  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2;
> +  ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture = TO_BE_FILLED_BY_VENDOR;
> +  SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);

Please wrap long line.

> +  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1;
> +  ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE;
> +  ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> +  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> +  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
> +  ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE;
> +  ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR;
> +  ProcessorDataHob.SmbiosType4Processor.CoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);
> +  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);
> +  ProcessorDataHob.SmbiosType4Processor.ThreadCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported);

Please wrap long lines.
There are several more cases in this file, I'll stop pointing them out,
but the general rule is no longer than 80. PatchCheck.py is a bit lax
on this.

> +  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable
> +  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64;
> +  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
> +  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
> +  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;
> +  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
> +  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> +  if (ProcessorDataHobPtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
> +    ASSERT (FALSE);
> +  }
> +
> +  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> +  SmbiosDataHob.Processor = ProcessorDataHobPtr;
> +  SmbiosDataHob.L1InstCache = NULL;
> +  SmbiosDataHob.L1DataCache = NULL;
> +  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
> +  SmbiosDataHob.L3Cache = NULL;
> +  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
> +  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> +  if (SmbiosDataHobPtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
> +    ASSERT (FALSE);
> +  }
> +  *SmbiosHobPtr = SmbiosDataHobPtr;
> +  DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> new file mode 100644
> index 00000000..915021f9
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> @@ -0,0 +1,58 @@
> +## @file
> +#  Library instance to create core information HOB
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = SiliconSiFiveU5MCCoreplexInfoLib
> +  FILE_GUID                      = 4E397A71-5164-4E69-9884-70CBE2740AAB
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SiliconSiFiveU5MCCoreplexInfoLib
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV
> +#
> +
> +[Sources]
> + CoreInfoHob.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec
> +  Platform/RiscV/SiFive/U500Pkg/U500.dec
> +  Silicon/SiFive/SiFive.dec
> +  RiscVPkg/RiscVPkg.dec

Please sort alphabetically.

> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  MemoryAllocationLib
> +  PrintLib
> +  SiliconSiFiveE51CoreInfoLib
> +  SiliconSiFiveU54CoreInfoLib

Please sort alphabetically.

> +
> +[Guids]
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid

I'm reasonably sure you don't need to declare the TokenSpaceGuid in
order to access the Pcds.

> +
> +[Ppis]
> +
> +[FixedPcd]
> +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
> +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
> +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid
> +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId

Please sort alphabetically.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
> new file mode 100644
> index 00000000..bb4aafb9
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
> @@ -0,0 +1,48 @@
> +//------------------------------------------------------------------------------
> +//
> +// SiFive U500 Timer CSR functions.
> +//
> +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//------------------------------------------------------------------------------
> +#include <Base.h>
> +#include <RiscV.h>
> +#include <U500Clint.h>
> +
> +.data
> +
> +.text
> +.align 3
> +
> +.global ASM_PFX(RiscVReadMachineTimer)
> +.global ASM_PFX(RiscVSetMachineTimerCmp)
> +.global ASM_PFX(RiscVReadMachineTimerCmp)
> +
> +//
> +// Read machine timer CSR.
> +// @retval a0 : 64-bit machine timer.
> +//
> +ASM_PFX (RiscVReadMachineTimer):
> +    li t1, CLINT_REG_MTIME
> +    ld a0, (t1)
> +    ret
> +
> +//
> +// Set machine timer compare CSR.
> +// @param a0 : UINT64
> +//
> +ASM_PFX (RiscVSetMachineTimerCmp):
> +    li t1, CLINT_REG_MTIMECMP0
> +    sd a0, (t1)
> +    ret
> +
> +//
> +// Read machine timer compare CSR.
> +// @param a0 : UINT64
> +//
> +ASM_PFX (RiscVReadMachineTimerCmp):
> +    li t1, CLINT_REG_MTIMECMP0
> +    ld a0, (t1)
> +    ret
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
> new file mode 100644
> index 00000000..62771b68
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# RISC-V CPU lib to override timer mechanism for U500 platform.
> +#
> +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = RiscVPlatformTimerLib
> +  FILE_GUID                      = AFA75BBD-DE9D-4E77-BD88-1EA401BE931D
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = RiscVPlatformTimerLib
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV32 RISCV64
> +#
> +
> +[Sources]
> +
> +[Sources.RISCV32]
> +  RiscVPlatformTimerLib.s
> +

Please drop RISCV32 for now.

> +[Sources.RISCV64]
> +  RiscVPlatformTimerLib.s
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +  Platform/RiscV/SiFive/U500Pkg/U500.dec

Please sort alphabetically.

> +
> +
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> new file mode 100644
> index 00000000..85af1fbd
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> @@ -0,0 +1,31 @@
> +## @file
> +#   Library instance for SerialIo library class
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = U500SerialPortLib
> +  MODULE_UNI_FILE                = U500SerialPortLib.uni
> +  FILE_GUID                      = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SerialPortLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec

Please sort alphabetically.

> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  RiscVOpensbiLib
> +
> +[Sources]
> +  SerialPortLib.c
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> new file mode 100644
> index 00000000..e51bf9c1
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> @@ -0,0 +1,241 @@
> +/** @file
> +  UART Serial Port library functions
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/IoLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <sbi_utils/serial/sifive-uart.h>
> +
> +#define REG32(p, i) ((p)[(i) >> 2])

Please use the IoLib functions instead.

> +
> +//---------------------------------------------
> +// UART Register Offsets
> +//---------------------------------------------
> +
> +#define UART_REG_IP     0x14
> +  #define UART_IP_RXWM 0x02

Please drop indentation at start of line.

> +
> +//---------------------------------------------
> +// UART Settings
> +//---------------------------------------------
> +
> +#define U500_UART_ADDR      0x54000000
> +#define U500_UART_BAUDRATE  115200
> +#define U500_SYS_CLK        100000000
> +
> +/**
> +  Initialize the serial device hardware.
> +
> +  If no initialization is required, then return RETURN_SUCCESS.
> +  If the serial device was successfuly initialized, then return RETURN_SUCCESS.
> +  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
> +
> +  @retval RETURN_SUCCESS        The serial device was initialized.
> +  @retval RETURN_DEVICE_ERROR   The serail device could not be initialized.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortInitialize (
> +  VOID
> +  )
> +{
> +  if (sifive_uart_init (U500_UART_ADDR, U500_SYS_CLK/2, U500_UART_BAUDRATE) != 0) {
> +      return EFI_DEVICE_ERROR;

Indentation is only 2 spaces.

> +  }
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Write data from buffer to serial device.
> +
> +  Writes NumberOfBytes data bytes from Buffer to the serial device.
> +  The number of bytes actually written to the serial device is returned.
> +  If the return value is less than NumberOfBytes, then the write operation failed.
> +
> +  If Buffer is NULL, then ASSERT().
> +
> +  If NumberOfBytes is zero, then return 0.
> +
> +  @param  Buffer           Pointer to the data buffer to be written.
> +  @param  NumberOfBytes    Number of bytes to written to the serial device.
> +
> +  @retval 0                NumberOfBytes is 0.
> +  @retval >0               The number of bytes written to the serial device.
> +                           If this value is less than NumberOfBytes, then the write operation failed.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortWrite (
> +  IN UINT8     *Buffer,
> +  IN UINTN     NumberOfBytes
> +  )
> +{
> +  UINTN i;

I

> +
> +  if (Buffer == NULL) {
> +    return 0;
> +  }
> +
> +  for(i=0; i < NumberOfBytes; i++) {

     for (I = 0; I < NumberOfBytes; I++) {

> +    sifive_uart_putc (Buffer[i]);
> +  }
> +
> +  return i;
> +}
> +
> +
> +/**
> +  Reads data from a serial device into a buffer.
> +
> +  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.
> +  @param  NumberOfBytes    Number of bytes to read from the serial device.
> +
> +  @retval 0                NumberOfBytes is 0.
> +  @retval >0               The number of bytes read from the serial device.
> +                           If this value is less than NumberOfBytes, then the read operation failed.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortRead (
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes
> +  )
> +{
> +  UINTN i;

I

> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  for(i=0; i < NumberOfBytes; i++) {

     for (I = 0; I < NumberOfBytes; I++) {
  
> +    Buffer[i] = (UINT8)sifive_uart_getc ();
> +  }
> +
> +  return i;
> +}
> +
> +/**
> +  Polls a serial device to see if there is any data waiting to be read.
> +
> +  Polls aserial device to see if there is any data waiting to be read.
> +  If there is data waiting to be read from the serial device, then TRUE is returned.
> +  If there is no data waiting to be read from the serial device, then FALSE is returned.
> +
> +  @retval TRUE             Data is waiting to be read from the serial device.
> +  @retval FALSE            There is no data waiting to be read from the serial device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +SerialPortPoll (
> +  VOID
> +  )
> +{
> +  static volatile UINT32 * const uart = (void *)(U500_UART_ADDR);

Please use IoLib functions instead.

> +  UINT32 ip;

IP

> +
> +  ip = REG32(uart, UART_REG_IP);
> +  if(ip & UART_IP_RXWM) {

Space before (

> +    return TRUE;
> +  }
> +  else {

} else {

/
    Leif

> +    return FALSE;
> +  }
> +}
> +
> +/**
> +  Sets the control bits on a serial device.
> +
> +  @param Control                Sets the bits of Control that are settable.
> +
> +  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
> +  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
> +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetControl (
> +  IN UINT32 Control
> +  )
> +{
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Retrieve the status of the control bits on a serial device.
> +
> +  @param Control                A pointer to return the current control signals from the serial device.
> +
> +  @retval RETURN_SUCCESS        The control bits were read from the serial device.
> +  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
> +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortGetControl (
> +  OUT UINT32 *Control
> +  )
> +{
> +  *Control = 0;
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
> +  data bits, and stop bits on a serial device.
> +
> +  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
> +                            device's default interface speed.
> +                            On output, the value actually set.
> +  @param ReveiveFifoDepth   The requested depth of the FIFO on the receive side of the
> +                            serial interface. A ReceiveFifoDepth value of 0 will use
> +                            the device's default FIFO depth.
> +                            On output, the value actually set.
> +  @param Timeout            The requested time out for a single character in microseconds.
> +                            This timeout applies to both the transmit and receive side of the
> +                            interface. A Timeout value of 0 will use the device's default time
> +                            out value.
> +                            On output, the value actually set.
> +  @param Parity             The type of parity to use on this serial device. A Parity value of
> +                            DefaultParity will use the device's default parity value.
> +                            On output, the value actually set.
> +  @param DataBits           The number of data bits to use on the serial device. A DataBits
> +                            vaule of 0 will use the device's default data bit setting.
> +                            On output, the value actually set.
> +  @param StopBits           The number of stop bits to use on this serial device. A StopBits
> +                            value of DefaultStopBits will use the device's default number of
> +                            stop bits.
> +                            On output, the value actually set.
> +
> +  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
> +  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
> +  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
> +  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetAttributes (
> +  IN OUT UINT64             *BaudRate,
> +  IN OUT UINT32             *ReceiveFifoDepth,
> +  IN OUT UINT32             *Timeout,
> +  IN OUT EFI_PARITY_TYPE    *Parity,
> +  IN OUT UINT8              *DataBits,
> +  IN OUT EFI_STOP_BITS_TYPE *StopBits
> +  )
> +{
> +  return RETURN_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
> new file mode 100644
> index 00000000..49163bd8
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.uni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// Library instance for SerialIo library class
> +//
> +// Library instance for SerialIO library class.
> +//
> +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Library instance for SerialIO library class"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "Library instance for SerialIO library class."
> +
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable.
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable Gilbert Chen
@ 2019-10-03 16:58   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-03 16:58 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:28AM +0800, Gilbert Chen wrote:
> Firmware Volume Block driver instance for ram based EFI variable on U500
>  platform.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c         |  127 +++
>  .../FvbServicesRuntimeDxe.inf                      |   81 ++
>  .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c  | 1123 ++++++++++++++++++++
>  .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h  |  187 ++++
>  .../RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c   |  151 +++
>  .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.c        |  144 +++
>  .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.h        |   85 ++
>  .../Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c     |   20 +
>  8 files changed, 1918 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
> new file mode 100644
> index 00000000..1ade0d14
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
> @@ -0,0 +1,127 @@
> +/**@file
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:
> +
> +    FvbInfo.c
> +
> +  Abstract:
> +
> +    Defines data structure that is the volume header found.These data is intent
> +    to decouple FVB driver with FV header.
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <Pi/PiFirmwareVolume.h>
> +
> +//
> +// The protocols, PPI and GUID defintions for this module
> +//
> +#include <Guid/SystemNvDataGuid.h>
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +
> +typedef struct {
> +  UINT64                      FvLength;
> +  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
> +  //
> +  // EFI_FV_BLOCK_MAP_ENTRY    ExtraBlockMap[n];//n=0
> +  //
> +  EFI_FV_BLOCK_MAP_ENTRY      End[1];
> +} EFI_FVB_MEDIA_INFO;
> +
> +EFI_FVB_MEDIA_INFO  mPlatformFvbMediaInfo[] = {
> +  //
> +  // Systen NvStorage FVB
> +  //
> +  {
> +    FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +    FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +    FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
> +    {
> +      {
> +        0,
> +      },  // ZeroVector[16]
> +      EFI_SYSTEM_NV_DATA_FV_GUID,
> +      FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +      FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +      FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
> +      EFI_FVH_SIGNATURE,
> +      EFI_FVB2_MEMORY_MAPPED |
> +        EFI_FVB2_READ_ENABLED_CAP |
> +        EFI_FVB2_READ_STATUS |
> +        EFI_FVB2_WRITE_ENABLED_CAP |
> +        EFI_FVB2_WRITE_STATUS |
> +        EFI_FVB2_ERASE_POLARITY |
> +        EFI_FVB2_ALIGNMENT_16,
> +      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
> +      0,  // CheckSum
> +      0,  // ExtHeaderOffset
> +      {
> +        0,
> +      },  // Reserved[1]
> +      2,  // Revision
> +      {
> +        {
> +          (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +           FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +           FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)) /
> +          FixedPcdGet32 (PcdVariableFdBlockSize),
> +          FixedPcdGet32 (PcdVariableFdBlockSize),
> +        }
> +      } // BlockMap[1]
> +    },
> +    {
> +      {
> +        0,
> +        0
> +      }
> +    }  // End[1]
> +  }
> +};
> +
> +EFI_STATUS
> +GetFvbInfo (
> +  IN  UINT64                        FvLength,
> +  OUT EFI_FIRMWARE_VOLUME_HEADER    **FvbInfo
> +  )
> +{
> +  STATIC BOOLEAN Checksummed = FALSE;
> +  UINTN Index;
> +
> +  if (!Checksummed) {
> +    for (Index = 0;
> +         Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO);
> +         Index += 1) {
> +      UINT16 Checksum;
> +      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0;
> +      Checksum = CalculateCheckSum16 (
> +                   (UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo,
> +                   mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength
> +                   );
> +      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum;
> +    }
> +    Checksummed = TRUE;
> +  }
> +
> +  for (Index = 0;
> +       Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO);
> +       Index += 1) {
> +    if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
> +      *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> new file mode 100644
> index 00000000..1e8aa592
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> @@ -0,0 +1,81 @@
> +## @file
> +#  Component description file for RAM Flash Fimware Volume Block DXE driver
> +#  module.
> +#
> +#  This DXE runtime driver implements and produces the Fimware Volue Block
> +#  Protocol for a RAM flash device.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FvbServicesRuntimeDxe
> +  FILE_GUID                      = B04036D3-4C60-43D6-9850-0FCC090FF054
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = FvbInitialize
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  FvbInfo.c
> +  FwBlockService.c
> +  FwBlockServiceDxe.c
> +  RamFlash.c
> +  RamFlashDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  DxeServicesTableLib
> +  MemoryAllocationLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiRuntimeLib
> +
> +[Guids]
> +  gEfiEventVirtualAddressChangeGuid   # ALWAYS_CONSUMED
> +  # gEfiEventVirtualAddressChangeGuid # Create Event: EVENT_GROUP_GUID
> +
> +[Protocols]
> +  gEfiFirmwareVolumeBlockProtocolGuid           # PROTOCOL SOMETIMES_PRODUCED
> +  gEfiDevicePathProtocolGuid                    # PROTOCOL SOMETIMES_PRODUCED
> +
> +[FixedPcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
> +
> +[Depex]
> +  TRUE
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
> new file mode 100644
> index 00000000..8b89d2e0
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
> @@ -0,0 +1,1123 @@
> +/**@file
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:
> +
> +    FWBlockService.c
> +
> +  Abstract:
> +
> +  Revision History
> +
> +**/
> +
> +//
> +// The protocols, PPI and GUID defintions for this module
> +//
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/FirmwareVolumeBlock.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include "FwBlockService.h"
> +#include "RamFlash.h"
> +
> +#define EFI_FVB2_STATUS \
> +          (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
> +
> +ESAL_FWB_GLOBAL         *mFvbModuleGlobal;
> +
> +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_MEMMAP_DP,
> +      {
> +        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
> +        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
> +      }
> +    },
> +    EfiMemoryMappedIO,
> +    (EFI_PHYSICAL_ADDRESS) 0,
> +    (EFI_PHYSICAL_ADDRESS) 0,
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      END_DEVICE_PATH_LENGTH,
> +      0
> +    }
> +  }
> +};
> +
> +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
> +  {
> +    {
> +      MEDIA_DEVICE_PATH,
> +      MEDIA_PIWG_FW_VOL_DP,
> +      {
> +        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
> +        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
> +      }
> +    },
> +    { 0 }
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      END_DEVICE_PATH_LENGTH,
> +      0
> +    }
> +  }
> +};
> +
> +EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
> +  FVB_DEVICE_SIGNATURE,
> +  NULL,
> +  0,
> +  {
> +    FvbProtocolGetAttributes,
> +    FvbProtocolSetAttributes,
> +    FvbProtocolGetPhysicalAddress,
> +    FvbProtocolGetBlockSize,
> +    FvbProtocolRead,
> +    FvbProtocolWrite,
> +    FvbProtocolEraseBlocks,
> +    NULL
> +  }
> +};
> +
> +
> +EFI_STATUS
> +GetFvbInstance (
> +  IN  UINTN                               Instance,
> +  IN  ESAL_FWB_GLOBAL                     *Global,
> +  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance
> +  )
> +/*++
> +
> +  Routine Description:
> +    Retrieves the physical address of a memory mapped FV
> +
> +  Arguments:
> +    Instance              - The FV instance whose base address is going to be
> +                            returned
> +    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
> +                            instance data
> +    FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +    EFI_INVALID_PARAMETER - Instance not found
> +
> +--*/
> +{
> +  EFI_FW_VOL_INSTANCE *FwhRecord;
> +
> +  *FwhInstance = NULL;
> +  if (Instance >= Global->NumFv) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Find the right instance of the FVB private data
> +  //
> +  FwhRecord = Global->FvInstance;
> +  while (Instance > 0) {
> +    FwhRecord = (EFI_FW_VOL_INSTANCE *)
> +      (
> +        (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +

Please don't cast to UINT8 * to get around integer arithmetic, just
cast to UINTN from the start.

> +          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
> +      );
> +    Instance--;
> +  }
> +
> +  *FwhInstance = FwhRecord;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +FvbGetPhysicalAddress (
> +  IN UINTN                                Instance,
> +  OUT EFI_PHYSICAL_ADDRESS                *Address,
> +  IN ESAL_FWB_GLOBAL                      *Global
> +  )
> +/*++
> +
> +  Routine Description:
> +    Retrieves the physical address of a memory mapped FV
> +
> +  Arguments:
> +    Instance              - The FV instance whose base address is going to be
> +                            returned
> +    Address               - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
> +                            that on successful return, contains the base
> +                            address of the firmware volume.
> +    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
> +                            instance data
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +    EFI_INVALID_PARAMETER - Instance not found
> +
> +--*/
> +{
> +  EFI_FW_VOL_INSTANCE *FwhInstance;
> +  EFI_STATUS          Status;
> +
> +  //
> +  // Find the right instance of the FVB private data
> +  //
> +  Status = GetFvbInstance (Instance, Global, &FwhInstance);
> +  ASSERT_EFI_ERROR (Status);
> +  *Address = FwhInstance->FvBase;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +FvbGetVolumeAttributes (
> +  IN UINTN                                Instance,
> +  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
> +  IN ESAL_FWB_GLOBAL                      *Global
> +  )
> +/*++
> +
> +  Routine Description:
> +    Retrieves attributes, insures positive polarity of attribute bits, returns
> +    resulting attributes in output parameter
> +
> +  Arguments:
> +    Instance              - The FV instance whose attributes is going to be
> +                            returned
> +    Attributes            - Output buffer which contains attributes
> +    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
> +                            instance data
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +    EFI_INVALID_PARAMETER - Instance not found
> +
> +--*/
> +{
> +  EFI_FW_VOL_INSTANCE *FwhInstance;
> +  EFI_STATUS          Status;
> +
> +  //
> +  // Find the right instance of the FVB private data
> +  //
> +  Status = GetFvbInstance (Instance, Global, &FwhInstance);
> +  ASSERT_EFI_ERROR (Status);
> +  *Attributes = FwhInstance->VolumeHeader.Attributes;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +FvbGetLbaAddress (
> +  IN  UINTN                               Instance,
> +  IN  EFI_LBA                             Lba,
> +  OUT UINTN                               *LbaAddress,
> +  OUT UINTN                               *LbaLength,
> +  OUT UINTN                               *NumOfBlocks,
> +  IN  ESAL_FWB_GLOBAL                     *Global
> +  )
> +/*++
> +
> +  Routine Description:
> +    Retrieves the starting address of an LBA in an FV
> +
> +  Arguments:
> +    Instance              - The FV instance which the Lba belongs to
> +    Lba                   - The logical block address
> +    LbaAddress            - On output, contains the physical starting address
> +                            of the Lba
> +    LbaLength             - On output, contains the length of the block
> +    NumOfBlocks           - A 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
> +    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
> +                            instance data
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +    EFI_INVALID_PARAMETER - Instance not found
> +
> +--*/
> +{
> +  UINT32                  NumBlocks;
> +  UINT32                  BlockLength;
> +  UINTN                   Offset;
> +  EFI_LBA                 StartLba;
> +  EFI_LBA                 NextLba;
> +  EFI_FW_VOL_INSTANCE     *FwhInstance;
> +  EFI_FV_BLOCK_MAP_ENTRY  *BlockMap;
> +  EFI_STATUS              Status;
> +
> +  //
> +  // Find the right instance of the FVB private data
> +  //
> +  Status = GetFvbInstance (Instance, Global, &FwhInstance);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  StartLba  = 0;
> +  Offset    = 0;
> +  BlockMap  = &(FwhInstance->VolumeHeader.BlockMap[0]);
> +
> +  //
> +  // Parse the blockmap of the FV to find which map entry the Lba belongs to
> +  //
> +  while (TRUE) {
> +    NumBlocks   = BlockMap->NumBlocks;
> +    BlockLength = BlockMap->Length;
> +
> +    if (NumBlocks == 0 || BlockLength == 0) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    NextLba = StartLba + NumBlocks;
> +
> +    //
> +    // The map entry found
> +    //
> +    if (Lba >= StartLba && Lba < NextLba) {
> +      Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);
> +      if (LbaAddress != NULL) {
> +        *LbaAddress = FwhInstance->FvBase + Offset;
> +      }
> +
> +      if (LbaLength != NULL) {
> +        *LbaLength = BlockLength;
> +      }
> +
> +      if (NumOfBlocks != NULL) {
> +        *NumOfBlocks = (UINTN) (NextLba - Lba);
> +      }
> +
> +      return EFI_SUCCESS;
> +    }
> +
> +    StartLba  = NextLba;
> +    Offset    = Offset + NumBlocks * BlockLength;
> +    BlockMap++;
> +  }
> +}
> +
> +EFI_STATUS
> +FvbSetVolumeAttributes (
> +  IN UINTN                                  Instance,
> +  IN OUT EFI_FVB_ATTRIBUTES_2               *Attributes,
> +  IN ESAL_FWB_GLOBAL                        *Global
> +  )
> +/*++
> +
> +  Routine Description:
> +    Modifies the current settings of the firmware volume according to the
> +    input parameter, and returns the new setting of the volume
> +
> +  Arguments:
> +    Instance              - The FV instance whose attributes is going to be
> +                            modified
> +    Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
> +                            containing the desired firmware volume settings.
> +                            On successful return, it contains the new settings
> +                            of the firmware volume
> +    Global                - Pointer to ESAL_FWB_GLOBAL that contains all
> +                            instance data
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +    EFI_ACCESS_DENIED     - The volume setting is locked and cannot be modified
> +    EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
> +                            in conflict with the capabilities as declared in
> +                            the firmware volume header
> +
> +--*/
> +{
> +  EFI_FW_VOL_INSTANCE   *FwhInstance;
> +  EFI_FVB_ATTRIBUTES_2  OldAttributes;
> +  EFI_FVB_ATTRIBUTES_2  *AttribPtr;
> +  UINT32                Capabilities;
> +  UINT32                OldStatus;
> +  UINT32                NewStatus;
> +  EFI_STATUS            Status;
> +  EFI_FVB_ATTRIBUTES_2  UnchangedAttributes;
> +
> +  //
> +  // Find the right instance of the FVB private data
> +  //
> +  Status = GetFvbInstance (Instance, Global, &FwhInstance);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  AttribPtr     =
> +    (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
> +  OldAttributes = *AttribPtr;
> +  Capabilities  = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \
> +                                   EFI_FVB2_READ_ENABLED_CAP | \
> +                                   EFI_FVB2_WRITE_DISABLED_CAP | \
> +                                   EFI_FVB2_WRITE_ENABLED_CAP | \
> +                                   EFI_FVB2_LOCK_CAP \
> +                                   );
> +  OldStatus     = OldAttributes & EFI_FVB2_STATUS;
> +  NewStatus     = *Attributes & EFI_FVB2_STATUS;
> +
> +  UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP  | \
> +                        EFI_FVB2_READ_ENABLED_CAP   | \
> +                        EFI_FVB2_WRITE_DISABLED_CAP | \
> +                        EFI_FVB2_WRITE_ENABLED_CAP  | \
> +                        EFI_FVB2_LOCK_CAP           | \
> +                        EFI_FVB2_STICKY_WRITE       | \
> +                        EFI_FVB2_MEMORY_MAPPED      | \
> +                        EFI_FVB2_ERASE_POLARITY     | \
> +                        EFI_FVB2_READ_LOCK_CAP      | \
> +                        EFI_FVB2_WRITE_LOCK_CAP     | \
> +                        EFI_FVB2_ALIGNMENT;
> +
> +  //
> +  // Some attributes of FV is read only can *not* be set
> +  //
> +  if ((OldAttributes & UnchangedAttributes) ^
> +      (*Attributes & UnchangedAttributes)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // If firmware volume is locked, no status bit can be updated
> +  //
> +  if (OldAttributes & EFI_FVB2_LOCK_STATUS) {
> +    if (OldStatus ^ NewStatus) {
> +      return EFI_ACCESS_DENIED;
> +    }
> +  }
> +  //
> +  // Test read disable
> +  //
> +  if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
> +    if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // Test read enable
> +  //
> +  if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
> +    if (NewStatus & EFI_FVB2_READ_STATUS) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // Test write disable
> +  //
> +  if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
> +    if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // Test write enable
> +  //
> +  if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
> +    if (NewStatus & EFI_FVB2_WRITE_STATUS) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // Test lock
> +  //
> +  if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
> +    if (NewStatus & EFI_FVB2_LOCK_STATUS) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
> +  *AttribPtr  = (*AttribPtr) | NewStatus;
> +  *Attributes = *AttribPtr;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// FVB protocol APIs
> +//
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetPhysicalAddress (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  OUT EFI_PHYSICAL_ADDRESS                        *Address
> +  )
> +/*++
> +
> +  Routine Description:
> +
> +    Retrieves the physical address of the device.
> +
> +  Arguments:
> +
> +    This                  - Calling context
> +    Address               - Output buffer containing the address.
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +
> +--*/
> +{
> +  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
> +
> +  FvbDevice = FVB_DEVICE_FROM_THIS (This);
> +
> +  return FvbGetPhysicalAddress (FvbDevice->Instance, Address,
> +           mFvbModuleGlobal);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetBlockSize (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN CONST EFI_LBA                                     Lba,
> +  OUT UINTN                                       *BlockSize,
> +  OUT UINTN                                       *NumOfBlocks
> +  )
> +/*++
> +
> +  Routine Description:
> +    Retrieve the size of a logical block
> +
> +  Arguments:
> +    This                  - Calling context
> +    Lba                   - Indicates which block to return the size for.
> +    BlockSize             - A pointer to a caller allocated UINTN in which
> +                            the size of the block is returned
> +    NumOfBlocks           - a 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
> +
> +  Returns:
> +    EFI_SUCCESS           - The firmware volume was read successfully and
> +                            contents are in Buffer
> +
> +--*/
> +{
> +  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
> +
> +  FvbDevice = FVB_DEVICE_FROM_THIS (This);
> +
> +  return FvbGetLbaAddress (
> +          FvbDevice->Instance,
> +          Lba,
> +          NULL,
> +          BlockSize,
> +          NumOfBlocks,
> +          mFvbModuleGlobal
> +          );
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  OUT EFI_FVB_ATTRIBUTES_2                              *Attributes
> +  )
> +/*++
> +
> +  Routine Description:
> +      Retrieves Volume attributes.  No polarity translations are done.
> +
> +  Arguments:
> +      This                - Calling context
> +      Attributes          - output buffer which contains attributes
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +
> +--*/
> +{
> +  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
> +
> +  FvbDevice = FVB_DEVICE_FROM_THIS (This);
> +
> +  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes,
> +           mFvbModuleGlobal);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolSetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN OUT EFI_FVB_ATTRIBUTES_2                           *Attributes
> +  )
> +/*++
> +
> +  Routine Description:
> +    Sets Volume attributes. No polarity translations are done.
> +
> +  Arguments:
> +    This                  - Calling context
> +    Attributes            - output buffer which contains attributes
> +
> +  Returns:
> +    EFI_SUCCESS           - Successfully returns
> +
> +--*/
> +{
> +  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
> +
> +  FvbDevice = FVB_DEVICE_FROM_THIS (This);
> +
> +  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes,
> +           mFvbModuleGlobal);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolEraseBlocks (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
> +  ...
> +  )
> +/*++
> +
> +  Routine Description:
> +
> +    The EraseBlock() function erases one or more blocks as denoted by the
> +    variable argument list. The entire parameter list of blocks must be
> +    verified prior to 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 EraseBlock() function must
> +    return EFI_INVALID_PARAMETER without modifying the contents of the firmware
> +    volume.
> +
> +  Arguments:
> +    This                  - Calling context
> +    ...                   - Starting LBA followed by Number of Lba to erase.
> +                            a -1 to terminate the list.
> +
> +  Returns:
> +    EFI_SUCCESS           - The erase request was successfully completed
> +    EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
> +    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
> +                            could not be written. Firmware device may have been
> +                            partially erased
> +
> +--*/
> +{
> +  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
> +  EFI_FW_VOL_INSTANCE     *FwhInstance;
> +  UINTN                   NumOfBlocks;
> +  VA_LIST                 args;
> +  EFI_LBA                 StartingLba;
> +  UINTN                   NumOfLba;
> +  EFI_STATUS              Status;
> +
> +  FvbDevice = FVB_DEVICE_FROM_THIS (This);
> +
> +  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal,
> +                &FwhInstance);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  NumOfBlocks = FwhInstance->NumOfBlocks;
> +
> +  VA_START (args, This);
> +
> +  do {
> +    StartingLba = VA_ARG (args, EFI_LBA);
> +    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
> +      break;
> +    }
> +
> +    NumOfLba = VA_ARG (args, UINT32);
> +
> +    //
> +    // Check input parameters
> +    //
> +    if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) {
> +      VA_END (args);
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } while (1);
> +
> +  VA_END (args);
> +
> +  VA_START (args, This);
> +  do {
> +    StartingLba = VA_ARG (args, EFI_LBA);
> +    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
> +      break;
> +    }
> +
> +    NumOfLba = VA_ARG (args, UINT32);
> +
> +    while (NumOfLba > 0) {
> +      Status = RamFlashEraseBlock (StartingLba);
> +      if (EFI_ERROR (Status)) {
> +        VA_END (args);
> +        return Status;
> +      }
> +
> +      StartingLba++;
> +      NumOfLba--;
> +    }
> +
> +  } while (1);
> +
> +  VA_END (args);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolWrite (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN       EFI_LBA                                      Lba,
> +  IN       UINTN                                        Offset,
> +  IN OUT   UINTN                                    *NumBytes,
> +  IN       UINT8                                        *Buffer
> +  )

Urgh, please move prototype below document comment - throughout.

> +/*++
> +
> +  Routine Description:
> +
> +    Writes data beginning at Lba:Offset from FV. The write terminates either
> +    when *NumBytes of data have been written, or when a block boundary is
> +    reached.  *NumBytes is updated to reflect the actual number of bytes
> +    written. The write opertion does not include erase. This routine will
> +    attempt to write only the specified bytes. If the writes do not stick,
> +    it will return an error.
> +
> +  Arguments:
> +    This                  - Calling context
> +    Lba                   - Block in which to begin write
> +    Offset                - Offset in the block at which to begin write
> +    NumBytes              - On input, indicates the requested write size. On
> +                            output, indicates the actual number of bytes
> +                            written
> +    Buffer                - Buffer containing source data for the write.
> +
> +  Returns:
> +    EFI_SUCCESS           - The firmware volume was written successfully
> +    EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,
> +                            NumBytes contains the total number of bytes
> +                            actually written
> +    EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
> +    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
> +                            could not be written
> +    EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
> +
> +--*/
> +{
> +  return RamFlashWrite ((EFI_LBA)Lba, (UINTN)Offset, NumBytes,
> +           (UINT8 *)Buffer);

Buffer is a UINT8 *, why the cast?

> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolRead (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN CONST EFI_LBA                                      Lba,
> +  IN CONST UINTN                                        Offset,
> +  IN OUT UINTN                                    *NumBytes,
> +  IN UINT8                                        *Buffer
> +  )
> +/*++
> +
> +  Routine Description:
> +
> +    Reads data beginning at Lba:Offset from FV. The Read terminates either
> +    when *NumBytes of data have been read, or when a block boundary is
> +    reached.  *NumBytes is updated to reflect the actual number of bytes
> +    written. The write opertion does not include erase. This routine will
> +    attempt to write only the specified bytes. If the writes do not stick,
> +    it will return an error.
> +
> +  Arguments:
> +    This                  - Calling context
> +    Lba                   - Block in which to begin Read
> +    Offset                - Offset in the block at which to begin Read
> +    NumBytes              - On input, indicates the requested write size. On
> +                            output, indicates the actual number of bytes Read
> +    Buffer                - Buffer containing source data for the Read.
> +
> +  Returns:
> +    EFI_SUCCESS           - The firmware volume was read successfully and
> +                            contents are in Buffer
> +    EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,
> +                            NumBytes contains the total number of bytes
> +                            returned in Buffer
> +    EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state
> +    EFI_DEVICE_ERROR      - The block device is not functioning correctly and
> +                            could not be read
> +    EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
> +
> +--*/
> +{
> +  return RamFlashRead ((EFI_LBA)Lba, (UINTN)Offset, NumBytes,
> +           (UINT8 *)Buffer);

Buffer is already a UINT8 *, why the cast?

> +}
> +
> +EFI_STATUS
> +ValidateFvHeader (
> +  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
> +  )
> +/*++
> +
> +  Routine Description:
> +    Check the integrity of firmware volume header
> +
> +  Arguments:
> +    FwVolHeader           - A pointer to a firmware volume header
> +
> +  Returns:
> +    EFI_SUCCESS           - The firmware volume is consistent
> +    EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an
> +                            FV
> +
> +--*/
> +{
> +  UINT16 Checksum;
> +
> +  //
> +  // 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 == ((UINTN) -1)) ||
> +      ((FwVolHeader->HeaderLength & 0x01) != 0)
> +      ) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Verify the header checksum
> +  //
> +
> +  Checksum = CalculateSum16 ((UINT16 *) FwVolHeader,
> +               FwVolHeader->HeaderLength);
> +  if (Checksum != 0) {
> +    UINT16 Expected;
> +
> +    Expected =
> +      (UINT16) (((UINTN) FwVolHeader->Checksum + 0x10000 - Checksum) & 0xffff);
> +
> +    DEBUG ((DEBUG_INFO, "FV@%p Checksum is 0x%x, expected 0x%x\n",
> +            FwVolHeader, FwVolHeader->Checksum, Expected));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MarkMemoryRangeForRuntimeAccess (
> +  EFI_PHYSICAL_ADDRESS                BaseAddress,
> +  UINTN                               Length
> +  )
> +{
> +  EFI_STATUS                          Status;
> +
> +  //
> +  // Mark flash region as runtime memory
> +  //
> +  Status = gDS->RemoveMemorySpace (
> +                  BaseAddress,
> +                  Length
> +                  );
> +
> +  Status = gDS->AddMemorySpace (
> +                  EfiGcdMemoryTypeSystemMemory,
> +                  BaseAddress,
> +                  Length,
> +                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->AllocatePages (
> +                  AllocateAddress,
> +                  EfiRuntimeServicesData,
> +                  EFI_SIZE_TO_PAGES (Length),
> +                  &BaseAddress
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +InitializeVariableFvHeader (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_FIRMWARE_VOLUME_HEADER          *GoodFwVolHeader;
> +  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
> +  UINTN                               Length;
> +  UINTN                               WriteLength;
> +  UINTN                               BlockSize;
> +
> +  FwVolHeader =
> +    (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
> +      PcdGet32 (PcdPlatformFlashNvStorageVariableBase);
> +
> +  Length =
> +    (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +     FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +     FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize));
> +
> +  BlockSize = PcdGet32 (PcdVariableFdBlockSize);
> +
> +  Status      = ValidateFvHeader (FwVolHeader);
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "ValidateFvHeader() return ok\n"));
> +    if (FwVolHeader->FvLength != Length ||
> +        FwVolHeader->BlockMap[0].Length != BlockSize) {
> +      Status = EFI_VOLUME_CORRUPTED;
> +     DEBUG ((DEBUG_INFO, "FwVolHeader->FvLength(%x) != Length(%x) || FwVolHeader->BlockMap[0].Length(%x) != BlockSize(%x)\n", FwVolHeader->FvLength, Length, FwVolHeader->BlockMap[0].Length, BlockSize));
> +    }
> +  }
> +  else {
> +    DEBUG ((DEBUG_INFO, "ValidateFvHeader() return failed\n"));
> +  }
> +  if (EFI_ERROR (Status)) {
> +    UINTN   Offset;
> +    UINTN   Start;
> +
> +    DEBUG ((DEBUG_INFO,
> +      "Variable FV header is not valid. It will be reinitialized.\n"));
> +
> +    //
> +    // Get FvbInfo to provide in FwhInstance.
> +    //
> +    Status = GetFvbInfo (Length, &GoodFwVolHeader);
> +    ASSERT (!EFI_ERROR (Status));
> +
> +    Start = (UINTN)(UINT8*) FwVolHeader - PcdGet32 (PcdVariableFdBaseAddress);
> +    ASSERT (Start % BlockSize == 0 && Length % BlockSize == 0);
> +    ASSERT (GoodFwVolHeader->HeaderLength <= BlockSize);
> +
> +    //
> +    // Erase all the blocks
> +    //
> +    for (Offset = Start; Offset < Start + Length; Offset += BlockSize) {
> +      Status = RamFlashEraseBlock (Offset / BlockSize);
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +
> +    //
> +    // Write good FV header
> +    //
> +    WriteLength = GoodFwVolHeader->HeaderLength;
> +    Status = RamFlashWrite (
> +               Start / BlockSize,
> +               0,
> +               &WriteLength,
> +               (UINT8 *) GoodFwVolHeader);
> +    ASSERT_EFI_ERROR (Status);
> +    ASSERT (WriteLength == GoodFwVolHeader->HeaderLength);
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FvbInitialize (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +/*++
> +
> +  Routine Description:
> +    This function does common initialization for FVB services
> +
> +  Arguments:
> +
> +  Returns:
> +
> +--*/
> +{
> +  EFI_STATUS                          Status;
> +  EFI_FW_VOL_INSTANCE                 *FwhInstance;
> +  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
> +  UINT32                              BufferSize;
> +  EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;
> +  EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;
> +  UINT32                              MaxLbaSize;
> +  EFI_PHYSICAL_ADDRESS                BaseAddress;
> +  UINTN                               Length;
> +  UINTN                               NumOfBlocks;
> +
> +  if (EFI_ERROR (RamFlashInitialize ())) {
> +    //
> +    // Return an error so image will be unloaded
> +    //
> +    DEBUG ((DEBUG_INFO,
> +      "RAM flash was not detected. Writable FVB is not being installed.\n"));
> +    return EFI_WRITE_PROTECTED;
> +  }
> +
> +  //
> +  // Allocate runtime services data for global variable, which contains
> +  // the private data of all firmware volume block instances
> +  //
> +  mFvbModuleGlobal = AllocateRuntimePool (sizeof (ESAL_FWB_GLOBAL));
> +  ASSERT (mFvbModuleGlobal != NULL);
> +
> +  BaseAddress = (UINTN) PcdGet32 (PcdVariableFdBaseAddress);
> +  Length = PcdGet32 (PcdVariableFdSize);
> +  DEBUG ((DEBUG_INFO, "FvbInitialize(): BaseAddress: 0x%lx Length:0x%x\n", BaseAddress, Length));
> +  Status = InitializeVariableFvHeader ();
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO,
> +      "RAM Flash: Unable to initialize variable FV header\n"));
> +    return EFI_WRITE_PROTECTED;
> +  }
> +
> +  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
> +  Status      = ValidateFvHeader (FwVolHeader);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Get FvbInfo
> +    //
> +    DEBUG ((DEBUG_INFO, "FvbInitialize(): ValidateFvHeader() return error(%r)\n", Status));
> +
> +    Status = GetFvbInfo (Length, &FwVolHeader);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "FvbInitialize(): GetFvbInfo (Length, &FwVolHeader) return error(%r)\n", Status));
> +      return EFI_WRITE_PROTECTED;
> +    }
> +  }
> +
> +  BufferSize = (sizeof (EFI_FW_VOL_INSTANCE) +
> +                FwVolHeader->HeaderLength -
> +                sizeof (EFI_FIRMWARE_VOLUME_HEADER)
> +                );
> +  mFvbModuleGlobal->FvInstance = AllocateRuntimePool (BufferSize);
> +  ASSERT (mFvbModuleGlobal->FvInstance != NULL);
> +
> +  FwhInstance = mFvbModuleGlobal->FvInstance;
> +
> +  mFvbModuleGlobal->NumFv                   = 0;
> +  MaxLbaSize = 0;
> +
> +  FwVolHeader =
> +    (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
> +      PcdGet32 (PcdPlatformFlashNvStorageVariableBase);
> +
> +  FwhInstance->FvBase = (UINTN) BaseAddress;
> +
> +  CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader,
> +    FwVolHeader->HeaderLength);
> +  FwVolHeader = &(FwhInstance->VolumeHeader);
> +
> +  NumOfBlocks = 0;
> +
> +  for (PtrBlockMapEntry = FwVolHeader->BlockMap;
> +       PtrBlockMapEntry->NumBlocks != 0;
> +       PtrBlockMapEntry++) {
> +    //
> +    // Get the maximum size of a block.
> +    //
> +    if (MaxLbaSize < PtrBlockMapEntry->Length) {
> +      MaxLbaSize = PtrBlockMapEntry->Length;
> +    }
> +
> +    NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
> +  }
> +
> +  //
> +  // The total number of blocks in the FV.
> +  //
> +  FwhInstance->NumOfBlocks = NumOfBlocks;
> +
> +  //
> +  // Add a FVB Protocol Instance
> +  //
> +  FvbDevice = AllocateRuntimePool (sizeof (EFI_FW_VOL_BLOCK_DEVICE));
> +  ASSERT (FvbDevice != NULL);
> +
> +  CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));
> +
> +  FvbDevice->Instance = mFvbModuleGlobal->NumFv;
> +  mFvbModuleGlobal->NumFv++;
> +
> +  //
> +  // Set up the devicepath
> +  //
> +  if (FwVolHeader->ExtHeaderOffset == 0) {
> +    FV_MEMMAP_DEVICE_PATH *FvMemmapDevicePath;
> +
> +    //
> +    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
> +    //
> +    FvMemmapDevicePath = AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH),
> +                           &mFvMemmapDevicePathTemplate);
> +    FvMemmapDevicePath->MemMapDevPath.StartingAddress = BaseAddress;
> +    FvMemmapDevicePath->MemMapDevPath.EndingAddress   =
> +      BaseAddress + FwVolHeader->FvLength - 1;
> +    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvMemmapDevicePath;
> +  } else {
> +    FV_PIWG_DEVICE_PATH *FvPiwgDevicePath;
> +
> +    FvPiwgDevicePath = AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH),
> +                         &mFvPIWGDevicePathTemplate);
> +    CopyGuid (
> +      &FvPiwgDevicePath->FvDevPath.FvName,
> +      (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
> +      );
> +    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvPiwgDevicePath;
> +  }
> +
> +  //
> +  // Module type specific hook.
> +  //
> +  InstallProtocolInterfaces (FvbDevice);
> +
> +  MarkMemoryRangeForRuntimeAccess (BaseAddress, Length);
> +
> +  //
> +  // Set several PCD values to point to flash
> +  //
> +  PcdSet64 (
> +    PcdFlashNvStorageVariableBase64,
> +    (UINTN) PcdGet32 (PcdPlatformFlashNvStorageVariableBase)
> +    );
> +  PcdSet32 (
> +    PcdFlashNvStorageFtwWorkingBase,
> +    PcdGet32 (PcdPlatformFlashNvStorageFtwWorkingBase)
> +    );
> +  PcdSet32 (
> +    PcdFlashNvStorageFtwSpareBase,
> +    PcdGet32 (PcdPlatformFlashNvStorageFtwSpareBase)
> +    );
> +
> +  FwhInstance = (EFI_FW_VOL_INSTANCE *)
> +    (
> +      (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +

Please don't cast to UINT8 * to get around pointer arithmetic - cast
it directly to UINTN.

> +      (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
> +    );
> +
> +  //
> +  // Module type specific hook.
> +  //
> +  InstallVirtualAddressChangeHandler ();
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
> new file mode 100644
> index 00000000..a1aeb2c3
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
> @@ -0,0 +1,187 @@
> +/**@file
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:
> +
> +    FwBlockService.h
> +
> +  Abstract:
> +
> +    Firmware volume block driver for Intel Firmware Hub (FWH) device
> +
> +**/
> +
> +#ifndef _FW_BLOCK_SERVICE_H_
> +#define _FW_BLOCK_SERVICE_H_

Please drop leading _.

> +
> +typedef struct {
> +  UINTN                       FvBase;
> +  UINTN                       NumOfBlocks;
> +  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
> +} EFI_FW_VOL_INSTANCE;
> +
> +typedef struct {
> +  UINT32              NumFv;
> +  EFI_FW_VOL_INSTANCE *FvInstance;
> +} ESAL_FWB_GLOBAL;
> +
> +extern ESAL_FWB_GLOBAL *mFvbModuleGlobal;
> +
> +//
> +// Fvb Protocol instance data
> +//
> +#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \
> +                                  FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
> +
> +#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \
> +                                         FvbExtension, FVB_DEVICE_SIGNATURE)
> +
> +#define FVB_DEVICE_SIGNATURE            SIGNATURE_32 ('F', 'V', 'B', 'N')
> +
> +typedef struct {
> +  MEDIA_FW_VOL_DEVICE_PATH  FvDevPath;
> +  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
> +} FV_PIWG_DEVICE_PATH;
> +
> +typedef struct {
> +  MEMMAP_DEVICE_PATH          MemMapDevPath;
> +  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
> +} FV_MEMMAP_DEVICE_PATH;
> +
> +typedef struct {
> +  UINTN                               Signature;
> +  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
> +  UINTN                               Instance;
> +  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;
> +} EFI_FW_VOL_BLOCK_DEVICE;
> +
> +EFI_STATUS
> +GetFvbInfo (
> +  IN  UINT64                            FvLength,
> +  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo
> +  );
> +
> +EFI_STATUS
> +FvbSetVolumeAttributes (
> +  IN UINTN                                Instance,
> +  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes,
> +  IN ESAL_FWB_GLOBAL                      *Global
> +  );
> +
> +EFI_STATUS
> +FvbGetVolumeAttributes (
> +  IN UINTN                                Instance,
> +  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
> +  IN ESAL_FWB_GLOBAL                      *Global
> +  );
> +
> +EFI_STATUS
> +FvbGetPhysicalAddress (
> +  IN UINTN                                Instance,
> +  OUT EFI_PHYSICAL_ADDRESS                *Address,
> +  IN ESAL_FWB_GLOBAL                      *Global
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbInitialize (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +
> +VOID
> +EFIAPI
> +FvbClassAddressChangeEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  );
> +
> +EFI_STATUS
> +FvbGetLbaAddress (
> +  IN  UINTN                               Instance,
> +  IN  EFI_LBA                             Lba,
> +  OUT UINTN                               *LbaAddress,
> +  OUT UINTN                               *LbaLength,
> +  OUT UINTN                               *NumOfBlocks,
> +  IN  ESAL_FWB_GLOBAL                     *Global
> +  );
> +
> +//
> +// Protocol APIs
> +//
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  OUT EFI_FVB_ATTRIBUTES_2                              *Attributes
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolSetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN OUT EFI_FVB_ATTRIBUTES_2                           *Attributes
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetPhysicalAddress (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  OUT EFI_PHYSICAL_ADDRESS                        *Address
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolGetBlockSize (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN CONST EFI_LBA                                     Lba,
> +  OUT UINTN                                       *BlockSize,
> +  OUT UINTN                                       *NumOfBlocks
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolRead (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN CONST EFI_LBA                                      Lba,
> +  IN CONST UINTN                                        Offset,
> +  IN OUT UINTN                                    *NumBytes,
> +  IN UINT8                                        *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolWrite (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
> +  IN       EFI_LBA                                      Lba,
> +  IN       UINTN                                        Offset,
> +  IN OUT   UINTN                                        *NumBytes,
> +  IN       UINT8                                        *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbProtocolEraseBlocks (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
> +  ...
> +  );
> +
> +//
> +// The following functions have different implementations dependent on the
> +// module type chosen for building this driver.
> +//
> +VOID
> +InstallProtocolInterfaces (
> +  IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice
> +  );
> +
> +VOID
> +InstallVirtualAddressChangeHandler (
> +  VOID
> +  );
> +#endif
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
> new file mode 100644
> index 00000000..46112365
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
> @@ -0,0 +1,151 @@
> +/**@file
> +  Functions related to the Firmware Volume Block service whose
> +  implementation is specific to the runtime DXE driver build.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (C) 2015, Red Hat, Inc.
> +  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/EventGroup.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/FirmwareVolumeBlock.h>
> +
> +#include "FwBlockService.h"
> +#include "RamFlash.h"
> +
> +VOID
> +InstallProtocolInterfaces (
> +  IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  EFI_HANDLE                         FwbHandle;
> +  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
> +
> +  //
> +  // Find a handle with a matching device path that has supports FW Block
> +  // protocol
> +  //
> +  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid,
> +                  &FvbDevice->DevicePath, &FwbHandle);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // LocateDevicePath fails so install a new interface and device path
> +    //
> +    FwbHandle = NULL;
> +    DEBUG ((DEBUG_INFO, "Installing RAM FVB\n"));
> +    Status = gBS->InstallMultipleProtocolInterfaces (
> +                    &FwbHandle,
> +                    &gEfiFirmwareVolumeBlockProtocolGuid,
> +                    &FvbDevice->FwVolBlockInstance,
> +                    &gEfiDevicePathProtocolGuid,
> +                    FvbDevice->DevicePath,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
> +    //
> +    // Device already exists, so reinstall the FVB protocol
> +    //
> +    Status = gBS->HandleProtocol (
> +                    FwbHandle,
> +                    &gEfiFirmwareVolumeBlockProtocolGuid,
> +                    (VOID**)&OldFwbInterface
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    DEBUG ((DEBUG_INFO, "Reinstalling FVB for Ram flash region\n"));
> +    Status = gBS->ReinstallProtocolInterface (
> +                    FwbHandle,
> +                    &gEfiFirmwareVolumeBlockProtocolGuid,
> +                    OldFwbInterface,
> +                    &FvbDevice->FwVolBlockInstance
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  } else {
> +    //
> +    // There was a FVB protocol on an End Device Path node
> +    //
> +    ASSERT (FALSE);
> +  }
> +}
> +
> +
> +STATIC
> +VOID
> +EFIAPI
> +FvbVirtualAddressChangeEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +/*++
> +
> +  Routine Description:
> +
> +    Fixup internal data so that EFI and SAL can be call in virtual mode.
> +    Call the passed in Child Notify event and convert the mFvbModuleGlobal
> +    date items to there virtual address.
> +
> +  Arguments:
> +
> +    (Standard EFI notify event - EFI_EVENT_NOTIFY)
> +
> +  Returns:
> +
> +    None
> +
> +--*/
> +{
> +  EFI_FW_VOL_INSTANCE *FwhInstance;
> +  UINTN               Index;
> +
> +  FwhInstance = mFvbModuleGlobal->FvInstance;
> +  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance);
> +
> +  //
> +  // Convert the base address of all the instances
> +  //
> +  Index       = 0;
> +  while (Index < mFvbModuleGlobal->NumFv) {
> +    EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase);
> +    FwhInstance = (EFI_FW_VOL_INSTANCE *)
> +      (
> +        (UINTN) ((UINT8 *) FwhInstance) +

Please don't cast to UINT8 * to get around pointer arithmetic - cast
it directly to UINTN.

> +        FwhInstance->VolumeHeader.HeaderLength +
> +        (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
> +      );
> +    Index++;
> +  }
> +
> +  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);
> +  RamFlashConvertPointers ();
> +}
> +
> +
> +VOID
> +InstallVirtualAddressChangeHandler (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  VirtualAddressChangeEvent;
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  FvbVirtualAddressChangeEvent,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &VirtualAddressChangeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
> new file mode 100644
> index 00000000..6c3e613a
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
> @@ -0,0 +1,144 @@
> +/** @file
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include "RamFlash.h"
> +
> +UINT8 *mFlashBase;

This appears to be set as UINT8 * only to avoid pointer arithmetic
effects. Please don't do that. If there is no actual type that is
suitable, please use VOID *.

> +
> +STATIC UINTN       mFdBlockSize = 0;
> +STATIC UINTN       mFdBlockCount = 0;
> +
> +STATIC
> +volatile UINT8*

It would be VOLATILE, but I'm pretty sure this doesn't do what you
expect it to do.

> +RamFlashPtr (
> +  IN        EFI_LBA                             Lba,
> +  IN        UINTN                               Offset
> +  )
> +{
> +  return mFlashBase + ((UINTN)Lba * mFdBlockSize) + Offset;
> +}
> +
> +/**
> +  Read from Ram Flash
> +
> +  @param[in] Lba      The starting logical block index to read from.
> +  @param[in] Offset   Offset into the block at which to begin reading.
> +  @param[in] NumBytes On input, indicates the requested read size. On
> +                      output, indicates the actual number of bytes read
> +  @param[in] Buffer   Pointer to the buffer to read into.
> +
> +**/
> +EFI_STATUS
> +RamFlashRead (
> +  IN        EFI_LBA                              Lba,
> +  IN        UINTN                                Offset,
> +  IN        UINTN                                *NumBytes,
> +  IN        UINT8                                *Buffer
> +  )
> +{
> +  UINT8  *Ptr;
> +
> +  //
> +  // Only write to the first 64k. We don't bother saving the FTW Spare
> +  // block into the flash memory.
> +  //
> +  if (Lba >= mFdBlockCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Get flash address
> +  //
> +  Ptr = (UINT8*) RamFlashPtr (Lba, Offset);
> +
> +  CopyMem (Buffer, Ptr, *NumBytes);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Write to Ram Flash
> +
> +  @param[in] Lba      The starting logical block index to write to.
> +  @param[in] Offset   Offset into the block at which to begin writing.
> +  @param[in] NumBytes On input, indicates the requested write size. On
> +                      output, indicates the actual number of bytes written
> +  @param[in] Buffer   Pointer to the data to write.
> +
> +**/
> +EFI_STATUS
> +RamFlashWrite (
> +  IN        EFI_LBA                             Lba,
> +  IN        UINTN                               Offset,
> +  IN        UINTN                               *NumBytes,
> +  IN        UINT8                               *Buffer
> +  )
> +{
> +  volatile UINT8  *Ptr;

I would much rather see the use of IoLib.

> +  UINTN           Loop;
> +
> +  //
> +  // Only write to the first 64k. We don't bother saving the FTW Spare
> +  // block into the flash memory.
> +  //
> +  if (Lba >= mFdBlockCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Program flash
> +  //
> +  Ptr = RamFlashPtr (Lba, Offset);
> +  for (Loop = 0; Loop < *NumBytes; Loop++) {
> +    *Ptr = Buffer[Loop];
> +    Ptr++;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Erase a Ram Flash block
> +
> +  @param Lba    The logical block index to erase.
> +
> +**/
> +EFI_STATUS
> +RamFlashEraseBlock (
> +  IN   EFI_LBA      Lba
> +  )
> +{
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Initializes Ram flash memory support
> +
> +  @retval EFI_WRITE_PROTECTED   The Ram flash device is not present.
> +  @retval EFI_SUCCESS           The Ram flash device is supported.
> +
> +**/
> +EFI_STATUS
> +RamFlashInitialize (
> +  VOID
> +  )
> +{
> +  mFlashBase = (UINT8*)(UINTN) PcdGet32 (PcdVariableFdBaseAddress);
> +  mFdBlockSize = PcdGet32 (PcdVariableFdBlockSize);
> +  ASSERT(PcdGet32 (PcdVariableFdSize) % mFdBlockSize == 0);
> +  mFdBlockCount = PcdGet32 (PcdVariableFdSize) / mFdBlockSize;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
> new file mode 100644
> index 00000000..008c795e
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
> @@ -0,0 +1,85 @@
> +/** @file
> +  Ram flash device for EFI variable
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _RAM_FLASH_H_
> +#define _RAM_FLASH_H_

Please drop leading _.

> +
> +#include <Protocol/FirmwareVolumeBlock.h>
> +
> +extern UINT8 *mFlashBase;

Please change also this extern declaration.

/
    Leif

> +
> +/**
> +  Read from Ram Flash
> +
> +  @param[in] Lba      The starting logical block index to read from.
> +  @param[in] Offset   Offset into the block at which to begin reading.
> +  @param[in] NumBytes On input, indicates the requested read size. On
> +                      output, indicates the actual number of bytes read
> +  @param[in] Buffer   Pointer to the buffer to read into.
> +
> +**/
> +EFI_STATUS
> +RamFlashRead (
> +  IN        EFI_LBA                              Lba,
> +  IN        UINTN                                Offset,
> +  IN        UINTN                                *NumBytes,
> +  IN        UINT8                                *Buffer
> +  );
> +
> +
> +/**
> +  Write to Ram Flash
> +
> +  @param[in] Lba      The starting logical block index to write to.
> +  @param[in] Offset   Offset into the block at which to begin writing.
> +  @param[in] NumBytes On input, indicates the requested write size. On
> +                      output, indicates the actual number of bytes written
> +  @param[in] Buffer   Pointer to the data to write.
> +
> +**/
> +EFI_STATUS
> +RamFlashWrite (
> +  IN        EFI_LBA                              Lba,
> +  IN        UINTN                                Offset,
> +  IN        UINTN                                *NumBytes,
> +  IN        UINT8                                *Buffer
> +  );
> +
> +
> +/**
> +  Erase a Ram Flash block
> +
> +  @param Lba    The logical block index to erase.
> +
> +**/
> +EFI_STATUS
> +RamFlashEraseBlock (
> +  IN   EFI_LBA      Lba
> +  );
> +
> +
> +/**
> +  Initializes Ram flash memory support
> +
> +  @retval EFI_WRITE_PROTECTED   The Ram flash device is not present.
> +  @retval EFI_SUCCESS           The Ram flash device is supported.
> +
> +**/
> +EFI_STATUS
> +RamFlashInitialize (
> +  VOID
> +  );
> +
> +
> +VOID
> +RamFlashConvertPointers (
> +  VOID
> +  );
> +
> +#endif
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
> new file mode 100644
> index 00000000..a9d48637
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
> @@ -0,0 +1,20 @@
> +/** @file
> +  Ram flash device for EFI variable
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/UefiRuntimeLib.h>
> +
> +#include "RamFlash.h"
> +
> +VOID
> +RamFlashConvertPointers (
> +  VOID
> +  )
> +{
> +  EfiConvertPointer (0x0, (VOID **) &mFlashBase);
> +}
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver Gilbert Chen
@ 2019-10-03 17:30   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-03 17:30 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:29AM +0800, Gilbert Chen wrote:
> Timer DXE driver for U500 platform based U500 platform implementation
>  specifc timer registers.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c  | 311 +++++++++++++++++++++
>  .../SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h  | 174 ++++++++++++
>  .../U500Pkg/Universal/Dxe/TimerDxe/Timer.uni       |  14 +
>  .../U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf    |  48 ++++
>  .../U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni  |  12 +
>  5 files changed, 559 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
> new file mode 100644
> index 00000000..5cb42943
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.c
> @@ -0,0 +1,311 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol for U500 platform.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Timer.h"
> +#include <sbi/riscv_asm.h>
> +#include <sbi/riscv_encoding.h>
> +#include <sbi/sbi.h>
> +#include <sbi/riscv_io.h>
> +#include <sbi/riscv_atomic.h>
> +
> +#define CLINT_REG_MTIME     0x0200BFF8
> +#define CLINT_REG_MTIMECMP0 0x02004000
> +#define CLINT_REG_MTIMECMP1 0x02004008
> +#define CLINT_REG_MTIMECMP2 0x02004010
> +#define CLINT_REG_MTIMECMP3 0x02004018
> +#define CLINT_REG_MTIMECMP4 0x02004020
> +
> +static volatile void * const p_mtime = (void *)CLINT_REG_MTIME;
> +#define MTIME          (*p_mtime)
> +#define MTIMECMP(i)    (p_mtimecmp[i])
> +
> +//
> +// The handle onto which the Timer Architectural Protocol will be installed
> +//
> +EFI_HANDLE                mTimerHandle = NULL;

This one is exported? Or can it be STATIC?

> +
> +//
> +// The Timer Architectural Protocol that this driver produces
> +//
> +EFI_TIMER_ARCH_PROTOCOL   mTimer = {
> +  TimerDriverRegisterHandler,
> +  TimerDriverSetTimerPeriod,
> +  TimerDriverGetTimerPeriod,
> +  TimerDriverGenerateSoftInterrupt
> +};
> +
> +//
> +// Pointer to the CPU Architectural Protocol instance
> +//
> +EFI_CPU_ARCH_PROTOCOL     *mCpu;

But this is only for internal use surely? STATIC?

> +
> +//
> +// The notification function to call on every timer interrupt.
> +// A bug in the compiler prevents us from initializing this here.
> +//
> +EFI_TIMER_NOTIFY mTimerNotifyFunction;

STATIC?

> +
> +//
> +// The current period of the timer interrupt
> +//
> +volatile UINT64 mTimerPeriod = 0;

This would be VOLATILE, but I dont think it has the effect you think it does.

> +
> +
> +/**
> +  8254 Timer #0 Interrupt Handler.
> +
> +  @param InterruptType    The type of interrupt that occured
> +  @param SystemContext    A pointer to the system context when the interrupt occured
> +**/
> +
> +VOID
> +EFIAPI
> +TimerInterruptHandler (
> +  IN EFI_EXCEPTION_TYPE   InterruptType,
> +  IN EFI_SYSTEM_CONTEXT   SystemContext
> +  )
> +{
> +  EFI_TPL OriginalTPL;
> +  UINT64 RiscvTimer;
> +
> +  csr_clear(CSR_SIE, MIP_STIP); // enable timer int
> +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  if (mTimerPeriod == 0) {
> +    gBS->RestoreTPL (OriginalTPL);
> +    mCpu->DisableInterrupt(mCpu);
> +    return;
> +  }
> +  if (mTimerNotifyFunction != NULL) {
> +    mTimerNotifyFunction (mTimerPeriod);
> +  }
> +  gBS->RestoreTPL (OriginalTPL);
> +
> +
> +  RiscvTimer = readq_relaxed(p_mtime);
> +  sbi_set_timer(RiscvTimer += mTimerPeriod);
> +  csr_set(CSR_SIE, MIP_STIP); // enable timer int
> +
> +}
> +
> +/**
> +
> +  This function registers the handler NotifyFunction so it is called every time
> +  the timer interrupt fires.  It also passes the amount of time since the last
> +  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
> +  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
> +  returned.  If the CPU does not support registering a timer interrupt handler,
> +  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
> +  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
> +  If an attempt is made to unregister a handler when a handler is not registered,
> +  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
> +  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
> +  is returned.
> +
> +  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction   The function to call when a timer interrupt fires.  This
> +                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
> +                          register a handler for the timer interrupt, so it can know
> +                          how much time has passed.  This information is used to
> +                          signal timer based events.  NULL will unregister the handler.
> +
> +  @retval        EFI_SUCCESS            The timer handler was registered.
> +  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
> +  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
> +                                        registered.
> +  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
> +                                        previously registered.
> +  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", NotifyFunction));
> +  mTimerNotifyFunction = NotifyFunction;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +{
> +  UINT64 RiscvTimer;
> +
> +  DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));
> +
> +  if (TimerPeriod == 0) {
> +    mTimerPeriod = 0;
> +    mCpu->DisableInterrupt(mCpu);
> +    csr_clear(CSR_SIE, MIP_STIP); // disable timer int
> +    return EFI_SUCCESS;
> +  }
> +
> +  mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us
> +
> +  mCpu->EnableInterrupt(mCpu);
> +  csr_set(CSR_SIE, MIP_STIP); // enable timer int
> +
> +  RiscvTimer = readq_relaxed(p_mtime);
> +  sbi_set_timer(RiscvTimer + mTimerPeriod);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL   *This,
> +  OUT UINT64                   *TimerPeriod
> +  )
> +{
> +  *TimerPeriod = mTimerPeriod;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
> +  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt is
> +  enabled when this service is called, then the registered handler will be invoked. The
> +  registered handler should not be able to distinguish a hardware-generated timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Initialize the pointer to our notify function.
> +  //
> +  mTimerNotifyFunction = NULL;
> +
> +  //
> +  // Make sure the Timer Architectural Protocol is not already installed in the system
> +  //
> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
> +
> +  //
> +  // Find the CPU architectural protocol.
> +  //
> +  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Force the timer to be disabled
> +  //
> +  Status = TimerDriverSetTimerPeriod (&mTimer, 0);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install interrupt handler for RISC-V Timer.
> +  //
> +  Status = mCpu->RegisterInterruptHandler (mCpu, EXCEPT_RISCV_TIMER_INT, TimerInterruptHandler);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Force the timer to be enabled at its default period
> +  //
> +  Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install the Timer Architectural Protocol onto a new handle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mTimerHandle,
> +                  &gEfiTimerArchProtocolGuid, &mTimer,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
> new file mode 100644
> index 00000000..3bfc415d
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.h
> @@ -0,0 +1,174 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol definitions for U500 platform,
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _TIMER_H_
> +#define _TIMER_H_

Please drop leading _.
But also, TIMER_H_ is a bit too generic for an include guard.
U500_TIMER_H_?

> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/Timer.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/RiscVCpuLib.h>
> +
> +//
> +// RISC-V use 100us timer.
> +// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units
> +//
> +#define DEFAULT_TIMER_TICK_DURATION 100000
> +
> +extern VOID RiscvSetTimerPeriod (UINT32 TimerPeriod);
> +
> +//
> +// Function Prototypes
> +//
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL   *This,
> +  OUT UINT64                   *TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
> +  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt is
> +  enabled when this service is called, then the registered handler will be invoked. The
> +  registered handler should not be able to distinguish a hardware-generated timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +;
> +
> +#endif
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
> new file mode 100644
> index 00000000..38302244
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/Timer.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +//
> +// RISC-V Timer Arch protocol strings.
> +//
> +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "RISC-V timer driver that provides Timer Arch protocol"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "RISC-V timer driver that provides Timer Arch protocol."
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
> new file mode 100644
> index 00000000..f8af6889
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerDxe.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# RISC-V Timer Arch protocol module for U500 platform
> +#
> +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = Timer
> +  MODULE_UNI_FILE                = Timer.uni
> +  FILE_GUID                      = 3F75D495-23FF-46B6-9D19-0DECC8A4EA91
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = TimerDriverInitialize
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  BaseLib
> +  DebugLib
> +  UefiDriverEntryPoint
> +  IoLib
> +  RiscVCpuLib
> +  RiscVOpensbiLib

Please sort alphabetically.

/
    Leif

> +
> +[Sources]
> +  Timer.h
> +  Timer.c
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid       ## CONSUMES
> +  gEfiTimerArchProtocolGuid     ## PRODUCES
> +
> +[Pcd]
> +  gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz
> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  TimerExtra.uni
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
> new file mode 100644
> index 00000000..cf25ff14
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/TimerDxe/TimerExtra.uni
> @@ -0,0 +1,12 @@
> +// /** @file
> +// Timer Localized Strings and Content
> +//
> +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"RISC-V Timer DXE Driver"
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM Gilbert Chen
@ 2019-10-03 17:38   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-03 17:38 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt

On Thu, Sep 19, 2019 at 11:51:30AM +0800, Gilbert Chen wrote:
> This is the platform-implementation specific library which is executed
>  in early PEI phase for platform initialization.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c  |  49 ++++
>  .../U500Pkg/Universal/Pei/PlatformPei/MemDetect.c  |  74 +++++
>  .../U500Pkg/Universal/Pei/PlatformPei/Platform.c   | 313 +++++++++++++++++++++
>  .../U500Pkg/Universal/Pei/PlatformPei/Platform.h   |  92 ++++++
>  .../Universal/Pei/PlatformPei/PlatformPei.inf      |  75 +++++
>  5 files changed, 603 insertions(+)
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
> new file mode 100644
> index 00000000..74e4d433
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Fv.c
> @@ -0,0 +1,49 @@
> +/** @file
> +  Build FV related hobs for platform.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PiPei.h"
> +#include "Platform.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>

Please flip above two lines around.

> +
> +/**
> +  Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
> +  and DXE know about them.
> +
> +  @retval EFI_SUCCESS   Platform PEI FVs were initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PeiFvInitialization (
> +  VOID
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n"));
> +  //
> +  // Let DXE know about the DXE FV
> +  //
> +  BuildFvHob (PcdGet32 (PcdRiscVDxeFvBase), PcdGet32 (PcdRiscVDxeFvSize));
> +  DEBUG ((DEBUG_INFO, "Platform builds DXE FV at %x, size %x.\n", PcdGet32 (PcdRiscVDxeFvBase), PcdGet32 (PcdRiscVDxeFvSize)));

Please wrap long line.

> +
> +  //
> +  // Let PEI know about the DXE FV so it can find the DXE Core
> +  //
> +  PeiServicesInstallFvInfoPpi (
> +    NULL,
> +    (VOID *)(UINTN) PcdGet32 (PcdRiscVDxeFvBase),
> +    PcdGet32 (PcdRiscVDxeFvSize),
> +    NULL,
> +    NULL
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
> new file mode 100644
> index 00000000..dc99f2e0
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/MemDetect.c
> @@ -0,0 +1,74 @@
> +/**@file
> +  Memory Detection for Virtual Machines.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MemDetect.c
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/ResourcePublicationLib.h>
> +
> +#include "Platform.h"
> +
> +
> +/**
> +  Publish PEI core memory
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PublishPeiMemory (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PHYSICAL_ADDRESS        MemoryBase;
> +  UINT64                      MemorySize;
> +
> +  MemoryBase = 0x80000000UL + 0x1000000UL;
> +  MemorySize = 0x40000000UL - 0x1000000UL; //1GB - 16MB
> +
> +  DEBUG((DEBUG_INFO, "%a: MemoryBase:0x%x MemorySize:%d\n", __FUNCTION__, MemoryBase, MemorySize));
> +
> +  //
> +  // Publish this memory to the PEI Core
> +  //
> +  Status = PublishSystemMemory(MemoryBase, MemorySize);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +  Publish system RAM and reserve memory regions
> +
> +**/
> +VOID
> +InitializeRamRegions (
> +  VOID
> +  )
> +{
> +  AddMemoryRangeHob(0x81000000UL, 0x81000000UL + 0x3F000000UL);
> +
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
> new file mode 100644
> index 00000000..45356399
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.c
> @@ -0,0 +1,313 @@
> +/**@file
> +  Platform PEI driver
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#include <SiFiveU5MCCoreplex.h>
> +
> +#include "Platform.h"
> +
> +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
> +  { EfiACPIMemoryNVS,       0x004 },
> +  { EfiACPIReclaimMemory,   0x008 },
> +  { EfiReservedMemoryType,  0x004 },
> +  { EfiRuntimeServicesData, 0x024 },
> +  { EfiRuntimeServicesCode, 0x030 },
> +  { EfiBootServicesCode,    0x180 },
> +  { EfiBootServicesData,    0xF00 },
> +  { EfiMaxMemoryType,       0x000 }
> +};
> +
> +
> +EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gEfiPeiMasterBootModePpiGuid,
> +    NULL
> +  }
> +};
> +
> +EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +BOOLEAN mS3Supported = FALSE;

Can any/all of the above global variables be made STATIC?

> +
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_RESERVED,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +VOID
> +AddIoMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  )
> +{
> +  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
> +}
> +
> +
> +VOID
> +AddMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_SYSTEM_MEMORY,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +
> +VOID
> +AddMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  )
> +{
> +  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
> +}
> +
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_SYSTEM_MEMORY,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +VOID
> +AddUntestedMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  )
> +{
> +  AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
> +}
> +
> +VOID
> +AddPciResource (
> +  VOID
> +  )
> +{
> +  //
> +  // Platform-specific
> +  //
> +}
> +
> +VOID
> +MemMapInitialization (
> +  VOID
> +  )
> +{
> +  //
> +  // Create Memory Type Information HOB
> +  //
> +  BuildGuidDataHob (
> +    &gEfiMemoryTypeInformationGuid,
> +    mDefaultMemoryTypeInformation,
> +    sizeof(mDefaultMemoryTypeInformation)
> +    );
> +
> +  //
> +  // Add PCI IO Port space available for PCI resource allocations.
> +  //
> +  AddPciResource ();
> +}
> +
> +VOID
> +MiscInitialization (
> +  VOID
> +  )
> +{
> +  //
> +  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
> +  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
> +  // S3 resume as well, so we build it unconditionally.)
> +  //
> +  BuildCpuHob (32, 32);
> +}
> +
> +/**
> +  Check if system retunrs from S3.
> +
> +  @return BOOLEAN   TRUE, system returned from S3
> +                    FALSE, system is not returned from S3
> +
> +**/
> +BOOLEAN
> +CheckResumeFromS3 (
> +  VOID
> +  )
> +{
> +  //
> +  //Platform implementation-specific
> +  //
> +  return FALSE;
> +}
> +
> +
> +VOID
> +BootModeInitialization (
> +  VOID
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  if (CheckResumeFromS3 () == TRUE) {
> +    DEBUG ((DEBUG_INFO, "This is wake from S3\n"));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "This is normal boot\n"));
> +  }
> +  Status = PeiServicesSetBootMode (mBootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = PeiServicesInstallPpi (mPpiBootMode);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  Build processor information for U54 Coreplex processor.
> +
> +  @return EFI_SUCCESS     Status.
> +
> +**/
> +EFI_STATUS
> +BuildCoreInformationHob (
> +  VOID
> +)
> +{
> +  EFI_STATUS Status;
> +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosHobPtr;
> +
> +  Status = CreateU5MCCoreplexProcessorSpecificDataHob (0);
> +  if (EFI_ERROR (Status)) {
> +    ASSERT(FALSE);
> +  }
> +  Status = CreateU5MCProcessorSmbiosDataHob(0, &SmbiosHobPtr);
> +  if (EFI_ERROR (Status)) {
> +    ASSERT(FALSE);
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "U5 MC Coreplex SMBIOS DATA HOB at address 0x%x\n", SmbiosHobPtr));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Perform Platform PEI initialization.
> +
> +  @param  FileHandle      Handle of the file being invoked.
> +  @param  PeiServices     Describes the list of possible PEI Services.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePlatform (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
> +
> +  BootModeInitialization ();
> +  DEBUG ((DEBUG_INFO, "Platform BOOT mode initiated.\n"));
> +  PublishPeiMemory ();
> +  DEBUG ((DEBUG_INFO, "PEI memory published.\n"));
> +  InitializeRamRegions ();
> +  DEBUG ((DEBUG_INFO, "Platform RAM regions initiated.\n"));
> +
> +  if (mBootMode != BOOT_ON_S3_RESUME) {
> +    PeiFvInitialization ();
> +    MemMapInitialization ();
> +  }
> +
> +  MiscInitialization ();
> +  Status = BuildCoreInformationHob ();
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Fail to build processor informstion HOB.\n"));
> +    ASSERT(FALSE);
> +  }
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
> new file mode 100644
> index 00000000..23600203
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/Platform.h
> @@ -0,0 +1,92 @@
> +/** @file
> +  Platform PEI module include file.
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _PLATFORM_PEI_H_INCLUDED_
> +#define _PLATFORM_PEI_H_INCLUDED_

Please drop leading _.

> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddIoMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  );
> +
> +VOID
> +AddMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  );
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddUntestedMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  );
> +
> +VOID
> +AddressWidthInitialization (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PublishPeiMemory (
> +  VOID
> +  );
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> +  VOID
> +  );
> +
> +VOID
> +InitializeRamRegions (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PeiFvInitialization (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +InitializeXen (
> +  VOID
> +  );
> +
> +extern EFI_BOOT_MODE mBootMode;
> +
> +extern BOOLEAN mS3Supported;
> +
> +extern UINT8 mPhysMemAddressWidth;
> +
> +#endif // _PLATFORM_PEI_H_INCLUDED_
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
> new file mode 100644
> index 00000000..420b0702
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Pei/PlatformPei/PlatformPei.inf
> @@ -0,0 +1,75 @@
> +## @file
> +#  Platform PEI driver
> +#
> +#  This module provides platform specific function to detect boot mode.
> +#
> +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump spec version?

> +  BASE_NAME                      = PlatformPei
> +  FILE_GUID                      = 222c386d-5abc-4fb4-b124-fbb82488acf4
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializePlatform
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC RISCV64
> +#
> +
> +[Sources]
> +  Fv.c
> +  MemDetect.c
> +  Platform.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  RiscVPkg/RiscVPkg.dec
> +  Platform/RiscV/RiscVPlatformPkg.dec
> +  Silicon/SiFive/SiFive.dec
> +  Platform/RiscV/SiFive/U500Pkg/U500.dec

Please sort alphabetically.

> +
> +[Guids]
> +  gEfiMemoryTypeInformationGuid
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid
> +
> +[LibraryClasses]
> +  DebugLib
> +  HobLib
> +  IoLib
> +  PciLib
> +  PeiResourcePublicationLib
> +  PeiServicesLib
> +  PeiServicesTablePointerLib
> +  PeimEntryPoint
> +  PcdLib
> +  SiliconSiFiveU5MCCoreplexInfoLib
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration

Please sort alphabetically.

/
    Leif

> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize
> +
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
> +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
> +
> +
> +[Ppis]
> +  gEfiPeiMasterBootModePpiGuid
> +
> +[Depex]
> +  TRUE
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates
  2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates Gilbert Chen
@ 2019-10-03 17:45   ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-03 17:45 UTC (permalink / raw)
  To: devel, gilbert.chen; +Cc: Palmer Dabbelt



On Thu, Sep 19, 2019 at 11:51:31AM +0800, Gilbert Chen wrote:
> Update Readme.md and Maintainers.txt for RISV-V platforms.
> 
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  Maintainers.txt |  9 +++++++++
>  Readme.md       | 11 +++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt
> index 876ae561..c494c9d5 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -108,6 +108,11 @@ R: Marcin Wojtas <mw@semihalf.com>
>  Platform/SolidRun/Armada80x0McBin
>  R: Marcin Wojtas <mw@semihalf.com>
>  
> +Platform/RiscV
> +Platform/RiscV/SiFive/U500Pkg

Since we're on a -devel branch anyway ... could you turn these into F:
entries even though we haven't converted
edk2-platforms/Maintainers.txt to the new format yet?

> +R: Abner Chang <abner.chang@hpe.com>
> +R: Gilbert Chen <gilbert.chen@hpe.com>
> +
>  Silicon
>  M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>  M: Leif Lindholm <leif.lindholm@linaro.org>
> @@ -151,3 +156,7 @@ M: Liming Gao <liming.gao@intel.com>
>  
>  Silicon/Marvell
>  R: Marcin Wojtas <mw@semihalf.com>
> +
> +Silicon/SiFive

Same here.

/
    Leif

> +R: Abner Chang <abner.chang@hpe.com>
> +R: Gilbert Chen <gilbert.chen@hpe.com>
> diff --git a/Readme.md b/Readme.md
> index 63e59f60..0395e20a 100644
> --- a/Readme.md
> +++ b/Readme.md
> @@ -52,6 +52,7 @@ ARM                 | arm-linux-gnueabihf-
>  IA32                | i?86-linux-gnu-* _or_ x86_64-linux-gnu-
>  IPF                 | ia64-linux-gnu
>  X64                 | x86_64-linux-gnu-
> +RISCV64             | riscv64-unknown-elf-
>  
>  \* i386, i486, i586 or i686
>  
> @@ -62,6 +63,12 @@ and [arm-linux-gnueabihf](https://releases.linaro.org/components/toolchain/binar
>  compiled to run on x86_64/i686 Linux and i686 Windows. Some Linux distributions
>  provide their own packaged cross-toolchains.
>  
> +### GCC for RISC-V
> +RISC-V open source community provides GCC toolchains for
> +[riscv64-unknown-elf](https://github.com/riscv/riscv-gnu-toolchain)
> +compiled to run on x86 Linux. The commit ID 64879b24 is verified to build RISC-V EDK2 platform and boot to EFI
> +SHELL successfully.
> +
>  ### clang
>  Clang does not require separate cross compilers, but it does need a
>  target-specific binutils. These are included with any prepackaged GCC toolchain
> @@ -243,6 +250,10 @@ For more information, see the
>  ## Raspberry Pi
>  * [Pi 3](Platform/RaspberryPi/RPi3)
>  
> +## RISC-V
> +### SiFive
> +* [Freedom U500 VC707 FPGA](Platform/RiscV/SiFive/U500Pkg)
> +
>  ## Socionext
>  * [SynQuacer](Platform/Socionext/DeveloperBox)
>  
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package
  2019-10-02  9:07   ` [edk2-devel] " Leif Lindholm
@ 2019-10-15 15:24     ` Abner Chang
  0 siblings, 0 replies; 43+ messages in thread
From: Abner Chang @ 2019-10-15 15:24 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Wednesday, October 2, 2019 5:08 PM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 03/14]
> platforms/RiscV: Initial version of RISC-V platform package
> 
> On Thu, Sep 19, 2019 at 11:51:20AM +0800, Gilbert Chen wrote:
> > Initial version of RISC-V platform package which provides the common
> > libraries, drivers, PCD and etc. for RISC-V platform development.
> >
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  Platform/RiscV/Readme.md                 | 89
> ++++++++++++++++++++++++++++++++
> >  Platform/RiscV/RiscVPlatformPkg.dec      | 72
> ++++++++++++++++++++++++++
> >  Platform/RiscV/RiscVPlatformPkg.uni      | 15 ++++++
> >  Platform/RiscV/RiscVPlatformPkgExtra.uni | 12 +++++
> >  4 files changed, 188 insertions(+)
> >  create mode 100644 Platform/RiscV/Readme.md  create mode 100644
> > Platform/RiscV/RiscVPlatformPkg.dec
> >  create mode 100644 Platform/RiscV/RiscVPlatformPkg.uni
> >  create mode 100644 Platform/RiscV/RiscVPlatformPkgExtra.uni
> >
> > diff --git a/Platform/RiscV/Readme.md b/Platform/RiscV/Readme.md new
> > file mode 100644 index 00000000..277782e3
> > --- /dev/null
> > +++ b/Platform/RiscV/Readme.md
> 
> Please also add a link to this file from the top-level Readme.md.
> High up since this is intended for a branch specifically for this.
> 
> > @@ -0,0 +1,89 @@
> > +# Introduction
> > +
> > +## EDK2 RISC-V Platform Package
> > +RISC-V platform package provides the generic and common modules for
> RISC-V platforms. RISC-V platform package could include RiscPlatformPkg.dec
> to use the common drivers, libraries, definitions, PCDs and etc. for the
> platform development.
> 
> Please wrap lines at max 80 characters.
> 
> > +
> > +## EDK2 RISC-V Platforms
> > +RISC-V platform is created and maintained by RISC-V platform vendors.
> The directory of RISC-V platform should be created under Platform/RiscV.
> Vendor should create the folder under Platform/RiscV and name it using
> vendor name, under the vendor folder is the platform folder named by
> platform model name, code name or etc. (e.g.
> Platform/RiscV/SiFive/U500Pkg)
> > +
> > +## Build EDK2 RISC-V Platforms
> > +RISC-V platform package should provide EDK2 metafiles under RISC-V
> platform package folder (Platform/RiscV/{Vendor}/{Platform}). Build RISC-V
> platform package against edk2 and follow the build guidence mentioned in
> Readme.md under below link.<br>
> 
> OK, so we reach this topic here for the first time.
> We don't have a Platforms/ARM and we don't have a Platforms/X86, so I
> don't want to see a Platforms/RiscV. The paths should be
> Platforms/Vendor. I will comment on the patch adding the code where
> the content currently there should go.

There is a new package RiscVPlatformPkg in edk2-staging. You will see this in v3 set of edk2-staging patches.

> 
> > +https://github.com/tianocore/edk2-platforms<br>
> > +
> > +### Download the sources ###
> > +```
> > +git clone https://github.com/tianocore/edk2-staging.git
> > +# Checkout RISC-V-V2 branch
> > +git clone https://github.com/tianocore/edk2-platforms.git
> > +# Checkout devel-riscv-v2 branch
> > +git clone https://github.com/tianocore/edk2-non-osi.git
> > +```
> > +
> > +### Requirements
> > +Build EDK2 RISC-V platform requires GCC RISC-V toolchain. Refer to
> https://github.com/riscv/riscv-gnu-toolchain for the details.
> 
> Please add all of the missing details I pointed out for the Readme.md
> on the edks-staging branch.
> 
> > +The commit ID 64879b24 is verified to build RISC-V EDK2 platform and boot
> to EFI SHELL successfully.
> > +
> > +### EDK2 project
> > +Currently, the EDK2 RISC-V platform can only build with edk2 project in
> **edk2-staging/RISC-V-V2** branch. The build architecture whcih is
> supported and verified so far is "RISCV64". The verified RISC-V toolchain is
> https://github.com/riscv/riscv-gnu-toolchain @64879b24, toolchain tag is
> "GCCRISCV" declared in tools_def.txt<br>
> 
> It's GCC5 now, not GCCRISCV.
> 
> > +
> > +### Linux Build Instructions
> > +You can build the RISC-V platform using below script, <br>
> > +`build -a RISCV64 -p Platform/{Vendor}/{Platform}/{Platform}.dsc -t
> GCCRISCV`
> > +
> > +Or modify target.txt to set up your build parameters.
> 
> Which target.txt?
> 
> > +
> > +## RISC-V Platform PCD settings
> > +### EDK2 Firmware Volume Settings
> > +EDK2 Firmware volume related PCDs which declared in platform FDF file.
> > +
> > +| **PCD name** |**Usage**|
> > +|----------------|----------|
> > +|PcdRiscVSecFvBase| The base address of SEC Firmware Volume|
> > +|PcdRiscVSecFvSize| The size of SEC Firmware Volume|
> > +|PcdRiscVPeiFvBase| The base address of SEC Firmware Volume|
> > +|PcdRiscVPeiFvSize| The size of SEC Firmware Volume|
> 
> PEI Firmware Volume
> 
> > +|PcdRiscVDxeFvBase| The base address of SEC Firmware Volume|
> > +|PcdRiscVDxeFvSize| The size of SEC Firmware Volume|
> 
> DXE Firmware Volume
> 
> > +
> > +### EDK2 EFI Variable Region Settings
> > +The PCD settings regard to EFI Variable
> > +
> > +| **PCD name** |**Usage**|
> > +|----------------|----------|
> > +|PcdVariableFdBaseAddress| The EFI variable firmware device base
> address|
> > +|PcdVariableFdSize| The EFI variable firmware device size|
> > +|PcdVariableFdBlockSize| The block size of EFI variable firmware device|
> > +|PcdPlatformFlashNvStorageVariableBase| EFI variable base address
> within firmware device|
> > +|PcdPlatformFlashNvStorageFtwWorkingBase| The base address of EFI
> variable fault tolerance worksapce (FTW) within firmware device|
> > +|PcdPlatformFlashNvStorageFtwSpareBase| The base address of EFI
> variable spare FTW within firmware device|
> > +
> > +### RISC-V Physical Memory Protection (PMP) Region Settings
> > +Below PCDs could be set in platform FDF file.
> > +
> > +| **PCD name** |**Usage**|
> > +|----------------|----------|
> > +|PcdFwStartAddress| The starting address of firmware region to
> protected by PMP|
> > +|PcdFwEndAddress| The ending address of firmware region to protected
> by PMP|
> > +
> > +### RISC-V Processor HART Settings
> > +
> > +| **PCD name** |**Usage**|
> > +|----------------|----------|
> > +|PcdHartCount| Number of RISC-V HARTs, the value is processor-
> implementation specific|
> > +|PcdBootHartId| The ID of RISC-V HART to execute main fimrware code
> and boot system to OS|
> > +
> > +### RISC-V OpenSBI Settings
> > +
> > +| **PCD name** |**Usage**|
> > +|----------------|----------|
> > +|PcdScratchRamBase| The base address of OpenSBI scratch buffer for all
> RISC-V HARTs|
> > +|PcdScratchRamSize| The total size of OpenSBI scratch buffer for all RISC-
> V HARTs|
> > +|PcdOpenSbiStackSize| The size of initial stack of each RISC-V HART for
> booting system use OpenSBI|
> > +|PcdTemporaryRamBase| The base address of temporary memory for PEI
> phase|
> > +|PcdTemporaryRamSize| The temporary memory size for PEI phase|
> > +
> > +## Supported Operating Systems
> > +Only support to boot to EFI Shell so far
> > +
> > +## Known Issues and Limitations
> > +Only RISC-V RV64 is verified
> > diff --git a/Platform/RiscV/RiscVPlatformPkg.dec
> b/Platform/RiscV/RiscVPlatformPkg.dec
> > new file mode 100644
> > index 00000000..3ce16bfc
> > --- /dev/null
> > +++ b/Platform/RiscV/RiscVPlatformPkg.dec
> 
> I think all of this content should either go into:
> Silicon/SiFive/SiFive.dec
> or
> <edk2>/RiscVPkg/RiscVPkg.dec
> 
> /
>     Leif
> 
> > @@ -0,0 +1,72 @@
> > +## @file  RiscVPlatformPkg.dec
> > +# This Package provides UEFI RISC-V platform modules and libraries.
> > +#
> > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  DEC_SPECIFICATION              = 0x00010005
> > +  PACKAGE_NAME                   = RiscPlatformPkg
> > +  PACKAGE_UNI_FILE               = RiscPlatformPkg.uni
> > +  PACKAGE_GUID                   = 6A67AF99-4592-40F8-B6BE-62BCA10DA1EC
> > +  PACKAGE_VERSION                = 1.0
> > +
> > +[Includes]
> > +  Include
> > +
> > +[LibraryClasses]
> > +
> > +[LibraryClasses.RISCV32, LibraryClasses.RISCV64]
> > +
> > +[Guids]
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid  = {0x6A67AF99, 0x4592, 0x40F8,
> { 0xB6, 0xBE, 0x62, 0xBC, 0xA1, 0x0D, 0xA1, 0xEC}}
> > +
> > +[PcdsFixedAtBuild]
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|0x0|UINT32|0x
> 00001000
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize|0x0|UINT32|0x0
> 0001001
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|0x0|UINT32|0x
> 00001002
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize|0x0|UINT32|0x0
> 0001003
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|0x0|UINT32|0x
> 00001004
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize|0x0|UINT32|0x
> 00001005
> > +
> > +#
> > +# Definition of EFI Variable region
> > +#
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress|0|UINT
> 32|0x00001010
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize|0|UINT32|0x000
> 01011
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize|0|UINT32|0
> x00001012
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariable
> Base|0|UINT32|0x00001013
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWor
> kingBase|0|UINT32|0x00001014
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpar
> eBase|0|UINT32|0x00001015
> > +#
> > +# Firmware region which is protected by PMP.
> > +#
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwBlockSize|0|UINT32|0x00001
> 020
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress|0|UINT32|0x00
> 001021
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress|0|UINT32|0x000
> 01022
> > +#
> > +# Definition of RISC-V Hart
> > +#
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount|0|UINT32|0x0000102
> 3
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId|0|UINT32|0x000010
> 24
> > +#
> > +# Definitions for OpenSbi
> > +#
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase|0|UINT32|0x00
> 001025
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize|0|UINT32|0x00
> 001026
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize|0|UINT32|0x
> 00001027
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase|0|UINT32|
> 0x00001028
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize|0|UINT32|0
> x00001029
> > +
> > +[PcdsPatchableInModule]
> > +
> > +[PcdsFeatureFlag]
> > +
> gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable|FALSE|BO
> OLEAN|0x00001006
> > +
> > +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
> PcdsDynamicEx]
> > +
> > +[UserExtensions.TianoCore."ExtraFiles"]
> > +  RiscVPlatformPkgExtra.uni
> > diff --git a/Platform/RiscV/RiscVPlatformPkg.uni
> b/Platform/RiscV/RiscVPlatformPkg.uni
> > new file mode 100644
> > index 00000000..deb91fa1
> > --- /dev/null
> > +++ b/Platform/RiscV/RiscVPlatformPkg.uni
> > @@ -0,0 +1,15 @@
> > +// /** @file
> > +// RISC-V Package Localized Strings and Content.
> > +//
> > +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +
> > +#string STR_PACKAGE_ABSTRACT            #language en-US "Provides UEFI
> compatible RISC-V platform modules and libraries"
> > +
> > +#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package
> provides UEFI compatible RISC-V platform modules and libraries."
> > +
> > +
> > diff --git a/Platform/RiscV/RiscVPlatformPkgExtra.uni
> b/Platform/RiscV/RiscVPlatformPkgExtra.uni
> > new file mode 100644
> > index 00000000..98d81aed
> > --- /dev/null
> > +++ b/Platform/RiscV/RiscVPlatformPkgExtra.uni
> > @@ -0,0 +1,12 @@
> > +// /** @file
> > +// RISC-V Package Localized Strings and Content.
> > +//
> > +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#string STR_PROPERTIES_PACKAGE_NAME
> > +#language en-US
> > +"RiscV platform package"
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced in RISC-V platform package
  2019-10-02 17:04   ` [edk2-devel] " Leif Lindholm
@ 2019-10-15 15:26     ` Abner Chang
  2019-10-18  5:23     ` Abner Chang
  1 sibling, 0 replies; 43+ messages in thread
From: Abner Chang @ 2019-10-15 15:26 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 1:05 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 05/14]
> RiscV/Library: Initial version of libraries introduced in RISC-V platform
> package
> 
> On Thu, Sep 19, 2019 at 11:51:22AM +0800, Gilbert Chen wrote:
> > FirmwareContextProcessorSpecificLib
> > - Common library to consume
> EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> >  and build up processor specific data HOB.
> >
> > RealTimClockLibNull
> > - NULL instance of Real Time Clock library.
> >
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../FirmwareContextProcessorSpecificLib.c          |  82 +++++++++
> >  .../FirmwareContextProcessorSpecificLib.inf        |  33 ++++
> >  .../RealTimeClockLibNull/RealTimeClockLibNull.c    | 204
> +++++++++++++++++++++
> >  .../RealTimeClockLibNull/RealTimeClockLibNull.inf  |  30 +++
> 
> I think you can replace this NULL RealTimeClockLib implementation with
> EmbeddedPkg/Library/VirtualRealTimeClockLib/ (which did not exist at the
> time of the original port).
> 
> >  4 files changed, 349 insertions(+)
> >  create mode 100644
> >
> Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareCon
> > textProcessorSpecificLib.c  create mode 100644
> >
> Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareCon
> > textProcessorSpecificLib.inf  create mode 100644
> > Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
> >  create mode 100644
> > Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
> >
> > diff --git
> > a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.c
> >
> b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.c
> > new file mode 100644
> > index 00000000..4d4c51dc
> > --- /dev/null
> > +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/Firmw
> > +++ areContextProcessorSpecificLib.c
> > @@ -0,0 +1,82 @@
> > +/**@file
> > +  Common library to build upfirmware context processor-specific
> > +information
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +//
> > +// The package level header files this module uses // #include
> > +<PiPei.h>
> > +
> > +//
> > +// The Library classes this module consumes // #include
> > +<Library/DebugLib.h> #include <Library/PeiServicesLib.h> #include
> > +<Library/BaseMemoryLib.h>
> 
> Please sort these includes alphabetically.
> 
> > +
> > +#include <RiscV.h>
> > +#include <SmbiosProcessorSpecificData.h> #include
> > +<ProcessorSpecificDataHob.h>
> 
> Please sort these includes alphabetically.
> 
> > +#include <sbi/sbi_hart.h>
> > +#include <sbi/sbi.h>
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +/**
> > +  Build up common firmware context processor-specific information
> > +
> > +  @param  FirmwareContextHartSpecific  Pointer to
> EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > +  @param  ParentProcessorGuid          Pointer to GUID of Processor which
> contains this core
> > +  @param  ParentProcessorUid           Unique ID of pysical processor which
> owns this core.
> > +  @param  CoreGuid                     Pointer to GUID of core
> > +  @param  HartId                       Hart ID of this core.
> > +  @param  IsBootHart                   This is boot hart or not
> > +  @param  ProcessorSpecDataHob         Pointer to
> RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
> > +
> > +  @return EFI_STATUS
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CommonFirmwareContextHartSpecificInfo (
> > +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > +*FirmwareContextHartSpecific,
> > +  EFI_GUID  *ParentProcessorGuid,
> > +  UINTN     ParentProcessorUid,
> > +  EFI_GUID  *CoreGuid,
> > +  UINTN     HartId,
> > +  BOOLEAN   IsBootHart,
> > +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob
> 
> Spec is not a clear enough abbreviation, please use Specific.
> Or call it something else. If you keep the name, it certainly wouldn't hurt to
> use a local variable with a shorter name..

This will be RISC_V_PROCESSOR_SPECIFIC_HOB_DATA in v3 edk2-staging patches.
> 
> > +  )
> > +{
> > +  //
> > +  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
> > +  //
> > +  CopyGuid (&ProcessorSpecDataHob->ParentPrcessorGuid,
> > +ParentProcessorGuid);
> > +  ProcessorSpecDataHob->ParentProcessorUid = ParentProcessorUid;
> > +  CopyGuid (&ProcessorSpecDataHob->CoreGuid, CoreGuid);
> > +  ProcessorSpecDataHob->Context = NULL;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.Revision         =
> SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA_REVISION;
> 
> 80 Characters is up to                                                      here ->
> These lines are way too long, please wrap them.
> 
> > +  ProcessorSpecDataHob->ProcessorSpecificData.Length           = sizeof
> (SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA);
> > +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_L =
> > +(UINT64)HartId;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_H = 0;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.BootHartId       =
> (UINT8)IsBootHart;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported =
> FirmwareContextHartSpecific->IsaExtensionSupported;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.PrivilegeModeSupported   =
> SMBIOS_RISC_V_PSD_MACHINE_MODE_SUPPORTED;
> > +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported &
> RISC_V_ISA_SUPERVISOR_MODE_IMPLEMENTED) != 0) {
> > +
> > +ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported
> |=
> > +SMBIOS_RISC_V_PSD_SUPERVISOR_MODE_SUPPORTED;
> > +  }
> > +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported &
> RISC_V_ISA_USER_MODE_IMPLEMENTED) != 0) {
> > +
> > +ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported
> |=
> > +SMBIOS_RISC_V_PSD_USER_MODE_SUPPORTED;
> > +  }
> > +
> > +ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineVendorId.Value64_L
> > += FirmwareContextHartSpecific->MachineVendorId.Value64_L;
> > +
> > +ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineVendorId.Value64_H
> > += FirmwareContextHartSpecific->MachineVendorId.Value64_H;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineArchId.Value64_L
> > += FirmwareContextHartSpecific->MachineArchId.Value64_L;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineArchId.Value64_H
> > += FirmwareContextHartSpecific->MachineArchId.Value64_H;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineImplId.Value64_L
> > += FirmwareContextHartSpecific->MachineImplId.Value64_L;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineImplId.Value64_H
> > += FirmwareContextHartSpecific->MachineImplId.Value64_H;
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> > a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.inf
> >
> b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.inf
> > new file mode 100644
> > index 00000000..ff841c3e
> > --- /dev/null
> > +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/Firmw
> > +++ areContextProcessorSpecificLib.inf
> > @@ -0,0 +1,33 @@
> > +#/** @file
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # #  SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # #**/
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Can we update to a more recent specification version?
> 
> > +  BASE_NAME                      = FirmwareContextProcessorSpecificLib
> > +  FILE_GUID                      = 8BEC9FD7-C554-403A-94F1-0EBBFD81A242
> > +  MODULE_TYPE                    = PEIM
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FirmwareContextProcessorSpecificLib
> > +
> > +[Sources.common]
> > +  FirmwareContextProcessorSpecificLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> 
> Please sort the above alphabetically.
> 
> > +  RiscVPkg/RiscVPkg.dec
> > +  Silicon/SiFive/SiFive.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  PcdLib
> > +  MemoryAllocationLib
> 
> Please sort the above alphabetically.
> 
> > +  PrintLib
> > +
> > +[Pcd]
> > +
> 
> /
>     Leif
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module
  2019-10-02 19:43   ` [edk2-devel] " Leif Lindholm
@ 2019-10-15 15:27     ` Abner Chang
  0 siblings, 0 replies; 43+ messages in thread
From: Abner Chang @ 2019-10-15 15:27 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 3:43 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 06/14]
> RiscV/Universal: Initial version of common RISC-V SEC module
> 
> On Thu, Sep 19, 2019 at 11:51:23AM +0800, Gilbert Chen wrote:
> > Common RISC-V SEC module for RISC-V platforms.
> 
> If this is common to RISC-V platforms, this really should live in edk2/RiscVPkg.
Edk2/RiscVPlatformPkg is the package of SEC module now. You will see this in v3 edk2-staging patches.
> 
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438
> ++++++++++++++++++++
> >  Platform/RiscV/Universal/Sec/SecMain.c          | 524
> ++++++++++++++++++++++++
> >  Platform/RiscV/Universal/Sec/SecMain.h          |  57 +++
> >  Platform/RiscV/Universal/Sec/SecMain.inf        |  75 ++++
> >  4 files changed, 1094 insertions(+)
> >  create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> >  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
> >  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
> >  create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
> >
> > diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > new file mode 100644
> > index 00000000..18b54b84
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > @@ -0,0 +1,438 @@
> > +/*
> > + * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All
> rights reserved.
> > + *
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * Authors:
> > + *   Anup Patel <anup.patel@wdc.com>
> 
> If Anup is the author, he should be indicated in the commit as the Author.
> 
> If you further modify the patch, you can add a comment above your
> signed-off-by: of the form
> [Updated coding style issues.]
> Signed-off-by: ...
> 
> > + *
> > + */
> > +
> > +#include <Base.h>
> > +#include <RiscV.h>
> > +#include <sbi/riscv_asm.h>
> > +#include <sbi/riscv_encoding.h>
> > +#include <sbi/sbi_platform.h>
> > +#include <sbi/sbi_scratch.h>
> > +#include <sbi/sbi_trap.h>
> > +
> > +#include <SecMain.h>
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +.text
> > +.align 3
> > +.global ASM_PFX(_ModuleEntryPoint)
> > +ASM_PFX(_ModuleEntryPoint):
> > +  /*
> > +   * Jump to warm-boot if this is not the selected core booting,
> > +   */
> > +  csrr a6, CSR_MHARTID
> > +  li a5, FixedPcdGet32 (PcdBootHartId)
> > +  bne a6, a5, _wait_for_boot_hart
> 
> We don't actually have a coding style for assembler, but I find it really helps
> readability to have the arguments aligned across all lines. Compare (for
> example) with OvmfPkg/Sec/X64/SecEntry.nasm.
> 
> > +
> > +  // light LED on
> > +  li a5, 0x54002000
> > +  li a4, 0xff
> > +  sw a4, 0x08(a5)
> > +  li a4, 0x11
> > +  sw a4, 0x0c(a5)
> > +
> > +  li ra, 0
> > +  call _reset_regs
> > +
> > +  /* Preload HART details
> > +   * s7 -> HART Count
> > +   * s8 -> HART Stack Size
> > +   */
> > +  li s7, FixedPcdGet32 (PcdHartCount)  li s8, FixedPcdGet32
> > + (PcdOpenSbiStackSize)
> > +
> > +  /* Setup scratch space for all the HARTs*/
> > +  li  tp, FixedPcdGet32 (PcdScratchRamBase)
> > +  mul a5, s7, s8
> > +  add tp, tp, a5
> > +  /* Keep a copy of tp */
> > +  add t3, tp, zero
> > +  /* Counter */
> > +  li t2, 1
> > +  /* hartid 0 is mandated by ISA */
> > +  li t1, 0
> > +_scratch_init:
> > +  add tp, t3, zero
> > +  mul a5, s8, t1
> > +  sub tp, tp, a5
> > +  li a5, SBI_SCRATCH_SIZE
> > +  sub tp, tp, a5
> > +
> > +  /* Initialize scratch space */
> > +  li  a4, FixedPcdGet32 (PcdFwStartAddress)  li  a5, FixedPcdGet32
> > + (PcdFwEndAddress)  sub a5, a5, a4  sd a4,
> > + SBI_SCRATCH_FW_START_OFFSET(tp)  sd a5,
> > + SBI_SCRATCH_FW_SIZE_OFFSET(tp)
> 
> Can you add a blank line here?
> 
> > +  /* Note: fw_next_arg1() uses a0, a1, and ra */  call fw_next_arg1
> > + sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
> 
> Can you add a blank line here?
> 
> > +  /* Note: fw_next_addr() uses a0, a1, and ra */  call fw_next_addr
> 
> Can you add a blank line here?
> 
> > +  sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)  li a4, PRV_S  sd a4,
> > + SBI_SCRATCH_NEXT_MODE_OFFSET(tp)  la a4, _start_warm  sd a4,
> > + SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
> > +  la a4, platform
> > +  sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
> > +  la a4, _hartid_to_scratch
> > +  sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
> > +  sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)
> 
> Can you add a blank line here?
> 
> > +#ifdef FW_OPTIONS
> > +  li a4, FW_OPTIONS
> > +  sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp) #else
> > +  sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp) #endif
> 
> Can you add a blank line here?
> 
> > +  add t1, t1, t2
> > +  blt t1, s7, _scratch_init
> > +
> > +  /* Fill-out temporary memory with 55aa*/
> > +  li a4, FixedPcdGet32 (PcdTemporaryRamBase)
> > +  li a5, FixedPcdGet32 (PcdTemporaryRamSize)
> > +  add a5, a4, a5
> > +1:
> > +  li a3, 0x5AA55AA55AA55AA5
> > +  sd a3, (a4)
> > +  add a4, a4, __SIZEOF_POINTER__
> > +  blt a4, a5, 1b
> > +
> > +  /* Update boot hart flag */
> > +  la a4, _boot_hart_done
> > +  li a5, 1
> > +  sd a5, (a4)
> > +
> > +  /* Wait for boot hart */
> > +_wait_for_boot_hart:
> > +  la a4, _boot_hart_done
> > +  ld a5, (a4)
> > +  /* Reduce the bus traffic so that boot hart may proceed faster */
> > +  nop
> > +  nop
> > +  nop
> > +  beqz a5, _wait_for_boot_hart
> > +
> > +_start_warm:
> > +  li ra, 0
> > +  call _reset_regs
> > +
> > +  /* Disable and clear all interrupts */  csrw CSR_MIE, zero  csrw
> > + CSR_MIP, zero
> > +
> > +  li s7, FixedPcdGet32 (PcdHartCount)  li s8, FixedPcdGet32
> > + (PcdOpenSbiStackSize)
> > +
> > +  /* HART ID should be within expected limit */  csrr s6, CSR_MHARTID
> > + bge s6, s7, _start_hang
> > +
> > +  /* find the scratch space for this hart */  li tp, FixedPcdGet32
> > + (PcdScratchRamBase)  mul a5, s7, s8  add tp, tp, a5  mul a5, s8, s6
> > + sub tp, tp, a5  li a5, SBI_SCRATCH_SIZE  sub tp, tp, a5
> > +
> > +  /* update the mscratch */
> > +  csrw CSR_MSCRATCH, tp
> > +
> > +  /*make room for Hart specific Firmware Context*/  li a5,
> > + FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> > +  sub tp, tp, a5
> > +
> > +  /* Setup stack */
> > +  add sp, tp, zero
> > +
> > +  /* Setup stack for the Hart executing EFI to top of temporary ram*/
> > + csrr a6, CSR_MHARTID  li a5, FixedPcdGet32 (PcdBootHartId)  bne a6,
> > + a5, 1f
> > +
> > +  li a4, FixedPcdGet32(PcdTemporaryRamBase)
> > +  li a5, FixedPcdGet32(PcdTemporaryRamSize)
> > +  add sp, a4, a5
> > +  1:
> > +
> > +  /* Setup trap handler */
> > +  la a4, _trap_handler
> > +  csrw CSR_MTVEC, a4
> 
> Can you add a blank line here?
> 
> > +  /* Make sure that mtvec is updated */
> > +  1:
> > +  csrr a5, CSR_MTVEC
> > +  bne a4, a5, 1b
> > +
> > +  /* Call library constructors before jup to SEC core */  call
> > + ProcessLibraryConstructorList
> > +
> > +  /* jump to SEC Core C */
> > +  csrr a0, CSR_MHARTID
> > +  csrr a1, CSR_MSCRATCH
> > +  call SecCoreStartUpWithStack
> > +
> > +  /* We do not expect to reach here hence just hang */  j _start_hang
> > +
> > +  .align 3
> > +  .section .data, "aw"
> > +_boot_hart_done:
> > +  RISCV_PTR 0
> > +
> > +  .align 3
> > +  .section .entry, "ax", %progbits
> > +  .globl _hartid_to_scratch
> > +_hartid_to_scratch:
> > +  add sp, sp, -(3 * __SIZEOF_POINTER__)
> > +  sd s0, (sp)
> > +  sd s1, (__SIZEOF_POINTER__)(sp)
> > +  sd s2, (__SIZEOF_POINTER__ * 2)(sp)
> 
> Can you add a blank line here?
> 
> > +  /*
> > +   * a0 -> HART ID (passed by caller)
> > +   * s0 -> HART Stack Size
> > +   * s1 -> HART Stack End
> > +   * s2 -> Temporary
> > +   */
> > +  la s2, platform
> > +#if __riscv_xlen == 64
> > +  lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> > +  lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> > +#else
> > +  lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> > +  lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> > +#endif
> > +  mul s2, s2, s0
> > +  li s1, FixedPcdGet32 (PcdScratchRamBase)
> > +  add s1, s1, s2
> > +  mul s2, s0, a0
> > +  sub s1, s1, s2
> > +  li s2, SBI_SCRATCH_SIZE
> > +  sub a0, s1, s2
> > +  ld s0, (sp)
> > +  ld s1, (__SIZEOF_POINTER__)(sp)
> > +  ld s2, (__SIZEOF_POINTER__ * 2)(sp)
> > +  add sp, sp, (3 * __SIZEOF_POINTER__)
> > +  ret
> > +
> > +  .align 3
> > +  .section .entry, "ax", %progbits
> > +  .globl _start_hang
> > +_start_hang:
> > +  wfi
> > +  j _start_hang
> > +
> > +  .align 3
> > +  .section .entry, "ax", %progbits
> > +  .globl _trap_handler
> > +_trap_handler:
> > +  /* Swap TP and MSCRATCH */
> > +  csrrw tp, CSR_MSCRATCH, tp
> > +
> > +  /* Save T0 in scratch space */
> > +  sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> > +
> > +  /* Check which mode we came from */  csrr t0, CSR_MSTATUS  srl t0,
> > + t0, MSTATUS_MPP_SHIFT  and t0, t0, PRV_M  xori t0, t0, PRV_M  beq
> > + t0, zero, _trap_handler_m_mode
> > +
> > +  /* We came from S-mode or U-mode */
> > +_trap_handler_s_mode:
> > +  /* Set T0 to original SP */
> > +  add t0, sp, zero
> > +
> > +  /* Setup exception stack */
> > +  add sp, tp, -(SBI_TRAP_REGS_SIZE)
> > +
> > +  /* Jump to code common for all modes */  j _trap_handler_all_mode
> > +
> > +  /* We came from M-mode */
> > +_trap_handler_m_mode:
> > +  /* Set T0 to original SP */
> > +  add t0, sp, zero
> > +
> > +  /* Re-use current SP as exception stack */  add sp, sp,
> > + -(SBI_TRAP_REGS_SIZE)
> > +
> > +_trap_handler_all_mode:
> > +  /* Save original SP (from T0) on stack */
> > +  sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
> > +
> > +  /* Restore T0 from scratch space */  ld t0,
> > + SBI_SCRATCH_TMP0_OFFSET(tp)
> > +
> > +  /* Save T0 on stack */
> > +  sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> > +
> > +  /* Swap TP and MSCRATCH */
> > +  csrrw tp, CSR_MSCRATCH, tp
> > +
> > +  /* Save MEPC and MSTATUS CSRs */
> > +  csrr t0, CSR_MEPC
> > +  sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)  csrr t0, CSR_MSTATUS  sd t0,
> > + SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> > +
> > +  /* Save all general regisers except SP and T0 */  sd zero,
> > + SBI_TRAP_REGS_OFFSET(zero)(sp)  sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> > + sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp)  sd tp,
> > + SBI_TRAP_REGS_OFFSET(tp)(sp)  sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> > + sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp)  sd s0,
> > + SBI_TRAP_REGS_OFFSET(s0)(sp)  sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> > + sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp)  sd a1,
> > + SBI_TRAP_REGS_OFFSET(a1)(sp)  sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> > + sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp)  sd a4,
> > + SBI_TRAP_REGS_OFFSET(a4)(sp)  sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> > + sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp)  sd a7,
> > + SBI_TRAP_REGS_OFFSET(a7)(sp)  sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> > + sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp)  sd s4,
> > + SBI_TRAP_REGS_OFFSET(s4)(sp)  sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> > + sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp)  sd s7,
> > + SBI_TRAP_REGS_OFFSET(s7)(sp)  sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> > + sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp)  sd s10,
> > + SBI_TRAP_REGS_OFFSET(s10)(sp)  sd s11,
> SBI_TRAP_REGS_OFFSET(s11)(sp)
> > + sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp)  sd t4,
> > + SBI_TRAP_REGS_OFFSET(t4)(sp)  sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> > + sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +
> > +  /* Call C routine */
> > +  add a0, sp, zero
> > +  csrr a1, CSR_MSCRATCH
> > +  call sbi_trap_handler
> > +
> > +  /* Restore all general regisers except SP and T0 */  ld ra,
> > + SBI_TRAP_REGS_OFFSET(ra)(sp)  ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> > + ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp)  ld t1,
> > + SBI_TRAP_REGS_OFFSET(t1)(sp)  ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> > + ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp)  ld s1,
> > + SBI_TRAP_REGS_OFFSET(s1)(sp)  ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> > + ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp)  ld a2,
> > + SBI_TRAP_REGS_OFFSET(a2)(sp)  ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> > + ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp)  ld a5,
> > + SBI_TRAP_REGS_OFFSET(a5)(sp)  ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> > + ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp)  ld s2,
> > + SBI_TRAP_REGS_OFFSET(s2)(sp)  ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> > + ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp)  ld s5,
> > + SBI_TRAP_REGS_OFFSET(s5)(sp)  ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> > + ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp)  ld s8,
> > + SBI_TRAP_REGS_OFFSET(s8)(sp)  ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> > + ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp)  ld s11,
> > + SBI_TRAP_REGS_OFFSET(s11)(sp)  ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> > + ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp)  ld t5,
> > + SBI_TRAP_REGS_OFFSET(t5)(sp)  ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +
> > +  /* Restore MEPC and MSTATUS CSRs */  ld t0,
> > + SBI_TRAP_REGS_OFFSET(mepc)(sp)  csrw CSR_MEPC, t0  ld t0,
> > + SBI_TRAP_REGS_OFFSET(mstatus)(sp)  csrw CSR_MSTATUS, t0
> > +
> > +  /* Restore T0 */
> > +  ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> > +
> > +  /* Restore SP */
> > +  ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
> > +
> > +  mret
> > +
> > +  .align 3
> > +  .section .entry, "ax", %progbits
> > +  .globl _reset_regs
> > +_reset_regs:
> > +
> > +  /* flush the instruction cache */
> > +  fence.i
> > +  /* Reset all registers except ra, a0,a1 */  li sp, 0  li gp, 0  li
> > + tp, 0  li t0, 0  li t1, 0  li t2, 0  li s0, 0  li s1, 0  li a2, 0
> > + li a3, 0  li a4, 0  li a5, 0  li a6, 0  li a7, 0  li s2, 0  li s3, 0
> > + li s4, 0  li s5, 0  li s6, 0  li s7, 0  li s8, 0  li s9, 0  li s10,
> > + 0  li s11, 0  li t3, 0  li t4, 0  li t5, 0  li t6, 0  csrw
> > + CSR_MSCRATCH, 0  ret
> > +
> > +    .align 3
> > +    .section .entry, "ax", %progbits
> > +    .global fw_prev_arg1
> > +fw_prev_arg1:
> > +    /* We return previous arg1 in 'a0' */
> > +    add a0, zero, zero
> > +    ret
> > +
> > +    .align 3
> > +    .section .entry, "ax", %progbits
> > +    .global fw_next_arg1
> > +fw_next_arg1:
> > +    /* We return next arg1 in 'a0' */
> > +    li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
> > +    ret
> > +
> > +    .align 3
> > +    .section .entry, "ax", %progbits
> > +    .global fw_next_addr
> > +fw_next_addr:
> > +    /* We return next address in 'a0' */
> > +    la a0, _jump_addr
> > +    ld a0, (a0)
> > +    ret
> > +
> > +  .align 3
> > + .section .entry, "ax", %progbits
> > +_jump_addr:
> > + RISCV_PTR SecCoreStartUpWithStack
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.c
> > b/Platform/RiscV/Universal/Sec/SecMain.c
> > new file mode 100644
> > index 00000000..40b351ca
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.c
> > @@ -0,0 +1,524 @@
> > +/** @file
> > +  RISC-V SEC phase module.
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SecMain.h"
> > +#include <Library/SerialPortLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <Library/DebugPrintErrorLevelLib.h>
> > +#include <sbi/sbi_hart.h>
> > +#include <sbi/sbi_scratch.h>
> > +#include <sbi/sbi_platform.h>
> > +#include <sbi/sbi.h>
> > +#include <sbi/sbi_init.h>
> 
> Please sort includes alphabetically.
> 
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +int HartsIn = 0;
> 
> UINTN?
> 
> > +
> > +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =
> {
> > +  TemporaryRamMigration
> > +};
> > +
> > +EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
> > +  TemporaryRamDone
> > +};
> > +
> > +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> > +  {
> > +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> > +    &gEfiTemporaryRamSupportPpiGuid,
> > +    &mTemporaryRamSupportPpi
> > +  },
> > +  {
> > +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +    &gEfiTemporaryRamDonePpiGuid,
> > +    &mTemporaryRamDonePpi
> > +  },
> > +};
> 
> Can the above three variables all be made STATIC?
> 
> > +
> > +/**
> > +  Locates a section within a series of sections
> > +  with the specified section type.
> > +
> > +  The Instance parameter indicates which instance of the section
> > + type to return. (0 is first instance, 1 is second...)
> > +
> > +  @param[in]   Sections        The sections to search
> > +  @param[in]   SizeOfSections  Total size of all sections
> > +  @param[in]   SectionType     The section type to locate
> > +  @param[in]   Instance        The section instance number
> > +  @param[out]  FoundSection    The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInstance (
> 
> This is a note, not something that needs to be addressed for setting up the -
> devel branch: but this function is identical to the one in
> <edk2>/OvmfPkg/Sec/SecMain.c and the one in
> Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> We should address this.
> 
> > +  IN  VOID                             *Sections,
> > +  IN  UINTN                            SizeOfSections,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  IN  UINTN                            Instance,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> > +  UINT32                      Size;
> > +  EFI_PHYSICAL_ADDRESS        EndOfSections;
> > +  EFI_COMMON_SECTION_HEADER   *Section;
> > +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> > +
> > +  //
> > +  // Loop through the FFS file sections within the PEI Core FFS file
> > + //  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> > + EndOfSections = EndOfSection + SizeOfSections;  for (;;) {
> > +    if (EndOfSection == EndOfSections) {
> > +      break;
> > +    }
> > +    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> > +    if (CurrentAddress >= EndOfSections) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> > +
> > +    Size = SECTION_SIZE (Section);
> > +    if (Size < sizeof (*Section)) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    EndOfSection = CurrentAddress + Size;
> > +    if (EndOfSection > EndOfSections) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    //
> > +    // Look for the requested section type
> > +    //
> > +    if (Section->Type == SectionType) {
> > +      if (Instance == 0) {
> > +        *FoundSection = Section;
> > +        return EFI_SUCCESS;
> > +      } else {
> > +        Instance--;
> > +      }
> > +    }
> > +  }
> > +
> > +  return EFI_NOT_FOUND;
> > +}
> > +
> > +/**
> > +  Locates a section within a series of sections
> > +  with the specified section type.
> > +
> > +  @param[in]   Sections        The sections to search
> > +  @param[in]   SizeOfSections  Total size of all sections
> > +  @param[in]   SectionType     The section type to locate
> > +  @param[out]  FoundSection    The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInSections (
> 
> The same applies to this one.
> 
> > +  IN  VOID                             *Sections,
> > +  IN  UINTN                            SizeOfSections,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  return FindFfsSectionInstance (
> > +           Sections,
> > +           SizeOfSections,
> > +           SectionType,
> > +           0,
> > +           FoundSection
> > +           );
> > +}
> > +
> > +/**
> > +  Locates a FFS file with the specified file type and a section
> > +  within that file with the specified section type.
> > +
> > +  @param[in]   Fv            The firmware volume to search
> > +  @param[in]   FileType      The file type to locate
> > +  @param[in]   SectionType   The section type to locate
> > +  @param[out]  FoundSection  The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsFileAndSection (
> 
> And this one.
> 
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> > +  IN  EFI_FV_FILETYPE                  FileType,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> > +  EFI_FFS_FILE_HEADER         *File;
> > +  UINT32                      Size;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> > +
> > +  if (Fv->Signature != EFI_FVH_SIGNATURE) {
> > +    DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header
> signature\n", Fv));
> > +    return EFI_VOLUME_CORRUPTED;
> > +  }
> > +
> > +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> > + EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> > +
> > +  //
> > +  // Loop through the FFS files in the Boot Firmware Volume  //  for
> > + (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> > +
> > +    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> > +    if (CurrentAddress > EndOfFirmwareVolume) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> > +    Size = *(UINT32*) File->Size & 0xffffff;
> > +    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    EndOfFile = CurrentAddress + Size;
> > +    if (EndOfFile > EndOfFirmwareVolume) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    //
> > +    // Look for the request file type
> > +    //
> > +    if (File->Type != FileType) {
> > +      continue;
> > +    }
> > +
> > +    Status = FindFfsSectionInSections (
> > +               (VOID*) (File + 1),
> > +               (UINTN) EndOfFile - (UINTN) (File + 1),
> > +               SectionType,
> > +               FoundSection
> > +               );
> > +    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> > +      return Status;
> > +    }
> > +  }
> > +}
> > +
> > +/**
> > +  Locates the PEI Core entry point address
> > +
> > +  @param[in]  Fv                 The firmware volume to search
> > +  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core
> > + image
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindPeiCoreImageBaseInFv (
> 
> And this.
> 
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> > +  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_COMMON_SECTION_HEADER   *Section;
> > +
> > +  Status = FindFfsFileAndSection (
> > +             Fv,
> > +             EFI_FV_FILETYPE_PEI_CORE,
> > +             EFI_SECTION_PE32,
> > +             &Section
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    Status = FindFfsFileAndSection (
> > +               Fv,
> > +               EFI_FV_FILETYPE_PEI_CORE,
> > +               EFI_SECTION_TE,
> > +               &Section
> > +               );
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
> > +      return Status;
> > +    }
> > +  }
> > +  DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
> > +  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Locates the PEI Core entry point address
> > +
> > +  @param[in,out]  Fv                 The firmware volume to search
> > +  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +VOID
> > +FindPeiCoreImageBase (
> > +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
> > +     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> > +  )
> > +{
> > +  *PeiCoreImageBase = 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));
> 
> This one is the same with S3 support ripped out, and the above line added.
> Can you delete the message, or change it to something more human friendly?
> I personally would interpret that as something that was printed _from_ that
> function (and in that situation should be using %a __FUNCTION__).
> 
> > +  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); }
> > +
> > +/*
> > +  Find and return Pei Core entry point.
> > +
> > +  It also find SEC and PEI Core file debug inforamtion. It will
> > + report them if  remote debug is enabled.
> > +
> > +**/
> > +VOID
> > +FindAndReportEntryPoints (
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
> > +  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> > +  )
> > +{
> > +  EFI_STATUS                       Status;
> > +  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> > +
> > +  DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));
> 
> Use %a __FUNCTION__.
> 
> > +
> > +  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> > + //  // Find PEI Core entry point  //  Status =
> > + PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> > + (VOID**) PeiCoreEntryPoint);  if (EFI_ERROR(Status)) {
> > +    *PeiCoreEntryPoint = 0;
> > +  }
> > +  DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n",
> > + *PeiCoreEntryPoint));
> > +
> > +  return;
> > +}
> > +/*
> > +  Print out the content of firmware context.
> > +
> > +**/
> > +VOID
> > +DebutPrintFirmwareContext (
> 
> Debut -> Debug?
> 
> > +    EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
> > +    )
> > +{
> > +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at
> > +0x%x\n", FirmwareContext));
> 
> Please drop the [OpenSBI] prefix.
> 
> > +  DEBUG ((DEBUG_INFO, "           PEI Service at 0x%x\n\n",
> FirmwareContext->PeiServiceTable));
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> > +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> > +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> > +  IN UINTN                    CopySize
> > +  )
> > +{
> > +  VOID      *OldHeap;
> > +  VOID      *NewHeap;
> > +  VOID      *OldStack;
> > +  VOID      *NewStack;
> > +  struct sbi_platform *ThisSbiPlatform;
> > +
> > +  DEBUG ((DEBUG_INFO,
> > +    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
> 
> %a
> __FUNCTION__
> 
> > +    TemporaryMemoryBase,
> > +    PermanentMemoryBase,
> > +    (UINT64)CopySize
> > +    ));
> > +
> > +  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> > +  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> > +
> > +  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> > + NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> > +
> > +  CopyMem (NewHeap, OldHeap, CopySize >> 1);   // Migrate Heap
> > +  CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
> > +
> > +  //
> > +  // Reset firmware context pointer
> > +  //
> > +  ThisSbiPlatform = (struct sbi_platform
> > + *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> > +  ThisSbiPlatform->firmware_context += (unsigned
> > + long)((UINTN)NewStack - (UINTN)OldStack);
> 
> "unsigned long" is not a type that exists in UEFI.
> Please use UINTN. Applies throughout.
> 
> > +  //
> > +  // Relocate PEI Service **
> > +  //
> > +  ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT
> > + *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned
> > + long)((UINTN)NewStack - (UINTN)OldStack);
> 
> The above line is begging for a temporary pointer for the firmware_context.
> 
> > +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is
> > + relocated to 0x%x\n", ThisSbiPlatform->firmware_context));
> 
> Please
> 
> > +  DebutPrintFirmwareContext
> ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT
> > + *)ThisSbiPlatform->firmware_context);
> > +
> > +  register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack -
> > + (UINTN)OldStack);  asm volatile ("add sp, sp, a0"::"r"(a0):);
> 
> Urgh.
> Is there any way this could be broken out into a separate assembler function
> instead? If not, we still need to get rid of the uintptr_t:s.
> 
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS EFIAPI TemporaryRamDone (VOID) {
> > +  DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +#if 1
> 
> Just delete the #if 1?
> 
> > +#define GPIO_CTRL_ADDR  0x54002000
> > +#define GPIO_OUTPUT_VAL 0x0C
> > +static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
> > +#define REG32(p, i)   ((p)[(i)>>2])
> > +#endif
> 
> And the #endif
> 
> Moreover, please move the ADDRESS/VALUE macros to SecMain.h, and use
> IoLib instead of defining your own variables and macros.
> 
> > +
> > +static VOID EFIAPI PeiCore(VOID)
> 
> STATIC
> Also, please follow coding style for function definition, this is supposed to be
> over multiple lines.
> 
> > +{
> > +  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> > +  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> > +  EFI_FIRMWARE_VOLUME_HEADER *BootFv =
> (EFI_FIRMWARE_VOLUME_HEADER
> > +*)FixedPcdGet32(PcdRiscVPeiFvBase);
> > +  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
> > +  struct sbi_platform *ThisSbiPlatform;
> > +  UINT32 HartId;
> > +
> > +  REG32(gpio, GPIO_OUTPUT_VAL) = 0x88;  FindAndReportEntryPoints
> > + (&BootFv, &PeiCoreEntryPoint);
> > +
> > +  SecCoreData.DataSize               = sizeof(EFI_SEC_PEI_HAND_OFF);
> > +  SecCoreData.BootFirmwareVolumeBase = BootFv;
> > + SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> > +  SecCoreData.TemporaryRamBase       = (VOID*)(UINT64)
> FixedPcdGet32(PcdTemporaryRamBase);
> > +  SecCoreData.TemporaryRamSize       = (UINTN)
> FixedPcdGet32(PcdTemporaryRamSize);
> > +  SecCoreData.PeiTemporaryRamBase    =
> SecCoreData.TemporaryRamBase;
> > +  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize
> >> 1;
> > +  SecCoreData.StackBase              = (UINT8
> *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >>
> 1);
> 
> Please don't use UINT8 * to get away from pointer arithmetic. It disguises
> what function is actually being performed.
> (VOID *)((UINTN) ...) is a much preferred form where that level of
> description is required.
> 
> > +  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
> > +
> > +  //
> > +  // Print out scratch address of each hart  //  DEBUG ((DEBUG_INFO,
> > + "[OpenSBI]: OpenSBI scratch address for each hart:\n"));
> 
> Please drop [OpenSBI] tag.
> 
> > +  for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> > +    DEBUG ((DEBUG_INFO, "          Hart %d: 0x%x\n", HartId,
> sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));
> 
> Please wrap long line.
> 
> > +  }
> > +
> > +  //
> > +  // Set up OpepSBI firmware context poitner on boot hart OpenSbi
> > + scratch. Firmware context residents in stack and will be
> 
> Please wrap long line.
> 
> > +  // switched to memory when temporary ram migration.
> > +  //
> > +  ZeroMem ((VOID *)&FirmwareContext, sizeof
> > + (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
> > +  ThisSbiPlatform = (struct sbi_platform
> > + *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> > +  if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
> > +      DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version
> 0x%x is newer than OpenSBI version 0x%x.\n"
> > +                           "There maybe be some backward compatable
> > + issues.\n",
> 
> Please drop [OpenSBI] tag. Please convert the two lines to two separate
> DEBUG prints.
> 
> > +             ThisSbiPlatform->opensbi_version,
> > +             OPENSBI_VERSION
> > +             ));
> > +      ASSERT(FALSE);
> > +  }
> > +  DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address:
> > + 0x%x\nFirmware Context is located at 0x%x\n",
> 
> Please drop [OpenSBI] tag.
> 
> > +             ThisSbiPlatform,
> > +             &FirmwareContext
> > +             ));
> > +  ThisSbiPlatform->firmware_context = (unsigned
> > + long)&FirmwareContext;
> 
> UINTN (probably best to do a global search and replace on this).
> 
> > +  //
> > +  // Set firmware context Hart-specific pointer  //  for (HartId = 0;
> > + HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> > +    FirmwareContext.HartSpecific [HartId] = \
> > +      (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8
> > + *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) -
> > + FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
> 
> Please don't use (UINT8 *) to get away from pointer arithmetic.
> UINTN should work fine in this context.
> 
> Screaming out for a temporary variable.
> 
> > +    DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware
> Context
> > + Hart-specific at address: 0x%x\n",
> 
> Please drop [OpenSBI] tag.
> 
> > +             HartId,
> > +             FirmwareContext.HartSpecific [HartId]
> > +             ));
> > +  }
> > +
> > +  //
> > +  // Transfer the control to the PEI core
> > +  //
> > +  (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> > +*)&mPrivateDispatchTable); }
> > +/**
> > +  This function initilizes hart specific information and SBI.
> > +  For the boot hart, it boots system through PEI core and initial SBI in the
> DXE IPL.
> > +  For others, it goes to initial SBI and halt.
> > +
> > +  the lay out of memory region for each hart is as below delineates,
> > +
> > +                                               _                                        ____
> > +  |----Scratch ends                             |                                           |
> > +  |                                             | sizeof (sbi_scratch)                      |
> > +  |                                            _|                                           |
> > +  |----Scratch buffer start s                  <----- *scratch                              |
> > +  |----Firmware Context Hart-specific ends     _                                            |
> > +  |                                             |                                           |
> > +  |                                             | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> |
> > +  |                                             |                                           |  PcdOpenSbiStackSize
> > +  |                                            _|                                           |
> > +  |----Firmware Context Hart-specific starts   <-----
> **HartFirmwareContext                 |
> > +  |----Hart stack top                          _                                            |
> > +  |                                             |                                           |
> > +  |                                             |                                           |
> > +  |                                             |  Stack                                    |
> > +  |                                             |                                           |
> > +  |                                            _|                                       ____|
> > +  |----Hart stack bottom
> > +
> > +**/
> > +VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct
> > +sbi_scratch *scratch)
> 
> Split up over multiple lines.
> 
> > +{
> > +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> *HartFirmwareContext;
> > +
> > +  //
> > +  // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
> > +  //
> > +  HartFirmwareContext =
> (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > + *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
> 
> Please don't use UINT8 * to get away from pointer arithmetic.
> In this context, UINTN should work just fine.
> 
> > +  HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
> > + HartFirmwareContext->MachineVendorId.Value64_L =
> RiscVReadMVendorId
> > + ();  HartFirmwareContext->MachineVendorId.Value64_H = 0;
> > + HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId
> ();
> > + HartFirmwareContext->MachineArchId.Value64_H = 0;
> > + HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
> > + HartFirmwareContext->MachineImplId.Value64_H = 0;
> > +
> > +#if 0
> 
> Please don't leave unused code in.
> If you want to keep the printouts for extreme debugging sessions, change
> the loglevel to DEBUG_VERBOSE.
> 
> > +  while (HartsIn != hartid);
> > +  DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context
> > + Hart-specific for HART ID:%d\n", hartid));
> 
> Please drop [OpenSBI] tag.
> 
> > +  DEBUG ((DEBUG_INFO, "           Scratch at address: 0x%x\n", scratch));
> > +  DEBUG ((DEBUG_INFO, "           Firmware Context Hart-specific at address:
> 0x%x\n", HartFirmwareContext));
> > +  DEBUG ((DEBUG_INFO, "           stack pointer at address: 0x%x\n",
> stack_point));
> > +  DEBUG ((DEBUG_INFO, "                    MISA: 0x%x\n",
> HartFirmwareContext->IsaExtensionSupported));
> > +  DEBUG ((DEBUG_INFO, "                    MVENDORID: 0x%x\n",
> HartFirmwareContext->MachineVendorId.Value64_L));
> > +  DEBUG ((DEBUG_INFO, "                    MARCHID: 0x%x\n",
> HartFirmwareContext->MachineArchId.Value64_L));
> > +  DEBUG ((DEBUG_INFO, "                    MIMPID: 0x%x\n\n",
> HartFirmwareContext->MachineImplId.Value64_L));
> > +  HartsIn ++;
> > +  for (;;);
> > +#endif
> > +
> > +  if (hartid == FixedPcdGet32(PcdBootHartId)) {
> > +    PeiCore();
> > +  }
> > +  sbi_init(scratch);
> > +}
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.h
> > b/Platform/RiscV/Universal/Sec/SecMain.h
> > new file mode 100644
> > index 00000000..e7565f5e
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.h
> > @@ -0,0 +1,57 @@
> > +/** @file
> > +  RISC-V SEC phase module definitions..
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _SECMAIN_H_
> > +#define _SECMAIN_H_
> 
> Plese drop leading _.
> 
> > +
> > +#include <PiPei.h>
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/DebugAgentLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/PeCoffLib.h>
> > +#include <Library/PeCoffGetEntryPointLib.h>
> > +#include <Library/PeCoffExtraActionLib.h> #include
> > +<Library/ExtractGuidedSectionLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Ppi/TemporaryRamSupport.h>
> > +#include <Ppi/TemporaryRamDone.h>
> > +#include <Library/RiscVCpuLib.h>
> 
> Please drop all include statements not required by this file, and add them
> instead in the files that do use them.
> 
> > +
> > +VOID
> > +SecMachineModeTrapHandler (
> > +  IN VOID
> > +  );
> > +
> > +VOID
> > +EFIAPI
> > +SecStartupPhase2 (
> > +  IN VOID                     *Context
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> > +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> > +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> > +  IN UINTN                    CopySize
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamDone (
> > +  VOID
> > +  );
> > +
> > +#endif // _SECMAIN_H_
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf
> > b/Platform/RiscV/Universal/Sec/SecMain.inf
> > new file mode 100644
> > index 00000000..c408fc8d
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.inf
> > @@ -0,0 +1,75 @@
> > +## @file
> > +#  RISC-V SEC module.
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # #  SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Can this be updated to a recent specification version.
> 
> > +  BASE_NAME                      = SecMain
> > +  FILE_GUID                      = df1ccef6-f301-4a63-9661-fc6030dcc880
> > +  MODULE_TYPE                    = SEC
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = SecMain
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = RISCV64 EBC
> 
> Pretty sure EBC is not valid here.
> 
> > +#
> > +
> > +[Sources]
> > +  SecMain.c
> > +
> > +[Sources.RISCV64]
> > +  Riscv64/SecEntry.s
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  RiscVPkg/RiscVPkg.dec
> > +  Platform/RiscV/RiscVPlatformPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +  PcdLib
> > +  DebugAgentLib
> > +  IoLib
> > +  PeCoffLib
> > +  PeCoffGetEntryPointLib
> > +  PeCoffExtraActionLib
> > +  ExtractGuidedSectionLib
> > +  RiscVCpuLib
> > +  PrintLib
> > +  SerialPortLib
> > +  RiscVOpensbiLib
> > +  OpenSbiPlatformLib # This is required library which
> > +                     # provides platform level opensbi
> > +                     # functions.
> 
> I don't doubt it, but I can tell it's required from the fact that it is listed. And
> the name itself says all of the rest. The comment is superfluous and can be
> deleted.
> 
> > +
> > +[Ppis]
> > +  gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> > +  gEfiTemporaryRamDonePpiGuid    # PPI ALWAYS_PRODUCED
> > +
> > +[Guids]
> > +  gUefiRiscVMachineContextGuid
> > +
> > +[FixedPcd]
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
> > +
> > +[Pcd]
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize
> 
> Please sort the above alphabetically (
> apart from where it makes sense not to - for example PcdFwStartAddress
> before PcdFwEndAddress makes more sense than the other way around).
> 
> /
>     Leif
> 
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores
  2019-10-01 21:14   ` [edk2-devel] " Leif Lindholm
@ 2019-10-16  1:36     ` Abner Chang
  2019-10-17 10:33       ` Leif Lindholm
  0 siblings, 1 reply; 43+ messages in thread
From: Abner Chang @ 2019-10-16  1:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Wednesday, October 2, 2019 5:15 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 02/14]
> Silicon/SiFive: Add library module of SiFive RISC-V cores
> 
> On Thu, Sep 19, 2019 at 11:51:19AM +0800, Gilbert Chen wrote:
> > Initial version of SiFive RISC-V core libraries. Library of each core
> > creates processor core SMBIOS data hob for building SMBIOS  records in
> > DXE phase.
> 
> So yes, this implementation needs to change.
> These should all implement the same LibraryClass.
No. It shouldn't be the same library class (If you were saying the same LibraryClass). RISC-V SoC could be the combination of different RISC-V cores, or even the cores from different vendors. This depends on how SoC vendor combine those IPs.
Either U54 or E51 could be a standalone SoC, while U54MC is the combination of 4 x U54 core and one E51 core.

U5MC under Platform/SiFive could be 1-8 U5 core and optionally support E5 core.  This is the special case for U500 VC707 platform because the core number could be customized.

> Also, U54 appears to be a simple superset of U51.
U54 is a single core. 

> 
> What I would suggest is creating a
> Silicon/SiFive/Library/SiFiveCoreInfoLib, which calls into a
> SiFiveSoCCoreInfoLib in Silicon/SiFive/<SoC>/Library, providing the acual SoC-
> specific bits.

Platform system firmware integrator just pull in the necessary core libraries from Silicon/{vendor}  and invoke the function to create specific core bits.
I think this implementation is well and flexible which has no need to change.

> 
> /
>     Leif
> 
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 242
> +++++++++++++++++
> >  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
> >  .../U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c    | 294
> +++++++++++++++++++++
> >  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  51 ++++
> >  .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 185 +++++++++++++
> >  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  50 ++++
> >  6 files changed, 873 insertions(+)
> >  create mode 100644
> > Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> >  create mode 100644
> > Silicon/SiFive/E51/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> >  create mode 100644
> > Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> >  create mode 100644
> > Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
> >  create mode 100644
> > Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> >  create mode 100644
> >
> Silicon/SiFive/U54MCCoreplex/Library/PeiCoreInfoHobLib/PeiCoreInfoHobL
> > ib.inf
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-03 16:32   ` [edk2-devel] " Leif Lindholm
@ 2019-10-17  2:21     ` Abner Chang
  2019-10-17  7:44       ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Abner Chang @ 2019-10-17  2:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Friday, October 4, 2019 12:32 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> U500Pkg/Library: Library instances of U500 platform library
> 
> On Thu, Sep 19, 2019 at 11:51:27AM +0800, Gilbert Chen wrote:
> > OpneSbiPlatformLib
> > - In order to reduce the dependencies with RISC-V OpenSBI project
> > (https://github.com/riscv/opensbi) and less burdens to EDK2 build
> > process, the implementation of RISC-V EDK2 platform is leverage
> > platform source code from OpenSBI code tree. The "platform.c"
> >  under OpenSbiPlatformLib is cloned from RISC-V OpenSBI code tree  (in
> > EDK2 RiscVPkg) and built based on EDK2 build environment.
> >
> > PeiCoreInfoHobLib
> > - This is the library to create RISC-V core characteristics for
> > building  up RISC-V related SMBIOS records to support the unified boot
> > loader  and OS image.
> >
> > - RiscVPlatformTimerLib
> > This is U500 platform timer library which has the platform-specific
> > timer implementation.
> >
> > - SerialPortLib
> > U500 serial port platform library
> 
> Please split this up into the 4 logical commits.
> And add the specific header files with those commits.
> 
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../OpenSbiPlatformLib/OpenSbiPlatformLib.inf      |  47 ++++
> >  .../U500Pkg/Library/OpenSbiPlatformLib/platform.c  | 214
> ++++++++++++++++++
> >  .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 195
> +++++++++++++++++
> >  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  58 +++++
> >  .../RiscVPlatformTimerLib/RiscVPlatformTimerLib.S  |  48 ++++
> >  .../RiscVPlatformTimerLib.inf                      |  39 ++++
> >  .../U500Pkg/Library/SerialIoLib/SerialIoLib.inf    |  31 +++
> >  .../U500Pkg/Library/SerialIoLib/SerialPortLib.c    | 241
> +++++++++++++++++++++
> >  .../Library/SerialIoLib/U500SerialPortLib.uni      |  16 ++
> >  9 files changed, 889 insertions(+)
> >  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatfo
> > rmLib.inf  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> >  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
> >  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHob
> > Lib.inf  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatf
> > ormTimerLib.S  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPlatf
> > ormTimerLib.inf  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> >  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> >  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.un
> > i
> >
> > diff --git
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlat
> > formLib.inf
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlat
> > formLib.inf
> > new file mode 100644
> > index 00000000..473386d2
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbi
> > +++ PlatformLib.inf
> > @@ -0,0 +1,47 @@
> > +## @file
> > +#  RISC-V OpenSbi Platform Library
> > +#  This is the the required library which provides platform
> 
> Please don't use the word required. (If it wasn't, why would you include it at
> all?)
> 
> > +#  level opensbi functions follow RISC-V opensbi implementation.
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # #  SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = OpenSbiPlatformLib
> > +  FILE_GUID                      = 9424ED54-EBDA-4FB5-8FF6-8291B07BB151
> > +  MODULE_TYPE                    = SEC
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = OpenSbiPlatformLib
> 
> Seeing this, I have a bit of a feeling that this Opensbi isn't being consistently
> treated/named:
> - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
>   class RiscVOpensbiLib.
> - Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing the
>   class OpenSbiPlatformLib.
> - *Logically*, what we have is
>   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
>   OpensbiLib which depends on the OpenSbiPlatformLib.
>   - However, there is no OpenSbiPlatformLib in edk2, which is very
>     unfortunate because that does not let us build edk2/RiscVPkg in
>     isolation (like we can with all the other packages in edk2).
Will name it as Opensbi.
> 
> Here is my preferred solution for untangling this:
> 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
>    already use for Openssl, so would be my preference.
> 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
>    LibararyClasses. Either is fine, the former is less likely to clash
>    with other imported projects in the future (but I would estimate
>    this risk as *very* low to begin with).
> 3) Implement a (RiscV)OpensbiPlatformLibNull in edk2/RiscVPkg/Library,
I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library

>    containing only what is required to build/link
>    RiscVPkg/Library/(RiscV)OpensbiLib/.
>    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
>    3.6) Add a depedency on OpensbiPlatformLib to
>         (RiscV)OpensbiLib.inf
>    3.7) Drop the dependency on OpensbiPlatformLib from
>         Platform/RiscV/Universal/Sec/SecMain.inf
Above work for me
> 
> (That might read like a lot of work, but really it's a 5 minute job and if we
> untangle this now, this won't cascade over umpteen
> platforms.)


> 
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = RISCV64 EBC
> 
> Drop EBC.
> 
> > +#
> > +
> > +[Sources]
> > +  platform.c
> 
> Please rename as Platform.c.
> 
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  RiscVPkg/RiscVPkg.dec
> > +  Platform/RiscV/RiscVPlatformPkg.dec
> 
> Please sort files alphabetically.
> 
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +  PcdLib
> > +  DebugAgentLib
> > +  RiscVCpuLib
> > +  PrintLib
> 
> Please sort LibraryClasses alphabetically.
> 
> > +
> > +[FixedPcd]
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> 
> Please sort Pcds alphabetically.
> 
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> > b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> > new file mode 100644
> > index 00000000..4dca75f2
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platfor
> > +++ m.c
> > @@ -0,0 +1,214 @@
> > +/*
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR>
> > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * Authors:
> > + *   Atish Patra <atish.patra@wdc.com>
> 
> Please change commit Author instead.
> 
> Please point out that this is the platform-specific portion of OpensbiLib. With
> that, I'm OK with it not following EDK2 coding style. *However*, it needs to
> follow OpenSBI coding style, and it currently doesn't - 3-space indentation
> follows nothing.
> 
> From what I see, OpenSBI follows Linux coding style. So please update to
> that, throughout this file. *if* you untabify it (8 spaces/tab) before
> submission, our tools will complain less, so do consider that.
> 
> > + */
> > +
> > +#include <libfdt.h>
> > +#include <fdt.h>
> > +#include <sbi/riscv_encoding.h>
> > +#include <sbi/sbi_const.h>
> > +#include <sbi/sbi_hart.h>
> > +#include <sbi/sbi_console.h>
> > +#include <sbi/sbi_platform.h>
> > +#include <sbi/riscv_io.h>
> > +#include <sbi_utils/irqchip/plic.h>
> > +#include <sbi_utils/serial/sifive-uart.h> #include
> > +<sbi_utils/sys/clint.h>
> > +
> > +
> > +#define U500_HART_COUNT         FixedPcdGet32(PcdHartCount)
> > +#define U500_HART_STACK_SIZE   FixedPcdGet32(PcdOpenSbiStackSize)
> > +#define U500_BOOT_HART_ID       FixedPcdGet32(PcdBootHartId)
> > +
> > +#define U500_SYS_CLK         100000000
> > +
> > +#define U500_CLINT_ADDR         0x2000000
> > +
> > +#define U500_PLIC_ADDR            0xc000000
> > +#define U500_PLIC_NUM_SOURCES      0x35
> > +#define U500_PLIC_NUM_PRIORITIES   7
> > +
> > +#define U500_UART_ADDR            0x54000000
> > +
> > +#define U500_UART_BAUDRATE         115200
> > +
> > +/**
> > + * The U500 SoC has 8 HARTs but HART ID 0 doesn't have S mode.
> > + * HARTs 1 is selected as boot HART
> > + */
> > +#ifndef U500_ENABLED_HART_MASK
> > +#define U500_ENABLED_HART_MASK   (1 << U500_BOOT_HART_ID)
> > +#endif
> > +
> > +#define U500_HARTID_DISABLED   ~(U500_ENABLED_HART_MASK)
> > +
> > +/* PRCI clock related macros */
> > +//TODO: Do we need a separate driver for this ?
> 
> Well, do we?
> 
> > +#define U500_PRCI_BASE_ADDR         0x10000000
> > +#define U500_PRCI_CLKMUXSTATUSREG   0x002C
> > +#define U500_PRCI_CLKMUX_STATUS_TLCLKSEL   (0x1 << 1)
> 
> Please adjust right-column alignment through the defines above.
> 
> > +
> > +static void U500_modify_dt(void *fdt) {
> > +   u32 i, size;
> 
> 
> > +   int chosen_offset, err;
> > +   int cpu_offset;
> > +   char cpu_node[32] = "";
> > +   const char *mmu_type;
> > +
> > +   for (i = 0; i < U500_HART_COUNT; i++) {
> > +      sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
> > +      cpu_offset = fdt_path_offset(fdt, cpu_node);
> > +      mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
> > +      if (mmu_type && (!strcmp(mmu_type, "riscv,sv39") ||
> > +          !strcmp(mmu_type,"riscv,sv48")))
> > +         continue;
> > +      else
> > +         fdt_setprop_string(fdt, cpu_offset, "status", "masked");
> > +      memset(cpu_node, 0, sizeof(cpu_node));
> > +   }
> > +   size = fdt_totalsize(fdt);
> > +   err = fdt_open_into(fdt, fdt, size + 256);
> > +   if (err < 0)
> > +      sbi_printf("Device Tree can't be expanded to accmodate new
> > + node");
> > +
> > +   chosen_offset = fdt_path_offset(fdt, "/chosen");
> > +   fdt_setprop_string(fdt, chosen_offset, "stdout-path",
> > +            "/soc/serial@10010000:115200");
> > +
> > +   plic_fdt_fixup(fdt, "riscv,plic0"); }
> > +
> > +static int U500_final_init(bool cold_boot) {
> > +   void *fdt;
> > +
> > +   if (!cold_boot)
> > +      return 0;
> > +
> > +   fdt = sbi_scratch_thishart_arg1_ptr();
> > +   U500_modify_dt(fdt);
> > +
> > +   return 0;
> > +}
> > +
> > +static u32 U500_pmp_region_count(u32 hartid) {
> > +   return 1;
> > +}
> > +
> > +static int U500_pmp_region_info(u32 hartid, u32 index,
> > +             ulong *prot, ulong *addr, ulong *log2size) {
> > +   int ret = 0;
> > +
> > +   switch (index) {
> > +   case 0:
> > +      *prot = PMP_R | PMP_W | PMP_X;
> > +      *addr = 0;
> > +      *log2size = __riscv_xlen;
> > +      break;
> > +   default:
> > +      ret = -1;
> > +      break;
> > +   };
> > +
> > +   return ret;
> > +}
> > +
> > +static int U500_console_init(void)
> > +{
> > +   unsigned long peri_in_freq;
> > +
> > +   peri_in_freq = U500_SYS_CLK/2;
> > +   return sifive_uart_init(U500_UART_ADDR, peri_in_freq,
> > +U500_UART_BAUDRATE); }
> > +
> > +static int U500_irqchip_init(bool cold_boot) {
> > +   int rc;
> > +   u32 hartid = sbi_current_hartid();
> > +
> > +   if (cold_boot) {
> > +      rc = plic_cold_irqchip_init(U500_PLIC_ADDR,
> > +                   U500_PLIC_NUM_SOURCES,
> > +                   U500_HART_COUNT);
> > +      if (rc)
> > +         return rc;
> > +   }
> > +
> > +   return plic_warm_irqchip_init(hartid,
> > +         (hartid) ? (2 * hartid - 1) : 0,
> > +         (hartid) ? (2 * hartid) : -1); }
> > +
> > +static int U500_ipi_init(bool cold_boot) {
> > +   int rc;
> > +
> > +   if (cold_boot) {
> > +      rc = clint_cold_ipi_init(U500_CLINT_ADDR,
> > +                U500_HART_COUNT);
> > +      if (rc)
> > +         return rc;
> > +
> > +   }
> > +
> > +   return clint_warm_ipi_init();
> > +}
> > +
> > +static int U500_timer_init(bool cold_boot) {
> > +   int rc;
> > +
> > +   if (cold_boot) {
> > +      rc = clint_cold_timer_init(U500_CLINT_ADDR,
> > +                  U500_HART_COUNT);
> > +      if (rc)
> > +         return rc;
> > +   }
> > +
> > +   return clint_warm_timer_init();
> > +}
> > +
> > +static int U500_system_down(u32 type) {
> > +   /* For now nothing to do. */
> > +   return 0;
> > +}
> > +
> > +const struct sbi_platform_operations platform_ops = {
> > +   .pmp_region_count = U500_pmp_region_count,
> > +   .pmp_region_info = U500_pmp_region_info,
> > +   .final_init = U500_final_init,
> > +   .console_putc = sifive_uart_putc,
> > +   .console_getc = sifive_uart_getc,
> > +   .console_init = U500_console_init,
> > +   .irqchip_init = U500_irqchip_init,
> > +   .ipi_send = clint_ipi_send,
> > +   .ipi_sync = clint_ipi_sync,
> > +   .ipi_clear = clint_ipi_clear,
> > +   .ipi_init = U500_ipi_init,
> > +   .timer_value = clint_timer_value,
> > +   .timer_event_stop = clint_timer_event_stop,
> > +   .timer_event_start = clint_timer_event_start,
> > +   .timer_init = U500_timer_init,
> > +   .system_reboot = U500_system_down,
> > +   .system_shutdown = U500_system_down };
> > +
> > +const struct sbi_platform platform = {
> > +   .opensbi_version   = OPENSBI_VERSION,                  // The OpenSBI
> version this platform table is built bassed on.
> > +   .platform_version   = SBI_PLATFORM_VERSION(0x0001, 0x0000),   // SBI
> Platform version 1.0
> > +   .name               = "SiFive Freedom U500",
> > +   .features      = SBI_PLATFORM_DEFAULT_FEATURES,
> > +   .hart_count      = U500_HART_COUNT,
> > +   .hart_stack_size   = U500_HART_STACK_SIZE,
> > +   .disabled_hart_mask   = U500_HARTID_DISABLED,
> > +   .platform_ops_addr   = (unsigned long)&platform_ops
> > +};
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.
> > c
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.
> > c
> > new file mode 100644
> > index 00000000..bfb97351
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfo
> > +++ Hob.c
> > @@ -0,0 +1,195 @@
> > +/**@file
> > +  Build up platform processor information.
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +//
> > +// The package level header files this module uses // #include
> > +<PiPei.h>
> > +
> > +//
> > +// The Library classes this module consumes // #include
> > +<Library/DebugLib.h> #include <Library/HobLib.h> #include
> > +<Library/BaseMemoryLib.h>
> > +
> > +#include <SmbiosProcessorSpecificData.h> #include
> > +<ProcessorSpecificDataHob.h> #include <SiFiveU5MCCoreplex.h>
> #include
> > +<Library/SiFiveE51.h> #include <Library/SiFiveU54.h>
> 
> Please sort includes alphabetically.
> 
> > +
> > +/**
> > +  Build up processor-specific HOB for U5MC Coreplex
> > +
> > +  @param  UniqueId      Unique ID of this U5MC Coreplex processor
> > +
> > +  @return EFI_SUCCESS     The PEIM initialized successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CreateU5MCCoreplexProcessorSpecificDataHob (
> > +  IN UINTN UniqueId
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +  UINT32 HartIdNumber;
> > +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *GuidHobData;
> > +  EFI_GUID *ParentCoreGuid;
> > +  BOOLEAN MCSupport;
> > +
> > +  DEBUG ((DEBUG_INFO, "Building U5 Coreplex processor information
> > + HOB\n"));
> > +
> > +  HartIdNumber = 0;
> > +  ParentCoreGuid = PcdGetPtr(PcdSiFiveU5MCCoreplexGuid);
> > +  MCSupport = PcdGetBool (PcdE5MCSupported);  if (MCSupport == TRUE)
> > + {
> > +    Status = CreateE51CoreProcessorSpecificDataHob (ParentCoreGuid,
> UniqueId, HartIdNumber, FALSE, &GuidHobData);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino
> HOB\n"));
> > +      ASSERT (FALSE);
> > +    }
> > +    HartIdNumber ++;
> > +    DEBUG ((DEBUG_INFO, "Support E5 Monitor core on U500 platform,
> > + HOB at address 0x%x\n", GuidHobData));
> 
> Hmm, OK, this was why you had the different LibraryClasses?
> I still don't think it should be a separate libraryclass per CPU. If possible, I
> would prefer MonitorCoreInfoLib and ApplicationCoreInfoLib.
> 
> > +  }
> > +  for (; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) +
> (UINT32)MCSupport); HartIdNumber ++) {
> > +    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid,
> > + UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32
> > + (PcdBootHartId))? TRUE: FALSE, &GuidHobData);
> 
> Nesting that ternary saves you nothing other than typing, and not much of
> that. Please use a temporary variable instead:
> 
>    BOOL IsBootHart;
>    IsBootHart = HartIdNumber == FixedPcdGet32 (PcdBootHartId)) ? TRUE :
> FALSE
>    /* Also, always spaces around ? and : for ternaries. */
>    /* No, don't actually include this comment. */
>    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid,
> UniqueId,
>               HartIdNumber, IsBootHart, &GuidHobData);
> 
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino
> HOB\n"));
> > +      ASSERT (FALSE);
> > +    }
> > +    DEBUG ((DEBUG_INFO, "Support U5 application core on U500
> > + platform, HOB Data at address 0x%x\n", GuidHobData));  }  DEBUG
> > + ((DEBUG_INFO, "Support %d U5 application cores on U500 platform\n",
> > + HartIdNumber - (UINT32)MCSupport));
> 
> Please wrap those DEBUG lines. Not the strings, just the arguments.
> 
> > +
> > +  if (HartIdNumber != FixedPcdGet32 (PcdHartCount)) {
> > +    DEBUG ((DEBUG_ERROR, "Improper core settings...\n"));
> > +    DEBUG ((DEBUG_ERROR, "    PcdHartCount\n"));
> > +    DEBUG ((DEBUG_ERROR, "    PcdNumberofU5Cores\n"));
> > +    DEBUG ((DEBUG_ERROR, "    PcdE5MCSupported\n\n"));
> > +    ASSERT (FALSE);
> > +  }
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Function to build processor related SMBIOS information. RISC-V
> > +SMBIOS DXE driver collect
> > +  this information and build SMBIOS Type4 and Type7 record.
> > +
> > +  @param  ProcessorUid    Unique ID of pysical processor which owns this
> core.
> > +  @param  SmbiosHobPtr    Pointer to receive
> RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> > +                          maintained in this structure is only valid before memory is
> discovered.
> > +                          Access to those pointers after memory is installed will cause
> unexpected issues.
> > +
> > +  @return EFI_SUCCESS     The PEIM initialized successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CreateU5MCProcessorSmbiosDataHob (
> > +  IN UINTN     ProcessorUid,
> > +  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> > +  )
> > +{
> > +  EFI_GUID *GuidPtr;
> > +  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
> > +  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
> > +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
> > +  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
> > +  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
> > +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
> > +
> > +  DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
> > +
> > +  if (SmbiosHobPtr == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // Build up SMBIOS type 7 L2 cache record.
> > +  //
> > +  ZeroMem((VOID *)&L2CacheDataHob, sizeof
> > + (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
> > +  L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr
> > + (PcdSiFiveU5MCCoreplexGuid));  L2CacheDataHob.ProcessorUid =
> > + ProcessorUid;  L2CacheDataHob.SmbiosType7Cache.SocketDesignation =
> > + TO_BE_FILLED_BY_VENDOR;
> L2CacheDataHob.SmbiosType7Cache.CacheConfiguration =
> RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
> > +      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
> > +      RISC_V_CACHE_CONFIGURATION_ENABLED | \
> > +      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
> > +  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize =
> > + TO_BE_FILLED_BY_VENDOR;
> > + L2CacheDataHob.SmbiosType7Cache.InstalledSize =
> > + TO_BE_FILLED_BY_VENDOR;
> > + L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1;
> > + L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
> > + L2CacheDataHob.SmbiosType7Cache.CacheSpeed =
> TO_BE_FILLED_BY_VENDOR;
> > + L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType =
> > + TO_BE_FILLED_BY_VENDOR;
> > + L2CacheDataHob.SmbiosType7Cache.SystemCacheType =
> CacheTypeUnified;
> > + L2CacheDataHob.SmbiosType7Cache.Associativity =
> > + TO_BE_FILLED_BY_VENDOR;  GuidPtr = (EFI_GUID *)PcdGetPtr
> > + (PcdProcessorSmbiosType7GuidHobGuid);
> > +  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB
> > + *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof
> > + (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
> 
> Please wrap long line.
> 
> > +  if (L2CacheDataHobPtr == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC
> > + Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
> 
> Please wrap long line. (That format string is longer than 80 characters on its
> own, consider shortening it.)
> 
> > +    ASSERT (FALSE);
> > +  }
> > +
> > +  //
> > +  // Build up SMBIOS type 4 record.
> > +  //
> > +  ZeroMem((VOID *)&ProcessorDataHob, sizeof
> > + (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> > +  ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr
> > + (PcdSiFiveU5MCCoreplexGuid));  ProcessorDataHob.ProcessorUid =
> > + ProcessorUid;  ProcessorDataHob.SmbiosType4Processor.Socket =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.ProcessorType =
> > + CentralProcessor;
> > + ProcessorDataHob.SmbiosType4Processor.ProcessorFamily =
> > + ProcessorFamilyIndicatorFamily2;
> > + ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture =
> > + TO_BE_FILLED_BY_VENDOR;  SetMem ((VOID
> > + *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof
> > + (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
> 
> Please wrap long line.
> 
> > +  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion =
> > + TO_BE_FILLED_BY_VENDOR;
> > +
> ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapabi
> > + lity3_3V = 1;  ProcessorDataHob.SmbiosType4Processor.ExternalClock =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.MaxSpeed =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.CurrentSpeed =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.Status =
> TO_BE_FILLED_BY_CODE;
> > + ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.L1CacheHandle =
> > + TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> > +  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle =
> > + TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> > +  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
> > + ProcessorDataHob.SmbiosType4Processor.SerialNumber =
> > + TO_BE_FILLED_BY_CODE;
> > + ProcessorDataHob.SmbiosType4Processor.AssetTag =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.PartNumber =
> > + TO_BE_FILLED_BY_VENDOR;
> > + ProcessorDataHob.SmbiosType4Processor.CoreCount =
> > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > + (PcdE5MCSupported);
> > + ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount =
> > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > + (PcdE5MCSupported);
> > + ProcessorDataHob.SmbiosType4Processor.ThreadCount =
> > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > + (PcdE5MCSupported);
> 
> Please wrap long lines.
> There are several more cases in this file, I'll stop pointing them out, but the
> general rule is no longer than 80. PatchCheck.py is a bit lax on this.
> 
> > +  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics =
> > + (UINT16)(1 << 2); // 64-bit capable
> > +  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 =
> > + ProcessorFamilyRiscVRV64;
> > +  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
> > +  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
> > +  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;  GuidPtr =
> > + (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
> > +  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB
> > + *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof
> > + (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> > +  if (ProcessorDataHobPtr == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC
> Coreplex RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
> > +    ASSERT (FALSE);
> > +  }
> > +
> > +  ZeroMem((VOID *)&SmbiosDataHob, sizeof
> > +(RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> > +  SmbiosDataHob.Processor = ProcessorDataHobPtr;
> > +  SmbiosDataHob.L1InstCache = NULL;
> > +  SmbiosDataHob.L1DataCache = NULL;
> > +  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
> > +  SmbiosDataHob.L3Cache = NULL;
> > +  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
> > +  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB
> > +*)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof
> > +(RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> > +  if (SmbiosDataHobPtr == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC
> Coreplex RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
> > +    ASSERT (FALSE);
> > +  }
> > +  *SmbiosHobPtr = SmbiosDataHobPtr;
> > +  DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoH
> > obLib.inf
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoH
> > obLib.inf
> > new file mode 100644
> > index 00000000..915021f9
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreI
> > +++ nfoHobLib.inf
> > @@ -0,0 +1,58 @@
> > +## @file
> > +#  Library instance to create core information HOB # #  Copyright (c)
> > +2019, Hewlett Packard Enterprise Development LP. All rights
> > +reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = SiliconSiFiveU5MCCoreplexInfoLib
> > +  FILE_GUID                      = 4E397A71-5164-4E69-9884-70CBE2740AAB
> > +  MODULE_TYPE                    = PEIM
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = SiliconSiFiveU5MCCoreplexInfoLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = RISCV
> > +#
> > +
> > +[Sources]
> > + CoreInfoHob.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  Platform/RiscV/RiscVPlatformPkg.dec
> > +  Platform/RiscV/SiFive/U500Pkg/U500.dec
> > +  Silicon/SiFive/SiFive.dec
> > +  RiscVPkg/RiscVPkg.dec
> 
> Please sort alphabetically.
> 
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  PcdLib
> > +  MemoryAllocationLib
> > +  PrintLib
> > +  SiliconSiFiveE51CoreInfoLib
> > +  SiliconSiFiveU54CoreInfoLib
> 
> Please sort alphabetically.
> 
> > +
> > +[Guids]
> > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid
> 
> I'm reasonably sure you don't need to declare the TokenSpaceGuid in order
> to access the Pcds.
> 
> > +
> > +[Ppis]
> > +
> > +[FixedPcd]
> > +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
> > +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
> > +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
> > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid
> > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid
> > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid
> > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
> > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> 
> Please sort alphabetically.
> 
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > tformTimerLib.S
> > b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > tformTimerLib.S
> > new file mode 100644
> > index 00000000..bb4aafb9
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/Risc
> > +++ VPlatformTimerLib.S
> > @@ -0,0 +1,48 @@
> > +//-------------------------------------------------------------------
> > +-----------
> > +//
> > +// SiFive U500 Timer CSR functions.
> > +//
> > +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> // // SPDX-License-Identifier:
> > +BSD-2-Clause-Patent //
> > +//-------------------------------------------------------------------
> > +-----------
> > +#include <Base.h>
> > +#include <RiscV.h>
> > +#include <U500Clint.h>
> > +
> > +.data
> > +
> > +.text
> > +.align 3
> > +
> > +.global ASM_PFX(RiscVReadMachineTimer) .global
> > +ASM_PFX(RiscVSetMachineTimerCmp) .global
> > +ASM_PFX(RiscVReadMachineTimerCmp)
> > +
> > +//
> > +// Read machine timer CSR.
> > +// @retval a0 : 64-bit machine timer.
> > +//
> > +ASM_PFX (RiscVReadMachineTimer):
> > +    li t1, CLINT_REG_MTIME
> > +    ld a0, (t1)
> > +    ret
> > +
> > +//
> > +// Set machine timer compare CSR.
> > +// @param a0 : UINT64
> > +//
> > +ASM_PFX (RiscVSetMachineTimerCmp):
> > +    li t1, CLINT_REG_MTIMECMP0
> > +    sd a0, (t1)
> > +    ret
> > +
> > +//
> > +// Read machine timer compare CSR.
> > +// @param a0 : UINT64
> > +//
> > +ASM_PFX (RiscVReadMachineTimerCmp):
> > +    li t1, CLINT_REG_MTIMECMP0
> > +    ld a0, (t1)
> > +    ret
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > tformTimerLib.inf
> > b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > tformTimerLib.inf
> > new file mode 100644
> > index 00000000..62771b68
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/Risc
> > +++ VPlatformTimerLib.inf
> > @@ -0,0 +1,39 @@
> > +## @file
> > +# RISC-V CPU lib to override timer mechanism for U500 platform.
> > +#
> > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # Copyright (c) 2007 - 2010, Intel Corporation.
> > +All rights reserved.<BR> # # SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = RiscVPlatformTimerLib
> > +  FILE_GUID                      = AFA75BBD-DE9D-4E77-BD88-1EA401BE931D
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = RiscVPlatformTimerLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = RISCV32 RISCV64
> > +#
> > +
> > +[Sources]
> > +
> > +[Sources.RISCV32]
> > +  RiscVPlatformTimerLib.s
> > +
> 
> Please drop RISCV32 for now.
> 
> > +[Sources.RISCV64]
> > +  RiscVPlatformTimerLib.s
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  RiscVPkg/RiscVPkg.dec
> > +  Platform/RiscV/SiFive/U500Pkg/U500.dec
> 
> Please sort alphabetically.
> 
> > +
> > +
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> > new file mode 100644
> > index 00000000..85af1fbd
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.in
> > +++ f
> > @@ -0,0 +1,31 @@
> > +## @file
> > +#   Library instance for SerialIo library class
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> #  Copyright (c) 2006 - 2014, Intel Corporation.
> > +All rights reserved.<BR> # #  SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = U500SerialPortLib
> > +  MODULE_UNI_FILE                = U500SerialPortLib.uni
> > +  FILE_GUID                      = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = SerialPortLib
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  RiscVPkg/RiscVPkg.dec
> > +  Platform/RiscV/RiscVPlatformPkg.dec
> 
> Please sort alphabetically.
> 
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  IoLib
> > +  RiscVOpensbiLib
> > +
> > +[Sources]
> > +  SerialPortLib.c
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> > new file mode 100644
> > index 00000000..e51bf9c1
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.
> > +++ c
> > @@ -0,0 +1,241 @@
> > +/** @file
> > +  UART Serial Port library functions
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>  Copyright (c) 2006 - 2016, Intel Corporation.
> > + All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Base.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/SerialPortLib.h>
> > +#include <sbi_utils/serial/sifive-uart.h>
> > +
> > +#define REG32(p, i) ((p)[(i) >> 2])
> 
> Please use the IoLib functions instead.
> 
> > +
> > +//---------------------------------------------
> > +// UART Register Offsets
> > +//---------------------------------------------
> > +
> > +#define UART_REG_IP     0x14
> > +  #define UART_IP_RXWM 0x02
> 
> Please drop indentation at start of line.
> 
> > +
> > +//---------------------------------------------
> > +// UART Settings
> > +//---------------------------------------------
> > +
> > +#define U500_UART_ADDR      0x54000000
> > +#define U500_UART_BAUDRATE  115200
> > +#define U500_SYS_CLK        100000000
> > +
> > +/**
> > +  Initialize the serial device hardware.
> > +
> > +  If no initialization is required, then return RETURN_SUCCESS.
> > +  If the serial device was successfuly initialized, then return
> RETURN_SUCCESS.
> > +  If the serial device could not be initialized, then return
> RETURN_DEVICE_ERROR.
> > +
> > +  @retval RETURN_SUCCESS        The serial device was initialized.
> > +  @retval RETURN_DEVICE_ERROR   The serail device could not be
> initialized.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +SerialPortInitialize (
> > +  VOID
> > +  )
> > +{
> > +  if (sifive_uart_init (U500_UART_ADDR, U500_SYS_CLK/2,
> U500_UART_BAUDRATE) != 0) {
> > +      return EFI_DEVICE_ERROR;
> 
> Indentation is only 2 spaces.
> 
> > +  }
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Write data from buffer to serial device.
> > +
> > +  Writes NumberOfBytes data bytes from Buffer to the serial device.
> > +  The number of bytes actually written to the serial device is returned.
> > +  If the return value is less than NumberOfBytes, then the write operation
> failed.
> > +
> > +  If Buffer is NULL, then ASSERT().
> > +
> > +  If NumberOfBytes is zero, then return 0.
> > +
> > +  @param  Buffer           Pointer to the data buffer to be written.
> > +  @param  NumberOfBytes    Number of bytes to written to the serial
> device.
> > +
> > +  @retval 0                NumberOfBytes is 0.
> > +  @retval >0               The number of bytes written to the serial device.
> > +                           If this value is less than NumberOfBytes, then the write
> operation failed.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +SerialPortWrite (
> > +  IN UINT8     *Buffer,
> > +  IN UINTN     NumberOfBytes
> > +  )
> > +{
> > +  UINTN i;
> 
> I
> 
> > +
> > +  if (Buffer == NULL) {
> > +    return 0;
> > +  }
> > +
> > +  for(i=0; i < NumberOfBytes; i++) {
> 
>      for (I = 0; I < NumberOfBytes; I++) {
> 
> > +    sifive_uart_putc (Buffer[i]);
> > +  }
> > +
> > +  return i;
> > +}
> > +
> > +
> > +/**
> > +  Reads data from a serial device into a buffer.
> > +
> > +  @param  Buffer           Pointer to the data buffer to store the data read
> from the serial device.
> > +  @param  NumberOfBytes    Number of bytes to read from the serial
> device.
> > +
> > +  @retval 0                NumberOfBytes is 0.
> > +  @retval >0               The number of bytes read from the serial device.
> > +                           If this value is less than NumberOfBytes, then the read
> operation failed.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +SerialPortRead (
> > +  OUT UINT8     *Buffer,
> > +  IN  UINTN     NumberOfBytes
> > +  )
> > +{
> > +  UINTN i;
> 
> I
> 
> > +
> > +  if (NULL == Buffer) {
> > +    return 0;
> > +  }
> > +
> > +  for(i=0; i < NumberOfBytes; i++) {
> 
>      for (I = 0; I < NumberOfBytes; I++) {
> 
> > +    Buffer[i] = (UINT8)sifive_uart_getc ();  }
> > +
> > +  return i;
> > +}
> > +
> > +/**
> > +  Polls a serial device to see if there is any data waiting to be read.
> > +
> > +  Polls aserial device to see if there is any data waiting to be read.
> > +  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> > +  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> > +
> > +  @retval TRUE             Data is waiting to be read from the serial device.
> > +  @retval FALSE            There is no data waiting to be read from the serial
> device.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +SerialPortPoll (
> > +  VOID
> > +  )
> > +{
> > +  static volatile UINT32 * const uart = (void *)(U500_UART_ADDR);
> 
> Please use IoLib functions instead.
> 
> > +  UINT32 ip;
> 
> IP
> 
> > +
> > +  ip = REG32(uart, UART_REG_IP);
> > +  if(ip & UART_IP_RXWM) {
> 
> Space before (
> 
> > +    return TRUE;
> > +  }
> > +  else {
> 
> } else {
> 
> /
>     Leif
> 
> > +    return FALSE;
> > +  }
> > +}
> > +
> > +/**
> > +  Sets the control bits on a serial device.
> > +
> > +  @param Control                Sets the bits of Control that are settable.
> > +
> > +  @retval RETURN_SUCCESS        The new control bits were set on the
> serial device.
> > +  @retval RETURN_UNSUPPORTED    The serial device does not support
> this operation.
> > +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +SerialPortSetControl (
> > +  IN UINT32 Control
> > +  )
> > +{
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Retrieve the status of the control bits on a serial device.
> > +
> > +  @param Control                A pointer to return the current control signals
> from the serial device.
> > +
> > +  @retval RETURN_SUCCESS        The control bits were read from the serial
> device.
> > +  @retval RETURN_UNSUPPORTED    The serial device does not support
> this operation.
> > +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +SerialPortGetControl (
> > +  OUT UINT32 *Control
> > +  )
> > +{
> > +  *Control = 0;
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Sets the baud rate, receive FIFO depth, transmit/receice time out,
> > +parity,
> > +  data bits, and stop bits on a serial device.
> > +
> > +  @param BaudRate           The requested baud rate. A BaudRate value of 0
> will use the
> > +                            device's default interface speed.
> > +                            On output, the value actually set.
> > +  @param ReveiveFifoDepth   The requested depth of the FIFO on the
> receive side of the
> > +                            serial interface. A ReceiveFifoDepth value of 0 will use
> > +                            the device's default FIFO depth.
> > +                            On output, the value actually set.
> > +  @param Timeout            The requested time out for a single character in
> microseconds.
> > +                            This timeout applies to both the transmit and receive side of
> the
> > +                            interface. A Timeout value of 0 will use the device's default
> time
> > +                            out value.
> > +                            On output, the value actually set.
> > +  @param Parity             The type of parity to use on this serial device. A
> Parity value of
> > +                            DefaultParity will use the device's default parity value.
> > +                            On output, the value actually set.
> > +  @param DataBits           The number of data bits to use on the serial
> device. A DataBits
> > +                            vaule of 0 will use the device's default data bit setting.
> > +                            On output, the value actually set.
> > +  @param StopBits           The number of stop bits to use on this serial
> device. A StopBits
> > +                            value of DefaultStopBits will use the device's default
> number of
> > +                            stop bits.
> > +                            On output, the value actually set.
> > +
> > +  @retval RETURN_SUCCESS            The new attributes were set on the
> serial device.
> > +  @retval RETURN_UNSUPPORTED        The serial device does not support
> this operation.
> > +  @retval RETURN_INVALID_PARAMETER  One or more of the attributes
> has an unsupported value.
> > +  @retval RETURN_DEVICE_ERROR       The serial device is not functioning
> correctly.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +SerialPortSetAttributes (
> > +  IN OUT UINT64             *BaudRate,
> > +  IN OUT UINT32             *ReceiveFifoDepth,
> > +  IN OUT UINT32             *Timeout,
> > +  IN OUT EFI_PARITY_TYPE    *Parity,
> > +  IN OUT UINT8              *DataBits,
> > +  IN OUT EFI_STOP_BITS_TYPE *StopBits
> > +  )
> > +{
> > +  return RETURN_SUCCESS;
> > +}
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.
> > uni
> > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.
> > uni
> > new file mode 100644
> > index 00000000..49163bd8
> > --- /dev/null
> > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPort
> > +++ Lib.uni
> > @@ -0,0 +1,16 @@
> > +// /** @file
> > +// Library instance for SerialIo library class // // Library instance
> > +for SerialIO library class.
> > +//
> > +// Copyright (c) 2006 - 2014, Intel Corporation. All rights
> > +reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent //
> > +// **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT             #language en-US "Library instance
> for SerialIO library class"
> > +
> > +#string STR_MODULE_DESCRIPTION          #language en-US "Library
> instance for SerialIO library class."
> > +
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-17  2:21     ` Abner Chang
@ 2019-10-17  7:44       ` Abner Chang
  2019-10-17 11:19         ` Leif Lindholm
  0 siblings, 1 reply; 43+ messages in thread
From: Abner Chang @ 2019-10-17  7:44 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: Chang, Abner (HPS SW/FW Technologist)
> Sent: Thursday, October 17, 2019 10:21 AM
> To: devel@edk2.groups.io; leif.lindholm@linaro.org; Chen, Gilbert
> <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: RE: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> U500Pkg/Library: Library instances of U500 platform library
> 
> 
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Leif Lindholm
> > Sent: Friday, October 4, 2019 12:32 AM
> > To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > U500Pkg/Library: Library instances of U500 platform library
> >
> > On Thu, Sep 19, 2019 at 11:51:27AM +0800, Gilbert Chen wrote:
> > > OpneSbiPlatformLib
> > > - In order to reduce the dependencies with RISC-V OpenSBI project
> > > (https://github.com/riscv/opensbi) and less burdens to EDK2 build
> > > process, the implementation of RISC-V EDK2 platform is leverage
> > > platform source code from OpenSBI code tree. The "platform.c"
> > >  under OpenSbiPlatformLib is cloned from RISC-V OpenSBI code tree
> > > (in
> > > EDK2 RiscVPkg) and built based on EDK2 build environment.
> > >
> > > PeiCoreInfoHobLib
> > > - This is the library to create RISC-V core characteristics for
> > > building  up RISC-V related SMBIOS records to support the unified
> > > boot loader  and OS image.
> > >
> > > - RiscVPlatformTimerLib
> > > This is U500 platform timer library which has the platform-specific
> > > timer implementation.
> > >
> > > - SerialPortLib
> > > U500 serial port platform library
> >
> > Please split this up into the 4 logical commits.
> > And add the specific header files with those commits.
> >
> > > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > > ---
> > >  .../OpenSbiPlatformLib/OpenSbiPlatformLib.inf      |  47 ++++
> > >  .../U500Pkg/Library/OpenSbiPlatformLib/platform.c  | 214
> > ++++++++++++++++++
> > >  .../Library/PeiCoreInfoHobLib/CoreInfoHob.c        | 195
> > +++++++++++++++++
> > >  .../PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf        |  58 +++++
> > >  .../RiscVPlatformTimerLib/RiscVPlatformTimerLib.S  |  48 ++++
> > >  .../RiscVPlatformTimerLib.inf                      |  39 ++++
> > >  .../U500Pkg/Library/SerialIoLib/SerialIoLib.inf    |  31 +++
> > >  .../U500Pkg/Library/SerialIoLib/SerialPortLib.c    | 241
> > +++++++++++++++++++++
> > >  .../Library/SerialIoLib/U500SerialPortLib.uni      |  16 ++
> > >  9 files changed, 889 insertions(+)
> > >  create mode 100644
> > >
> >
> Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlatfo
> > > rmLib.inf  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.c
> > >  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.
> > > c
> > >  create mode 100644
> > >
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHob
> > > Lib.inf  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > > tf
> > > ormTimerLib.S  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVPla
> > > tf
> > > ormTimerLib.inf  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> > >  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> > >  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.
> > > un
> > > i
> > >
> > > diff --git
> > >
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlat
> > > formLib.inf
> > >
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbiPlat
> > > formLib.inf
> > > new file mode 100644
> > > index 00000000..473386d2
> > > --- /dev/null
> > > +++
> > b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/OpenSbi
> > > +++ PlatformLib.inf
> > > @@ -0,0 +1,47 @@
> > > +## @file
> > > +#  RISC-V OpenSbi Platform Library
> > > +#  This is the the required library which provides platform
> >
> > Please don't use the word required. (If it wasn't, why would you
> > include it at
> > all?)
> >
> > > +#  level opensbi functions follow RISC-V opensbi implementation.
> > > +#
> > > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > +All rights reserved.<BR> # #  SPDX-License-Identifier:
> > > +BSD-2-Clause-Patent # ##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x00010005
> >
> > Please bump specification version.
> >
> > > +  BASE_NAME                      = OpenSbiPlatformLib
> > > +  FILE_GUID                      = 9424ED54-EBDA-4FB5-8FF6-8291B07BB151
> > > +  MODULE_TYPE                    = SEC
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = OpenSbiPlatformLib
> >
> > Seeing this, I have a bit of a feeling that this Opensbi isn't being
> > consistently
> > treated/named:
> > - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
> >   class RiscVOpensbiLib.
> > - Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing the
> >   class OpenSbiPlatformLib.
> > - *Logically*, what we have is
> >   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
> >   OpensbiLib which depends on the OpenSbiPlatformLib.
> >   - However, there is no OpenSbiPlatformLib in edk2, which is very
> >     unfortunate because that does not let us build edk2/RiscVPkg in
> >     isolation (like we can with all the other packages in edk2).
> Will name it as Opensbi.
> >
> > Here is my preferred solution for untangling this:
> > 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
> >    already use for Openssl, so would be my preference.
> > 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
> >    LibararyClasses. Either is fine, the former is less likely to clash
> >    with other imported projects in the future (but I would estimate
> >    this risk as *very* low to begin with).
> > 3) Implement a (RiscV)OpensbiPlatformLibNull in edk2/RiscVPkg/Library,
> I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library
> 
> >    containing only what is required to build/link
> >    RiscVPkg/Library/(RiscV)OpensbiLib/.
> >    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
> >    3.6) Add a depedency on OpensbiPlatformLib to
> >         (RiscV)OpensbiLib.inf
> >    3.7) Drop the dependency on OpensbiPlatformLib from
> >         Platform/RiscV/Universal/Sec/SecMain.inf
> Above work for me
I changed my mind. Due to SecMain is moved to RiscVPlatformPkg in edk2 and requires both RiscVOpensbiPlatformLib and RiscVOpensbLiib, SecMain.inf still has dependency with these two libs.
> >
> > (That might read like a lot of work, but really it's a 5 minute job
> > and if we untangle this now, this won't cascade over umpteen
> > platforms.)
> 
> 
> >
> > > +
> > > +#
> > > +# The following information is for reference only and not required
> > > +by the
> > build tools.
> > > +#
> > > +#  VALID_ARCHITECTURES           = RISCV64 EBC
> >
> > Drop EBC.
> >
> > > +#
> > > +
> > > +[Sources]
> > > +  platform.c
> >
> > Please rename as Platform.c.
> >
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +  MdeModulePkg/MdeModulePkg.dec
> > > +  RiscVPkg/RiscVPkg.dec
> > > +  Platform/RiscV/RiscVPlatformPkg.dec
> >
> > Please sort files alphabetically.
> >
> > > +
> > > +[LibraryClasses]
> > > +  BaseLib
> > > +  DebugLib
> > > +  BaseMemoryLib
> > > +  PcdLib
> > > +  DebugAgentLib
> > > +  RiscVCpuLib
> > > +  PrintLib
> >
> > Please sort LibraryClasses alphabetically.
> >
> > > +
> > > +[FixedPcd]
> > > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> > > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> >
> > Please sort Pcds alphabetically.
> >
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.
> > > c
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platform.
> > > c
> > > new file mode 100644
> > > index 00000000..4dca75f2
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/OpenSbiPlatformLib/platf
> > > +++ or
> > > +++ m.c
> > > @@ -0,0 +1,214 @@
> > > +/*
> > > + * SPDX-License-Identifier: BSD-2-Clause
> > > + *
> > > + * Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > +All rights reserved.<BR>
> > > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > > + *
> > > + * Authors:
> > > + *   Atish Patra <atish.patra@wdc.com>
> >
> > Please change commit Author instead.
> >
> > Please point out that this is the platform-specific portion of
> > OpensbiLib. With that, I'm OK with it not following EDK2 coding style.
> > *However*, it needs to follow OpenSBI coding style, and it currently
> > doesn't - 3-space indentation follows nothing.
> >
> > From what I see, OpenSBI follows Linux coding style. So please update
> > to that, throughout this file. *if* you untabify it (8 spaces/tab)
> > before submission, our tools will complain less, so do consider that.
> >
> > > + */
> > > +
> > > +#include <libfdt.h>
> > > +#include <fdt.h>
> > > +#include <sbi/riscv_encoding.h>
> > > +#include <sbi/sbi_const.h>
> > > +#include <sbi/sbi_hart.h>
> > > +#include <sbi/sbi_console.h>
> > > +#include <sbi/sbi_platform.h>
> > > +#include <sbi/riscv_io.h>
> > > +#include <sbi_utils/irqchip/plic.h> #include
> > > +<sbi_utils/serial/sifive-uart.h> #include <sbi_utils/sys/clint.h>
> > > +
> > > +
> > > +#define U500_HART_COUNT         FixedPcdGet32(PcdHartCount)
> > > +#define U500_HART_STACK_SIZE   FixedPcdGet32(PcdOpenSbiStackSize)
> > > +#define U500_BOOT_HART_ID       FixedPcdGet32(PcdBootHartId)
> > > +
> > > +#define U500_SYS_CLK         100000000
> > > +
> > > +#define U500_CLINT_ADDR         0x2000000
> > > +
> > > +#define U500_PLIC_ADDR            0xc000000
> > > +#define U500_PLIC_NUM_SOURCES      0x35
> > > +#define U500_PLIC_NUM_PRIORITIES   7
> > > +
> > > +#define U500_UART_ADDR            0x54000000
> > > +
> > > +#define U500_UART_BAUDRATE         115200
> > > +
> > > +/**
> > > + * The U500 SoC has 8 HARTs but HART ID 0 doesn't have S mode.
> > > + * HARTs 1 is selected as boot HART  */ #ifndef
> > > +U500_ENABLED_HART_MASK
> > > +#define U500_ENABLED_HART_MASK   (1 << U500_BOOT_HART_ID)
> > > +#endif
> > > +
> > > +#define U500_HARTID_DISABLED   ~(U500_ENABLED_HART_MASK)
> > > +
> > > +/* PRCI clock related macros */
> > > +//TODO: Do we need a separate driver for this ?
> >
> > Well, do we?
> >
> > > +#define U500_PRCI_BASE_ADDR         0x10000000
> > > +#define U500_PRCI_CLKMUXSTATUSREG   0x002C
> > > +#define U500_PRCI_CLKMUX_STATUS_TLCLKSEL   (0x1 << 1)
> >
> > Please adjust right-column alignment through the defines above.
> >
> > > +
> > > +static void U500_modify_dt(void *fdt) {
> > > +   u32 i, size;
> >
> >
> > > +   int chosen_offset, err;
> > > +   int cpu_offset;
> > > +   char cpu_node[32] = "";
> > > +   const char *mmu_type;
> > > +
> > > +   for (i = 0; i < U500_HART_COUNT; i++) {
> > > +      sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
> > > +      cpu_offset = fdt_path_offset(fdt, cpu_node);
> > > +      mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
> > > +      if (mmu_type && (!strcmp(mmu_type, "riscv,sv39") ||
> > > +          !strcmp(mmu_type,"riscv,sv48")))
> > > +         continue;
> > > +      else
> > > +         fdt_setprop_string(fdt, cpu_offset, "status", "masked");
> > > +      memset(cpu_node, 0, sizeof(cpu_node));
> > > +   }
> > > +   size = fdt_totalsize(fdt);
> > > +   err = fdt_open_into(fdt, fdt, size + 256);
> > > +   if (err < 0)
> > > +      sbi_printf("Device Tree can't be expanded to accmodate new
> > > + node");
> > > +
> > > +   chosen_offset = fdt_path_offset(fdt, "/chosen");
> > > +   fdt_setprop_string(fdt, chosen_offset, "stdout-path",
> > > +            "/soc/serial@10010000:115200");
> > > +
> > > +   plic_fdt_fixup(fdt, "riscv,plic0"); }
> > > +
> > > +static int U500_final_init(bool cold_boot) {
> > > +   void *fdt;
> > > +
> > > +   if (!cold_boot)
> > > +      return 0;
> > > +
> > > +   fdt = sbi_scratch_thishart_arg1_ptr();
> > > +   U500_modify_dt(fdt);
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +static u32 U500_pmp_region_count(u32 hartid) {
> > > +   return 1;
> > > +}
> > > +
> > > +static int U500_pmp_region_info(u32 hartid, u32 index,
> > > +             ulong *prot, ulong *addr, ulong *log2size) {
> > > +   int ret = 0;
> > > +
> > > +   switch (index) {
> > > +   case 0:
> > > +      *prot = PMP_R | PMP_W | PMP_X;
> > > +      *addr = 0;
> > > +      *log2size = __riscv_xlen;
> > > +      break;
> > > +   default:
> > > +      ret = -1;
> > > +      break;
> > > +   };
> > > +
> > > +   return ret;
> > > +}
> > > +
> > > +static int U500_console_init(void)
> > > +{
> > > +   unsigned long peri_in_freq;
> > > +
> > > +   peri_in_freq = U500_SYS_CLK/2;
> > > +   return sifive_uart_init(U500_UART_ADDR, peri_in_freq,
> > > +U500_UART_BAUDRATE); }
> > > +
> > > +static int U500_irqchip_init(bool cold_boot) {
> > > +   int rc;
> > > +   u32 hartid = sbi_current_hartid();
> > > +
> > > +   if (cold_boot) {
> > > +      rc = plic_cold_irqchip_init(U500_PLIC_ADDR,
> > > +                   U500_PLIC_NUM_SOURCES,
> > > +                   U500_HART_COUNT);
> > > +      if (rc)
> > > +         return rc;
> > > +   }
> > > +
> > > +   return plic_warm_irqchip_init(hartid,
> > > +         (hartid) ? (2 * hartid - 1) : 0,
> > > +         (hartid) ? (2 * hartid) : -1); }
> > > +
> > > +static int U500_ipi_init(bool cold_boot) {
> > > +   int rc;
> > > +
> > > +   if (cold_boot) {
> > > +      rc = clint_cold_ipi_init(U500_CLINT_ADDR,
> > > +                U500_HART_COUNT);
> > > +      if (rc)
> > > +         return rc;
> > > +
> > > +   }
> > > +
> > > +   return clint_warm_ipi_init();
> > > +}
> > > +
> > > +static int U500_timer_init(bool cold_boot) {
> > > +   int rc;
> > > +
> > > +   if (cold_boot) {
> > > +      rc = clint_cold_timer_init(U500_CLINT_ADDR,
> > > +                  U500_HART_COUNT);
> > > +      if (rc)
> > > +         return rc;
> > > +   }
> > > +
> > > +   return clint_warm_timer_init();
> > > +}
> > > +
> > > +static int U500_system_down(u32 type) {
> > > +   /* For now nothing to do. */
> > > +   return 0;
> > > +}
> > > +
> > > +const struct sbi_platform_operations platform_ops = {
> > > +   .pmp_region_count = U500_pmp_region_count,
> > > +   .pmp_region_info = U500_pmp_region_info,
> > > +   .final_init = U500_final_init,
> > > +   .console_putc = sifive_uart_putc,
> > > +   .console_getc = sifive_uart_getc,
> > > +   .console_init = U500_console_init,
> > > +   .irqchip_init = U500_irqchip_init,
> > > +   .ipi_send = clint_ipi_send,
> > > +   .ipi_sync = clint_ipi_sync,
> > > +   .ipi_clear = clint_ipi_clear,
> > > +   .ipi_init = U500_ipi_init,
> > > +   .timer_value = clint_timer_value,
> > > +   .timer_event_stop = clint_timer_event_stop,
> > > +   .timer_event_start = clint_timer_event_start,
> > > +   .timer_init = U500_timer_init,
> > > +   .system_reboot = U500_system_down,
> > > +   .system_shutdown = U500_system_down };
> > > +
> > > +const struct sbi_platform platform = {
> > > +   .opensbi_version   = OPENSBI_VERSION,                  // The OpenSBI
> > version this platform table is built bassed on.
> > > +   .platform_version   = SBI_PLATFORM_VERSION(0x0001, 0x0000),   //
> SBI
> > Platform version 1.0
> > > +   .name               = "SiFive Freedom U500",
> > > +   .features      = SBI_PLATFORM_DEFAULT_FEATURES,
> > > +   .hart_count      = U500_HART_COUNT,
> > > +   .hart_stack_size   = U500_HART_STACK_SIZE,
> > > +   .disabled_hart_mask   = U500_HARTID_DISABLED,
> > > +   .platform_ops_addr   = (unsigned long)&platform_ops
> > > +};
> > > diff --git
> > >
> a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.
> > > c
> > >
> b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfoHob.
> > > c
> > > new file mode 100644
> > > index 00000000..bfb97351
> > > --- /dev/null
> > > +++
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/CoreInfo
> > > +++ Hob.c
> > > @@ -0,0 +1,195 @@
> > > +/**@file
> > > +  Build up platform processor information.
> > > +
> > > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > + All rights reserved.<BR>
> > > +
> > > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +//
> > > +// The package level header files this module uses // #include
> > > +<PiPei.h>
> > > +
> > > +//
> > > +// The Library classes this module consumes // #include
> > > +<Library/DebugLib.h> #include <Library/HobLib.h> #include
> > > +<Library/BaseMemoryLib.h>
> > > +
> > > +#include <SmbiosProcessorSpecificData.h> #include
> > > +<ProcessorSpecificDataHob.h> #include <SiFiveU5MCCoreplex.h>
> > #include
> > > +<Library/SiFiveE51.h> #include <Library/SiFiveU54.h>
> >
> > Please sort includes alphabetically.
> >
> > > +
> > > +/**
> > > +  Build up processor-specific HOB for U5MC Coreplex
> > > +
> > > +  @param  UniqueId      Unique ID of this U5MC Coreplex processor
> > > +
> > > +  @return EFI_SUCCESS     The PEIM initialized successfully.
> > > +
> > > +**/
> > > +EFI_STATUS
> > > +EFIAPI
> > > +CreateU5MCCoreplexProcessorSpecificDataHob (
> > > +  IN UINTN UniqueId
> > > +  )
> > > +{
> > > +  EFI_STATUS Status;
> > > +  UINT32 HartIdNumber;
> > > +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *GuidHobData;
> > > +  EFI_GUID *ParentCoreGuid;
> > > +  BOOLEAN MCSupport;
> > > +
> > > +  DEBUG ((DEBUG_INFO, "Building U5 Coreplex processor information
> > > + HOB\n"));
> > > +
> > > +  HartIdNumber = 0;
> > > +  ParentCoreGuid = PcdGetPtr(PcdSiFiveU5MCCoreplexGuid);
> > > +  MCSupport = PcdGetBool (PcdE5MCSupported);  if (MCSupport ==
> > > + TRUE) {
> > > +    Status = CreateE51CoreProcessorSpecificDataHob (ParentCoreGuid,
> > UniqueId, HartIdNumber, FALSE, &GuidHobData);
> > > +    if (EFI_ERROR (Status)) {
> > > +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor
> > > + informatino
> > HOB\n"));
> > > +      ASSERT (FALSE);
> > > +    }
> > > +    HartIdNumber ++;
> > > +    DEBUG ((DEBUG_INFO, "Support E5 Monitor core on U500 platform,
> > > + HOB at address 0x%x\n", GuidHobData));
> >
> > Hmm, OK, this was why you had the different LibraryClasses?
> > I still don't think it should be a separate libraryclass per CPU. If
> > possible, I would prefer MonitorCoreInfoLib and ApplicationCoreInfoLib.
> >
> > > +  }
> > > +  for (; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) +
> > (UINT32)MCSupport); HartIdNumber ++) {
> > > +    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid,
> > > + UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32
> > > + (PcdBootHartId))? TRUE: FALSE, &GuidHobData);
> >
> > Nesting that ternary saves you nothing other than typing, and not much
> > of that. Please use a temporary variable instead:
> >
> >    BOOL IsBootHart;
> >    IsBootHart = HartIdNumber == FixedPcdGet32 (PcdBootHartId)) ? TRUE :
> > FALSE
> >    /* Also, always spaces around ? and : for ternaries. */
> >    /* No, don't actually include this comment. */
> >    Status = CreateU54CoreProcessorSpecificDataHob (ParentCoreGuid,
> > UniqueId,
> >               HartIdNumber, IsBootHart, &GuidHobData);
> >
> > > +    if (EFI_ERROR (Status)) {
> > > +      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor
> > > + informatino
> > HOB\n"));
> > > +      ASSERT (FALSE);
> > > +    }
> > > +    DEBUG ((DEBUG_INFO, "Support U5 application core on U500
> > > + platform, HOB Data at address 0x%x\n", GuidHobData));  }  DEBUG
> > > + ((DEBUG_INFO, "Support %d U5 application cores on U500
> > > + platform\n", HartIdNumber - (UINT32)MCSupport));
> >
> > Please wrap those DEBUG lines. Not the strings, just the arguments.
> >
> > > +
> > > +  if (HartIdNumber != FixedPcdGet32 (PcdHartCount)) {
> > > +    DEBUG ((DEBUG_ERROR, "Improper core settings...\n"));
> > > +    DEBUG ((DEBUG_ERROR, "    PcdHartCount\n"));
> > > +    DEBUG ((DEBUG_ERROR, "    PcdNumberofU5Cores\n"));
> > > +    DEBUG ((DEBUG_ERROR, "    PcdE5MCSupported\n\n"));
> > > +    ASSERT (FALSE);
> > > +  }
> > > +  return Status;
> > > +}
> > > +
> > > +/**
> > > +  Function to build processor related SMBIOS information. RISC-V
> > > +SMBIOS DXE driver collect
> > > +  this information and build SMBIOS Type4 and Type7 record.
> > > +
> > > +  @param  ProcessorUid    Unique ID of pysical processor which owns this
> > core.
> > > +  @param  SmbiosHobPtr    Pointer to receive
> > RISC_V_PROCESSOR_SMBIOS_DATA_HOB. The pointers
> > > +                          maintained in this structure is only
> > > + valid before memory is
> > discovered.
> > > +                          Access to those pointers after memory is
> > > + installed will cause
> > unexpected issues.
> > > +
> > > +  @return EFI_SUCCESS     The PEIM initialized successfully.
> > > +
> > > +**/
> > > +EFI_STATUS
> > > +EFIAPI
> > > +CreateU5MCProcessorSmbiosDataHob (
> > > +  IN UINTN     ProcessorUid,
> > > +  OUT RISC_V_PROCESSOR_SMBIOS_DATA_HOB **SmbiosHobPtr
> > > +  )
> > > +{
> > > +  EFI_GUID *GuidPtr;
> > > +  RISC_V_PROCESSOR_TYPE4_DATA_HOB ProcessorDataHob;
> > > +  RISC_V_PROCESSOR_TYPE7_DATA_HOB L2CacheDataHob;
> > > +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB SmbiosDataHob;
> > > +  RISC_V_PROCESSOR_TYPE4_DATA_HOB *ProcessorDataHobPtr;
> > > +  RISC_V_PROCESSOR_TYPE7_DATA_HOB *L2CacheDataHobPtr;
> > > +  RISC_V_PROCESSOR_SMBIOS_DATA_HOB *SmbiosDataHobPtr;
> > > +
> > > +  DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
> > > +
> > > +  if (SmbiosHobPtr == NULL) {
> > > +    return EFI_INVALID_PARAMETER;
> > > +  }
> > > +
> > > +  //
> > > +  // Build up SMBIOS type 7 L2 cache record.
> > > +  //
> > > +  ZeroMem((VOID *)&L2CacheDataHob, sizeof
> > > + (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
> > > +  L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr
> > > + (PcdSiFiveU5MCCoreplexGuid));  L2CacheDataHob.ProcessorUid =
> > > + ProcessorUid;  L2CacheDataHob.SmbiosType7Cache.SocketDesignation
> =
> > > + TO_BE_FILLED_BY_VENDOR;
> > L2CacheDataHob.SmbiosType7Cache.CacheConfiguration =
> > RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \
> > > +      RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \
> > > +      RISC_V_CACHE_CONFIGURATION_ENABLED | \
> > > +      RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN;
> > > +  L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + L2CacheDataHob.SmbiosType7Cache.InstalledSize =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown =
> 1;
> > > + L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1;
> > > + L2CacheDataHob.SmbiosType7Cache.CacheSpeed =
> > TO_BE_FILLED_BY_VENDOR;
> > > + L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + L2CacheDataHob.SmbiosType7Cache.SystemCacheType =
> > CacheTypeUnified;
> > > + L2CacheDataHob.SmbiosType7Cache.Associativity =
> > > + TO_BE_FILLED_BY_VENDOR;  GuidPtr = (EFI_GUID *)PcdGetPtr
> > > + (PcdProcessorSmbiosType7GuidHobGuid);
> > > +  L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_DATA_HOB
> > > + *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof
> > > + (RISC_V_PROCESSOR_TYPE7_DATA_HOB));
> >
> > Please wrap long line.
> >
> > > +  if (L2CacheDataHobPtr == NULL) {
> > > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC
> > > + Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_DATA_HOB.\n"));
> >
> > Please wrap long line. (That format string is longer than 80
> > characters on its own, consider shortening it.)
> >
> > > +    ASSERT (FALSE);
> > > +  }
> > > +
> > > +  //
> > > +  // Build up SMBIOS type 4 record.
> > > +  //
> > > +  ZeroMem((VOID *)&ProcessorDataHob, sizeof
> > > + (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> > > +  ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr
> > > + (PcdSiFiveU5MCCoreplexGuid));  ProcessorDataHob.ProcessorUid =
> > > + ProcessorUid;  ProcessorDataHob.SmbiosType4Processor.Socket =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.ProcessorType =
> > > + CentralProcessor;
> > > + ProcessorDataHob.SmbiosType4Processor.ProcessorFamily =
> > > + ProcessorFamilyIndicatorFamily2;
> > > + ProcessorDataHob.SmbiosType4Processor.ProcessorManufacture =
> > > + TO_BE_FILLED_BY_VENDOR;  SetMem ((VOID
> > > + *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof
> > > + (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE);
> >
> > Please wrap long line.
> >
> > > +  ProcessorDataHob.SmbiosType4Processor.ProcessorVersion =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > +
> >
> ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapabi
> > > + lity3_3V = 1;  ProcessorDataHob.SmbiosType4Processor.ExternalClock
> > > + = TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.MaxSpeed =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.CurrentSpeed =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.Status =
> > TO_BE_FILLED_BY_CODE;
> > > + ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.L1CacheHandle =
> > > + TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> > > +  ProcessorDataHob.SmbiosType4Processor.L2CacheHandle =
> > > + TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER;
> > > +  ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff;
> > > + ProcessorDataHob.SmbiosType4Processor.SerialNumber =
> > > + TO_BE_FILLED_BY_CODE;
> > > + ProcessorDataHob.SmbiosType4Processor.AssetTag =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.PartNumber =
> > > + TO_BE_FILLED_BY_VENDOR;
> > > + ProcessorDataHob.SmbiosType4Processor.CoreCount =
> > > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > > + (PcdE5MCSupported);
> > > + ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount =
> > > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > > + (PcdE5MCSupported);
> > > + ProcessorDataHob.SmbiosType4Processor.ThreadCount =
> > > + (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool
> > > + (PcdE5MCSupported);
> >
> > Please wrap long lines.
> > There are several more cases in this file, I'll stop pointing them
> > out, but the general rule is no longer than 80. PatchCheck.py is a bit lax on
> this.
> >
> > > +  ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics =
> > > + (UINT16)(1 << 2); // 64-bit capable
> > > +  ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 =
> > > + ProcessorFamilyRiscVRV64;
> > > +  ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0;
> > > +  ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0;
> > > +  ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0;  GuidPtr
> > > + = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid);
> > > +  ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_DATA_HOB
> > > + *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof
> > > + (RISC_V_PROCESSOR_TYPE4_DATA_HOB));
> > > +  if (ProcessorDataHobPtr == NULL) {
> > > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC
> > Coreplex RISC_V_PROCESSOR_TYPE4_DATA_HOB.\n"));
> > > +    ASSERT (FALSE);
> > > +  }
> > > +
> > > +  ZeroMem((VOID *)&SmbiosDataHob, sizeof
> > > +(RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> > > +  SmbiosDataHob.Processor = ProcessorDataHobPtr;
> > > +  SmbiosDataHob.L1InstCache = NULL;
> > > +  SmbiosDataHob.L1DataCache = NULL;
> > > +  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
> > > +  SmbiosDataHob.L3Cache = NULL;
> > > +  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
> > > +  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_DATA_HOB
> > > +*)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof
> > > +(RISC_V_PROCESSOR_SMBIOS_DATA_HOB));
> > > +  if (SmbiosDataHobPtr == NULL) {
> > > +    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC
> > Coreplex RISC_V_PROCESSOR_SMBIOS_DATA_HOB.\n"));
> > > +    ASSERT (FALSE);
> > > +  }
> > > +  *SmbiosHobPtr = SmbiosDataHobPtr;
> > > +  DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
> > > +  return EFI_SUCCESS;
> > > +}
> > > diff --git
> > >
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoH
> > > obLib.inf
> > >
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCoreInfoH
> > > obLib.inf
> > > new file mode 100644
> > > index 00000000..915021f9
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PeiCoreInfoHobLib/PeiCor
> > > +++ eI
> > > +++ nfoHobLib.inf
> > > @@ -0,0 +1,58 @@
> > > +## @file
> > > +#  Library instance to create core information HOB # #  Copyright
> > > +(c) 2019, Hewlett Packard Enterprise Development LP. All rights
> > > +reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent #
> > > +##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x00010005
> >
> > Please bump specification version.
> >
> > > +  BASE_NAME                      = SiliconSiFiveU5MCCoreplexInfoLib
> > > +  FILE_GUID                      = 4E397A71-5164-4E69-9884-70CBE2740AAB
> > > +  MODULE_TYPE                    = PEIM
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = SiliconSiFiveU5MCCoreplexInfoLib
> > > +
> > > +#
> > > +# The following information is for reference only and not required
> > > +by the
> > build tools.
> > > +#
> > > +#  VALID_ARCHITECTURES           = RISCV
> > > +#
> > > +
> > > +[Sources]
> > > + CoreInfoHob.c
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +  MdeModulePkg/MdeModulePkg.dec
> > > +  Platform/RiscV/RiscVPlatformPkg.dec
> > > +  Platform/RiscV/SiFive/U500Pkg/U500.dec
> > > +  Silicon/SiFive/SiFive.dec
> > > +  RiscVPkg/RiscVPkg.dec
> >
> > Please sort alphabetically.
> >
> > > +
> > > +[LibraryClasses]
> > > +  BaseLib
> > > +  PcdLib
> > > +  MemoryAllocationLib
> > > +  PrintLib
> > > +  SiliconSiFiveE51CoreInfoLib
> > > +  SiliconSiFiveU54CoreInfoLib
> >
> > Please sort alphabetically.
> >
> > > +
> > > +[Guids]
> > > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid
> >
> > I'm reasonably sure you don't need to declare the TokenSpaceGuid in
> > order to access the Pcds.
> >
> > > +
> > > +[Ppis]
> > > +
> > > +[FixedPcd]
> > > +  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
> > > +
> gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
> > > +
> gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
> > > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU54CoreGuid
> > > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveE51CoreGuid
> > > +  gEfiSiFiveSiliconSpaceGuid.PcdSiFiveU5MCCoreplexGuid
> > > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdNumberofU5Cores
> > > +  gUefiRiscVPlatformU500PkgTokenSpaceGuid.PcdE5MCSupported
> > > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> >
> > Please sort alphabetically.
> >
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVP
> > > la
> > > tformTimerLib.S
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVP
> > > la
> > > tformTimerLib.S
> > > new file mode 100644
> > > index 00000000..bb4aafb9
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/Ri
> > > +++ sc
> > > +++ VPlatformTimerLib.S
> > > @@ -0,0 +1,48 @@
> > > +//-----------------------------------------------------------------
> > > +--
> > > +-----------
> > > +//
> > > +// SiFive U500 Timer CSR functions.
> > > +//
> > > +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > +All rights reserved.<BR> // // SPDX-License-Identifier:
> > > +BSD-2-Clause-Patent //
> > > +//-----------------------------------------------------------------
> > > +--
> > > +-----------
> > > +#include <Base.h>
> > > +#include <RiscV.h>
> > > +#include <U500Clint.h>
> > > +
> > > +.data
> > > +
> > > +.text
> > > +.align 3
> > > +
> > > +.global ASM_PFX(RiscVReadMachineTimer) .global
> > > +ASM_PFX(RiscVSetMachineTimerCmp) .global
> > > +ASM_PFX(RiscVReadMachineTimerCmp)
> > > +
> > > +//
> > > +// Read machine timer CSR.
> > > +// @retval a0 : 64-bit machine timer.
> > > +//
> > > +ASM_PFX (RiscVReadMachineTimer):
> > > +    li t1, CLINT_REG_MTIME
> > > +    ld a0, (t1)
> > > +    ret
> > > +
> > > +//
> > > +// Set machine timer compare CSR.
> > > +// @param a0 : UINT64
> > > +//
> > > +ASM_PFX (RiscVSetMachineTimerCmp):
> > > +    li t1, CLINT_REG_MTIMECMP0
> > > +    sd a0, (t1)
> > > +    ret
> > > +
> > > +//
> > > +// Read machine timer compare CSR.
> > > +// @param a0 : UINT64
> > > +//
> > > +ASM_PFX (RiscVReadMachineTimerCmp):
> > > +    li t1, CLINT_REG_MTIMECMP0
> > > +    ld a0, (t1)
> > > +    ret
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVP
> > > la
> > > tformTimerLib.inf
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/RiscVP
> > > la
> > > tformTimerLib.inf
> > > new file mode 100644
> > > index 00000000..62771b68
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/RiscVPlatformTimerLib/Ri
> > > +++ sc
> > > +++ VPlatformTimerLib.inf
> > > @@ -0,0 +1,39 @@
> > > +## @file
> > > +# RISC-V CPU lib to override timer mechanism for U500 platform.
> > > +#
> > > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > +All rights reserved.<BR> # Copyright (c) 2007 - 2010, Intel Corporation.
> > > +All rights reserved.<BR> # # SPDX-License-Identifier:
> > > +BSD-2-Clause-Patent # ##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x00010005
> >
> > Please bump specification version.
> >
> > > +  BASE_NAME                      = RiscVPlatformTimerLib
> > > +  FILE_GUID                      = AFA75BBD-DE9D-4E77-BD88-1EA401BE931D
> > > +  MODULE_TYPE                    = BASE
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = RiscVPlatformTimerLib
> > > +
> > > +#
> > > +# The following information is for reference only and not required
> > > +by the
> > build tools.
> > > +#
> > > +#  VALID_ARCHITECTURES           = RISCV32 RISCV64
> > > +#
> > > +
> > > +[Sources]
> > > +
> > > +[Sources.RISCV32]
> > > +  RiscVPlatformTimerLib.s
> > > +
> >
> > Please drop RISCV32 for now.
> >
> > > +[Sources.RISCV64]
> > > +  RiscVPlatformTimerLib.s
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +  MdeModulePkg/MdeModulePkg.dec
> > > +  RiscVPkg/RiscVPkg.dec
> > > +  Platform/RiscV/SiFive/U500Pkg/U500.dec
> >
> > Please sort alphabetically.
> >
> > > +
> > > +
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.inf
> > > new file mode 100644
> > > index 00000000..85af1fbd
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialIoLib.
> > > +++ in
> > > +++ f
> > > @@ -0,0 +1,31 @@
> > > +## @file
> > > +#   Library instance for SerialIo library class
> > > +#
> > > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > +All rights reserved.<BR> #  Copyright (c) 2006 - 2014, Intel Corporation.
> > > +All rights reserved.<BR> # #  SPDX-License-Identifier:
> > > +BSD-2-Clause-Patent # ##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x00010005
> >
> > Please bump specification version.
> >
> > > +  BASE_NAME                      = U500SerialPortLib
> > > +  MODULE_UNI_FILE                = U500SerialPortLib.uni
> > > +  FILE_GUID                      = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9
> > > +  MODULE_TYPE                    = BASE
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = SerialPortLib
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +  RiscVPkg/RiscVPkg.dec
> > > +  Platform/RiscV/RiscVPlatformPkg.dec
> >
> > Please sort alphabetically.
> >
> > > +
> > > +[LibraryClasses]
> > > +  BaseLib
> > > +  IoLib
> > > +  RiscVOpensbiLib
> > > +
> > > +[Sources]
> > > +  SerialPortLib.c
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.c
> > > new file mode 100644
> > > index 00000000..e51bf9c1
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/SerialPortLib.
> > > +++ c
> > > @@ -0,0 +1,241 @@
> > > +/** @file
> > > +  UART Serial Port library functions
> > > +
> > > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP.
> > > + All rights reserved.<BR>  Copyright (c) 2006 - 2016, Intel Corporation.
> > > + All rights reserved.<BR>
> > > +
> > > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#include <Base.h>
> > > +#include <Library/IoLib.h>
> > > +#include <Library/SerialPortLib.h>
> > > +#include <sbi_utils/serial/sifive-uart.h>
> > > +
> > > +#define REG32(p, i) ((p)[(i) >> 2])
> >
> > Please use the IoLib functions instead.
> >
> > > +
> > > +//---------------------------------------------
> > > +// UART Register Offsets
> > > +//---------------------------------------------
> > > +
> > > +#define UART_REG_IP     0x14
> > > +  #define UART_IP_RXWM 0x02
> >
> > Please drop indentation at start of line.
> >
> > > +
> > > +//---------------------------------------------
> > > +// UART Settings
> > > +//---------------------------------------------
> > > +
> > > +#define U500_UART_ADDR      0x54000000
> > > +#define U500_UART_BAUDRATE  115200
> > > +#define U500_SYS_CLK        100000000
> > > +
> > > +/**
> > > +  Initialize the serial device hardware.
> > > +
> > > +  If no initialization is required, then return RETURN_SUCCESS.
> > > +  If the serial device was successfuly initialized, then return
> > RETURN_SUCCESS.
> > > +  If the serial device could not be initialized, then return
> > RETURN_DEVICE_ERROR.
> > > +
> > > +  @retval RETURN_SUCCESS        The serial device was initialized.
> > > +  @retval RETURN_DEVICE_ERROR   The serail device could not be
> > initialized.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +SerialPortInitialize (
> > > +  VOID
> > > +  )
> > > +{
> > > +  if (sifive_uart_init (U500_UART_ADDR, U500_SYS_CLK/2,
> > U500_UART_BAUDRATE) != 0) {
> > > +      return EFI_DEVICE_ERROR;
> >
> > Indentation is only 2 spaces.
> >
> > > +  }
> > > +  return RETURN_SUCCESS;
> > > +}
> > > +
> > > +/**
> > > +  Write data from buffer to serial device.
> > > +
> > > +  Writes NumberOfBytes data bytes from Buffer to the serial device.
> > > +  The number of bytes actually written to the serial device is returned.
> > > +  If the return value is less than NumberOfBytes, then the write
> > > + operation
> > failed.
> > > +
> > > +  If Buffer is NULL, then ASSERT().
> > > +
> > > +  If NumberOfBytes is zero, then return 0.
> > > +
> > > +  @param  Buffer           Pointer to the data buffer to be written.
> > > +  @param  NumberOfBytes    Number of bytes to written to the serial
> > device.
> > > +
> > > +  @retval 0                NumberOfBytes is 0.
> > > +  @retval >0               The number of bytes written to the serial device.
> > > +                           If this value is less than
> > > + NumberOfBytes, then the write
> > operation failed.
> > > +
> > > +**/
> > > +UINTN
> > > +EFIAPI
> > > +SerialPortWrite (
> > > +  IN UINT8     *Buffer,
> > > +  IN UINTN     NumberOfBytes
> > > +  )
> > > +{
> > > +  UINTN i;
> >
> > I
> >
> > > +
> > > +  if (Buffer == NULL) {
> > > +    return 0;
> > > +  }
> > > +
> > > +  for(i=0; i < NumberOfBytes; i++) {
> >
> >      for (I = 0; I < NumberOfBytes; I++) {
> >
> > > +    sifive_uart_putc (Buffer[i]);
> > > +  }
> > > +
> > > +  return i;
> > > +}
> > > +
> > > +
> > > +/**
> > > +  Reads data from a serial device into a buffer.
> > > +
> > > +  @param  Buffer           Pointer to the data buffer to store the data read
> > from the serial device.
> > > +  @param  NumberOfBytes    Number of bytes to read from the serial
> > device.
> > > +
> > > +  @retval 0                NumberOfBytes is 0.
> > > +  @retval >0               The number of bytes read from the serial device.
> > > +                           If this value is less than
> > > + NumberOfBytes, then the read
> > operation failed.
> > > +
> > > +**/
> > > +UINTN
> > > +EFIAPI
> > > +SerialPortRead (
> > > +  OUT UINT8     *Buffer,
> > > +  IN  UINTN     NumberOfBytes
> > > +  )
> > > +{
> > > +  UINTN i;
> >
> > I
> >
> > > +
> > > +  if (NULL == Buffer) {
> > > +    return 0;
> > > +  }
> > > +
> > > +  for(i=0; i < NumberOfBytes; i++) {
> >
> >      for (I = 0; I < NumberOfBytes; I++) {
> >
> > > +    Buffer[i] = (UINT8)sifive_uart_getc ();  }
> > > +
> > > +  return i;
> > > +}
> > > +
> > > +/**
> > > +  Polls a serial device to see if there is any data waiting to be read.
> > > +
> > > +  Polls aserial device to see if there is any data waiting to be read.
> > > +  If there is data waiting to be read from the serial device, then
> > > + TRUE is
> > returned.
> > > +  If there is no data waiting to be read from the serial device,
> > > + then FALSE is
> > returned.
> > > +
> > > +  @retval TRUE             Data is waiting to be read from the serial device.
> > > +  @retval FALSE            There is no data waiting to be read from the serial
> > device.
> > > +
> > > +**/
> > > +BOOLEAN
> > > +EFIAPI
> > > +SerialPortPoll (
> > > +  VOID
> > > +  )
> > > +{
> > > +  static volatile UINT32 * const uart = (void *)(U500_UART_ADDR);
> >
> > Please use IoLib functions instead.
> >
> > > +  UINT32 ip;
> >
> > IP
> >
> > > +
> > > +  ip = REG32(uart, UART_REG_IP);
> > > +  if(ip & UART_IP_RXWM) {
> >
> > Space before (
> >
> > > +    return TRUE;
> > > +  }
> > > +  else {
> >
> > } else {
> >
> > /
> >     Leif
> >
> > > +    return FALSE;
> > > +  }
> > > +}
> > > +
> > > +/**
> > > +  Sets the control bits on a serial device.
> > > +
> > > +  @param Control                Sets the bits of Control that are settable.
> > > +
> > > +  @retval RETURN_SUCCESS        The new control bits were set on the
> > serial device.
> > > +  @retval RETURN_UNSUPPORTED    The serial device does not support
> > this operation.
> > > +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> > correctly.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +SerialPortSetControl (
> > > +  IN UINT32 Control
> > > +  )
> > > +{
> > > +
> > > +  return RETURN_SUCCESS;
> > > +}
> > > +
> > > +/**
> > > +  Retrieve the status of the control bits on a serial device.
> > > +
> > > +  @param Control                A pointer to return the current control signals
> > from the serial device.
> > > +
> > > +  @retval RETURN_SUCCESS        The control bits were read from the
> serial
> > device.
> > > +  @retval RETURN_UNSUPPORTED    The serial device does not support
> > this operation.
> > > +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> > correctly.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +SerialPortGetControl (
> > > +  OUT UINT32 *Control
> > > +  )
> > > +{
> > > +  *Control = 0;
> > > +  return RETURN_SUCCESS;
> > > +}
> > > +
> > > +/**
> > > +  Sets the baud rate, receive FIFO depth, transmit/receice time
> > > +out, parity,
> > > +  data bits, and stop bits on a serial device.
> > > +
> > > +  @param BaudRate           The requested baud rate. A BaudRate value of
> 0
> > will use the
> > > +                            device's default interface speed.
> > > +                            On output, the value actually set.
> > > +  @param ReveiveFifoDepth   The requested depth of the FIFO on the
> > receive side of the
> > > +                            serial interface. A ReceiveFifoDepth value of 0 will use
> > > +                            the device's default FIFO depth.
> > > +                            On output, the value actually set.
> > > +  @param Timeout            The requested time out for a single character in
> > microseconds.
> > > +                            This timeout applies to both the
> > > + transmit and receive side of
> > the
> > > +                            interface. A Timeout value of 0 will
> > > + use the device's default
> > time
> > > +                            out value.
> > > +                            On output, the value actually set.
> > > +  @param Parity             The type of parity to use on this serial device. A
> > Parity value of
> > > +                            DefaultParity will use the device's default parity value.
> > > +                            On output, the value actually set.
> > > +  @param DataBits           The number of data bits to use on the serial
> > device. A DataBits
> > > +                            vaule of 0 will use the device's default data bit setting.
> > > +                            On output, the value actually set.
> > > +  @param StopBits           The number of stop bits to use on this serial
> > device. A StopBits
> > > +                            value of DefaultStopBits will use the
> > > + device's default
> > number of
> > > +                            stop bits.
> > > +                            On output, the value actually set.
> > > +
> > > +  @retval RETURN_SUCCESS            The new attributes were set on the
> > serial device.
> > > +  @retval RETURN_UNSUPPORTED        The serial device does not
> support
> > this operation.
> > > +  @retval RETURN_INVALID_PARAMETER  One or more of the attributes
> > has an unsupported value.
> > > +  @retval RETURN_DEVICE_ERROR       The serial device is not functioning
> > correctly.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +SerialPortSetAttributes (
> > > +  IN OUT UINT64             *BaudRate,
> > > +  IN OUT UINT32             *ReceiveFifoDepth,
> > > +  IN OUT UINT32             *Timeout,
> > > +  IN OUT EFI_PARITY_TYPE    *Parity,
> > > +  IN OUT UINT8              *DataBits,
> > > +  IN OUT EFI_STOP_BITS_TYPE *StopBits
> > > +  )
> > > +{
> > > +  return RETURN_SUCCESS;
> > > +}
> > > diff --git
> > > a/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.
> > > uni
> > > b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPortLib.
> > > uni
> > > new file mode 100644
> > > index 00000000..49163bd8
> > > --- /dev/null
> > > +++ b/Platform/RiscV/SiFive/U500Pkg/Library/SerialIoLib/U500SerialPo
> > > +++ rt
> > > +++ Lib.uni
> > > @@ -0,0 +1,16 @@
> > > +// /** @file
> > > +// Library instance for SerialIo library class // // Library
> > > +instance for SerialIO library class.
> > > +//
> > > +// Copyright (c) 2006 - 2014, Intel Corporation. All rights
> > > +reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent //
> > > +// **/
> > > +
> > > +
> > > +#string STR_MODULE_ABSTRACT             #language en-US "Library
> instance
> > for SerialIO library class"
> > > +
> > > +#string STR_MODULE_DESCRIPTION          #language en-US "Library
> > instance for SerialIO library class."
> > > +
> > > --
> > > 2.12.0.windows.1
> > >
> > >
> > >
> > >
> >
> > 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores
  2019-10-16  1:36     ` Abner Chang
@ 2019-10-17 10:33       ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-17 10:33 UTC (permalink / raw)
  To: Chang, Abner (HPS SW/FW Technologist); +Cc: devel@edk2.groups.io, Chen, Gilbert

On Wed, Oct 16, 2019 at 01:36:07AM +0000, Chang, Abner (HPS SW/FW Technologist) wrote:
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Leif Lindholm
> > Sent: Wednesday, October 2, 2019 5:15 AM
> > To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 02/14]
> > Silicon/SiFive: Add library module of SiFive RISC-V cores
> > 
> > On Thu, Sep 19, 2019 at 11:51:19AM +0800, Gilbert Chen wrote:
> > > Initial version of SiFive RISC-V core libraries. Library of each core
> > > creates processor core SMBIOS data hob for building SMBIOS  records in
> > > DXE phase.
> > 
> > So yes, this implementation needs to change.
> > These should all implement the same LibraryClass.
>
> No. It shouldn't be the same library class (If you were saying the
> same LibraryClass). RISC-V SoC could be the combination of different
> RISC-V cores, or even the cores from different vendors. This depends
> on how SoC vendor combine those IPs.

Ah, OK. Sorry, did not realise this aspect.

> Either U54 or E51 could be a standalone SoC, while U54MC is the
> combination of 4 x U54 core and one E51 core.
> 
> U5MC under Platform/SiFive could be 1-8 U5 core and optionally
> support E5 core.  This is the special case for U500 VC707 platform
> because the core number could be customized.
> 
> > Also, U54 appears to be a simple superset of U51.
> U54 is a single core. 
> 
> > 
> > What I would suggest is creating a
> > Silicon/SiFive/Library/SiFiveCoreInfoLib, which calls into a
> > SiFiveSoCCoreInfoLib in Silicon/SiFive/<SoC>/Library, providing the acual SoC-
> > specific bits.
> 
> Platform system firmware integrator just pull in the necessary core
> libraries from Silicon/{vendor}  and invoke the function to create
> specific core bits.
>
> I think this implementation is well and flexible which has no need to change.

Oh, my criticism was that it was *too* flexible (with resulting code
overhead). I still feel the very small source differences, especially
between E51/U54, indicate that these could be implemented by the same
source file but different .inf files.

But this is not something that needs to be addressed before this patch
goes into -staging.

Regards,

Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-17  7:44       ` Abner Chang
@ 2019-10-17 11:19         ` Leif Lindholm
  2019-10-17 16:09           ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-17 11:19 UTC (permalink / raw)
  To: devel, abner.chang; +Cc: Chen, Gilbert, Palmer Dabbelt

On Thu, Oct 17, 2019 at 07:44:47AM +0000, Abner Chang wrote:
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist)
> > Sent: Thursday, October 17, 2019 10:21 AM
> > To: devel@edk2.groups.io; leif.lindholm@linaro.org; Chen, Gilbert
> > <gilbert.chen@hpe.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Subject: RE: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > U500Pkg/Library: Library instances of U500 platform library

> > > Seeing this, I have a bit of a feeling that this Opensbi isn't being
> > > consistently
> > > treated/named:
> > > - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
> > >   class RiscVOpensbiLib.
> > > - Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing the
> > >   class OpenSbiPlatformLib.
> > > - *Logically*, what we have is
> > >   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
> > >   OpensbiLib which depends on the OpenSbiPlatformLib.
> > >   - However, there is no OpenSbiPlatformLib in edk2, which is very
> > >     unfortunate because that does not let us build edk2/RiscVPkg in
> > >     isolation (like we can with all the other packages in edk2).
> > Will name it as Opensbi.
> > >
> > > Here is my preferred solution for untangling this:
> > > 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
> > >    already use for Openssl, so would be my preference.
> > > 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
> > >    LibararyClasses. Either is fine, the former is less likely to clash
> > >    with other imported projects in the future (but I would estimate
> > >    this risk as *very* low to begin with).
> > > 3) Implement a (RiscV)OpensbiPlatformLibNull in edk2/RiscVPkg/Library,
> > I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library
> > 
> > >    containing only what is required to build/link
> > >    RiscVPkg/Library/(RiscV)OpensbiLib/.
> > >    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
> > >    3.6) Add a depedency on OpensbiPlatformLib to
> > >         (RiscV)OpensbiLib.inf
> > >    3.7) Drop the dependency on OpensbiPlatformLib from
> > >         Platform/RiscV/Universal/Sec/SecMain.inf
> >
> > Above work for me
>
> I changed my mind. Due to SecMain is moved to RiscVPlatformPkg in
> edk2 and requires both RiscVOpensbiPlatformLib and RiscVOpensbLiib,
> SecMain.inf still has dependency with these two libs.

I am not sure I understand.

What I am saying is that OpensbiLib already has a dependency on
OpensbiPlatformLib. So there is no benefit to adding the
OpensbiPlatformLib dependency to SecMain. Or does that not work for
some reason?

Regards,

Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-17 11:19         ` Leif Lindholm
@ 2019-10-17 16:09           ` Abner Chang
  2019-10-17 16:38             ` Leif Lindholm
  0 siblings, 1 reply; 43+ messages in thread
From: Abner Chang @ 2019-10-17 16:09 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org
  Cc: Chen, Gilbert, Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 17, 2019 7:19 PM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>
> Cc: Chen, Gilbert <gilbert.chen@hpe.com>; Palmer Dabbelt
> <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> U500Pkg/Library: Library instances of U500 platform library
> 
> On Thu, Oct 17, 2019 at 07:44:47AM +0000, Abner Chang wrote:
> > > -----Original Message-----
> > > From: Chang, Abner (HPS SW/FW Technologist)
> > > Sent: Thursday, October 17, 2019 10:21 AM
> > > To: devel@edk2.groups.io; leif.lindholm@linaro.org; Chen, Gilbert
> > > <gilbert.chen@hpe.com>
> > > Cc: Palmer Dabbelt <palmer@sifive.com>
> > > Subject: RE: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > > U500Pkg/Library: Library instances of U500 platform library
> 
> > > > Seeing this, I have a bit of a feeling that this Opensbi isn't
> > > > being consistently
> > > > treated/named:
> > > > - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
> > > >   class RiscVOpensbiLib.
> > > > - Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing
> the
> > > >   class OpenSbiPlatformLib.
> > > > - *Logically*, what we have is
> > > >   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
> > > >   OpensbiLib which depends on the OpenSbiPlatformLib.
> > > >   - However, there is no OpenSbiPlatformLib in edk2, which is very
> > > >     unfortunate because that does not let us build edk2/RiscVPkg in
> > > >     isolation (like we can with all the other packages in edk2).
> > > Will name it as Opensbi.
> > > >
> > > > Here is my preferred solution for untangling this:
> > > > 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
> > > >    already use for Openssl, so would be my preference.
> > > > 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
> > > >    LibararyClasses. Either is fine, the former is less likely to clash
> > > >    with other imported projects in the future (but I would estimate
> > > >    this risk as *very* low to begin with).
> > > > 3) Implement a (RiscV)OpensbiPlatformLibNull in
> > > > edk2/RiscVPkg/Library,
> > > I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library
> > >
> > > >    containing only what is required to build/link
> > > >    RiscVPkg/Library/(RiscV)OpensbiLib/.
> > > >    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
> > > >    3.6) Add a depedency on OpensbiPlatformLib to
> > > >         (RiscV)OpensbiLib.inf
> > > >    3.7) Drop the dependency on OpensbiPlatformLib from
> > > >         Platform/RiscV/Universal/Sec/SecMain.inf
> > >
> > > Above work for me
> >
> > I changed my mind. Due to SecMain is moved to RiscVPlatformPkg in
> > edk2 and requires both RiscVOpensbiPlatformLib and RiscVOpensbLiib,
> > SecMain.inf still has dependency with these two libs.
> 
> I am not sure I understand.
> 
> What I am saying is that OpensbiLib already has a dependency on
> OpensbiPlatformLib. So there is no benefit to adding the OpensbiPlatformLib
> dependency to SecMain. Or does that not work for some reason?

In order to make those dependencies correct, below is the new changes,

RiscVOpensbiPlatformLib has NO dependency with RiscVOpensbiLib.
RiscVOpensbiLib has NO dependency with RiscVOpensbiPlatformLib.
SecMain.inf has dependencies with both RiscVOpensbiPlatformLib and RiscVOpensbiLib because SecMain.inf needs the functionalities of those libs.
Abner
> 
> Regards,
> 
> Leif
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-17 16:09           ` Abner Chang
@ 2019-10-17 16:38             ` Leif Lindholm
  2019-10-18  5:24               ` Abner Chang
  0 siblings, 1 reply; 43+ messages in thread
From: Leif Lindholm @ 2019-10-17 16:38 UTC (permalink / raw)
  To: devel, abner.chang; +Cc: Chen, Gilbert, Palmer Dabbelt

On Thu, Oct 17, 2019 at 04:09:44PM +0000, Abner Chang wrote:
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Leif Lindholm
> > Sent: Thursday, October 17, 2019 7:19 PM
> > To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>
> > Cc: Chen, Gilbert <gilbert.chen@hpe.com>; Palmer Dabbelt
> > <palmer@sifive.com>
> > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > U500Pkg/Library: Library instances of U500 platform library
> > 
> > On Thu, Oct 17, 2019 at 07:44:47AM +0000, Abner Chang wrote:
> > > > -----Original Message-----
> > > > From: Chang, Abner (HPS SW/FW Technologist)
> > > > Sent: Thursday, October 17, 2019 10:21 AM
> > > > To: devel@edk2.groups.io; leif.lindholm@linaro.org; Chen, Gilbert
> > > > <gilbert.chen@hpe.com>
> > > > Cc: Palmer Dabbelt <palmer@sifive.com>
> > > > Subject: RE: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > > > U500Pkg/Library: Library instances of U500 platform library
> > 
> > > > > Seeing this, I have a bit of a feeling that this Opensbi isn't
> > > > > being consistently
> > > > > treated/named:
> > > > > - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which implements
> > > > >   class RiscVOpensbiLib.
> > > > > - Here, we have U500Pkg/Library/OpenSbiPlatformLib implementing
> > the
> > > > >   class OpenSbiPlatformLib.
> > > > > - *Logically*, what we have is
> > > > >   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
> > > > >   OpensbiLib which depends on the OpenSbiPlatformLib.
> > > > >   - However, there is no OpenSbiPlatformLib in edk2, which is very
> > > > >     unfortunate because that does not let us build edk2/RiscVPkg in
> > > > >     isolation (like we can with all the other packages in edk2).
> > > > Will name it as Opensbi.
> > > > >
> > > > > Here is my preferred solution for untangling this:
> > > > > 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern we
> > > > >    already use for Openssl, so would be my preference.
> > > > > 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
> > > > >    LibararyClasses. Either is fine, the former is less likely to clash
> > > > >    with other imported projects in the future (but I would estimate
> > > > >    this risk as *very* low to begin with).
> > > > > 3) Implement a (RiscV)OpensbiPlatformLibNull in
> > > > > edk2/RiscVPkg/Library,
> > > > I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library
> > > >
> > > > >    containing only what is required to build/link
> > > > >    RiscVPkg/Library/(RiscV)OpensbiLib/.
> > > > >    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
> > > > >    3.6) Add a depedency on OpensbiPlatformLib to
> > > > >         (RiscV)OpensbiLib.inf
> > > > >    3.7) Drop the dependency on OpensbiPlatformLib from
> > > > >         Platform/RiscV/Universal/Sec/SecMain.inf
> > > >
> > > > Above work for me
> > >
> > > I changed my mind. Due to SecMain is moved to RiscVPlatformPkg in
> > > edk2 and requires both RiscVOpensbiPlatformLib and RiscVOpensbLiib,
> > > SecMain.inf still has dependency with these two libs.
> > 
> > I am not sure I understand.
> > 
> > What I am saying is that OpensbiLib already has a dependency on
> > OpensbiPlatformLib. So there is no benefit to adding the OpensbiPlatformLib
> > dependency to SecMain. Or does that not work for some reason?
> 
> In order to make those dependencies correct, below is the new changes,
> 
> RiscVOpensbiPlatformLib has NO dependency with RiscVOpensbiLib.
> RiscVOpensbiLib has NO dependency with RiscVOpensbiPlatformLib.
> SecMain.inf has dependencies with both RiscVOpensbiPlatformLib and
> RiscVOpensbiLib because SecMain.inf needs the functionalities of
> those libs.

Ah, OK - this is new for v3 then?
In that case, sure, the above sounds fine.

Regards,

Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced in RISC-V platform package
  2019-10-02 17:04   ` [edk2-devel] " Leif Lindholm
  2019-10-15 15:26     ` Abner Chang
@ 2019-10-18  5:23     ` Abner Chang
  1 sibling, 0 replies; 43+ messages in thread
From: Abner Chang @ 2019-10-18  5:23 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 1:05 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 05/14]
> RiscV/Library: Initial version of libraries introduced in RISC-V platform
> package
> 
> On Thu, Sep 19, 2019 at 11:51:22AM +0800, Gilbert Chen wrote:
> > FirmwareContextProcessorSpecificLib
> > - Common library to consume
> EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> >  and build up processor specific data HOB.
> >
> > RealTimClockLibNull
> > - NULL instance of Real Time Clock library.
> >
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../FirmwareContextProcessorSpecificLib.c          |  82 +++++++++
> >  .../FirmwareContextProcessorSpecificLib.inf        |  33 ++++
> >  .../RealTimeClockLibNull/RealTimeClockLibNull.c    | 204
> +++++++++++++++++++++
> >  .../RealTimeClockLibNull/RealTimeClockLibNull.inf  |  30 +++
> 
> I think you can replace this NULL RealTimeClockLib implementation with
> EmbeddedPkg/Library/VirtualRealTimeClockLib/ (which did not exist at the
> time of the original port).
Ok. U500.dsc will use VirtualRealTimeClockLib. The RiscVPlatformPkg keeps using the NULL one under RiscVPlatformPkg/Library. Same as RiscVPkg, no EmbeddedPkg modules involved.
> 
> >  4 files changed, 349 insertions(+)
> >  create mode 100644
> >
> Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareCon
> > textProcessorSpecificLib.c  create mode 100644
> >
> Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareCon
> > textProcessorSpecificLib.inf  create mode 100644
> > Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.c
> >  create mode 100644
> > Platform/RiscV/Library/RealTimeClockLibNull/RealTimeClockLibNull.inf
> >
> > diff --git
> > a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.c
> >
> b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.c
> > new file mode 100644
> > index 00000000..4d4c51dc
> > --- /dev/null
> > +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/Firmw
> > +++ areContextProcessorSpecificLib.c
> > @@ -0,0 +1,82 @@
> > +/**@file
> > +  Common library to build upfirmware context processor-specific
> > +information
> > +
> > +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +//
> > +// The package level header files this module uses // #include
> > +<PiPei.h>
> > +
> > +//
> > +// The Library classes this module consumes // #include
> > +<Library/DebugLib.h> #include <Library/PeiServicesLib.h> #include
> > +<Library/BaseMemoryLib.h>
> 
> Please sort these includes alphabetically.
> 
> > +
> > +#include <RiscV.h>
> > +#include <SmbiosProcessorSpecificData.h> #include
> > +<ProcessorSpecificDataHob.h>
> 
> Please sort these includes alphabetically.
> 
> > +#include <sbi/sbi_hart.h>
> > +#include <sbi/sbi.h>
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +/**
> > +  Build up common firmware context processor-specific information
> > +
> > +  @param  FirmwareContextHartSpecific  Pointer to
> EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > +  @param  ParentProcessorGuid          Pointer to GUID of Processor which
> contains this core
> > +  @param  ParentProcessorUid           Unique ID of pysical processor which
> owns this core.
> > +  @param  CoreGuid                     Pointer to GUID of core
> > +  @param  HartId                       Hart ID of this core.
> > +  @param  IsBootHart                   This is boot hart or not
> > +  @param  ProcessorSpecDataHob         Pointer to
> RISC_V_PROCESSOR_SPECIFIC_DATA_HOB
> > +
> > +  @return EFI_STATUS
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CommonFirmwareContextHartSpecificInfo (
> > +  EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > +*FirmwareContextHartSpecific,
> > +  EFI_GUID  *ParentProcessorGuid,
> > +  UINTN     ParentProcessorUid,
> > +  EFI_GUID  *CoreGuid,
> > +  UINTN     HartId,
> > +  BOOLEAN   IsBootHart,
> > +  RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecDataHob
> 
> Spec is not a clear enough abbreviation, please use Specific.
> Or call it something else. If you keep the name, it certainly wouldn't hurt to
> use a local variable with a shorter name..
> 
> > +  )
> > +{
> > +  //
> > +  // Build up RISC_V_PROCESSOR_SPECIFIC_DATA_HOB.
> > +  //
> > +  CopyGuid (&ProcessorSpecDataHob->ParentPrcessorGuid,
> > +ParentProcessorGuid);
> > +  ProcessorSpecDataHob->ParentProcessorUid = ParentProcessorUid;
> > +  CopyGuid (&ProcessorSpecDataHob->CoreGuid, CoreGuid);
> > +  ProcessorSpecDataHob->Context = NULL;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.Revision         =
> SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA_REVISION;
> 
> 80 Characters is up to                                                      here ->
> These lines are way too long, please wrap them.
> 
> > +  ProcessorSpecDataHob->ProcessorSpecificData.Length           = sizeof
> (SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA);
> > +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_L =
> > +(UINT64)HartId;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.HartId.Value64_H = 0;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.BootHartId       =
> (UINT8)IsBootHart;
> > +  ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported =
> FirmwareContextHartSpecific->IsaExtensionSupported;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.PrivilegeModeSupported   =
> SMBIOS_RISC_V_PSD_MACHINE_MODE_SUPPORTED;
> > +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported &
> RISC_V_ISA_SUPERVISOR_MODE_IMPLEMENTED) != 0) {
> > +
> > +ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported
> |=
> > +SMBIOS_RISC_V_PSD_SUPERVISOR_MODE_SUPPORTED;
> > +  }
> > +  if ((ProcessorSpecDataHob->ProcessorSpecificData.InstSetSupported &
> RISC_V_ISA_USER_MODE_IMPLEMENTED) != 0) {
> > +
> > +ProcessorSpecDataHob->ProcessorSpecificData.PrivilegeModeSupported
> |=
> > +SMBIOS_RISC_V_PSD_USER_MODE_SUPPORTED;
> > +  }
> > +
> > +ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineVendorId.Value64_L
> > += FirmwareContextHartSpecific->MachineVendorId.Value64_L;
> > +
> > +ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineVendorId.Value64_H
> > += FirmwareContextHartSpecific->MachineVendorId.Value64_H;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineArchId.Value64_L
> > += FirmwareContextHartSpecific->MachineArchId.Value64_L;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineArchId.Value64_H
> > += FirmwareContextHartSpecific->MachineArchId.Value64_H;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineImplId.Value64_L
> > += FirmwareContextHartSpecific->MachineImplId.Value64_L;
> > +  ProcessorSpecDataHob-
> >ProcessorSpecificData.MachineImplId.Value64_H
> > += FirmwareContextHartSpecific->MachineImplId.Value64_H;
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> > a/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.inf
> >
> b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/FirmwareC
> > ontextProcessorSpecificLib.inf
> > new file mode 100644
> > index 00000000..ff841c3e
> > --- /dev/null
> > +++ b/Platform/RiscV/Library/FirmwareContextProcessorSpecificLib/Firmw
> > +++ areContextProcessorSpecificLib.inf
> > @@ -0,0 +1,33 @@
> > +#/** @file
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # #  SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # #**/
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Can we update to a more recent specification version?
> 
> > +  BASE_NAME                      = FirmwareContextProcessorSpecificLib
> > +  FILE_GUID                      = 8BEC9FD7-C554-403A-94F1-0EBBFD81A242
> > +  MODULE_TYPE                    = PEIM
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FirmwareContextProcessorSpecificLib
> > +
> > +[Sources.common]
> > +  FirmwareContextProcessorSpecificLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> 
> Please sort the above alphabetically.
> 
> > +  RiscVPkg/RiscVPkg.dec
> > +  Silicon/SiFive/SiFive.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  PcdLib
> > +  MemoryAllocationLib
> 
> Please sort the above alphabetically.
> 
> > +  PrintLib
> > +
> > +[Pcd]
> > +
> 
> /
>     Leif
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library
  2019-10-17 16:38             ` Leif Lindholm
@ 2019-10-18  5:24               ` Abner Chang
  0 siblings, 0 replies; 43+ messages in thread
From: Abner Chang @ 2019-10-18  5:24 UTC (permalink / raw)
  To: Leif Lindholm, devel@edk2.groups.io; +Cc: Chen, Gilbert, Palmer Dabbelt



> -----Original Message-----
> From: Leif Lindholm [mailto:leif.lindholm@linaro.org]
> Sent: Friday, October 18, 2019 12:38 AM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>
> Cc: Chen, Gilbert <gilbert.chen@hpe.com>; Palmer Dabbelt
> <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> U500Pkg/Library: Library instances of U500 platform library
> 
> On Thu, Oct 17, 2019 at 04:09:44PM +0000, Abner Chang wrote:
> > > -----Original Message-----
> > > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf
> > > Of Leif Lindholm
> > > Sent: Thursday, October 17, 2019 7:19 PM
> > > To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> > > <abner.chang@hpe.com>
> > > Cc: Chen, Gilbert <gilbert.chen@hpe.com>; Palmer Dabbelt
> > > <palmer@sifive.com>
> > > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 10/14]
> > > U500Pkg/Library: Library instances of U500 platform library
> > >
> > > On Thu, Oct 17, 2019 at 07:44:47AM +0000, Abner Chang wrote:
> > > > > -----Original Message-----
> > > > > From: Chang, Abner (HPS SW/FW Technologist)
> > > > > Sent: Thursday, October 17, 2019 10:21 AM
> > > > > To: devel@edk2.groups.io; leif.lindholm@linaro.org; Chen,
> > > > > Gilbert <gilbert.chen@hpe.com>
> > > > > Cc: Palmer Dabbelt <palmer@sifive.com>
> > > > > Subject: RE: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2
> > > > > 10/14]
> > > > > U500Pkg/Library: Library instances of U500 platform library
> > >
> > > > > > Seeing this, I have a bit of a feeling that this Opensbi isn't
> > > > > > being consistently
> > > > > > treated/named:
> > > > > > - In edk2, we have RiscVPkg/Library/RiscVOpensbiLib which
> implements
> > > > > >   class RiscVOpensbiLib.
> > > > > > - Here, we have U500Pkg/Library/OpenSbiPlatformLib
> > > > > > implementing
> > > the
> > > > > >   class OpenSbiPlatformLib.
> > > > > > - *Logically*, what we have is
> > > > > >   Platform/RiscV/Universal/Sec/SecMain.inf which depends on the
> > > > > >   OpensbiLib which depends on the OpenSbiPlatformLib.
> > > > > >   - However, there is no OpenSbiPlatformLib in edk2, which is very
> > > > > >     unfortunate because that does not let us build edk2/RiscVPkg in
> > > > > >     isolation (like we can with all the other packages in edk2).
> > > > > Will name it as Opensbi.
> > > > > >
> > > > > > Here is my preferred solution for untangling this:
> > > > > > 1) Standardise on OpenSbi or Opensbi. Opensbi follows the pattern
> we
> > > > > >    already use for Openssl, so would be my preference.
> > > > > > 2) Standardise on RiscVOpensbi or Opensbi - both for filenames and
> > > > > >    LibararyClasses. Either is fine, the former is less likely to clash
> > > > > >    with other imported projects in the future (but I would estimate
> > > > > >    this risk as *very* low to begin with).
> > > > > > 3) Implement a (RiscV)OpensbiPlatformLibNull in
> > > > > > edk2/RiscVPkg/Library,
> > > > > I will have OpensbiPlatformLibNull  in RiscVPlatformPkg/Library
> > > > >
> > > > > >    containing only what is required to build/link
> > > > > >    RiscVPkg/Library/(RiscV)OpensbiLib/.
> > > > > >    3.5) Map that to OpensbiPlatformLib in RiscVPkg/RiscVPkg.dsc.
> > > > > >    3.6) Add a depedency on OpensbiPlatformLib to
> > > > > >         (RiscV)OpensbiLib.inf
> > > > > >    3.7) Drop the dependency on OpensbiPlatformLib from
> > > > > >         Platform/RiscV/Universal/Sec/SecMain.inf
> > > > >
> > > > > Above work for me
> > > >
> > > > I changed my mind. Due to SecMain is moved to RiscVPlatformPkg in
> > > > edk2 and requires both RiscVOpensbiPlatformLib and
> > > > RiscVOpensbLiib, SecMain.inf still has dependency with these two libs.
> > >
> > > I am not sure I understand.
> > >
> > > What I am saying is that OpensbiLib already has a dependency on
> > > OpensbiPlatformLib. So there is no benefit to adding the
> > > OpensbiPlatformLib dependency to SecMain. Or does that not work for
> some reason?
> >
> > In order to make those dependencies correct, below is the new changes,
> >
> > RiscVOpensbiPlatformLib has NO dependency with RiscVOpensbiLib.
> > RiscVOpensbiLib has NO dependency with RiscVOpensbiPlatformLib.
> > SecMain.inf has dependencies with both RiscVOpensbiPlatformLib and
> > RiscVOpensbiLib because SecMain.inf needs the functionalities of those
> > libs.
> 
> Ah, OK - this is new for v3 then?
> In that case, sure, the above sounds fine.
Yes, this will be in the next set of patches.
> 
> Regards,
> 
> Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
  2019-10-02 22:02   ` [edk2-devel] " Leif Lindholm
@ 2019-10-18  6:23     ` Abner Chang
  2019-10-21 14:51       ` Leif Lindholm
  0 siblings, 1 reply; 43+ messages in thread
From: Abner Chang @ 2019-10-18  6:23 UTC (permalink / raw)
  To: devel@edk2.groups.io, leif.lindholm@linaro.org, Chen, Gilbert
  Cc: Palmer Dabbelt



> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 6:03 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14]
> U500Pkg/Library: Initial version of PlatformBootManagerLib
> 
> On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> > SiFive RISC-V U500 Platform Boot Manager library.
> 
> First of all, let me say that I think before upstreaming to master, you ought to
> look into merging PlatformBootManagerLibs for all Risc-V platforms. Like we
> have for *most* ARM/AARCH64 platforms with
> ArmPkg/Library/PlatformBootManagerLib/.
> 
> (Longer-term we should merge them all together into a single one.)
> 
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../Library/PlatformBootManagerLib/MemoryTest.c    | 682
> +++++++++++++++++++++
> >  .../PlatformBootManagerLib/PlatformBootManager.c   | 274 +++++++++
> >  .../PlatformBootManagerLib/PlatformBootManager.h   | 135 ++++
> >  .../PlatformBootManagerLib.inf                     |  63 ++
> >  .../Library/PlatformBootManagerLib/PlatformData.c  |  49 ++
> >  .../Library/PlatformBootManagerLib/Strings.uni     |  28 +
> >  6 files changed, 1231 insertions(+)
> >  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryT
> es
> > t.c  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManager.c  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManager.h  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManagerLib.inf  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformD
> > ata.c  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> > ni
> >
> > diff --git
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memory
> T
> > est.c
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memor
> yT
> > est.c
> > new file mode 100644
> > index 00000000..8c6d89e9
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Mem
> > +++ oryTest.c
> 
> Why build a MemoryTest into the PlatformBootManagerLib?
Why not to do memory if platform provides memory test protocol?
> 
> > @@ -0,0 +1,682 @@
> > +/** @file
> > +  Perform the RISC-V platform memory test
> > +
> > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> Copyright (c) 2004 - 2015, Intel Corporation.
> > +All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +EFI_HII_HANDLE gStringPackHandle = NULL;
> > +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> > +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81,
> > +0x57, 0x88 }
> > +  };
> > +// extern UINT8  BdsDxeStrings[];
> 
> No need to keep commented-out code in.
> 
> > +
> > +//
> > +// BDS Platform Functions
> > +//
> > +/**
> > +
> > +  Show progress bar with title above it. It only works in Graphics mode.
> > +
> > +  @param TitleForeground Foreground color for Title.
> > +  @param TitleBackground Background color for Title.
> > +  @param Title           Title above progress bar.
> > +  @param ProgressColor   Progress bar color.
> > +  @param Progress        Progress (0-100)
> > +  @param PreviousValue   The previous value of the progress.
> > +
> > +  @retval  EFI_STATUS       Success update the progress bar
> > +
> > +**/
> > +EFI_STATUS
> > +PlatformBootManagerShowProgress (
> 
> I'm not a super fan of how this file integrates a custom memory test with a
> direct (copy) graphical progress indicator. There are both common memory
> test and common progress indicators - please use those instead. And
> improve them if they are currently insufficient for your needs.

Could you indicate where are those common libraries? Thanks.

> 
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> > mBootManager.c
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> > mBootManager.c
> > new file mode 100644
> > index 00000000..9ef85089
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Pla
> > +++ tformBootManager.c
> > @@ -0,0 +1,274 @@
> > +/** @file
> > +  This file include all platform action which can be customized
> > +  by IBV/OEM.
> > +
> > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> Copyright (c) 2015, Intel Corporation. All
> > +rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +
> > +EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD,
> > +0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1}};
> > +
> > +/**
> > +  Perform the platform diagnostic, such like test memory. OEM/IBV
> > +also
> > +  can customize this function to support specific platform diagnostic.
> > +
> > +  @param MemoryTestLevel  The memory test intensive level
> > +  @param QuietBoot        Indicate if need to enable the quiet boot
> > +
> > +**/
> > +VOID
> > +PlatformBootManagerDiagnostics (
> > +  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
> > +  IN BOOLEAN                     QuietBoot
> > +  )
> > +{
> > +  EFI_STATUS                     Status;
> > +
> > +  //
> > +  // Here we can decide if we need to show  // the diagnostics screen
> > + // Notes: this quiet boot code should be remove  // from the graphic
> > + lib  //  if (QuietBoot) {
> > +
> > +    //
> > +    // Perform system diagnostic
> > +    //
> > +    Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
> > +    return;
> > +  }
> > +
> > +  //
> > +  // Perform system diagnostic
> > +  //
> > +  Status = PlatformBootManagerMemoryTest (MemoryTestLevel);
> > +}
> > +
> > +/**
> > +  Return the index of the load option in the load option array.
> > +
> > +  The function consider two load options are equal when the
> > +  OptionType, Attributes, Description, FilePath and OptionalData are equal.
> > +
> > +  @param Key    Pointer to the load option to be found.
> > +  @param Array  Pointer to the array of load options to be found.
> > +  @param Count  Number of entries in the Array.
> > +
> > +  @retval -1          Key wasn't found in the Array.
> > +  @retval 0 ~ Count-1 The index of the Key in the Array.
> > +**/
> > +INTN
> > +PlatformFindLoadOption (
> > +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
> > +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
> > +  IN UINTN                              Count
> > +  )
> > +{
> > +  UINTN                             Index;
> > +
> > +  for (Index = 0; Index < Count; Index++) {
> > +    if ((Key->OptionType == Array[Index].OptionType) &&
> > +        (Key->Attributes == Array[Index].Attributes) &&
> > +        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
> > +        (CompareMem (Key->FilePath, Array[Index].FilePath,
> GetDevicePathSize (Key->FilePath)) == 0) &&
> > +        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
> > +        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key-
> >OptionalDataSize) == 0)) {
> > +      return (INTN) Index;
> > +    }
> > +  }
> > +
> > +  return -1;
> > +}
> > +
> > +VOID
> > +PlatformRegisterFvBootOption (
> > +  EFI_GUID                         *FileGuid,
> > +  CHAR16                           *Description,
> > +  UINT32                           Attributes
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  UINTN                             OptionIndex;
> > +  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
> > +  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
> > +  UINTN                             BootOptionCount;
> > +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
> > +  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
> > +  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
> > +
> > +  Status = gBS->HandleProtocol (gImageHandle,
> &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> > +  DevicePath = AppendDevicePathNode (
> > +                 DevicePathFromHandle (LoadedImage->DeviceHandle),
> > +                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
> > +                 );
> > +
> > +  Status = EfiBootManagerInitializeLoadOption (
> > +             &NewOption,
> > +             LoadOptionNumberUnassigned,
> > +             LoadOptionTypeBoot,
> > +             Attributes,
> > +             Description,
> > +             DevicePath,
> > +             NULL,
> > +             0
> > +             );
> > +  if (!EFI_ERROR (Status)) {
> > +    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
> LoadOptionTypeBoot);
> > +
> > +    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions,
> BootOptionCount);
> > +
> > +    if (OptionIndex == -1) {
> > +      Status = EfiBootManagerAddLoadOptionVariable (&NewOption,
> (UINTN) -1);
> > +      ASSERT_EFI_ERROR (Status);
> > +    }
> > +    EfiBootManagerFreeLoadOption (&NewOption);
> > +    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> > +  }
> > +}
> > +
> > +/**
> > +  Do the platform specific action before the console is connected.
> > +
> > +  Such as:
> > +    Update console variable;
> > +    Register new Driver#### or Boot####;
> > +    Signal ReadyToLock event.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformBootManagerBeforeConsole (
> > +  VOID
> > +  )
> > +{
> > +  UINTN                        Index;
> > +  EFI_STATUS                   Status;
> > +  EFI_INPUT_KEY                Enter;
> > +  EFI_INPUT_KEY                F2;
> > +  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
> > +
> > +  //
> > +  // Update the console variables.
> > +  //
> > +  for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
> > +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) ==
> CONSOLE_IN) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ConIn,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n",
> ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE,
> FALSE), Status));
> 
> Some really long lines here, can we wrap them?
> 
> > +    }
> > +
> > +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) ==
> CONSOLE_OUT) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ConOut,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n",
> ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE,
> FALSE), Status));
> > +    }
> > +
> > +    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) ==
> STD_ERROR) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ErrOut,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
> > +    }
> > +  }
> > +
> > +  //
> > +  // Register ENTER as CONTINUE key
> > +  //
> > +  Enter.ScanCode    = SCAN_NULL;
> > +  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> > +  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> > +  //
> > +  // Map F2 to Boot Manager Menu
> > +  //
> > +  F2.ScanCode    = SCAN_F2;
> > +  F2.UnicodeChar = CHAR_NULL;
> > +  EfiBootManagerGetBootManagerMenu (&BootOption);
> > +  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)
> BootOption.OptionNumber, 0, &F2, NULL);
> > +  //
> > +  // Register UEFI Shell
> > +  //
> > +  PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell",
> LOAD_OPTION_ACTIVE);
> > +}
> > +
> > +/**
> > +  Do the platform specific action after the console is connected.
> > +
> > +  Such as:
> > +    Dynamically switch output mode;
> > +    Signal console ready platform customized event;
> > +    Run diagnostics like memory testing;
> > +    Connect certain devices;
> > +    Dispatch aditional option roms.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformBootManagerAfterConsole (
> > +  VOID
> > +  )
> > +{
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Black;
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  White;
> > +
> > +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> > +  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
> > +
> > +  EfiBootManagerConnectAll ();
> > +  EfiBootManagerRefreshAllBootOption ();
> > +
> > +  PlatformBootManagerDiagnostics (QUICK, TRUE);
> > +
> > +  PrintXY (10, 10, &White, &Black, L"F2    to enter Boot Manager Menu.
> ");
> > +  PrintXY (10, 30, &White, &Black, L"Enter to boot directly.");
> > +}
> > +
> > +/**
> > +  This function is called each second during the boot manager waits the
> timeout.
> > +
> > +  @param TimeoutRemain  The remaining timeout.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformBootManagerWaitCallback (
> > +  UINT16          TimeoutRemain
> > +  )
> > +{
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
> > +  UINT16                        Timeout;
> > +
> > +  Timeout = PcdGet16 (PcdPlatformBootTimeOut);
> > +
> > +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> > +  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
> > +
> > +  PlatformBootManagerShowProgress (
> > +    White,
> > +    Black,
> > +    L"Start boot option",
> > +    White,
> > +    (Timeout - TimeoutRemain) * 100 / Timeout,
> > +    0
> > +    );
> > +}
> > +
> > +/**
> > +  The function is called when no boot option could be launched,
> > +  including platform recovery options and options pointing to applications
> > +  built into firmware volumes.
> > +
> > +  If this function returns, BDS attempts to enter an infinite loop.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformBootManagerUnableToBoot (
> > +  VOID
> > +  )
> > +{
> > +  return;
> > +}
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platform
> BootManager.h
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.h
> > new file mode 100644
> > index 00000000..20d66758
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.h
> > @@ -0,0 +1,135 @@
> > +/**@file
> > +   Head file for BDS Platform specific code
> > +
> > +Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _PLATFORM_BOOT_MANAGER_H_
> > +#define _PLATFORM_BOOT_MANAGER_H_
> 
> Please drop leading _.
> 
> > +
> > +#include <PiDxe.h>
> > +#include <IndustryStandard/Bmp.h>
> > +#include <Protocol/GenericMemoryTest.h>
> > +#include <Protocol/LoadedImage.h>
> > +#include <Protocol/UgaDraw.h>
> > +#include <Protocol/GraphicsOutput.h>
> > +#include <Protocol/BootLogo.h>
> > +#include <Protocol/DevicePath.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/UefiBootManagerLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/HiiLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <Library/DxeServicesLib.h>
> 
> Please remove any includes not needed by this file, and add them to
> the files that actually use them.
> 
> > +
> > +typedef struct {
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> > +  UINTN                     ConnectType;
> > +} PLATFORM_CONSOLE_CONNECT_ENTRY;
> > +
> > +extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
> > +
> > +#define gEndEntire \
> > +  { \
> > +    END_DEVICE_PATH_TYPE,\
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,\
> > +    END_DEVICE_PATH_LENGTH,\
> > +    0\
> > +  }
> > +
> > +#define CONSOLE_OUT BIT0
> > +#define CONSOLE_IN  BIT1
> > +#define STD_ERROR   BIT2
> > +
> > +//D3987D4B-971A-435F-8CAF-4967EB627241
> > +#define EFI_SERIAL_DXE_GUID \
> > +  { 0xD3987D4B, 0x971A, 0x435F, { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72,
> 0x41 } }
> > +
> > +typedef struct {
> > +  VENDOR_DEVICE_PATH        Guid;
> > +  UART_DEVICE_PATH          Uart;
> > +  VENDOR_DEVICE_PATH        TerminalType;
> > +  EFI_DEVICE_PATH_PROTOCOL  End;
> > +} SERIAL_CONSOLE_DEVICE_PATH;
> > +
> > +/**
> > +  Use SystemTable Conout to stop video based Simple Text Out consoles
> from going
> > +  to the video device. Put up LogoFile on every video device that is a
> console.
> > +
> > +  @param[in]  LogoFile   File name of logo to display on the center of the
> screen.
> > +
> > +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and
> logo displayed.
> > +  @retval EFI_UNSUPPORTED Logo not found
> > +
> > +**/
> > +EFI_STATUS
> > +PlatformBootManagerEnableQuietBoot (
> > +  IN  EFI_GUID  *LogoFile
> > +  );
> > +
> > +/**
> > +  Use SystemTable Conout to turn on video based Simple Text Out
> consoles. The
> > +  Simple Text Out screens will now be synced up with all non video output
> devices
> > +
> > +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced
> up.
> > +
> > +**/
> > +EFI_STATUS
> > +PlatformBootManagerDisableQuietBoot (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Perform the memory test base on the memory test intensive level,
> > +  and update the memory resource.
> > +
> > +  @param  Level         The memory test intensive level.
> > +
> > +  @retval EFI_STATUS    Success test all the system memory and update
> > +                        the memory resource
> > +
> > +**/
> > +EFI_STATUS
> > +PlatformBootManagerMemoryTest (
> > +  IN EXTENDMEM_COVERAGE_LEVEL Level
> > +  );
> > +
> > +/**
> > +
> > +  Show progress bar with title above it. It only works in Graphics mode.
> > +
> > +
> > +  @param TitleForeground Foreground color for Title.
> > +  @param TitleBackground Background color for Title.
> > +  @param Title           Title above progress bar.
> > +  @param ProgressColor   Progress bar color.
> > +  @param Progress        Progress (0-100)
> > +  @param PreviousValue   The previous value of the progress.
> > +
> > +  @retval  EFI_STATUS       Success update the progress bar
> > +
> > +**/
> > +EFI_STATUS
> > +PlatformBootManagerShowProgress (
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
> > +  IN CHAR16                        *Title,
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
> > +  IN UINTN                         Progress,
> > +  IN UINTN                         PreviousValue
> > +  );
> > +
> > +#endif // _PLATFORM_BOOT_MANAGER_H
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platform
> BootManagerLib.inf
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManagerLib.inf
> > new file mode 100644
> > index 00000000..92c31db4
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManagerLib.inf
> > @@ -0,0 +1,63 @@
> > +## @file
> > +#  Include all platform action which can be customized by IBV/OEM.
> > +#
> > +#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = PlatformBootManagerLib
> > +  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = RISCV
> > +#
> > +
> > +[Sources]
> > +  PlatformData.c
> > +  PlatformBootManager.c
> > +  PlatformBootManager.h
> > +  MemoryTest.c
> > +  Strings.uni
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  Platform/RiscV/RiscVPlatformPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  UefiBootServicesTableLib
> > +  UefiRuntimeServicesTableLib
> > +  UefiLib
> > +  UefiBootManagerLib
> > +  PcdLib
> > +  DxeServicesLib
> > +  MemoryAllocationLib
> > +  DevicePathLib
> > +  HiiLib
> > +  PrintLib
> 
> Please sort Sources, Packages and LibraryClasses alphabetically.
> 
> > +
> > +[Guids]
> > +
> > +[Protocols]
> > +  gEfiGenericMemTestProtocolGuid  ## CONSUMES
> > +  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
> > +  gEfiUgaDrawProtocolGuid         ## CONSUMES
> 
> You're hopefully not really using UGA, so please drop that.
> 
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> > +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable
> 
> Please sort Pcds alphabetically.
> 
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platform
> Data.c
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mData.c
> > new file mode 100644
> > index 00000000..3208051e
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mData.c
> > @@ -0,0 +1,49 @@
> > +/**@file
> > +  Defined the platform specific device path which will be filled to
> > +  ConIn/ConOut variables.
> > +
> > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +//
> > +// Platform specific serial device path
> > +//
> > +SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
> > +  {
> > +    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof
> (VENDOR_DEVICE_PATH), 0} },
> > +    EFI_SERIAL_DXE_GUID  // Use the driver's GUID
> > +  },
> > +  {
> > +    { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof
> (UART_DEVICE_PATH), 0} },
> > +    0,                  // Reserved
> > +    115200,             // BaudRate
> > +    8,                  // DataBits
> > +    1,                  // Parity
> > +    1                   // StopBits
> > +  },
> > +  {
> > +    { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, { sizeof
> (VENDOR_DEVICE_PATH), 0} },
> > +    DEVICE_PATH_MESSAGING_PC_ANSI
> > +  },
> > +  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
> { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
> > +};
> > +
> > +//
> > +// Predefined platform default console device path
> > +//
> > +PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
> > +  {
> > +    (EFI_DEVICE_PATH_PROTOCOL *) &gSerialConsoleDevicePath0,
> > +    CONSOLE_OUT | CONSOLE_IN
> > +  },
> > +  {
> > +    NULL,
> > +    0
> > +  }
> > +};
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> ni
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.
> uni
> > new file mode 100644
> > index 00000000..73bf5d51
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.
> uni
> > @@ -0,0 +1,28 @@
> > +///** @file
> > +//
> > +//    String definitions for PlatformBootManagerLib.
> > +//
> > +//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> > +//
> > +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +//**/
> > +
> > +/=#
> > +
> > +#langdef   en-US "English"
> > +#langdef   fr-FR "Français"
> > +
> > +#string STR_PERFORM_MEM_TEST           #language en-US  "Perform
> memory test (ESC to skip)"
> > +                                       #language fr-FR  "Exécute l'examen de mémoire (ESC
> pour sauter)"
> > +#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the
> system memory tested OK"
> > +                                       #language fr-FR  "% de la mémoire de système
> essayée D'ACCORD"
> > +#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC
> key to skip memory test"
> > +                                       #language fr-FR  "Appuie sur ESC sauter examen de
> mémoire"
> > +#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of
> system memory tested OK\r\n"
> > +                                       #language fr-FR  "octets dela mémoire de système
> essayée D'ACCORD\r\n"
> 
> if there's a space before 'bytes' you probably want one before
> 'octets'.
> 
> /
>     Leif
> 
> > +#string STR_SYSTEM_MEM_ERROR           #language en-US  "System
> encounters memory errors"
> > +                                       #language fr-FR  "le Système rencontre les erreurs de
> mémoire"
> > +#string STR_START_BOOT_OPTION          #language en-US  "Start boot
> option"
> > +                                       #language fr-FR  "l'option de botte de Début"
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
  2019-10-18  6:23     ` Abner Chang
@ 2019-10-21 14:51       ` Leif Lindholm
  0 siblings, 0 replies; 43+ messages in thread
From: Leif Lindholm @ 2019-10-21 14:51 UTC (permalink / raw)
  To: devel, abner.chang; +Cc: Chen, Gilbert, Palmer Dabbelt

On Fri, Oct 18, 2019 at 06:23:05AM +0000, Abner Chang wrote:
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Leif Lindholm
> > Sent: Thursday, October 3, 2019 6:03 AM
> > To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14]
> > U500Pkg/Library: Initial version of PlatformBootManagerLib
> > 
> > On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> > > SiFive RISC-V U500 Platform Boot Manager library.
> > 
> > First of all, let me say that I think before upstreaming to master, you ought to
> > look into merging PlatformBootManagerLibs for all Risc-V platforms. Like we
> > have for *most* ARM/AARCH64 platforms with
> > ArmPkg/Library/PlatformBootManagerLib/.
> > 
> > (Longer-term we should merge them all together into a single one.)
> > 
> > > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > > ---
> > >  .../Library/PlatformBootManagerLib/MemoryTest.c    | 682
> > +++++++++++++++++++++
> > >  .../PlatformBootManagerLib/PlatformBootManager.c   | 274 +++++++++
> > >  .../PlatformBootManagerLib/PlatformBootManager.h   | 135 ++++
> > >  .../PlatformBootManagerLib.inf                     |  63 ++
> > >  .../Library/PlatformBootManagerLib/PlatformData.c  |  49 ++
> > >  .../Library/PlatformBootManagerLib/Strings.uni     |  28 +
> > >  6 files changed, 1231 insertions(+)
> > >  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryT
> > es
> > > t.c  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManager.c  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManager.h  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManagerLib.inf  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformD
> > > ata.c  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> > > ni
> > >
> > > diff --git
> > >
> > a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memory
> > T
> > > est.c
> > >
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memor
> > yT
> > > est.c
> > > new file mode 100644
> > > index 00000000..8c6d89e9
> > > --- /dev/null
> > > +++
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Mem
> > > +++ oryTest.c
> > 
> > Why build a MemoryTest into the PlatformBootManagerLib?
>
> Why not to do memory if platform provides memory test protocol?

The question was why build it into the PlatformBootManagerLib?
I would much prefer something like what is done in existing plaforms
with gEfiGenericMemTestProtocolGuid.

> > 
> > > @@ -0,0 +1,682 @@
> > > +/** @file
> > > +  Perform the RISC-V platform memory test
> > > +
> > > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > > +rights reserved.<BR> Copyright (c) 2004 - 2015, Intel Corporation.
> > > +All rights reserved.<BR>
> > > +
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#include "PlatformBootManager.h"
> > > +
> > > +EFI_HII_HANDLE gStringPackHandle = NULL;
> > > +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> > > +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81,
> > > +0x57, 0x88 }
> > > +  };
> > > +// extern UINT8  BdsDxeStrings[];
> > 
> > No need to keep commented-out code in.
> > 
> > > +
> > > +//
> > > +// BDS Platform Functions
> > > +//
> > > +/**
> > > +
> > > +  Show progress bar with title above it. It only works in Graphics mode.
> > > +
> > > +  @param TitleForeground Foreground color for Title.
> > > +  @param TitleBackground Background color for Title.
> > > +  @param Title           Title above progress bar.
> > > +  @param ProgressColor   Progress bar color.
> > > +  @param Progress        Progress (0-100)
> > > +  @param PreviousValue   The previous value of the progress.
> > > +
> > > +  @retval  EFI_STATUS       Success update the progress bar
> > > +
> > > +**/
> > > +EFI_STATUS
> > > +PlatformBootManagerShowProgress (
> > 
> > I'm not a super fan of how this file integrates a custom memory test with a
> > direct (copy) graphical progress indicator. There are both common memory
> > test and common progress indicators - please use those instead. And
> > improve them if they are currently insufficient for your needs.
> 
> Could you indicate where are those common libraries? Thanks.

There is MdeModulePkg/Library/DisplayUpdateProgressLibGraphics and
MdeModulePkg/Library/DisplayUpdateProgressLibText.

/
    Leif

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2019-10-21 14:51 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-19  3:51 [plaforms/devel-riscv-v2 PATCHv2 00/14] Add SiFive U500 VC707 FPGA Platform Gilbert Chen
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 01/14] Silicon/SiFive: Initial version of SiFive silicon package Gilbert Chen
2019-10-01  0:41   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 02/14] Silicon/SiFive: Add library module of SiFive RISC-V cores Gilbert Chen
2019-10-01 21:14   ` [edk2-devel] " Leif Lindholm
2019-10-16  1:36     ` Abner Chang
2019-10-17 10:33       ` Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 03/14] platforms/RiscV: Initial version of RISC-V platform package Gilbert Chen
2019-10-02  9:07   ` [edk2-devel] " Leif Lindholm
2019-10-15 15:24     ` Abner Chang
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 04/14] RiscV/Include: Initial version of header files in " Gilbert Chen
2019-10-02 16:46   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 05/14] RiscV/Library: Initial version of libraries introduced " Gilbert Chen
2019-10-02 17:04   ` [edk2-devel] " Leif Lindholm
2019-10-15 15:26     ` Abner Chang
2019-10-18  5:23     ` Abner Chang
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 06/14] RiscV/Universal: Initial version of common RISC-V SEC module Gilbert Chen
2019-10-02 19:43   ` [edk2-devel] " Leif Lindholm
2019-10-15 15:27     ` Abner Chang
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 07/14] RiscV/SiFive: Initial version of SiFive U500 platform package Gilbert Chen
2019-10-02 20:16   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 08/14] U500Pkg/Include: Header files of SiFive U500 platform Gilbert Chen
2019-10-02 21:00   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib Gilbert Chen
2019-10-02 22:02   ` [edk2-devel] " Leif Lindholm
2019-10-18  6:23     ` Abner Chang
2019-10-21 14:51       ` Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 10/14] U500Pkg/Library: Library instances of U500 platform library Gilbert Chen
2019-10-03 16:32   ` [edk2-devel] " Leif Lindholm
2019-10-17  2:21     ` Abner Chang
2019-10-17  7:44       ` Abner Chang
2019-10-17 11:19         ` Leif Lindholm
2019-10-17 16:09           ` Abner Chang
2019-10-17 16:38             ` Leif Lindholm
2019-10-18  5:24               ` Abner Chang
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 11/14] U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable Gilbert Chen
2019-10-03 16:58   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 12/14] U500Pkg/TimerDxe: Platform Timer DXE driver Gilbert Chen
2019-10-03 17:30   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 13/14] U500Pkg/PlatformPei: Platform initialization PEIM Gilbert Chen
2019-10-03 17:38   ` [edk2-devel] " Leif Lindholm
2019-09-19  3:51 ` [plaforms/devel-riscv-v2 PATCHv2 14/14] Platforms: Readme file updates Gilbert Chen
2019-10-03 17:45   ` [edk2-devel] " Leif Lindholm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox