Browse Source

platform: add starfive 7110 platform.

The codes are most from sifive fu540.

Signed-off-by: minda.chen <minda.chen@starfivetech.com>
minda.chen 1 year ago
parent
commit
c436c46b8f
47 changed files with 7507 additions and 0 deletions
  1. 30 0
      Platform/StarFive/JH7110SeriesPkg/Include/SiFiveU5MCCoreplex.h
  2. 16 0
      Platform/StarFive/JH7110SeriesPkg/Include/StarFiveUart.h
  3. 20 0
      Platform/StarFive/JH7110SeriesPkg/Include/U5Clint.h
  4. 35 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree.fdf.inc
  5. 28 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/JH7110DeviceTree.inf
  6. 1459 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/jh7110.dtsi
  7. 116 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/jh7110_clk.dtsi
  8. 394 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-clkgen.h
  9. 53 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-isp.h
  10. 66 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-vout.h
  11. 219 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110.h
  12. 147 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive_visionfive2.dts
  13. 25 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.dec
  14. 587 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.dsc
  15. 341 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.fdf
  16. 107 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.fdf.inc
  17. 13 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.uni
  18. 12 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110PkgExtra.uni
  19. 36 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf
  20. 57 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/Library/RiscVSpecialPlatformLib/StarFiveJH7110.c
  21. 78 0
      Platform/StarFive/JH7110SeriesPkg/JH7110Board/VarStore.fdf.inc
  22. 34 0
      Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec
  23. 13 0
      Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.uni
  24. 12 0
      Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkgExtra.uni
  25. 188 0
      Platform/StarFive/JH7110SeriesPkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c
  26. 58 0
      Platform/StarFive/JH7110SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
  27. 148 0
      Platform/StarFive/JH7110SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.c
  28. 43 0
      Platform/StarFive/JH7110SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf
  29. 48 0
      Platform/StarFive/JH7110SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S
  30. 36 0
      Platform/StarFive/JH7110SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
  31. 39 0
      Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/SerialIoLib.inf
  32. 424 0
      Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/SerialPortLib.c
  33. 16 0
      Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni
  34. 129 0
      Platform/StarFive/JH7110SeriesPkg/Readme.md
  35. 127 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c
  36. 84 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
  37. 1117 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c
  38. 187 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h
  39. 150 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c
  40. 145 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c
  41. 85 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h
  42. 20 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c
  43. 311 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/Timer.c
  44. 174 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/Timer.h
  45. 14 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/Timer.uni
  46. 54 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf
  47. 12 0
      Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/TimerExtra.uni

+ 30 - 0
Platform/StarFive/JH7110SeriesPkg/Include/SiFiveU5MCCoreplex.h

@@ -0,0 +1,30 @@
+/** @file
+  SiFive U54 Coreplex library definitions.
+
+  Copyright (c) 2021, 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 <ProcessorSpecificHobData.h>
+
+#define SIFIVE_U5MC_COREPLEX_MC_HART_ID     0
+
+/**
+  Build processor and platform information for the U5 platform
+
+  @return EFI_SUCCESS     Status.
+
+**/
+EFI_STATUS
+BuildRiscVSmbiosHobs (
+  VOID
+);
+
+#endif

+ 16 - 0
Platform/StarFive/JH7110SeriesPkg/Include/StarFiveUart.h

@@ -0,0 +1,16 @@
+/** @file
+  SiFive U5 series UART header file. This is the wrapper file
+  of sifive-uart.h under opensib include/sbi_utils/serial.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef STARFIVE_JH7110_SERIES_UART_H_
+#define STARFIVE_JH7110_SERIES_UART_H_
+
+#include <include/sbi/riscv_io.h>
+#include <include/sbi_utils/serial/sifive-uart.h>
+
+#endif

+ 20 - 0
Platform/StarFive/JH7110SeriesPkg/Include/U5Clint.h

@@ -0,0 +1,20 @@
+/** @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 U5_CLINT_H_
+#define U5_CLINT_H_
+
+#define CLINT_REG_BASE_ADDR 0x02000000
+    #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

+ 35 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree.fdf.inc

@@ -0,0 +1,35 @@
+## @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
+#
+##
+
+$(DTB_OFFSET)|$(DTB_SIZE)
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDtbFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDtbFvSize
+FV = DTBFV
+
+[FV.DTBFV]
+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
+
+INF RuleOverride = DTB Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/JH7110DeviceTree.inf

+ 28 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/JH7110DeviceTree.inf

@@ -0,0 +1,28 @@
+## @file
+#
+#  Device tree description of the Hifive Unleashed platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION    = 0x0001001A
+  BASE_NAME      = JH7110DeviceTree
+  FILE_GUID      = 25462CDA-221F-47DF-AC1D-259CFAA4E326 # gDtPlatformDefaultDtbFileGuid
+  MODULE_TYPE    = USER_DEFINED
+  VERSION_STRING = 1.0
+
+[Sources]
+  starfive-jh7110-clkgen.h
+  starfive-jh7110-isp.h
+  starfive-jh7110-vout.h
+  starfive-jh7110.h
+  starfive_visionfive2.dts
+  jh7110.dtsi
+  jh7110_clk.dtsi
+
+[Packages]
+  MdePkg/MdePkg.dec

+ 1459 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/jh7110.dtsi

@@ -0,0 +1,1459 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+/dts-v1/;
+#include "jh7110_clk.dtsi"
+#include "starfive-jh7110.h"
+#include "starfive-jh7110-clkgen.h"
+#include "starfive-jh7110-vout.h"
+#include "starfive-jh7110-isp.h"
+
+/ {
+	compatible = "starfive,jh7110";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "sifive,u74-mc", "riscv";
+                        /* compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; */
+			reg = <0>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <8192>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <40>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <16384>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <40>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&cachectrl>;
+			riscv,isa = "rv64imacu";
+			tlb-split;
+			status = "disabled";
+
+			cpu0intctrl: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+
+		cpu1: cpu@1 {
+			compatible = "sifive,u74-mc", "riscv";
+                        /* compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; */
+			reg = <1>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <40>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <40>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&cachectrl>;
+			riscv,isa = "rv64imafdcbsux";
+			tlb-split;
+			status = "okay";
+
+			cpu1intctrl: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+
+		cpu2: cpu@2 {
+			compatible = "sifive,u74-mc", "riscv";
+                        /* compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; */
+			reg = <2>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <40>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <40>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&cachectrl>;
+			riscv,isa = "rv64imafdcbsux";
+			tlb-split;
+			status = "okay";
+
+			cpu2intctrl: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+
+		cpu3: cpu@3 {
+			compatible = "sifive,u74-mc", "riscv";
+                        /* compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; */
+			reg = <3>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <40>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <40>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&cachectrl>;
+			riscv,isa = "rv64imafdcbsux";
+			tlb-split;
+			status = "okay";
+
+			cpu3intctrl: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+
+		cpu4: cpu@4 {
+			compatible = "sifive,u74-mc", "riscv";
+                        /* compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; */
+			reg = <4>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <40>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <40>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&cachectrl>;
+			riscv,isa = "rv64imafdcbsux";
+			tlb-split;
+			status = "okay";
+
+			cpu4intctrl: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+	};
+
+	soc: soc {
+		compatible = "simple-bus";
+                /* compatible = "sifive,fu540-c000", "sifive,fu540", "simple-bus"; */
+		interrupt-parent = <&plic>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#clock-cells = <1>;
+		ranges;
+		/*
+		pmu {
+			compatible = "riscv,pmu";
+			riscv,event-to-mhpmcounters = <0x5 0x06 0x18
+						    0x08 0x09 0x18>;
+			riscv,event-to-mhpmevent = <0x05 0x00000000 0x4000
+						0x06 0x00000000 0x4001
+						0x08 0x00000000 0x4008
+						0x09 0x00000000 0x4009>;
+			riscv,raw-event-to-mhpmcounters =
+						<0x00000000 0x100 0xffffffff 0xffffffff 0x18
+						0x00000000 0x200 0xffffffff 0xffffffff 0x18
+						0x00000000 0x400 0xffffffff 0xffffffff 0x18
+						0x00000000 0x800 0xffffffff 0xffffffff 0x18
+						0x00000000 0x1000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x2000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x4000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x8000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x10000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x20000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x40000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x80000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x100000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x200000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x400000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x800000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x1000000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x2000000 0xffffffff 0xffffffff 0x18
+						0x00000000 0x101 0xffffffff 0xffffffff 0x18
+						0x00000000 0x201 0xffffffff 0xffffffff 0x18
+						0x00000000 0x401 0xffffffff 0xffffffff 0x18
+						0x00000000 0x801 0xffffffff 0xffffffff 0x18
+						0x00000000 0x1001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x2001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x4001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x8001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x10001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x20001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x40001 0xffffffff 0xffffffff 0x18
+						0x00000000 0x102 0xffffffff 0xffffffff 0x18
+						0x00000000 0x202 0xffffffff 0xffffffff 0x18
+						0x00000000 0x402 0xffffffff 0xffffffff 0x18
+						0x00000000 0x802 0xffffffff 0xffffffff 0x18
+						0x00000000 0x1002 0xffffffff 0xffffffff 0x18
+						0x00000000 0x2002 0xffffffff 0xffffffff 0x18>;
+		}; */
+
+		cachectrl: cache-controller@2010000 {
+			compatible = "sifive,fu740-c000-ccache", "cache";
+			reg = <0x0 0x2010000 0x0 0x4000 0x0 0x8000000 0x0 0x2000000>;
+			reg-names = "control", "sideband";
+			interrupts = <1 3 4 2>;
+			cache-block-size = <64>;
+			cache-level = <2>;
+			cache-sets = <2048>;
+			cache-size = <2097152>;
+			cache-unified;
+		};
+
+		aon_syscon: aon_syscon@17010000 {
+			compatible = "syscon";
+			reg = <0x0 0x17010000 0x0 0x1000>;
+		};
+
+		stg_syscon: stg_syscon@10240000 {
+			compatible = "syscon";
+			reg = <0x0 0x10240000 0x0 0x1000>;
+		};
+
+		sys_syscon: sys_syscon@13030000 {
+			compatible = "syscon";
+			reg = <0x0 0x13030000 0x0 0x1000>;
+		};
+
+		clint: clint@2000000 {
+			compatible = "riscv,clint0";
+			reg = <0x0 0x2000000 0x0 0x10000>;
+			reg-names = "control";
+			interrupts-extended = <&cpu0intctrl 3 &cpu0intctrl 7
+						&cpu1intctrl 3 &cpu1intctrl 7
+						&cpu2intctrl 3 &cpu2intctrl 7
+						&cpu3intctrl 3 &cpu3intctrl 7
+						&cpu4intctrl 3 &cpu4intctrl 7>;
+			#interrupt-cells = <1>;
+		};
+
+		plic: plic@c000000 {
+			compatible = "riscv,plic0";
+			reg = <0x0 0xc000000 0x0 0x4000000>;
+			reg-names = "control";
+			interrupts-extended = <&cpu0intctrl 11
+						&cpu1intctrl 11 &cpu1intctrl 9
+						&cpu2intctrl 11 &cpu2intctrl 9
+						&cpu3intctrl 11 &cpu3intctrl 9
+						&cpu4intctrl 11 &cpu4intctrl 9>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			riscv,max-priority = <7>;
+			riscv,ndev = <136>;
+		};
+
+		clkgen: clock-controller {
+			compatible = "starfive,jh7110-clkgen";
+			reg = <0x0 0x13020000 0x0 0x10000>,
+				<0x0 0x10230000 0x0 0x10000>,
+				<0x0 0x17000000 0x0 0x10000>;
+			reg-names = "sys", "stg", "aon";
+			clocks = <&osc>, <&gmac1_rmii_refin>,
+				 <&gmac1_rgmii_rxin>,
+				 <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
+				 <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
+				 <&tdm_ext>, <&mclk_ext>,
+				 <&jtag_tck_inner>, <&bist_apb>,
+				 <&stg_apb>, <&clk_rtc>,
+				 <&gmac0_rmii_refin>, <&gmac0_rgmii_rxin>;
+			clock-names = "osc", "gmac1_rmii_refin",
+				"gmac1_rgmii_rxin",
+				"i2stx_bclk_ext", "i2stx_lrck_ext",
+				"i2srx_bclk_ext", "i2srx_lrck_ext",
+				"tdm_ext", "mclk_ext",
+				"jtag_tck_inner", "bist_apb",
+				"stg_apb", "clk_rtc",
+				"gmac0_rmii_refin", "gmac0_rgmii_rxin";
+			#clock-cells = <1>;
+			status = "okay";
+		};
+
+		clkvout: clock-controller@295C0000 {
+			compatible = "starfive,jh7110-clk-vout";
+			reg = <0x0 0x295C0000 0x0 0x10000>;
+			reg-names = "vout";
+			clocks = <&hdmitx0_pixelclk>,
+				 <&mipitx_dphy_rxesc>,
+				 <&mipitx_dphy_txbytehs>;
+			clock-names = "hdmitx0_pixelclk",
+				"mipitx_dphy_rxesc",
+				"mipitx_dphy_txbytehs";
+			#clock-cells = <1>;
+			status = "okay";
+		};
+
+		clkisp: clock-controller@19810000 {
+			compatible = "starfive,jh7110-clk-isp";
+			reg = <0x0 0x19810000 0x0 0x10000>;
+			reg-names = "isp";
+			#clock-cells = <1>;
+			clocks = <&clkgen JH7110_ISP_TOP_CLK_DVP>,
+				 <&clkgen JH7110_ISP_TOP_CLK_ISPCORE_2X>,
+				 <&clkgen JH7110_ISP_TOP_CLK_ISP_AXI>;
+			clock-names = "u0_dom_isp_top_clk_dom_isp_top_clk_dvp",
+				      "u0_dom_isp_top_clk_dom_isp_top_clk_ispcore_2x",
+				      "u0_dom_isp_top_clk_dom_isp_top_clk_isp_axi";
+			resets = <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
+				 <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>;
+			reset-names = "rst_isp_top_n", "rst_isp_top_axi";
+			status = "disabled";
+		};
+
+		qspi: spi@13010000 {
+			compatible = "cdns,qspi-nor";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0 0x13010000 0x0 0x10000
+				0x0 0x21000000 0x0 0x400000>;
+			clocks = <&clkgen JH7110_QSPI_CLK_REF>;
+			clock-names = "clk_ref";
+			resets = <&rstgen RSTN_U0_CDNS_QSPI_APB>,
+				 <&rstgen RSTN_U0_CDNS_QSPI_AHB>,
+				 <&rstgen RSTN_U0_CDNS_QSPI_REF>;
+			resets-names = "rst_apb", "rst_ahb", "rst_ref";
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			spi-max-frequency = <250000000>;
+
+			nor_flash: nor-flash@0 {
+				compatible = "jedec,spi-nor";
+				reg=<0>;
+				spi-max-frequency = <100000000>;
+				cdns,tshsl-ns = <1>;
+				cdns,tsd2d-ns = <1>;
+				cdns,tchsh-ns = <1>;
+				cdns,tslch-ns = <1>;
+			};
+		};
+
+		otp: otp@17050000 {
+			compatible = "starfive,jh7110-otp";
+			reg = <0x0 0x17050000 0x0 0x10000>;
+			clock-frequency = <4000000>;
+			clocks = <&clkgen JH7110_OTPC_CLK_APB>;
+			clock-names = "apb";
+		};
+
+		usbdrd30: usbdrd{
+			compatible = "starfive,jh7110-cdns3";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			clocks = <&clkgen JH7110_USB0_CLK_APP_125>,
+				 <&clkgen JH7110_USB0_CLK_LPM>,
+				 <&clkgen JH7110_USB0_CLK_STB>,
+				 <&clkgen JH7110_USB0_CLK_USB_APB>,
+				 <&clkgen JH7110_USB0_CLK_AXI>,
+				 <&clkgen JH7110_USB0_CLK_UTMI_APB>;
+			clock-names = "app","lpm","stb","apb","axi","utmi";
+			resets = <&rstgen RSTN_U0_CDN_USB_PWRUP>,
+				 <&rstgen RSTN_U0_CDN_USB_APB>,
+				 <&rstgen RSTN_U0_CDN_USB_AXI>,
+				 <&rstgen RSTN_U0_CDN_USB_UTMI_APB>;
+			reset-names = "pwrup","apb","axi","utmi";
+			starfive,stg-syscon = <&stg_syscon 0x4>;
+			starfive,sys-syscon = <&sys_syscon 0x18>;
+			status = "disabled";
+
+			usbdrd_cdns3: usb@10100000 {
+				compatible = "cdns,usb3";
+				reg = <0x0 0x10100000 0x0 0x10000>,
+				      <0x0 0x10110000 0x0 0x10000>,
+				      <0x0 0x10120000 0x0 0x10000>;
+				reg-names = "otg", "xhci", "dev";
+				interrupts = <108>, <109>, <110>;
+				interrupt-names = "host", "peripheral", "otg";
+				phy-names = "cdns3,usb3-phy", "cnds3,usb2-phy";
+				maximum-speed = "super-speed";
+			};
+		};
+
+		timer: timer@13050000 {
+			compatible = "starfive,si5-timers";
+			reg = <0x0 0x13050000 0x0 0x10000>;
+			interrupts = <69>, <70>, <71> ,<72>;
+			interrupt-names = "timer0", "timer1",
+					  "timer2", "timer3";
+			clocks = <&clkgen JH7110_TIMER_CLK_TIMER0>,
+				 <&clkgen JH7110_TIMER_CLK_TIMER1>,
+				 <&clkgen JH7110_TIMER_CLK_TIMER2>,
+				 <&clkgen JH7110_TIMER_CLK_TIMER3>,
+				 <&clkgen JH7110_TIMER_CLK_APB>;
+			clock-names = "timer0", "timer1",
+				      "timer2", "timer3", "apb_clk";
+			clock-frequency = <2000000>;
+			status = "okay";
+		};
+
+		wdog: wdog@13070000 {
+			compatible = "starfive,dskit-wdt";
+			reg = <0x0 0x13070000 0x0 0x10000>;
+			interrupts = <68>;
+			interrupt-names = "wdog";
+			clock-frequency = <2000000>;
+			clocks = <&clkgen JH7110_DSKIT_WDT_CLK_WDT>,
+				 <&clkgen JH7110_DSKIT_WDT_CLK_APB>;
+			clock-names = "core_clk", "apb_clk";
+			resets = <&rstgen RSTN_U0_DSKIT_WDT_APB>,
+				 <&rstgen RSTN_U0_DSKIT_WDT_CORE>;
+			reset-names = "rst_apb", "rst_core";
+			timeout-sec = <15>;
+			status = "okay";
+		};
+
+		rtc: rtc@17040000 {
+			compatible = "starfive,rtc_hms";
+			reg = <0x0 0x17040000 0x0 0x10000>;
+			interrupts = <10>, <11>, <12>;
+			interrupt-names = "rtc_ms_pulse", "rtc_sec_pulse", "rtc";
+			clocks = <&clkgen JH7110_RTC_HMS_CLK_APB>,
+				 <&clkgen JH7110_RTC_HMS_CLK_CAL>;
+			clock-names = "pclk", "cal_clk";
+			resets = <&rstgen RSTN_U0_RTC_HMS_APB>,
+				 <&rstgen RSTN_U0_RTC_HMS_CAL>,
+				 <&rstgen RSTN_U0_RTC_HMS_OSC32K>;
+			reset-names = "rst_apb", "rst_cal", "rst_osc";
+			rtc,cal-clock-freq = <1000000>;
+			status = "okay";
+		};
+
+		pmu: pmu@17030000 {
+			compatible = "starfive,jh7110-pmu";
+			reg = <0x0 0x17030000 0x0 0x10000>;
+			interrupts = <111>;
+			status = "okay";
+		};
+
+		uart0: serial@10000000 {
+			compatible = "snps,dw-apb-uart";
+                        /* compatible = "sifive,fu540-c000-uart", "sifive,uart0"; */
+			reg = <0x0 0x10000000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART0_CLK_CORE>,
+				 <&clkgen JH7110_UART0_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U0_DW_UART_APB>,
+				<&rstgen RSTN_U0_DW_UART_CORE>;
+			interrupts = <32>;
+			status = "disabled";
+		};
+
+		uart1: serial@10010000 {
+			compatible = "snps,dw-apb-uart";
+                        /* compatible = "sifive,fu540-c000-uart", "sifive,uart0"; */
+			reg = <0x0 0x10010000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART1_CLK_CORE>,
+				 <&clkgen JH7110_UART1_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U1_DW_UART_APB>,
+				<&rstgen RSTN_U1_DW_UART_CORE>;
+			interrupts = <33>;
+			status = "disabled";
+		};
+
+		uart2: serial@10020000 {
+			compatible = "snps,dw-apb-uart";
+                        /* compatible = "sifive,fu540-c000-uart", "sifive,uart0"; */
+			reg = <0x0 0x10020000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART2_CLK_CORE>,
+				 <&clkgen JH7110_UART2_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U2_DW_UART_APB>,
+				<&rstgen RSTN_U2_DW_UART_CORE>;
+			interrupts = <34>;
+			status = "disabled";
+		};
+
+		uart3: serial@12000000 {
+			compatible = "snps,dw-apb-uart";
+                        //compatible = "sifive,fu540-c000-uart", "sifive,uart0";
+			reg = <0x0 0x12000000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART3_CLK_CORE>,
+				 <&clkgen JH7110_UART3_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U3_DW_UART_APB>,
+				<&rstgen RSTN_U3_DW_UART_CORE>;
+			interrupts = <45>;
+			status = "disabled";
+		};
+
+		uart4: serial@12010000 {
+			compatible = "snps,dw-apb-uart";
+                        //compatible = "sifive,fu540-c000-uart", "sifive,uart0";
+			reg = <0x0 0x12010000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART4_CLK_CORE>,
+				 <&clkgen JH7110_UART4_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U4_DW_UART_APB>,
+				<&rstgen RSTN_U4_DW_UART_CORE>;
+			interrupts = <46>;
+			status = "disabled";
+		};
+
+		uart5: serial@12020000 {
+			compatible = "snps,dw-apb-uart";
+                        //compatible = "sifive,fu540-c000-uart", "sifive,uart0";
+			reg = <0x0 0x12020000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&clkgen JH7110_UART5_CLK_CORE>,
+				 <&clkgen JH7110_UART5_CLK_APB>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&rstgen RSTN_U5_DW_UART_APB>,
+				<&rstgen RSTN_U5_DW_UART_CORE>;
+			interrupts = <47>;
+			status = "disabled";
+		};
+
+		dma: dma-controller@16050000 {
+			compatible = "starfive,axi-dma";
+			reg = <0x0 0x16050000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_DMA1P_CLK_AXI>,
+				 <&clkgen JH7110_DMA1P_CLK_AHB>;
+			clock-names = "core-clk", "cfgr-clk";
+			resets = <&rstgen RSTN_U0_DW_DMA1P_AXI>,
+				 <&rstgen RSTN_U0_DW_DMA1P_AHB>;
+			reset-names = "rst_axi", "rst_ahb";
+			interrupts = <73>;
+			#dma-cells = <2>;
+			dma-channels = <4>;
+			snps,dma-masters = <1>;
+			snps,data-width = <3>;
+			snps,num-hs-if = <56>;
+			snps,block-size = <65536 65536 65536 65536>;
+			nps,priority = <0 1 2 3>;
+			snps,axi-max-burst-len = <16>;
+			status = "disabled";
+		};
+
+		gpio: gpio@13040000 {
+			compatible = "starfive_jh7110-sys-pinctrl";
+			reg = <0x0 0x13040000 0x0 0x10000>;
+			reg-names = "control";
+			interrupts = <91>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			ngpios = <64>;
+			status = "okay";
+		};
+
+		gpioa: gpio@17020000 {
+			compatible = "starfive_jh7110-aon-pinctrl";
+			reg = <0x0 0x17020000 0x0 0x10000>;
+			reg-names = "control";
+			interrupts = <90>;
+			interrupt-controller;
+			#gpio-cells = <2>;
+			ngpios = <4>;
+			status = "okay";
+		};
+
+		trng: trng@1600C000 {
+			compatible = "starfive,trng";
+			reg = <0x0 0x1600C000 0x0 0x4000>;
+			clocks = <&clkgen JH7110_SEC_HCLK>,
+				 <&clkgen JH7110_SEC_MISCAHB_CLK>;
+			clock-names = "hclk", "miscahb_clk";
+			resets = <&rstgen RSTN_U0_SEC_TOP_HRESETN>;
+			interrupts = <30>;
+			status = "disabled";
+		};
+
+		sec_dma: sec_dma@16008000 {
+			/*compatible = "arm,pl080", "arm,primecell";*/
+			compatible = "starfive,pl080";
+			reg = <0x0 0x16008000 0x0 0x4000>;
+			reg-names = "sec_dma";
+			interrupts = <29>;
+			clocks = <&clkgen JH7110_SEC_HCLK>,
+				 <&clkgen JH7110_SEC_MISCAHB_CLK>;
+			clock-names = "sec_hclk","sec_ahb";
+			resets = <&rstgen RSTN_U0_SEC_TOP_HRESETN>;
+			reset-names = "sec_hre";
+			lli-bus-interface-ahb1;
+			mem-bus-interface-ahb1;
+			memcpy-burst-size = <256>;
+			memcpy-bus-width = <32>;
+			#dma-cells = <2>;
+			status = "disabled";
+		};
+
+		crypto: crypto@16000000 {
+			compatible = "starfive,jh7110-sec";
+			reg = <0x0 0x16000000 0x0 0x4000>,
+			      <0x0 0x16008000 0x0 0x4000>;
+			reg-names = "secreg","secdma";
+			interrupts = <28>, <29>;
+			interrupt-names = "secirq", "dmairq";
+			clocks = <&clkgen JH7110_SEC_HCLK>,
+				 <&clkgen JH7110_SEC_MISCAHB_CLK>;
+			clock-names = "sec_hclk","sec_ahb";
+			resets = <&rstgen RSTN_U0_SEC_TOP_HRESETN>;
+			reset-names = "sec_hre";
+			enable-dma = "true";
+			dmas = <&sec_dma 1 2>,
+			       <&sec_dma 0 2>;
+			dma-names = "sec_m","sec_p";
+			status = "disabled";
+		};
+
+		i2c6: i2c@12060000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x12060000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_I2C6_CLK_CORE>,
+				 <&clkgen JH7110_I2C6_CLK_APB>;
+			clock-names = "ref", "pclk";
+			resets = <&rstgen RSTN_U6_DW_I2C_APB>;
+			interrupts = <51>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c0: i2c@10030000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x10030000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_I2C0_CLK_CORE>,
+				 <&clkgen JH7110_I2C0_CLK_APB>;
+			clock-names = "ref", "pclk";
+			resets = <&rstgen RSTN_U0_DW_I2C_APB>;
+			interrupts = <35>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@10040000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x10040000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_I2C1_CLK_CORE>,
+				 <&clkgen JH7110_I2C1_CLK_APB>;
+			clock-names = "ref", "pclk";
+			resets = <&rstgen RSTN_U1_DW_I2C_APB>;
+			interrupts = <36>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@12050000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x12050000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_I2C5_CLK_CORE>,
+				 <&clkgen JH7110_I2C5_CLK_APB>;
+			clock-names = "ref", "pclk";
+			resets = <&rstgen RSTN_U5_DW_I2C_APB>;
+			interrupts = <50>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		/* unremovable emmc as mmcblk0 */
+		sdio0: sdio0@16010000 {
+			compatible = "snps,dw-mshc";
+			reg = <0x0 0x16010000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_SDIO0_CLK_AHB>,
+				 <&clkgen JH7110_SDIO0_CLK_SDCARD>;
+			clock-names = "biu","ciu";
+			resets = <&rstgen RSTN_U0_DW_SDIO_AHB>;
+			reset-names = "reset";
+		};
+
+		sdio1: sdio1@16020000 {
+			compatible = "snps,dw-mshc";
+			reg = <0x0 0x16020000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_SDIO1_CLK_AHB>,
+				 <&clkgen JH7110_SDIO1_CLK_SDCARD>;
+			clock-names = "biu","ciu";
+			resets = <&rstgen RSTN_U1_DW_SDIO_AHB>;
+			reset-names = "reset";
+		};
+
+		vin_sysctl: vin_sysctl@19800000 {
+			compatible = "starfive,stf-vin";
+			reg = <0x0 0x19800000 0x0 0x10000>,
+				<0x0 0x19810000 0x0 0x10000>,
+				<0x0 0x19820000 0x0 0x10000>,
+				<0x0 0x19830000 0x0 0x10000>,
+				<0x0 0x19840000 0x0 0x10000>,
+				<0x0 0x19870000 0x0 0x30000>,
+				<0x0 0x198a0000 0x0 0x30000>,
+				<0x0 0x11840000 0x0 0x10000>,
+				<0x0 0x17030000 0x0 0x10000>,
+				<0x0 0x13020000 0x0 0x10000>;
+			reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl",
+				"isp0", "isp1", "trst", "pmu", "syscrg";
+			clocks = <&clkisp JH7110_DOM4_APB_FUNC>,
+				 <&clkisp JH7110_U0_VIN_PCLK>,
+				 <&clkisp JH7110_U0_VIN_SYS_CLK>,
+				 <&clkisp JH7110_U0_ISPV2_TOP_WRAPPER_CLK_C>,
+				 <&clkisp JH7110_DVP_INV>,
+				 <&clkisp JH7110_U0_VIN_CLK_P_AXIWR>,
+				 <&clkisp JH7110_MIPI_RX0_PXL>,
+				 <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF0>,
+				 <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF1>,
+				 <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF2>,
+				 <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF3>;
+			clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
+				"clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
+				"clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
+				"clk_pixel_clk_if1", "clk_pixel_clk_if2",
+				"clk_pixel_clk_if3";
+			resets = <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
+				 <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_C>,
+				 <&rstgen RSTN_U0_VIN_N_PCLK>,
+				 <&rstgen RSTN_U0_VIN_N_SYS_CLK>,
+				 <&rstgen RSTN_U0_VIN_P_AXIRD>,
+				 <&rstgen RSTN_U0_VIN_P_AXIWR>,
+				 <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF0>,
+				 <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF1>,
+				 <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF2>,
+				 <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF3>,
+				 <&rstgen RSTN_U0_M31DPHY_HW>,
+				 <&rstgen RSTN_U0_M31DPHY_B09_ALWAYS_ON>;
+			reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
+				"rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
+				"rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
+				"rst_m31dphy_hw", "rst_m31dphy_b09_always_on";
+			interrupts = <92 87 86>;
+			status = "disabled";
+		};
+
+		jpu: jpu@11900000 {
+			compatible = "starfive,jpu";
+			reg = <0x0 0x13090000 0x0 0x300>;
+			interrupts = <14>;
+			clocks = <&clkgen JH7110_CODAJ12_CLK_AXI>,
+				 <&clkgen JH7110_CODAJ12_CLK_CORE>,
+				 <&clkgen JH7110_CODAJ12_CLK_APB>;
+			clock-names = "axi_clk", "core_clk", "apb_clk";
+			resets = <&rstgen RSTN_U0_CODAJ12_AXI>,
+				 <&rstgen RSTN_U0_CODAJ12_CORE>,
+				 <&rstgen RSTN_U0_CODAJ12_APB>;
+			reset-names = "rst_axi", "rst_core", "rst_apb";
+			status = "disabled";
+		};
+
+		vpu_dec: vpu_dec@130A0000 {
+			compatible = "starfive,vdec";
+			reg = <0x0 0x130A0000 0x0 0x10000>;
+			interrupts = <13>;
+			clocks = <&clkgen JH7110_WAVE511_CLK_AXI>,
+				 <&clkgen JH7110_WAVE511_CLK_BPU>,
+				 <&clkgen JH7110_WAVE511_CLK_VCE>,
+				 <&clkgen JH7110_WAVE511_CLK_APB>,
+				 <&clkgen JH7110_NOC_BUS_CLK_VDEC_AXI>;
+			clock-names = "axi_clk",
+				"bpu_clk",
+				"vce_clk",
+				"apb_clk",
+				"noc_bus";
+			resets = <&rstgen RSTN_U0_WAVE511_AXI>,
+				<&rstgen RSTN_U0_WAVE511_BPU>,
+				<&rstgen RSTN_U0_WAVE511_VCE>,
+				<&rstgen RSTN_U0_WAVE511_APB>,
+				<&rstgen RSTN_U0_AXIMEM_128B_AXI>;
+			reset-names = "rst_axi",
+				"rst_bpu",
+				"rst_vce",
+				"rst_apb",
+				"rst_sram";
+			starfive,vdec_noc_ctrl;
+			status = "disabled";
+		};
+
+		vpu_enc: vpu_enc@130B0000 {
+			compatible = "starfive,venc";
+			reg = <0x0 0x130B0000 0x0 0x10000>;
+			interrupts = <15>;
+			clocks = <&clkgen JH7110_WAVE420L_CLK_AXI>,
+				 <&clkgen JH7110_WAVE420L_CLK_BPU>,
+				 <&clkgen JH7110_WAVE420L_CLK_VCE>,
+				 <&clkgen JH7110_WAVE420L_CLK_APB>,
+				 <&clkgen JH7110_NOC_BUS_CLK_VENC_AXI>;
+			clock-names = "axi_clk",
+				"bpu_clk",
+				"vce_clk",
+				"apb_clk",
+				"noc_bus";
+			resets = <&rstgen RSTN_U0_WAVE420L_AXI>,
+				 <&rstgen RSTN_U0_WAVE420L_BPU>,
+				 <&rstgen RSTN_U0_WAVE420L_VCE>,
+				 <&rstgen RSTN_U0_WAVE420L_APB>,
+				 <&rstgen RSTN_U1_AXIMEM_128B_AXI>;
+			reset-names = "rst_axi",
+				"rst_bpu",
+				"rst_vce",
+				"rst_apb",
+				"rst_sram";
+			starfive,venc_noc_ctrl;
+			status = "disabled";
+		};
+
+		rstgen: reset-controller {
+			compatible = "starfive,jh7110-reset";
+			reg = <0x0 0x13020000 0x0 0x10000>,
+				<0x0 0x10230000 0x0 0x10000>,
+				<0x0 0x17000000 0x0 0x10000>,
+				<0x0 0x19810000 0x0 0x10000>,
+				<0x0 0x295C0000 0x0 0x10000>;
+			reg-names = "syscrg", "stgcrg", "aoncrg", "ispcrg", "voutcrg";
+			#reset-cells = <1>;
+			status = "okay";
+		};
+
+		stmmac_axi_setup: stmmac-axi-config {
+			snps,wr_osr_lmt = <0xf>;
+			snps,rd_osr_lmt = <0xf>;
+			snps,blen = <256 128 64 32 0 0 0>;
+		};
+
+		gmac0: ethernet@16030000 {
+			compatible = "starfive,jh7110-eqos-5.20";
+			reg = <0x0 0x16030000 0x0 0x10000>;
+			clock-names = "gtx",
+				"tx",
+				"ptp_ref",
+				"stmmaceth",
+				"pclk",
+				"gtxc",
+				"rmii_rtx";
+			clocks = <&clkgen JH7110_GMAC0_GTXCLK>,
+				 <&clkgen JH7110_U0_GMAC5_CLK_TX>,
+				 <&clkgen JH7110_GMAC0_PTP>,
+				 <&clkgen JH7110_U0_GMAC5_CLK_AHB>,
+				 <&clkgen JH7110_U0_GMAC5_CLK_AXI>,
+				 <&clkgen JH7110_GMAC0_GTXC>,
+				 <&clkgen JH7110_GMAC0_RMII_RTX>;
+			resets = <&rstgen RSTN_U0_DW_GMAC5_AXI64_AHB>,
+				 <&rstgen RSTN_U0_DW_GMAC5_AXI64_AXI>;
+			reset-names = "ahb", "stmmaceth";
+			interrupts = <7>, <6>, <5> ;
+			interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+			max-frame-size = <9000>;
+			phy-mode = "rgmii-id";
+			snps,multicast-filter-bins = <256>;
+			snps,perfect-filter-entries = <128>;
+			rx-fifo-depth = <262144>;
+			tx-fifo-depth = <131072>;
+			snps,fixed-burst;
+			snps,no-pbl-x8;
+			snps,force_thresh_dma_mode;
+			snps,axi-config = <&stmmac_axi_setup>;
+			snps,tso;
+			snps,en-tx-lpi-clockgating;
+			snps,en-lpi;
+			snps,write-requests = <2>;
+			snps,read-requests = <16>;
+			snps,burst-map = <0x7>;
+			snps,txpbl = <16>;
+			snps,rxpbl = <16>;
+			status = "disabled";
+		};
+
+		gmac1: ethernet@16040000 {
+			compatible = "starfive,jh7110-eqos-5.20";
+			reg = <0x0 0x16040000 0x0 0x10000>;
+			clock-names = "gtx",
+				"tx",
+				"ptp_ref",
+				"stmmaceth",
+				"pclk",
+				"gtxc",
+				"rmii_rtx";
+			clocks = <&clkgen JH7110_GMAC1_GTXCLK>,
+				 <&clkgen JH7110_GMAC5_CLK_TX>,
+				 <&clkgen JH7110_GMAC5_CLK_PTP>,
+				 <&clkgen JH7110_GMAC5_CLK_AHB>,
+				 <&clkgen JH7110_GMAC5_CLK_AXI>,
+				 <&clkgen JH7110_GMAC1_GTXC>,
+				 <&clkgen JH7110_GMAC1_RMII_RTX>;
+			resets = <&rstgen RSTN_U1_DW_GMAC5_AXI64_H_N>,
+				 <&rstgen RSTN_U1_DW_GMAC5_AXI64_A_I>;
+			reset-names = "ahb", "stmmaceth";
+			interrupts = <78>, <77>, <76> ;
+			interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+			max-frame-size = <9000>;
+			phy-mode = "rgmii-id";
+			snps,multicast-filter-bins = <256>;
+			snps,perfect-filter-entries = <128>;
+			rx-fifo-depth = <262144>;
+			tx-fifo-depth = <131072>;
+			snps,fixed-burst;
+			snps,no-pbl-x8;
+			snps,force_thresh_dma_mode;
+			snps,axi-config = <&stmmac_axi_setup>;
+			snps,tso;
+			snps,en-tx-lpi-clockgating;
+			snps,en-lpi;
+			snps,write-requests = <2>;
+			snps,read-requests = <16>;
+			snps,burst-map = <0x7>;
+			snps,txpbl = <16>;
+			snps,rxpbl = <16>;
+			status = "disabled";
+		};
+
+		gpu: gpu@18000000 {
+			compatible = "img-gpu";
+			reg = <0x0 0x18000000 0x0 0x100000>,
+				<0x0 0x130C000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_GPU_CLK_APB>,
+				<&clkgen JH7110_GPU_RTC_TOGGLE>,
+				<&clkgen JH7110_GPU_CORE_CLK>,
+				<&clkgen JH7110_GPU_SYS_CLK>,
+				<&clkgen JH7110_NOC_BUS_CLK_GPU_AXI>;
+			clock-names = "clk_apb", "clk_rtc",
+				"clk_core", "clk_sys",
+				"clk_axi";
+			resets = <&rstgen RSTN_U0_IMG_GPU_APB>,
+				 <&rstgen RSTN_U0_IMG_GPU_DOMA>;
+			reset-names = "rst_apb", "rst_doma";
+			interrupts = <82>;
+			current-clock = <8000000>;
+			status = "disabled";
+		};
+
+		can0: can@130d0000 {
+			compatible = "ipms,can";
+			reg = <0x0 0x130d0000 0x0 0x1000>;
+			interrupts = <112>;
+			clocks = <&clkgen JH7110_CAN0_CTRL_CLK_APB>,
+				 <&clkgen JH7110_CAN0_CTRL_CLK_CAN>,
+				 <&clkgen JH7110_CAN0_CTRL_CLK_TIMER>;
+			clock-names = "apb_clk", "core_clk", "timer_clk";
+			resets = <&rstgen RSTN_U0_CAN_CTRL_APB>,
+				 <&rstgen RSTN_U0_CAN_CTRL_CORE>,
+				 <&rstgen RSTN_U0_CAN_CTRL_TIMER>;
+			reset-names = "rst_apb", "rst_core", "rst_timer";
+			starfive,sys-syscon = <&sys_syscon 0x10 0x3 0x8>;
+			syscon,can_or_canfd = <0>;
+			status = "disabled";
+		};
+
+		can1: can@130e0000 {
+			compatible = "ipms,can";
+			reg = <0x0 0x130e0000 0x0 0x1000>;
+			interrupts = <113>;
+			clocks = <&clkgen JH7110_CAN1_CTRL_CLK_APB>,
+				 <&clkgen JH7110_CAN1_CTRL_CLK_CAN>,
+				 <&clkgen JH7110_CAN1_CTRL_CLK_TIMER>;
+			clock-names = "apb_clk", "core_clk", "timer_clk";
+			resets = <&rstgen RSTN_U1_CAN_CTRL_APB>,
+				 <&rstgen RSTN_U1_CAN_CTRL_CORE>,
+				 <&rstgen RSTN_U1_CAN_CTRL_TIMER>;
+			reset-names = "rst_apb", "rst_core", "rst_timer";
+			starfive,sys-syscon = <&sys_syscon 0x88 0x12 0x40000>;
+			syscon,can_or_canfd = <0>;
+			status = "disabled";
+		};
+
+		tdm: tdm@10090000 {
+			compatible = "starfive,sf-tdm";
+			reg = <0x0 0x10090000 0x0 0x1000>;
+			reg-names = "tdm";
+			clocks = <&clkgen JH7110_AHB0>,
+				 <&clkgen JH7110_TDM_CLK_AHB>,
+				 <&clkgen JH7110_APB0>,
+				 <&clkgen JH7110_TDM_CLK_APB>,
+				 <&clkgen JH7110_TDM_INTERNAL>;
+			clock-names = "clk_ahb0", "clk_tdm_ahb",
+				      "clk_apb0", "clk_tdm_apb",
+				      "clk_tdm_intl";
+			resets = <&rstgen RSTN_U0_TDM16SLOT_AHB>,
+				 <&rstgen RSTN_U0_TDM16SLOT_APB>,
+				 <&rstgen RSTN_U0_TDM16SLOT_TDM>;
+			reset-names = "tdm_ahb", "tdm_apb", "tdm_rst";
+			dmas = <&dma 20 1>, <&dma 21 1>;
+			dma-names = "rx","tx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		spdif0: spdif0@100a0000 {
+			compatible = "starfive,sf-spdif";
+			reg = <0x0 0x100a0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_SPDIF_CLK_APB>,
+				 <&clkgen JH7110_SPDIF_CLK_CORE>,
+				 <&clkgen JH7110_MCLK>;
+			clock-names = "spdif-apb", "spdif-core", "audioclk";
+			resets = <&rstgen RSTN_U0_CDNS_SPDIF_APB>;
+			reset-names = "rst_apb";
+			interrupts = <84>;
+			interrupt-names = "tx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		pwmdac: pwmdac@100b0000 {
+			compatible = "starfive,pwmdac";
+			reg = <0x0 0x100b0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_APB0>,
+				 <&clkgen JH7110_PWMDAC_CLK_APB>,
+				 <&clkgen JH7110_PWMDAC_CLK_CORE>;
+			clock-names = "apb0", "pwmdac-apb", "pwmdac-core";
+			resets = <&rstgen RSTN_U0_PWMDAC_APB>;
+			reset-names = "rst-apb";
+			dmas = <&dma 22 1>;
+			dma-names = "tx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		i2stx: i2stx@100c0000 {
+			compatible = "snps,designware-i2stx";
+			reg = <0x0 0x100c0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_APB0>;
+			clock-names = "i2sclk";
+			interrupt-names = "tx";
+			#sound-dai-cells = <0>;
+			dmas = <&dma 28 1>;
+			dma-names = "rx";
+			status = "disabled";
+		};
+
+		pdm: pdm@100d0000 {
+			compatible = "starfive,sf-pdm";
+			reg = <0x0 0x100d0000 0x0 0x1000>;
+			reg-names = "pdm";
+			clocks = <&clkgen JH7110_PDM_CLK_DMIC>,
+				 <&clkgen JH7110_APB0>,
+				 <&clkgen JH7110_PDM_CLK_APB>,
+				 <&clkgen JH7110_PDM_CLK_DMIC0_BCLK_SLV>,
+				 <&clkgen JH7110_PDM_CLK_DMIC0_LRCK_SLV>,
+				 <&clkgen JH7110_PDM_CLK_DMIC1_BCLK_SLV>,
+				 <&clkgen JH7110_PDM_CLK_DMIC1_LRCK_SLV>,
+				 <&clkgen JH7110_I2SRX0_3CH_BCLK>;
+			clock-names = "pdm_dmic", "clk_apb0", "pdm_apb",
+					"pdm_dmic0_bclk", "pdm_dmic0_lrck",
+					"pdm_dmic1_bclk", "pdm_dmic1_lrck",
+					"u0_i2srx_3ch_bclk";
+			resets = <&rstgen RSTN_U0_PDM_4MIC_DMIC>,
+				 <&rstgen RSTN_U0_PDM_4MIC_APB>;
+			reset-names = "pdm_dmic", "pdm_apb";
+			#sound-dai-cells = <0>;
+		};
+
+		i2srx_3ch: i2srx_3ch@100e0000 {
+			compatible = "snps,designware-i2srx";
+			reg = <0x0 0x100e0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_APB0>,
+				 <&clkgen JH7110_I2SRX0_3CH_CLK_APB>,
+				 <&clkgen JH7110_I2SRX_3CH_BCLK_MST>;
+			clock-names = "apb0", "3ch-apb",
+					"3ch-bclk";
+			resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>,
+				 <&rstgen RSTN_U0_I2SRX_3CH_BCLK>;
+			reset-names = "rst_apb_rx", "rst_bclk_rx";
+			interrupts = <42>;
+			interrupt-names = "rx";
+			dmas = <&dma 24 1>;
+			dma-names = "rx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		i2stx_4ch0: i2stx_4ch0@120b0000 {
+			compatible = "snps,designware-i2stx-4ch0";
+			reg = <0x0 0x120b0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_MCLK_INNER>,
+				 <&clkgen JH7110_I2STX_4CH0_BCLK_MST>,
+				 <&clkgen JH7110_I2STX_4CH0_LRCK_MST>,
+				 <&clkgen JH7110_MCLK>,
+				 <&clkgen JH7110_I2STX0_4CHBCLK>,
+				 <&clkgen JH7110_I2STX0_4CHLRCK>;
+			clock-names = "inner", "bclk-mst",
+					"lrck-mst", "mclk",
+					"bclk0", "lrck0";
+			resets = <&rstgen RSTN_U0_I2STX_4CH_APB>,
+				 <&rstgen RSTN_U0_I2STX_4CH_BCLK>;
+			reset-names = "rst_apb0", "rst_bclk0";
+			interrupts = <58>;
+			interrupt-names = "tx";
+			dmas = <&dma 47 1>;
+			dma-names = "tx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		i2stx_4ch1: i2stx_4ch1@120c0000 {
+			compatible = "snps,designware-i2stx-4ch1";
+			reg = <0x0 0x120c0000 0x0 0x1000>;
+			clocks = <&clkgen JH7110_MCLK_INNER>,
+				 <&clkgen JH7110_I2STX_4CH1_BCLK_MST>,
+				 <&clkgen JH7110_I2STX_4CH1_LRCK_MST>,
+				 <&clkgen JH7110_MCLK>,
+				 <&clkgen JH7110_I2STX1_4CHBCLK>,
+				 <&clkgen JH7110_I2STX1_4CHLRCK>;
+			clock-names = "inner", "bclk-mst1",
+					"lrck-mst1", "mclk",
+					"bclk1", "lrck1";
+			resets = <&rstgen RSTN_U1_I2STX_4CH_APB>,
+				 <&rstgen RSTN_U1_I2STX_4CH_BCLK>;
+			reset-names = "rst_apb1", "rst_bclk1";
+			interrupts = <59>;
+			interrupt-names = "tx";
+			dmas = <&dma 48 1>;
+			dma-names = "tx";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		ptc: pwm@120d0000 {
+			compatible = "starfive,pwm0";
+			reg = <0x0 0x120d0000 0x0 0x10000>;
+			reg-names = "control";
+			clocks = <&clkgen JH7110_PWM_CLK_APB>;
+			resets = <&rstgen RSTN_U0_PWM_8CH_APB>;
+			starfive,approx-period = <2000000>;
+			#pwm-cells=<3>;
+			starfive,npwm = <8>;
+			status = "disabled";
+		};
+
+		spdif_transmitter: spdif_transmitter {
+			compatible = "linux,spdif-dit";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		spdif_receiver: spdif_receiver {
+			compatible = "linux,spdif-dir";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		pwmdac_codec: pwmdac-transmitter {
+			compatible = "linux,pwmdac-dit";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		dmic_codec: dmic_codec {
+			compatible = "dmic-codec";
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		spi0: spi@10060000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0x0 0x10060000 0x0 0x10000>;
+			clocks = <&clkgen JH7110_SPI0_CLK_APB>;
+			clock-names = "apb_pclk";
+			resets = <&rstgen RSTN_U0_SSP_SPI_APB>;
+			reset-names = "rst_apb";
+			interrupts = <38>;
+			dmas = <&dma 14 1>, <&dma 15 1>;
+			dma-names = "rx","tx";
+			arm,primecell-periphid = <0x00041022>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		pcie0: pcie@2B000000 {
+			compatible = "plda,pci-xpressrich3-axi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			reg = <0x0 0x2B000000 0x0 0x1000000
+			       0x9 0x40000000 0x0 0x10000000>;
+			reg-names = "reg", "config";
+			device_type = "pci";
+			starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000  0x0 0x30000000  0x0 0x30000000 0x0 0x06000000>;
+			msi-parent = <&plic>;
+			interrupts = <56>;
+			interrupt-controller;
+			interrupt-names = "msi";
+			interrupt-parent = <&plic>;
+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+			interrupt-map = <0x0 0x0 0x0 0x1 &plic 0x1>,
+					<0x0 0x0 0x0 0x2 &plic 0x2>,
+					<0x0 0x0 0x0 0x3 &plic 0x3>,
+					<0x0 0x0 0x0 0x4 &plic 0x4>;
+			resets = <&rstgen RSTN_U0_PLDA_PCIE_AXI_MST0>,
+				 <&rstgen RSTN_U0_PLDA_PCIE_AXI_SLV0>,
+				 <&rstgen RSTN_U0_PLDA_PCIE_AXI_SLV>,
+				 <&rstgen RSTN_U0_PLDA_PCIE_BRG>,
+				 <&rstgen RSTN_U0_PLDA_PCIE_CORE>,
+				 <&rstgen RSTN_U0_PLDA_PCIE_APB>;
+			reset-names = "rst_mst0", "rst_slv0", "rst_slv",
+				      "rst_brg", "rst_core", "rst_apb";
+			clocks = <&clkgen JH7110_PCIE0_CLK_TL>,
+				 <&clkgen JH7110_PCIE0_CLK_AXI_MST0>,
+				 <&clkgen JH7110_PCIE0_CLK_APB>;
+			clock-names =  "tl", "axi_mst0", "apb";
+			status = "disabled";
+		};
+
+		pcie1: pcie@2C000000 {
+			compatible = "plda,pci-xpressrich3-axi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			reg = <0x0 0x2C000000 0x0 0x1000000
+			       0x9 0xc0000000 0x0 0x10000000>;
+			reg-names = "reg", "config";
+			device_type = "pci";
+			starfive,stg-syscon = <&stg_syscon 0x270 0x274 0x2e0>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000  0x0 0x38000000  0x0 0x38000000 0x0 0x06000000>;
+			msi-parent = <&plic>;
+			interrupts = <57>;
+			interrupt-controller;
+			interrupt-names = "msi";
+			interrupt-parent = <&plic>;
+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+			interrupt-map = <0x0 0x0 0x0 0x1 &plic 0x1>,
+					<0x0 0x0 0x0 0x2 &plic 0x2>,
+					<0x0 0x0 0x0 0x3 &plic 0x3>,
+					<0x0 0x0 0x0 0x4 &plic 0x4>;
+			resets = <&rstgen RSTN_U1_PLDA_PCIE_AXI_MST0>,
+				 <&rstgen RSTN_U1_PLDA_PCIE_AXI_SLV0>,
+				 <&rstgen RSTN_U1_PLDA_PCIE_AXI_SLV>,
+				 <&rstgen RSTN_U1_PLDA_PCIE_BRG>,
+				 <&rstgen RSTN_U1_PLDA_PCIE_CORE>,
+				 <&rstgen RSTN_U1_PLDA_PCIE_APB>;
+			reset-names = "rst_mst0", "rst_slv0", "rst_slv",
+				      "rst_brg", "rst_core", "rst_apb";
+			clocks = <&clkgen JH7110_PCIE1_CLK_TL>,
+				 <&clkgen JH7110_PCIE1_CLK_AXI_MST0>,
+				 <&clkgen JH7110_PCIE1_CLK_APB>;
+			clock-names =  "tl", "axi_mst0", "apb";
+			status = "disabled";
+		};
+
+		mailbox_contrl0: mailbox@0 {
+			compatible = "starfive,mail_box";
+			reg = <0x0 0x13060000 0x0 0x0001000>;
+			clocks = <&clkgen JH7110_MAILBOX_CLK_APB>;
+			clock-names = "clk_apb";
+			resets = <&rstgen RSTN_U0_MAILBOX_RRESETN>;
+			reset-names = "mbx_rre";
+			interrupts = <26 27>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		mailbox_client0: mailbox_client@0 {
+			compatible = "starfive,mailbox-test";
+			mbox-names = "rx", "tx";
+			mboxes = <&mailbox_contrl0 0 1>,<&mailbox_contrl0 1 0>;
+			status = "disabled";
+		};
+
+		dssctrl: dssctrl@295B0000 {
+			compatible = "verisilicon,dss-ctrl", "syscon";
+			reg = <0 0x295B0000 0 0x90>;
+		};
+
+		hdmi_output: hdmi-output {
+			compatible = "verisilicon,hdmi-encoder";
+			verisilicon,dss-syscon = <&dssctrl>;
+			verisilicon,mux-mask = <0x70 0x380>;
+			verisilicon,mux-val = <0x40 0x280>;
+			status = "disabled";
+		};
+
+		dc8200: dc8200@29400000 {
+			compatible = "verisilicon,dc8200";
+			reg = <0x0 0x29400000 0x0 0x100>,
+			      <0x0 0x29400800 0x0 0x2000>,
+			      <0x0 0x17030000 0x0 0x1000>;
+			interrupts = <95>;
+			status = "disabled";
+			clocks = <&clkgen JH7110_NOC_BUS_CLK_CPU_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_AXICFG0_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_GPU_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_VDEC_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_VENC_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_DISP_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_ISP_AXI>,
+				 <&clkgen JH7110_NOC_BUS_CLK_STG_AXI>,
+				 <&clkgen JH7110_VOUT_SRC>,
+				 <&clkgen JH7110_VOUT_TOP_CLK_VOUT_AXI>,
+				 <&clkgen JH7110_AHB1>,
+				 <&clkgen JH7110_VOUT_TOP_CLK_VOUT_AHB>,
+				 <&clkgen JH7110_VOUT_TOP_CLK_HDMITX0_MCLK>,
+				 <&clkgen JH7110_I2STX_4CH0_BCLK_MST>,
+				 <&clkvout JH7110_U0_DC8200_CLK_PIX0>,
+				 <&clkvout JH7110_U0_DC8200_CLK_PIX1>,
+				 <&clkvout JH7110_U0_DC8200_CLK_AXI>,
+				 <&clkvout JH7110_U0_DC8200_CLK_CORE>,
+				 <&clkvout JH7110_U0_DC8200_CLK_AHB>;
+			clock-names = "noc_cpu","noc_cfg0","noc_gpu","noc_vdec","noc_venc",
+					"noc_disp","noc_isp","noc_stg","vout_src",
+					"top_vout_axi","ahb1","top_vout_ahb",
+					"top_vout_hdmiTX0","i2stx","pix_clk","vout_pix1",
+					"axi_clk","core_clk","vout_ahb";
+
+			resets = <&rstgen RSTN_U0_DOM_VOUT_TOP_SRC>,
+				 <&rstgen RSTN_U0_DC8200_AXI>,
+				 <&rstgen RSTN_U0_DC8200_AHB>,
+				 <&rstgen RSTN_U0_DC8200_CORE>,
+				 <&rstgen RSTN_U0_NOC_BUS_CPU_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_AXICFG0_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_APB_BUS_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_GPU_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_VDEC_AXI_N>,
+				 <&rstgen RSTN_U0_JTAG2APB_PRESETN>,
+				 <&rstgen RSTN_U0_NOC_BUS_DISP_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_ISP_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_STG_AXI_N>,
+				 <&rstgen RSTN_U0_NOC_BUS_DDRC_N>;
+			reset-names = "rst_vout_src","rst_axi","rst_ahb","rst_core",
+					"rst_noc_cpu","rst_noc_axicfg0","rst_noc_apb",
+					"rst_noc_gpu","rst_noc_vdec","rst_jtag2apb",
+					"rst_noc_disp","rst_noc_isp","rst_noc_stg","rst_noc_ddrc";
+		};
+
+		mipi_dphy: mipi-dphy@295e0000{
+			compatible = "starfive,jh7100-mipi-dphy-tx";
+			reg = <0x0 0x295e0000 0x0 0x10000>;
+			clocks = <&clkvout JH7110_U0_MIPITX_DPHY_CLK_TXESC>;
+			clock-names = "dphy_txesc";
+			resets = <&rstgen RSTN_U0_MIPITX_DPHY_SYS>,
+				 <&rstgen RSTN_U0_MIPITX_DPHY_TXBYTEHS>;
+			reset-names = "dphy_sys", "dphy_txbytehs";
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		 mipi_dsi: mipi@295d0000 {
+			compatible = "cdns,dsi";
+			reg = <0x0 0x295d0000 0x0 0x10000>;
+			reg-names = "dsi";
+			clocks = <&clkvout JH7110_U0_CDNS_DSITX_CLK_SYS>,
+				 <&clkvout JH7110_U0_CDNS_DSITX_CLK_APB>,
+				 <&clkvout JH7110_U0_CDNS_DSITX_CLK_TXESC>,
+				 <&clkvout JH7110_U0_CDNS_DSITX_CLK_DPI>;
+			clock-names = "sys", "apb", "txesc", "dpi";
+			resets = <&rstgen RSTN_U0_CDNS_DSITX_DPI>,
+				 <&rstgen RSTN_U0_CDNS_DSITX_APB>,
+				 <&rstgen RSTN_U0_CDNS_DSITX_RXESC>,
+				 <&rstgen RSTN_U0_CDNS_DSITX_SYS>,
+				 <&rstgen RSTN_U0_CDNS_DSITX_TXBYTEHS>,
+				 <&rstgen RSTN_U0_CDNS_DSITX_TXESC>;
+			reset-names = "dsi_dpi", "dsi_apb", "dsi_rxesc",
+					"dsi_sys", "dsi_txbytehs", "dsi_txesc";
+			phys = <&mipi_dphy>;
+			phy-names = "dphy";
+			status = "disabled";
+
+			port {
+				dsi_out_port: endpoint {
+					/*remote-endpoint = <&panel_dsi_port>;*/
+				};
+			};
+
+			mipi_panel: panel@0 {
+				/*compatible = "";*/
+				status = "disabled";
+			};
+		};
+
+		hdmi: hdmi@29590000 {
+			compatible = "rockchip,rk3036-inno-hdmi";
+			reg = <0x0 0x29590000 0x0 0x4000>;
+			/*interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;*/
+			/*clocks = <&cru  PCLK_HDMI>;*/
+			/*clock-names = "pclk";*/
+			/*pinctrl-names = "default";*/
+			/*pinctrl-0 = <&hdmi_ctl>;*/
+			status = "disabled";
+			clocks = <&clkvout JH7110_U0_HDMI_TX_CLK_SYS>,
+				 <&clkvout JH7110_U0_HDMI_TX_CLK_MCLK>,
+				 <&clkvout JH7110_U0_HDMI_TX_CLK_BCLK>;
+			clock-names = "sysclk", "mclk", "bclk";
+			resets = <&rstgen RSTN_U0_HDMI_TX_HDMI>;
+			reset-names = "hdmi_tx";
+		};
+
+		sound: snd-card {
+			compatible = "simple-audio-card";
+			simple-audio-card,name = "Starfive-Multi-Sound-Card";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			simple-audio-card,dai-link@0 {
+				reg = <0>;
+				format = "left_j";
+				bitclock-master = <&sndcpu0>;
+				frame-master = <&sndcpu0>;
+				status = "okay";
+
+				sndcpu0: cpu {
+					sound-dai = <&pwmdac>;
+				};
+
+				codec {
+					sound-dai = <&pwmdac_codec>;
+				};
+			};
+		};
+
+		co_process: e24@0 {
+			compatible = "starfive,e24";
+			reg = <0x0 0xc0110000 0x0 0x00001000>,
+				<0x0 0xc0111000 0x0 0x0001f000>;
+			reg-names = "ecmd", "espace";
+			clocks = <&clkgen JH7110_E2_RTC_CLK>,
+				 <&clkgen JH7110_E2_CLK_CORE>,
+				 <&clkgen JH7110_E2_CLK_DBG>;
+			clock-names = "clk_rtc", "clk_core", "clk_dbg";
+			resets = <&rstgen RSTN_U0_E24_CORE>;
+			reset-names = "e24_core";
+			starfive,stg-syscon = <&stg_syscon>;
+			interrupt-parent = <&plic>;
+			firmware-name = "e24_elf";
+			irq-mode = <1>;
+			mbox-names = "tx", "rx";
+			mboxes = <&mailbox_contrl0 0 2>,<&mailbox_contrl0 2 0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0xc0000000 0x0 0xc0000000 0x200000>;
+			status = "disabled";
+			dsp@0 {};
+		};
+	};
+};

+ 116 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/jh7110_clk.dtsi

@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+/ {
+	/* clock tree external clocks */
+	osc: osc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+
+	gmac1_rmii_refin: gmac1_rmii_refin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	gmac1_rgmii_rxin: gmac1_rgmii_rxin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
+
+	i2stx_bclk_ext: i2stx_bclk_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12288000>;
+	};
+
+	i2stx_lrck_ext: i2stx_lrck_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <192000>;
+	};
+
+	i2srx_bclk_ext: i2srx_bclk_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12288000>;
+	};
+
+	i2srx_lrck_ext: i2srx_lrck_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <192000>;
+	};
+
+	tdm_ext: tdm_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <49152000>;
+	};
+
+	mclk_ext: mclk_ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <49152000>;
+	};
+
+	jtag_tck_inner: jtag_tck_inner {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	bist_apb: bist_apb {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	stg_apb: stg_apb {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <51200000>;
+	};
+
+	gmac0_rmii_refin: gmac0_rmii_refin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	gmac0_rgmii_rxin: gmac0_rgmii_rxin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
+
+	clk_rtc: clk_rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	hdmitx0_pixelclk: hdmitx0_pixelclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <297000000>;
+	};
+
+	mipitx_dphy_rxesc: mipitx_dphy_rxesc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <10000000>;
+	};
+
+	mipitx_dphy_txbytehs: mipitx_dphy_txbytehs {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <297000000>;
+	};
+	/* external clocks end */
+};

+ 394 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-clkgen.h

@@ -0,0 +1,394 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2022 StarFive, Inc <xingyu.wu@starfivetech.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CLKGEN_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CLKGEN_H__
+
+/* sys regisger */
+#define JH7110_CPU_ROOT                        0
+#define JH7110_CPU_CORE                        1
+#define JH7110_CPU_BUS                         2
+#define JH7110_GPU_ROOT                        3
+#define JH7110_PERH_ROOT                       4
+#define JH7110_BUS_ROOT                        5
+#define JH7110_NOCSTG_BUS                      6
+#define JH7110_AXI_CFG0                        7
+#define JH7110_STG_AXIAHB                      8
+#define JH7110_AHB0                            9
+#define JH7110_AHB1                            10
+#define JH7110_APB_BUS_FUNC                    11
+#define JH7110_APB0                            12
+#define JH7110_PLL0_DIV2                       13
+#define JH7110_PLL1_DIV2                       14
+#define JH7110_PLL2_DIV2                       15
+#define JH7110_AUDIO_ROOT                      16
+#define JH7110_MCLK_INNER                      17
+#define JH7110_MCLK                            18
+#define JH7110_MCLK_OUT                        19
+#define JH7110_ISP_2X                          20
+#define JH7110_ISP_AXI                         21
+#define JH7110_GCLK0                           22
+#define JH7110_GCLK1                           23
+#define JH7110_GCLK2                           24
+#define JH7110_U7_CORE_CLK                     25
+#define JH7110_U7_CORE_CLK1                    26
+#define JH7110_U7_CORE_CLK2                    27
+#define JH7110_U7_CORE_CLK3                    28
+#define JH7110_U7_CORE_CLK4                    29
+#define JH7110_U7_DEBUG_CLK                    30
+#define JH7110_U7_RTC_TOGGLE                   31
+#define JH7110_U7_TRACE_CLK0                   32
+#define JH7110_U7_TRACE_CLK1                   33
+#define JH7110_U7_TRACE_CLK2                   34
+#define JH7110_U7_TRACE_CLK3                   35
+#define JH7110_U7_TRACE_CLK4                   36
+#define JH7110_U7_TRACE_COM_CLK                37
+#define JH7110_NOC_BUS_CLK_CPU_AXI             38
+#define JH7110_NOC_BUS_CLK_AXICFG0_AXI         39
+#define JH7110_OSC_DIV2                        40
+#define JH7110_PLL1_DIV4                       41
+#define JH7110_PLL1_DIV8                       42
+#define JH7110_DDR_BUS                         43
+#define JH7110_DDR_CLK_AXI                     44
+#define JH7110_GPU_CORE                        45
+#define JH7110_GPU_CORE_CLK                    46
+#define JH7110_GPU_SYS_CLK                     47
+#define JH7110_GPU_CLK_APB                     48
+#define JH7110_GPU_RTC_TOGGLE                  49
+#define JH7110_NOC_BUS_CLK_GPU_AXI             50
+#define JH7110_ISP_TOP_CLK_ISPCORE_2X          51
+#define JH7110_ISP_TOP_CLK_ISP_AXI             52
+#define JH7110_NOC_BUS_CLK_ISP_AXI             53
+#define JH7110_HIFI4_CORE                      54
+#define JH7110_HIFI4_AXI                       55
+#define JH7110_AXI_CFG1_DEC_CLK_MAIN           56
+#define JH7110_AXI_CFG1_DEC_CLK_AHB            57
+#define JH7110_VOUT_SRC                        58
+#define JH7110_VOUT_AXI                        59
+#define JH7110_NOC_BUS_CLK_DISP_AXI            60
+#define JH7110_VOUT_TOP_CLK_VOUT_AHB           61
+#define JH7110_VOUT_TOP_CLK_VOUT_AXI           62
+#define JH7110_VOUT_TOP_CLK_HDMITX0_MCLK       63
+#define JH7110_VOUT_TOP_CLK_MIPIPHY_REF        64
+#define JH7110_JPEGC_AXI                       65
+#define JH7110_CODAJ12_CLK_AXI                 66
+#define JH7110_CODAJ12_CLK_CORE                67
+#define JH7110_CODAJ12_CLK_APB                 68
+#define JH7110_VDEC_AXI                        69
+#define JH7110_WAVE511_CLK_AXI                 70
+#define JH7110_WAVE511_CLK_BPU                 71
+#define JH7110_WAVE511_CLK_VCE                 72
+#define JH7110_WAVE511_CLK_APB                 73
+#define JH7110_VDEC_JPG_ARB_JPGCLK             74
+#define JH7110_VDEC_JPG_ARB_MAINCLK            75
+#define JH7110_NOC_BUS_CLK_VDEC_AXI            76
+#define JH7110_VENC_AXI                        77
+#define JH7110_WAVE420L_CLK_AXI                78
+#define JH7110_WAVE420L_CLK_BPU                79
+#define JH7110_WAVE420L_CLK_VCE                80
+#define JH7110_WAVE420L_CLK_APB                81
+#define JH7110_NOC_BUS_CLK_VENC_AXI            82
+#define JH7110_AXI_CFG0_DEC_CLK_MAIN_DIV       83
+#define JH7110_AXI_CFG0_DEC_CLK_MAIN           84
+#define JH7110_AXI_CFG0_DEC_CLK_HIFI4          85
+#define JH7110_AXIMEM2_128B_CLK_AXI            86
+#define JH7110_QSPI_CLK_AHB                    87
+#define JH7110_QSPI_CLK_APB                    88
+#define JH7110_QSPI_REF_SRC                    89
+#define JH7110_QSPI_CLK_REF                    90
+#define JH7110_SDIO0_CLK_AHB                   91
+#define JH7110_SDIO1_CLK_AHB                   92
+#define JH7110_SDIO0_CLK_SDCARD                93
+#define JH7110_SDIO1_CLK_SDCARD                94
+#define JH7110_USB_125M                        95
+#define JH7110_NOC_BUS_CLK_STG_AXI             96
+#define JH7110_GMAC5_CLK_AHB                   97
+#define JH7110_GMAC5_CLK_AXI                   98
+#define JH7110_GMAC_SRC                        99
+#define JH7110_GMAC1_GTXCLK                    100
+#define JH7110_GMAC1_RMII_RTX                  101
+#define JH7110_GMAC5_CLK_PTP                   102
+#define JH7110_GMAC5_CLK_RX                    103
+#define JH7110_GMAC5_CLK_RX_INV                104
+#define JH7110_GMAC5_CLK_TX                    105
+#define JH7110_GMAC5_CLK_TX_INV                106
+#define JH7110_GMAC1_GTXC                      107
+#define JH7110_GMAC0_GTXCLK                    108
+#define JH7110_GMAC0_PTP                       109
+#define JH7110_GMAC_PHY                        110
+#define JH7110_GMAC0_GTXC                      111
+#define JH7110_SYS_IOMUX_PCLK                  112
+#define JH7110_MAILBOX_CLK_APB                 113
+#define JH7110_INT_CTRL_CLK_APB                114
+#define JH7110_CAN0_CTRL_CLK_APB               115
+#define JH7110_CAN0_CTRL_CLK_TIMER             116
+#define JH7110_CAN0_CTRL_CLK_CAN               117
+#define JH7110_CAN1_CTRL_CLK_APB               118
+#define JH7110_CAN1_CTRL_CLK_TIMER             119
+#define JH7110_CAN1_CTRL_CLK_CAN               120
+#define JH7110_PWM_CLK_APB                     121
+#define JH7110_DSKIT_WDT_CLK_APB               122
+#define JH7110_DSKIT_WDT_CLK_WDT               123
+#define JH7110_TIMER_CLK_APB                   124
+#define JH7110_TIMER_CLK_TIMER0                125
+#define JH7110_TIMER_CLK_TIMER1                126
+#define JH7110_TIMER_CLK_TIMER2                127
+#define JH7110_TIMER_CLK_TIMER3                128
+#define JH7110_TEMP_SENSOR_CLK_APB             129
+#define JH7110_TEMP_SENSOR_CLK_TEMP            130
+#define JH7110_SPI0_CLK_APB                    131
+#define JH7110_SPI1_CLK_APB                    132
+#define JH7110_SPI2_CLK_APB                    133
+#define JH7110_SPI3_CLK_APB                    134
+#define JH7110_SPI4_CLK_APB                    135
+#define JH7110_SPI5_CLK_APB                    136
+#define JH7110_SPI6_CLK_APB                    137
+#define JH7110_I2C0_CLK_APB                    138
+#define JH7110_I2C1_CLK_APB                    139
+#define JH7110_I2C2_CLK_APB                    140
+#define JH7110_I2C3_CLK_APB                    141
+#define JH7110_I2C4_CLK_APB                    142
+#define JH7110_I2C5_CLK_APB                    143
+#define JH7110_I2C6_CLK_APB                    144
+#define JH7110_UART0_CLK_APB                   145
+#define JH7110_UART0_CLK_CORE                  146
+#define JH7110_UART1_CLK_APB                   147
+#define JH7110_UART1_CLK_CORE                  148
+#define JH7110_UART2_CLK_APB                   149
+#define JH7110_UART2_CLK_CORE                  150
+#define JH7110_UART3_CLK_APB                   151
+#define JH7110_UART3_CLK_CORE                  152
+#define JH7110_UART4_CLK_APB                   153
+#define JH7110_UART4_CLK_CORE                  154
+#define JH7110_UART5_CLK_APB                   155
+#define JH7110_UART5_CLK_CORE                  156
+#define JH7110_PWMDAC_CLK_APB                  157
+#define JH7110_PWMDAC_CLK_CORE                 158
+#define JH7110_SPDIF_CLK_APB                   159
+#define JH7110_SPDIF_CLK_CORE                  160
+#define JH7110_I2STX0_4CHCLK_APB               161
+#define JH7110_I2STX_4CH0_BCLK_MST             162
+#define JH7110_I2STX_4CH0_BCLK_MST_INV         163
+#define JH7110_I2STX_4CH0_LRCK_MST             164
+#define JH7110_I2STX0_4CHBCLK                  165
+#define JH7110_I2STX0_4CHBCLK_N                166
+#define JH7110_I2STX0_4CHLRCK                  167
+#define JH7110_I2STX1_4CHCLK_APB               168
+#define JH7110_I2STX_4CH1_BCLK_MST             169
+#define JH7110_I2STX_4CH1_BCLK_MST_INV         170
+#define JH7110_I2STX_4CH1_LRCK_MST             171
+#define JH7110_I2STX1_4CHBCLK                  172
+#define JH7110_I2STX1_4CHBCLK_N                173
+#define JH7110_I2STX1_4CHLRCK                  174
+#define JH7110_I2SRX0_3CH_CLK_APB              175
+#define JH7110_I2SRX_3CH_BCLK_MST              176
+#define JH7110_I2SRX_3CH_BCLK_MST_INV          177
+#define JH7110_I2SRX_3CH_LRCK_MST              178
+#define JH7110_I2SRX0_3CH_BCLK                 179
+#define JH7110_I2SRX0_3CH_BCLK_N               180
+#define JH7110_I2SRX0_3CH_LRCK                 181
+#define JH7110_PDM_CLK_DMIC                    182
+#define JH7110_PDM_CLK_APB                     183
+#define JH7110_TDM_CLK_AHB                     184
+#define JH7110_TDM_CLK_APB                     185
+#define JH7110_TDM_INTERNAL                    186
+#define JH7110_TDM_CLK_TDM                     187
+#define JH7110_TDM_CLK_TDM_N                   188
+#define JH7110_JTAG_CERTIFICATION_TRNG_CLK     189
+
+#define JH7110_CLK_SYS_REG_END                 190
+
+/* stg regisger */
+#define JH7110_HIFI4_CLK_CORE                   190
+#define JH7110_USB0_CLK_USB_APB                 191
+#define JH7110_USB0_CLK_UTMI_APB                192
+#define JH7110_USB0_CLK_AXI                     193
+#define JH7110_USB0_CLK_LPM                     194
+#define JH7110_USB0_CLK_STB                     195
+#define JH7110_USB0_CLK_APP_125                 196
+#define JH7110_USB0_REFCLK                      197
+#define JH7110_PCIE0_CLK_AXI_MST0               198
+#define JH7110_PCIE0_CLK_APB                    199
+#define JH7110_PCIE0_CLK_TL                     200
+#define JH7110_PCIE1_CLK_AXI_MST0               201
+#define JH7110_PCIE1_CLK_APB                    202
+#define JH7110_PCIE1_CLK_TL                     203
+#define JH7110_PCIE01_SLV_DEC_MAINCLK           204
+#define JH7110_SEC_HCLK                         205
+#define JH7110_SEC_MISCAHB_CLK                  206
+#define JH7110_STG_MTRX_GRP0_CLK_MAIN           207
+#define JH7110_STG_MTRX_GRP0_CLK_BUS            208
+#define JH7110_STG_MTRX_GRP0_CLK_STG            209
+#define JH7110_STG_MTRX_GRP1_CLK_MAIN           210
+#define JH7110_STG_MTRX_GRP1_CLK_BUS            211
+#define JH7110_STG_MTRX_GRP1_CLK_STG            212
+#define JH7110_STG_MTRX_GRP1_CLK_HIFI           213
+#define JH7110_E2_RTC_CLK                       214
+#define JH7110_E2_CLK_CORE                      215
+#define JH7110_E2_CLK_DBG                       216
+#define JH7110_DMA1P_CLK_AXI                    217
+#define JH7110_DMA1P_CLK_AHB                    218
+
+#define JH7110_CLK_STG_REG_END                  219
+
+/* aon regisger */
+#define JH7110_OSC_DIV4                         219
+#define JH7110_AON_APB_FUNC                     220
+#define JH7110_U0_GMAC5_CLK_AHB                 221
+#define JH7110_U0_GMAC5_CLK_AXI                 222
+#define JH7110_GMAC0_RMII_RTX                   223
+#define JH7110_U0_GMAC5_CLK_TX                  224
+#define JH7110_U0_GMAC5_CLK_TX_INV              225
+#define JH7110_U0_GMAC5_CLK_RX                  226
+#define JH7110_U0_GMAC5_CLK_RX_INV              227
+#define JH7110_OTPC_CLK_APB                     228
+#define JH7110_RTC_HMS_CLK_APB                  229
+#define JH7110_RTC_INTERNAL                     230
+#define JH7110_RTC_HMS_CLK_OSC32K               231
+#define JH7110_RTC_HMS_CLK_CAL                  232
+
+#define JH7110_CLK_REG_END			233
+
+/* sys other */
+#define JH7110_PLL0_OUT                        233
+#define JH7110_PLL1_OUT                        234
+#define JH7110_PLL2_OUT                        235
+#define JH7110_AON_APB                         236
+#define JH7110_RESET1_CTRL_CLK_SRC             237
+#define JH7110_DDR_ROOT                        238
+#define JH7110_VDEC_ROOT                       239
+#define JH7110_VENC_ROOT                       240
+#define JH7110_VOUT_ROOT                       241
+#define JH7110_GMACUSB_ROOT                    242
+#define JH7110_PCLK2_MUX_FUNC_PCLK             243
+#define JH7110_PCLK2_MUX_BIST_PCLK             244
+#define JH7110_APB_BUS                         245
+#define JH7110_APB12                           246
+#define JH7110_AXI_CFG1                        247
+#define JH7110_PLL_WRAP_CRG_GCLK0              248
+#define JH7110_PLL_WRAP_CRG_GCLK1              249
+#define JH7110_PLL_WRAP_CRG_GCLK2              250
+#define JH7110_JTAG2APB_PCLK                   251
+#define JH7110_U7_BUS_CLK                      252
+#define JH7110_U7_IRQ_SYNC_BUS_CLK             253
+#define JH7110_NOC_BUS_CLK2_CPU_AXI            254
+#define JH7110_NOC_BUS_CLK_APB_BUS             255
+#define JH7110_NOC_BUS_CLK2_APB_BUS            256
+#define JH7110_NOC_BUS_CLK2_AXICFG0_AXI        257
+#define JH7110_DDR_CLK_DDRPHY_PLL_BYPASS       258
+#define JH7110_DDR_CLK_OSC                     259
+#define JH7110_DDR_CLK_APB                     260
+#define JH7110_NOC_BUS_CLK_DDRC                261
+#define JH7110_NOC_BUS_CLK2_DDRC               262
+#define JH7110_SYS_AHB_DEC_CLK_AHB             263
+#define JH7110_STG_AHB_DEC_CLK_AHB             264
+#define JH7110_NOC_BUS_CLK2_GPU_AXI            265
+#define JH7110_ISP_TOP_CLK_DVP                 266
+#define JH7110_NOC_BUS_CLK2_ISP_AXI            267
+#define JH7110_ISP_TOP_CLK_BIST_APB            268
+#define JH7110_NOC_BUS_CLK2_DISP_AXI           269
+#define JH7110_VOUT_TOP_CLK_HDMITX0_BCLK       270
+#define JH7110_VOUT_TOP_U0_HDMI_TX_PIN_WS      271
+#define JH7110_VOUT_TOP_CLK_HDMIPHY_REF        272
+#define JH7110_VOUT_TOP_BIST_PCLK              273
+#define JH7110_AXIMEM0_128B_CLK_AXI            274
+#define JH7110_VDEC_INTSRAM_CLK_VDEC_AXI       275
+#define JH7110_NOC_BUS_CLK2_VDEC_AXI           276
+#define JH7110_AXIMEM1_128B_CLK_AXI            277
+#define JH7110_VENC_INTSRAM_CLK_VENC_AXI       278
+#define JH7110_NOC_BUS_CLK2_VENC_AXI           279
+#define JH7110_SRAM_CLK_ROM                    280
+#define JH7110_NOC_BUS_CLK2_STG_AXI            281
+#define JH7110_GMAC5_CLK_RMII                  282
+#define JH7110_AON_AHB                         283
+#define JH7110_SYS_CRG_PCLK                    284
+#define JH7110_SYS_SYSCON_PCLK                 285
+#define JH7110_SPI0_CLK_CORE                   286
+#define JH7110_SPI1_CLK_CORE                   287
+#define JH7110_SPI2_CLK_CORE                   288
+#define JH7110_SPI3_CLK_CORE                   289
+#define JH7110_SPI4_CLK_CORE                   290
+#define JH7110_SPI5_CLK_CORE                   291
+#define JH7110_SPI6_CLK_CORE                   292
+#define JH7110_I2C0_CLK_CORE                   293
+#define JH7110_I2C1_CLK_CORE                   294
+#define JH7110_I2C2_CLK_CORE                   295
+#define JH7110_I2C3_CLK_CORE                   296
+#define JH7110_I2C4_CLK_CORE                   297
+#define JH7110_I2C5_CLK_CORE                   298
+#define JH7110_I2C6_CLK_CORE                   299
+#define JH7110_I2STX_BCLK_MST                  300
+#define JH7110_I2STX_LRCK_MST                  301
+#define JH7110_I2SRX_BCLK_MST                  302
+#define JH7110_I2SRX_LRCK_MST                  303
+#define JH7110_PDM_CLK_DMIC0_BCLK_SLV          304
+#define JH7110_PDM_CLK_DMIC0_LRCK_SLV          305
+#define JH7110_PDM_CLK_DMIC1_BCLK_SLV          306
+#define JH7110_PDM_CLK_DMIC1_LRCK_SLV          307
+#define JH7110_TDM_CLK_MST                     308
+#define JH7110_AHB2APB_CLK_AHB                 309
+#define JH7110_P2P_ASYNC_CLK_APBS              310
+#define JH7110_P2P_ASYNC_CLK_APBM              311
+#define JH7110_JTAG_DAISY_CHAIN_JTAG_TCK       312
+#define JH7110_U7_DEBUG_SYSTEMJTAG_JTAG_TCK    313
+#define JH7110_E2_DEBUG_SYSTEMJTAG_TCK         314
+#define JH7110_JTAG_CERTIFICATION_TCK          315
+#define JH7110_SEC_SKP_CLK                     316
+#define JH7110_U2_PCLK_MUX_PCLK		317
+
+#define JH7110_CLK_SYS_END                     318
+
+/* stg other */
+#define JH7110_PCIE0_CLK_AXI_SLV0               318
+#define JH7110_PCIE0_CLK_AXI_SLV                319
+#define JH7110_PCIE0_CLK_OSC                    320
+#define JH7110_PCIE1_CLK_AXI_SLV0               321
+#define JH7110_PCIE1_CLK_AXI_SLV                322
+#define JH7110_PCIE1_CLK_OSC                    323
+#define JH7110_E2_IRQ_SYNC_CLK_CORE             324
+#define JH7110_STG_CRG_PCLK                     325
+#define JH7110_STG_SYSCON_PCLK                  326
+
+#define JH7110_CLK_STG_END                      327
+
+/* aon other */
+#define JH7110_U0_GMAC5_CLK_PTP                 327
+#define JH7110_U0_GMAC5_CLK_RMII                328
+#define JH7110_AON_SYSCON_PCLK                  329
+#define JH7110_AON_IOMUX_PCLK                   330
+#define JH7110_AON_CRG_PCLK                     331
+#define JH7110_PMU_CLK_APB                      332
+#define JH7110_PMU_CLK_WKUP                     333
+#define JH7110_RTC_HMS_CLK_OSC32K_G             334
+#define JH7110_32K_OUT                          335
+#define JH7110_RESET0_CTRL_CLK_SRC              336
+/* aon other and source */
+#define JH7110_PCLK_MUX_FUNC_PCLK               337
+#define JH7110_PCLK_MUX_BIST_PCLK               338
+
+#define JH7110_CLK_END                          339
+
+/* sys external clocks */
+#define JH7110_OSC                      (JH7110_CLK_END + 0)
+#define JH7110_GMAC1_RMII_REFIN         (JH7110_CLK_END + 1)
+#define JH7110_GMAC1_RGMII_RXIN         (JH7110_CLK_END + 2)
+#define JH7110_I2STX_BCLK_EXT           (JH7110_CLK_END + 3)
+#define JH7110_I2STX_LRCK_EXT           (JH7110_CLK_END + 4)
+#define JH7110_I2SRX_BCLK_EXT           (JH7110_CLK_END + 5)
+#define JH7110_I2SRX_LRCK_EXT           (JH7110_CLK_END + 6)
+#define JH7110_TDM_EXT                  (JH7110_CLK_END + 7)
+#define JH7110_MCLK_EXT                 (JH7110_CLK_END + 8)
+#define JH7110_JTAG_TCK_INNER           (JH7110_CLK_END + 9)
+#define JH7110_BIST_APB                 (JH7110_CLK_END + 10)
+
+/* stg external clocks */
+#define JH7110_STG_APB                  (JH7110_CLK_END + 11)
+
+/* aon external clocks */
+#define JH7110_GMAC0_RMII_REFIN         (JH7110_CLK_END + 12)
+#define JH7110_GMAC0_RGMII_RXIN         (JH7110_CLK_END + 13)
+#define JH7110_CLK_RTC                  (JH7110_CLK_END + 14)
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_H__ */

+ 53 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-isp.h

@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2022 StarFive, Inc <xingyu.wu@starfivetech.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_ISP_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_ISP_H__
+
+/* regisger */
+#define JH7110_DOM4_APB_FUNC					0
+#define JH7110_MIPI_RX0_PXL					1
+#define JH7110_DVP_INV						2
+#define JH7110_U0_M31DPHY_CFGCLK_IN				3
+#define JH7110_U0_M31DPHY_REFCLK_IN				4
+#define JH7110_U0_M31DPHY_TXCLKESC_LAN0				5
+#define JH7110_U0_VIN_PCLK					6
+#define JH7110_U0_VIN_SYS_CLK					7
+#define JH7110_U0_VIN_PIXEL_CLK_IF0				8
+#define JH7110_U0_VIN_PIXEL_CLK_IF1				9
+#define JH7110_U0_VIN_PIXEL_CLK_IF2				10
+#define JH7110_U0_VIN_PIXEL_CLK_IF3				11
+#define JH7110_U0_VIN_CLK_P_AXIWR				12
+#define JH7110_U0_ISPV2_TOP_WRAPPER_CLK_C			13
+
+#define JH7110_CLK_ISP_REG_END					14
+
+/* other */
+#define JH7110_U3_PCLK_MUX_FUNC_PCLK				14
+#define JH7110_U3_PCLK_MUX_BIST_PCLK				15
+#define JH7110_DOM4_APB						16
+#define JH7110_U0_VIN_PCLK_FREE					17
+#define JH7110_U0_VIN_CLK_P_AXIRD				18
+#define JH7110_U0_VIN_ACLK					19
+#define JH7110_U0_ISPV2_TOP_WRAPPER_CLK_ISP_AXI_IN		20
+#define JH7110_U0_ISPV2_TOP_WRAPPER_CLK_ISP_X2			21
+#define JH7110_U0_ISPV2_TOP_WRAPPER_CLK_ISP			22
+#define JH7110_U0_ISPV2_TOP_WRAPPER_CLK_P			23
+#define JH7110_U0_CRG_PCLK					24
+#define JH7110_U0_SYSCON_PCLK					25
+#define JH7110_U0_M31DPHY_APBCFG_PCLK				26
+#define JH7110_U0_AXI2APB_BRIDGE_CLK_DOM4_APB			27
+#define JH7110_U0_AXI2APB_BRIDGE_ISP_AXI4SLV_CLK		28
+#define JH7110_U3_PCLK_MUX_PCLK					29
+
+#define JH7110_CLK_ISP_END					30
+
+/* external clocks */
+#define JH7110_ISP_TOP_CLK_ISPCORE_2X_CLKGEN	(JH7110_CLK_ISP_END + 0)
+#define JH7110_ISP_TOP_CLK_ISP_AXI_CLKGEN	(JH7110_CLK_ISP_END + 1)
+#define JH7110_ISP_TOP_CLK_BIST_APB_CLKGEN	(JH7110_CLK_ISP_END + 2)
+#define JH7110_ISP_TOP_CLK_DVP_CLKGEN		(JH7110_CLK_ISP_END + 3)
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_H__ */

+ 66 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110-vout.h

@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2022 StarFive, Inc <xingyu.wu@starfivetech.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_VOUT_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_VOUT_H__
+
+/* regisger */
+#define JH7110_APB						0
+#define JH7110_DC8200_PIX0					1
+#define JH7110_DSI_SYS						2
+#define JH7110_TX_ESC						3
+#define JH7110_U0_DC8200_CLK_AXI				4
+#define JH7110_U0_DC8200_CLK_CORE				5
+#define JH7110_U0_DC8200_CLK_AHB				6
+#define JH7110_U0_DC8200_CLK_PIX0				7
+#define JH7110_U0_DC8200_CLK_PIX1				8
+#define JH7110_DOM_VOUT_TOP_LCD_CLK				9
+#define JH7110_U0_CDNS_DSITX_CLK_APB				10
+#define JH7110_U0_CDNS_DSITX_CLK_SYS				11
+#define JH7110_U0_CDNS_DSITX_CLK_DPI				12
+#define JH7110_U0_CDNS_DSITX_CLK_TXESC				13
+#define JH7110_U0_MIPITX_DPHY_CLK_TXESC				14
+#define JH7110_U0_HDMI_TX_CLK_MCLK				15
+#define JH7110_U0_HDMI_TX_CLK_BCLK				16
+#define JH7110_U0_HDMI_TX_CLK_SYS				17
+
+#define JH7110_CLK_VOUT_REG_END					18
+
+/* other */
+#define JH7110_DISP_ROOT					18
+#define JH7110_DISP_AXI						19
+#define JH7110_DISP_AHB						20
+#define JH7110_HDMI_PHY_REF					21
+#define JH7110_HDMITX0_MCLK					22
+#define JH7110_HDMITX0_SCK					23
+
+#define JH7110_MIPI_DPHY_REF					24
+#define JH7110_U0_PCLK_MUX_BIST_PCLK				25
+#define JH7110_DISP_APB						26
+#define JH7110_U0_PCLK_MUX_FUNC_PCLK				27
+#define JH7110_U0_DOM_VOUT_CRG_PCLK				28
+#define JH7110_U0_DOM_VOUT_SYSCON_PCLK				29
+#define JH7110_U0_SAIF_AMBA_DOM_VOUT_AHB_DEC_CLK_AHB		30
+#define JH7110_U0_AHB2APB_CLK_AHB				31
+#define JH7110_U0_P2P_ASYNC_CLK_APBS				32
+#define JH7110_U0_CDNS_DSITX_CLK_RXESC				33
+#define JH7110_U0_CDNS_DSITX_CLK_TXBYTEHS			34
+#define JH7110_U0_MIPITX_DPHY_CLK_SYS				35
+#define JH7110_U0_MIPITX_DPHY_CLK_DPHY_REF			36
+#define JH7110_U0_MIPITX_APBIF_PCLK				37
+#define JH7110_HDMI_TX_CLK_REF					38
+#define JH7110_U0_DC8200_CLK_PIX0_OUT				39
+#define JH7110_U0_DC8200_CLK_PIX1_OUT				40
+
+#define JH7110_CLK_VOUT_END					41
+
+/* external clocks */
+#define JH7110_HDMITX0_PIXELCLK			(JH7110_CLK_VOUT_END + 0)
+#define JH7110_MIPITX_DPHY_RXESC		(JH7110_CLK_VOUT_END + 1)
+#define JH7110_MIPITX_DPHY_TXBYTEHS		(JH7110_CLK_VOUT_END + 2)
+
+
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_H__ */

+ 219 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive-jh7110.h

@@ -0,0 +1,219 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2022 Starfive, Inc.
+ * Author:	samin <samin.guo@starfivetech.com>
+ *		yanhong <yanhong.wang@starfivetech.com>
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_H__
+
+/*
+ * group[0]: syscrg: assert0
+ */
+#define RSTN_U0_JTAG2APB_PRESETN	0
+#define	RSTN_U0_SYS_SYSCON_PRESETN	1
+#define	RSTN_U0_SYS_IOMUX_PRESETN	2
+#define	RSTN_U0_U7MC_RST_BUS		3
+#define	RSTN_U0_U7MC_DEBUG		4
+#define	RSTN_U0_U7MC_CORE0		5
+#define	RSTN_U0_U7MC_CORE1		6
+#define	RSTN_U0_U7MC_CORE2		7
+#define	RSTN_U0_U7MC_CORE3		8
+#define	RSTN_U0_U7MC_CORE4		9
+#define	RSTN_U0_U7MC_CORE0_ST		10
+#define	RSTN_U0_U7MC_CORE1_ST		11
+#define	RSTN_U0_U7MC_CORE2_ST		12
+#define	RSTN_U0_U7MC_CORE3_ST		13
+#define	RSTN_U0_U7MC_CORE4_ST		14
+#define	RSTN_U0_U7MC_TRACE_RST0		15
+#define	RSTN_U0_U7MC_TRACE_RST1		16
+#define	RSTN_U0_U7MC_TRACE_RST2		17
+#define	RSTN_U0_U7MC_TRACE_RST3		18
+#define	RSTN_U0_U7MC_TRACE_RST4		19
+#define	RSTN_U0_U7MC_TRACE_COM		20
+#define	RSTN_U0_IMG_GPU_APB		21
+#define	RSTN_U0_IMG_GPU_DOMA		22
+#define	RSTN_U0_NOC_BUS_APB_BUS_N	23
+#define	RSTN_U0_NOC_BUS_AXICFG0_AXI_N	24
+#define	RSTN_U0_NOC_BUS_CPU_AXI_N	25
+#define	RSTN_U0_NOC_BUS_DISP_AXI_N	26
+#define	RSTN_U0_NOC_BUS_GPU_AXI_N	27
+#define	RSTN_U0_NOC_BUS_ISP_AXI_N	28
+#define	RSTN_U0_NOC_BUS_DDRC_N		29
+#define	RSTN_U0_NOC_BUS_STG_AXI_N	30
+#define	RSTN_U0_NOC_BUS_VDEC_AXI_N	31
+/*
+ * group[1]: syscrg: assert1
+ */
+#define	RSTN_U0_NOC_BUS_VENC_AXI_N	32
+#define	RSTN_U0_AXI_CFG1_DEC_AHB	33
+#define	RSTN_U0_AXI_CFG1_DEC_MAIN	34
+#define	RSTN_U0_AXI_CFG0_DEC_MAIN	35
+#define	RSTN_U0_AXI_CFG0_DEC_MAIN_DIV	36
+#define	RSTN_U0_AXI_CFG0_DEC_HIFI4	37
+#define	RSTN_U0_DDR_AXI			38
+#define	RSTN_U0_DDR_OSC			39
+#define	RSTN_U0_DDR_APB			40
+#define	RSTN_U0_DOM_ISP_TOP_N		41
+#define	RSTN_U0_DOM_ISP_TOP_AXI		42
+#define	RSTN_U0_DOM_VOUT_TOP_SRC	43
+#define	RSTN_U0_CODAJ12_AXI		44
+#define	RSTN_U0_CODAJ12_CORE		45
+#define	RSTN_U0_CODAJ12_APB		46
+#define	RSTN_U0_WAVE511_AXI		47
+#define	RSTN_U0_WAVE511_BPU		48
+#define	RSTN_U0_WAVE511_VCE		49
+#define	RSTN_U0_WAVE511_APB		50
+#define	RSTN_U0_VDEC_JPG_ARB_JPG	51
+#define	RSTN_U0_VDEC_JPG_ARB_MAIN	52
+#define	RSTN_U0_AXIMEM_128B_AXI		53
+#define	RSTN_U0_WAVE420L_AXI		54
+#define	RSTN_U0_WAVE420L_BPU		55
+#define	RSTN_U0_WAVE420L_VCE		56
+#define	RSTN_U0_WAVE420L_APB		57
+#define	RSTN_U1_AXIMEM_128B_AXI		58
+#define	RSTN_U2_AXIMEM_128B_AXI		59
+#define	RSTN_U0_INTMEM_ROM_SRAM_ROM	60
+#define	RSTN_U0_CDNS_QSPI_AHB		61
+#define	RSTN_U0_CDNS_QSPI_APB		62
+#define	RSTN_U0_CDNS_QSPI_REF		63
+/*
+ * group[2]: syscrg: assert2
+ */
+#define	RSTN_U0_DW_SDIO_AHB		64
+#define	RSTN_U1_DW_SDIO_AHB		65
+#define	RSTN_U1_DW_GMAC5_AXI64_A_I	66
+#define	RSTN_U1_DW_GMAC5_AXI64_H_N	67
+#define	RSTN_U0_MAILBOX_RRESETN		68
+#define	RSTN_U0_SSP_SPI_APB		69
+#define	RSTN_U1_SSP_SPI_APB		70
+#define	RSTN_U2_SSP_SPI_APB		71
+#define	RSTN_U3_SSP_SPI_APB		72
+#define	RSTN_U4_SSP_SPI_APB		73
+#define	RSTN_U5_SSP_SPI_APB		74
+#define	RSTN_U6_SSP_SPI_APB		75
+#define	RSTN_U0_DW_I2C_APB		76
+#define	RSTN_U1_DW_I2C_APB		77
+#define	RSTN_U2_DW_I2C_APB		78
+#define	RSTN_U3_DW_I2C_APB		79
+#define	RSTN_U4_DW_I2C_APB		80
+#define	RSTN_U5_DW_I2C_APB		81
+#define	RSTN_U6_DW_I2C_APB		82
+#define	RSTN_U0_DW_UART_APB		83
+#define	RSTN_U0_DW_UART_CORE		84
+#define	RSTN_U1_DW_UART_APB		85
+#define	RSTN_U1_DW_UART_CORE		86
+#define	RSTN_U2_DW_UART_APB		87
+#define	RSTN_U2_DW_UART_CORE		88
+#define	RSTN_U3_DW_UART_APB		89
+#define	RSTN_U3_DW_UART_CORE		90
+#define	RSTN_U4_DW_UART_APB		91
+#define	RSTN_U4_DW_UART_CORE		92
+#define	RSTN_U5_DW_UART_APB		93
+#define	RSTN_U5_DW_UART_CORE		94
+#define	RSTN_U0_CDNS_SPDIF_APB		95
+/*
+ * group[3]: syscrg: assert3
+ */
+#define	RSTN_U0_PWMDAC_APB		96
+#define	RSTN_U0_PDM_4MIC_DMIC		97
+#define	RSTN_U0_PDM_4MIC_APB		98
+#define	RSTN_U0_I2SRX_3CH_APB		99
+#define	RSTN_U0_I2SRX_3CH_BCLK		100
+#define	RSTN_U0_I2STX_4CH_APB		101
+#define	RSTN_U0_I2STX_4CH_BCLK		102
+#define	RSTN_U1_I2STX_4CH_APB		103
+#define	RSTN_U1_I2STX_4CH_BCLK		104
+#define	RSTN_U0_TDM16SLOT_AHB		105
+#define	RSTN_U0_TDM16SLOT_TDM		106
+#define	RSTN_U0_TDM16SLOT_APB		107
+#define	RSTN_U0_PWM_8CH_APB		108
+#define	RSTN_U0_DSKIT_WDT_APB		109
+#define	RSTN_U0_DSKIT_WDT_CORE		110
+#define	RSTN_U0_CAN_CTRL_APB		111
+#define	RSTN_U0_CAN_CTRL_CORE		112
+#define	RSTN_U0_CAN_CTRL_TIMER		113
+#define	RSTN_U1_CAN_CTRL_APB		114
+#define	RSTN_U1_CAN_CTRL_CORE		115
+#define	RSTN_U1_CAN_CTRL_TIMER		116
+#define	RSTN_U0_SI5_TIMER_APB		117
+#define	RSTN_U0_SI5_TIMER_TIMER0	118
+#define	RSTN_U0_SI5_TIMER_TIMER1	119
+#define	RSTN_U0_SI5_TIMER_TIMER2	120
+#define	RSTN_U0_SI5_TIMER_TIMER3	121
+#define	RSTN_U0_INT_CTRL_APB		122
+#define	RSTN_U0_TEMP_SENSOR_APB		123
+#define	RSTN_U0_TEMP_SENSOR_TEMP	124
+#define	RSTN_U0_JTAG_CERTIFICATION_N	125
+/*
+ * group[4]: stgcrg
+ */
+#define	RSTN_U0_STG_SYSCON_PRESETN	128
+#define	RSTN_U0_HIFI4_CORE		129
+#define	RSTN_U0_HIFI4_AXI		130
+#define	RSTN_U0_SEC_TOP_HRESETN		131
+#define	RSTN_U0_E24_CORE		132
+#define	RSTN_U0_DW_DMA1P_AXI		133
+#define	RSTN_U0_DW_DMA1P_AHB		134
+#define	RSTN_U0_CDN_USB_AXI		135
+#define	RSTN_U0_CDN_USB_APB		136
+#define	RSTN_U0_CDN_USB_UTMI_APB	137
+#define	RSTN_U0_CDN_USB_PWRUP		138
+#define	RSTN_U0_PLDA_PCIE_AXI_MST0	139
+#define	RSTN_U0_PLDA_PCIE_AXI_SLV0	140
+#define	RSTN_U0_PLDA_PCIE_AXI_SLV	141
+#define	RSTN_U0_PLDA_PCIE_BRG		142
+#define	RSTN_U0_PLDA_PCIE_CORE		143
+#define	RSTN_U0_PLDA_PCIE_APB		144
+#define	RSTN_U1_PLDA_PCIE_AXI_MST0	145
+#define	RSTN_U1_PLDA_PCIE_AXI_SLV0	146
+#define	RSTN_U1_PLDA_PCIE_AXI_SLV	147
+#define	RSTN_U1_PLDA_PCIE_BRG		148
+#define	RSTN_U1_PLDA_PCIE_CORE		149
+#define	RSTN_U1_PLDA_PCIE_APB		150
+/*
+ * group[5]: aoncrg
+ */
+#define	RSTN_U0_DW_GMAC5_AXI64_AXI	160
+#define	RSTN_U0_DW_GMAC5_AXI64_AHB	161
+#define	RSTN_U0_AON_IOMUX_PRESETN	162
+#define	RSTN_U0_PMU_APB			163
+#define	RSTN_U0_PMU_WKUP		164
+#define	RSTN_U0_RTC_HMS_APB		165
+#define	RSTN_U0_RTC_HMS_CAL		166
+#define	RSTN_U0_RTC_HMS_OSC32K		167
+/*
+ * group[6]: ispcrg
+ */
+#define	RSTN_U0_ISPV2_TOP_WRAPPER_P	192
+#define	RSTN_U0_ISPV2_TOP_WRAPPER_C	193
+#define	RSTN_U0_M31DPHY_HW		194
+#define	RSTN_U0_M31DPHY_B09_ALWAYS_ON	195
+#define	RSTN_U0_VIN_N_PCLK		196
+#define	RSTN_U0_VIN_N_PIXEL_CLK_IF0	197
+#define	RSTN_U0_VIN_N_PIXEL_CLK_IF1	198
+#define	RSTN_U0_VIN_N_PIXEL_CLK_IF2	199
+#define	RSTN_U0_VIN_N_PIXEL_CLK_IF3	200
+#define	RSTN_U0_VIN_N_SYS_CLK		201
+#define	RSTN_U0_VIN_P_AXIRD		202
+#define	RSTN_U0_VIN_P_AXIWR		203
+/*
+ * group[7]: voutcrg
+ */
+#define	RSTN_U0_DC8200_AXI		224
+#define	RSTN_U0_DC8200_AHB		225
+#define	RSTN_U0_DC8200_CORE		226
+#define	RSTN_U0_CDNS_DSITX_DPI		227
+#define	RSTN_U0_CDNS_DSITX_APB		228
+#define	RSTN_U0_CDNS_DSITX_RXESC	229
+#define	RSTN_U0_CDNS_DSITX_SYS		230
+#define	RSTN_U0_CDNS_DSITX_TXBYTEHS	231
+#define	RSTN_U0_CDNS_DSITX_TXESC	232
+#define	RSTN_U0_HDMI_TX_HDMI		233
+#define	RSTN_U0_MIPITX_DPHY_SYS		234
+#define	RSTN_U0_MIPITX_DPHY_TXBYTEHS	235
+
+#define	RSTN_JH7110_RESET_END		236
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_H__ */

+ 147 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/starfive_visionfive2.dts

@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "jh7110.dtsi"
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	model = "StarFive VisionFive V2";
+	compatible = "starfive,jh7110";
+
+	aliases {
+		spi0="/soc/spi@13010000";
+		gpio0="/soc/gpio@13040000";
+		ethernet0=&gmac0;
+		ethernet1=&gmac1;
+		mmc0=&sdio0;
+		mmc1=&sdio1;
+		i2c0 = &i2c5;
+	};
+
+	chosen {
+			stdout-path = "/soc/serial@10000000:115200";
+	};
+
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x40000000 0x1 0x0>;
+	};
+
+	soc {
+	};
+};
+
+&cpu0 {
+	status = "okay";
+};
+
+&clkgen {
+	clocks = <&osc>, <&gmac1_rmii_refin>,
+		<&stg_apb>, <&gmac0_rmii_refin>;
+	clock-names = "osc", "gmac1_rmii_refin",
+		"stg_apb", "gmac0_rmii_refin";
+};
+
+&sdio0 {
+	fifo-depth = <32>;
+	bus-width = <8>;
+	status = "okay";
+};
+
+&sdio1 {
+	fifo-depth = <32>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&gmac0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	phy0: ethernet-phy@0 {
+		rxc_dly_en = <1>;
+		tx_delay_sel_fe = <5>;
+		tx_delay_sel = <0xa>;
+		tx_inverted_10 = <0x1>;
+		tx_inverted_100 = <0x1>;
+		tx_inverted_1000 = <0x1>;
+	};
+};
+
+&gmac1 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	phy1: ethernet-phy@1 {
+		tx_delay_sel_fe = <5>;
+		tx_delay_sel = <0>;
+		rxc_dly_en = <0>;
+		tx_inverted_10 = <0x1>;
+		tx_inverted_100 = <0x1>;
+		tx_inverted_1000 = <0x0>;
+	};
+};
+
+&gpio {
+	compatible = "starfive,jh7110-gpio";
+	gpio-controller;
+};
+
+&uart0 {
+	reg-offset = <0>;
+	current-speed = <115200>;
+	status = "okay";
+};
+
+&i2c5 {
+	clock-frequency = <100000>;
+	i2c-sda-hold-time-ns = <300>;
+	i2c-sda-falling-time-ns = <3000>;
+	i2c-scl-falling-time-ns = <3000>;
+	auto_calc_scl_lhcnt;
+	status = "okay";
+
+	eeprom@50 {
+		compatible = "atmel,24c04";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
+
+	pmic: axp15060_reg@36 {
+               compatible = "stf,axp15060-regulator";
+               reg = <0x36>;
+	};
+};
+
+&gpioa {
+	status = "disabled";
+};
+
+&usbdrd30 {
+	status = "okay";
+};
+
+&usbdrd_cdns3 {
+	dr_mode = "host";
+};
+
+&timer {
+	status = "disabled";
+};
+
+&wdog {
+	status = "disabled";
+};
+
+&clkvout {
+	status = "disabled";
+};
+
+&pdm {
+	status = "disabled";
+};

+ 25 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.dec

@@ -0,0 +1,25 @@
+## @file  U540.dec
+# This Package provides SiFive U540 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              = 0x0001001b
+  PACKAGE_NAME                   = JH7110
+  PACKAGE_UNI_FILE               = JH7110.uni
+  PACKAGE_GUID                   = B6569821-3FC0-4FE8-B98A-67CE1517C747
+  PACKAGE_VERSION                = 1.0
+
+[Includes]
+
+[LibraryClasses]
+
+[Guids]
+  gUefiRiscVPlatformU540PkgTokenSpaceGuid  = {0xDFD87009, 0x27A1, 0x41DD, { 0x84, 0xB1, 0x35, 0xB4, 0xB9, 0x0D, 0x17, 0x63 }}
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  JH7110PkgExtra.uni

+ 587 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.dsc

@@ -0,0 +1,587 @@
+## @file
+#  RISC-V EFI on SiFive Freedom U540 HiFive Unleashed RISC-V platform
+#
+#  Copyright (c) 2019-2021, 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                  = JH7110
+  PLATFORM_GUID                  = 8317E90F-428B-403F-9057-112B0C19008E
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x0001001c
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+  SUPPORTED_ARCHITECTURES        = RISCV64
+  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.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.
+#
+################################################################################
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[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
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.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/StarFive/JH7110SeriesPkg/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
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+  VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+
+# RISC-V Platform Library
+  TimeBaseLib|EmbeddedPkg//Library/TimeBaseLib/TimeBaseLib.inf
+  RealTimeClockLib|EmbeddedPkg//Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+
+# RISC-V Core Library
+  RiscVOpensbiLib|Silicon/RISC-V/ProcessorPkg/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
+  SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.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|Silicon/RISC-V/ProcessorPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
+  RiscVEdk2SbiLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf
+  RiscVPlatformTimerLib|Platform/StarFive/JH7110SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf
+  #MachineModeTimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVReadMachineModeTimer/MachineModeTimerLib/MachineModeTimerLib.inf
+  MachineModeTimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVReadMachineModeTimer/EmulatedMachineModeTimerLib/EmulatedMachineModeTimerLib.inf
+  CpuExceptionHandlerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
+
+
+  # Flattened Device Tree (FDT) access library
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.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
+  Edk2OpensbiPlatformWrapperLib|Platform/RISC-V/PlatformPkg/Library/Edk2OpensbiPlatformWrapperLib/Edk2OpensbiPlatformWrapperLib.inf
+  RiscVSpecialPlatformLib|Platform/StarFive/JH7110SeriesPkg/JH7110Board/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+
+#
+# OpenSBi Platform Library
+#
+  RiscVOpensbiPlatformLib|Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|Silicon/RISC-V/ProcessorPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
+  RiscVFirmwareContextLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVFirmwareContextSscratchLib/RiscVFirmwareContextSscratchLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.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
+  # RISC-V platform PEI core entry point.
+  PeiCoreEntryPoint|Platform/RISC-V/PlatformPkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PlatformSecPpiLib|Platform/StarFive/JH7110SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|Silicon/RISC-V/ProcessorPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
+  RiscVFirmwareContextLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVFirmwareContextSscratchLib/RiscVFirmwareContextSscratchLib.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/RISC-V/PlatformPkg/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf
+
+#
+# RISC-V core libraries
+#
+  SiliconSiFiveU54CoreInfoLib|Silicon/SiFive/U54/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
+  RiscVCoreplexInfoLib|Platform/StarFive/JH7110SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  TimerLib|Silicon/RISC-V/ProcessorPkg/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
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|Silicon/RISC-V/ProcessorPkg/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
+  ResetSystemLib|Platform/RISC-V/PlatformPkg/Library/ResetSystemLib/ResetSystemLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|Silicon/RISC-V/ProcessorPkg/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
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|Silicon/RISC-V/ProcessorPkg/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/RISC-V/PlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  PlatformMemoryTestLib|Platform/RISC-V/PlatformPkg/Library/PlatformMemoryTestLibNull/PlatformMemoryTestLibNull.inf
+  PlatformUpdateProgressLib|Platform/RISC-V/PlatformPkg/Library/PlatformUpdateProgressLibNull/PlatformUpdateProgressLibNull.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|Silicon/RISC-V/ProcessorPkg/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
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+[PcdsFixedAtBuild]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+  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
+
+!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 }
+
+ #
+  # DW MMC/SD card controller
+  #
+  gDesignWareTokenSpaceGuid.PcdDwEmmcDxeBaseAddress|0x16020000
+  gDesignWareTokenSpaceGuid.PcdDwEmmcDxeClockFrequencyInHz|198000000
+  gDesignWareTokenSpaceGuid.PcdDwEmmcDxeMaxClockFreqInHz|198000000
+  gDesignWareTokenSpaceGuid.PcdDwPermitObsoleteDrivers|TRUE
+  gDesignWareTokenSpaceGuid.PcdDwEmmcDxeFifoDepth|32
+
+################################################################################
+#
+# 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/RISC-V/PlatformPkg/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/RISC-V/PlatformPkg/Universal/Pei/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+  Platform/RISC-V/PlatformPkg/Universal/FdtPeim/FdtPeim.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
+
+  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
+  }
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+
+  #
+  # RISC-V Platform module
+  #
+  Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf
+  Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+  #
+  # RISC-V Core module
+  #
+  Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe/CpuDxe.inf
+  Silicon/RISC-V/ProcessorPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.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
+
+  Platform/StarFive/JH7110SeriesPkg/JH7110Board/DeviceTree/JH7110DeviceTree.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+  #
+  # Network Support
+  #
+  !include NetworkPkg/Network.dsc.inc
+
+  #
+  # sdio/mmc support
+  #
+  EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.inf
+
+  #
+  # 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
+
+  Silicon/RISC-V/ProcessorPkg/Universal/FdtDxe/FdtDxe.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning + UDF filesystem
+  #
+  FatPkg/EnhancedFatDxe/Fat.inf
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+
+  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+    <LibraryClasses>
+      ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+      SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.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
+      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
+  

+ 341 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.fdf

@@ -0,0 +1,341 @@
+# @file
+#  Flash definition file on SiFive Freedom U540 HiFive Unleashed RISC-V platform
+#
+#  Copyright (c) 2019-2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Platform definitions
+#
+!include JH7110.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.JH7110]
+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
+!include DeviceTree.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/RISC-V/PlatformPkg/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/RISC-V/PlatformPkg/Universal/Pei/PlatformPei/PlatformPei.inf
+INF  Platform/RISC-V/PlatformPkg/Universal/FdtPeim/FdtPeim.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/StarFive/JH7110SeriesPkg/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
+INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+
+# RISC-V Platform Drivers
+INF  Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+# RISC-V Core Drivers
+INF  Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf
+INF  Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe/CpuDxe.inf
+INF  Silicon/RISC-V/ProcessorPkg/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/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
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+INF  Silicon/RISC-V/ProcessorPkg/Universal/FdtDxe/FdtDxe.inf
+
+!ifndef $(SOURCE_DEBUG_ENABLE)
+INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+!endif
+
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.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
+
+#
+# SDIO/MMC support
+#
+INF  EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+INF  Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.inf
+
+#
+# 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
+  }
+
+[Rule.Common.USER_DEFINED.DTB]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW BIN                |.dtb
+  }

+ 107 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.fdf.inc

@@ -0,0 +1,107 @@
+## @file
+#  Definitions of Flash definition file on SiFive Freedom U540 HiFive Unleashed RISC-V platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+DEFINE BLOCK_SIZE        = 0x1000
+
+DEFINE FW_BASE_ADDRESS   = 0x40000000
+DEFINE FW_SIZE           = 0x00400000
+DEFINE FW_BLOCKS         = 0x400
+
+#
+# 0x000000-0x7DFFFF code
+# 0x7E0000-0x800000 variables
+#
+DEFINE CODE_BASE_ADDRESS = 0x40000000
+DEFINE CODE_SIZE         = 0x00380000
+DEFINE CODE_BLOCKS       = 0x3800
+DEFINE VARS_BLOCKS       = 0x20
+
+#
+# SEC + opensbi library is the root FW domain.
+# The base address must be round up to log2.
+#
+DEFINE SECFV_OFFSET        = 0x00000000
+DEFINE SECFV_SIZE          = 0x00040000
+DEFINE ROOT_FW_DOMAIN_SIZE = $(SECFV_SIZE)
+
+#
+# Other FV regions are in the second FW domain.
+# The size of memory region must be power of 2.
+# The base address must be aligned with the size.
+#
+# FW memory region
+#
+DEFINE PEIFV_OFFSET                  = 0x00200000
+DEFINE PEIFV_SIZE                    = 0x00060000
+DEFINE FVMAIN_OFFSET                 = 0x00260000
+DEFINE FVMAIN_SIZE                   = 0x00120000
+
+#
+# EFI Variable memory region.
+# The total size of EFI Variable FD must include
+# all of sub regions of EFI Variable
+#
+DEFINE VARS_OFFSET                   = 0x00380000
+DEFINE VARS_SIZE                     = 0x00007000
+DEFINE VARS_FTW_WORKING_OFFSET       = 0x00387000
+DEFINE VARS_FTW_WORKING_SIZE         = 0x00001000
+DEFINE VARS_FTW_SPARE_OFFSET         = 0x00388000
+DEFINE VARS_FTW_SPARE_SIZE           = 0x00018000
+
+#
+# Device Tree memory region
+#
+DEFINE DTB_OFFSET                    = 0x003a0000
+DEFINE DTB_SIZE                      = 0x00008000
+
+#
+# Scratch area memory region
+#
+DEFINE SCRATCH_OFFSET                = 0x003c0000
+DEFINE SCRATCH_SIZE                  = 0x00010000
+
+
+DEFINE FW_DOMAIN_SIZE    = $(FVMAIN_OFFSET) + $(FVMAIN_SIZE) - $(PEIFV_OFFSET)
+DEFINE VARIABLE_FW_SIZE  = $(VARS_FTW_SPARE_OFFSET) + $(VARS_FTW_SPARE_SIZE) - $(VARS_OFFSET)
+
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress = $(CODE_BASE_ADDRESS) + $(SECFV_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize        = $(ROOT_FW_DOMAIN_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress     = $(CODE_BASE_ADDRESS) + $(PEIFV_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize            = $(FW_DOMAIN_SIZE)
+
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress = $(FW_BASE_ADDRESS) + $(VARS_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize        = $(VARS_SIZE) + $(VARS_FTW_WORKING_SIZE) + $(VARS_FTW_SPARE_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize   = $(BLOCK_SIZE)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress = $(CODE_BASE_ADDRESS) + $(VARS_OFFSET)
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize        = $(VARIABLE_FW_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    = 4000000
+SET gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock = 24000000 # 1GHz system clock
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId                  = 1          # Boot hart ID
+
+#
+# The bootable hart number the platform would like to use during boot.
+#
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber          = 4
+#
+# Only use hart ID 1, 2, 3, 4
+#
+SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartIndexToId       = {0x1,0x2,0x3,0x4}
+                                                                                    # during boot
+SET gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU5Cores       = 4          # Total U5 cores enabled on U540 platform
+SET gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported         = True       # E51 MC exists.
+SET gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase            = 0x10000000 # Serial port base address
+

+ 13 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110.uni

@@ -0,0 +1,13 @@
+// /** @file
+// SiFive U540 HiFive Unleashed 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 StarFIve JH7110 platform modules and libraries"
+
+#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package StarFIve JH7110 platform modules and libraries."

+ 12 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/JH7110PkgExtra.uni

@@ -0,0 +1,12 @@
+// /** @file
+// SiFive U540 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
+"StarFive JH7110 board package"

+ 36 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf

@@ -0,0 +1,36 @@
+## @file
+#  Null library instance to provide platform_override for the
+#  special RISC-V platform. This module incorporates with
+#  OpensbiPlatformLib and RISC-V Opensbi library.
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = RiscVSpecialPlatformLib
+  FILE_GUID                      = FE0AE3E6-90A4-421D-851D-E092CBEEE645
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RiscVSpecialPlatformLib|SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  StarFiveJH7110.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+[LibraryClasses]
+  BaseLib

+ 57 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/Library/RiscVSpecialPlatformLib/StarFiveJH7110.c

@@ -0,0 +1,57 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *   Anup Patel <anup.patel@wdc.com>
+
+   Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+ */
+
+#include <Library/RiscVSpecialPlatformLib.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_fixup.h>
+
+static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
+{
+  /*
+   * The sfence.vma by virtual address does not work on
+   * SiFive FU540 so we return remote TLB flush limit as zero.
+   */
+  return 0;
+}
+
+static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
+{
+  /*
+   * SiFive Freedom U540 has an erratum that prevents S-mode software
+   * to access a PMP protected region using 1GB page table mapping, so
+   * always add the no-map attribute on this platform.
+   */
+  fdt_reserved_memory_nomap_fixup(fdt);
+
+  return 0;
+}
+
+static const struct fdt_match sifive_fu540_match[] = {
+  { .compatible = "sifive,fu540" },
+  { .compatible = "sifive,fu540g" },
+  { .compatible = "sifive,fu540-c000" },
+  { .compatible = "sifive,hifive-unleashed-a00" },
+  { .compatible = "starfive,jh7110" },
+  { },
+};
+
+const struct platform_override sifive_fu540 = {
+  .match_table = sifive_fu540_match,
+  .tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
+  .fdt_fixup = sifive_fu540_fdt_fixup,
+};
+
+const struct platform_override *special_platforms[] = {
+  &sifive_fu540,
+};
+INTN NumberOfPlaformsInArray = array_size(special_platforms);

+ 78 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110Board/VarStore.fdf.inc

@@ -0,0 +1,78 @@
+## @file
+#  FDF include file with Layout Regions that define an empty variable store.
+#
+#  Copyright (c) 2021, 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)|$(VARS_SIZE)
+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
+}
+
+$(VARS_FTW_WORKING_OFFSET)|$(VARS_FTW_WORKING_SIZE)
+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
+}
+
+$(VARS_FTW_SPARE_OFFSET)|$(VARS_FTW_SPARE_SIZE)
+gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#
+#NV_FTW_SPARE

+ 34 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec

@@ -0,0 +1,34 @@
+## @file  U5SeriesPkg.dec
+# This Package provides modules and libraries.for SiFive U5 series platforms.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001b
+  PACKAGE_NAME                   = JH7110SeriesPkg
+  PACKAGE_UNI_FILE               = JH7110SeriesPkg.uni
+  PACKAGE_GUID                   = AD6E43CA-7FED-4CEA-8151-68B2C5F12B3A
+  PACKAGE_VERSION                = 1.0
+
+[Includes]
+  Include
+
+[LibraryClasses]
+
+[Guids]
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid  = {0x725B804B, 0x10B5, 0x4326, { 0xAD, 0xFF, 0x59, 0xCE, 0x6E, 0xFD, 0x5B, 0x36 }}
+
+[PcdsFixedAtBuild]
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock|0x0|UINT32|0x00001000
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU5Cores|0x8|UINT32|0x00001001
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported|TRUE|BOOLEAN|0x00001002
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase|0x0|UINT32|0x00001003
+
+[PcdsPatchableInModule]
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  JH7110SeriesPkg.uni

+ 13 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.uni

@@ -0,0 +1,13 @@
+// /** @file
+// SiFive U5 Series 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 StarFIve RISC-V JH7110 platform modules and libraries"
+
+#string STR_PACKAGE_DESCRIPTION         #language en-US "This Package StarFIve RISC-V JH7110 platform modules and libraries."

+ 12 - 0
Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkgExtra.uni

@@ -0,0 +1,12 @@
+// /** @file
+// SiFive U5 Series 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
+"StarFive JH7110 series platform package"

+ 188 - 0
Platform/StarFive/JH7110SeriesPkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c

@@ -0,0 +1,188 @@
+/**@file
+  Build up platform processor information.
+
+  Copyright (c) 2021, 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 <ProcessorSpecificHobData.h>
+#include <SiFiveU5MCCoreplex.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.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateU5MCCoreplexProcessorSpecificDataHob (
+  IN UINTN UniqueId
+  )
+{
+  EFI_STATUS Status;
+  UINT32 HartIdNumber;
+  RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *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 = CreateU54E51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, FALSE, TRUE, &GuidHobData);
+    if (EFI_ERROR (Status) && Status != EFI_UNSUPPORTED) {
+      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
+      ASSERT (FALSE);
+    } else {
+      if (!EFI_ERROR (Status)) {
+        DEBUG((DEBUG_INFO, "Support E5 Monitor core on U5 platform, HOB at address 0x%x\n", GuidHobData));
+      }
+    }
+    HartIdNumber ++;
+  }
+  for (; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) + (UINT32)MCSupport); HartIdNumber ++) {
+    Status = CreateU54E51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32 (PcdBootHartId)), FALSE, &GuidHobData);
+    if (EFI_ERROR (Status) && Status != EFI_UNSUPPORTED) {
+      DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n"));
+      ASSERT (FALSE);
+    }  else {
+      if (!EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_INFO, "Support U5 application core on U5 platform, HOB Data at address 0x%x\n", GuidHobData));
+      }
+    }
+  }
+  DEBUG ((DEBUG_INFO, "Support %d U5 application cores on U5 platform\n", HartIdNumber - (UINT32)MCSupport));
+
+  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 physical processor which owns this core.
+  @param  SmbiosHobPtr    Pointer to receive RISC_V_PROCESSOR_SMBIOS_HOB_DATA. 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 SMBIOS Hobs were created successfully.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateU5MCProcessorSmbiosDataHob (
+  IN UINTN     ProcessorUid,
+  OUT RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr
+  )
+{
+  EFI_GUID *GuidPtr;
+  RISC_V_PROCESSOR_TYPE7_HOB_DATA L2CacheDataHob;
+  RISC_V_PROCESSOR_SMBIOS_HOB_DATA SmbiosDataHob;
+  RISC_V_PROCESSOR_TYPE4_HOB_DATA *ProcessorDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1CacheDataHobPtr;
+  RISC_V_PROCESSOR_TYPE7_HOB_DATA *L2CacheDataHobPtr;
+  RISC_V_PROCESSOR_SMBIOS_HOB_DATA *SmbiosDataHobPtr;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
+
+  if (SmbiosHobPtr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CreateU54SmbiosType7L1DataHob (ProcessorUid, &L1CacheDataHobPtr);
+  CreateU54SmbiosType4DataHob (ProcessorUid, &ProcessorDataHobPtr);
+
+  //
+  // Build up SMBIOS type 7 L2 cache record.
+  //
+  ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA));
+  L2CacheDataHob.ProcessorGuid = *((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_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA));
+  if (L2CacheDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n"));
+    ASSERT (FALSE);
+  }
+
+  ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA));
+  SmbiosDataHob.Processor = ProcessorDataHobPtr;
+  SmbiosDataHob.L1Cache = L1CacheDataHobPtr;
+  SmbiosDataHob.L2Cache = L2CacheDataHobPtr;
+  SmbiosDataHob.L3Cache = NULL;
+
+  GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid);
+  SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA));
+  if (SmbiosDataHobPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n"));
+    ASSERT (FALSE);
+  }
+  *SmbiosHobPtr = SmbiosDataHobPtr;
+  DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Build processor and platform information for the U5 platform
+
+  @return EFI_SUCCESS     Status.
+
+**/
+EFI_STATUS
+BuildRiscVSmbiosHobs (
+  VOID
+)
+{
+  EFI_STATUS Status;
+  RISC_V_PROCESSOR_SMBIOS_HOB_DATA *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;
+}

+ 58 - 0
Platform/StarFive/JH7110SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf

@@ -0,0 +1,58 @@
+## @file
+#  Library instance to create core information HOB
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = SiliconSiFiveU5MCCoreplexInfoLib
+  FILE_GUID                      = 4E397A71-5164-4E69-9884-70CBE2740AAB
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RiscVCoreplexInfoLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+ CoreInfoHob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec
+  Silicon/SiFive/SiFive.dec
+  Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  MemoryAllocationLib
+  PcdLib
+  PrintLib
+  RiscVFirmwareContextLib
+  SiliconSiFiveU54CoreInfoLib
+
+[Guids]
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid
+
+[Ppis]
+
+[FixedPcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+  gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+  gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU54CoreGuid
+  gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveE51CoreGuid
+  gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU5MCCoreplexGuid
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU5Cores
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId

+ 148 - 0
Platform/StarFive/JH7110SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.c

@@ -0,0 +1,148 @@
+/**@file
+  Library to install platform PPI before PEI Core
+
+  Copyright (c) 2021, 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>
+
+#include <IndustryStandard/RiscVOpensbi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PlatformSecPpiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/RiscVFirmwareContextLib.h>
+
+#include <Ppi/TemporaryRamDone.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+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
+  );
+
+STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+  TemporaryRamMigration
+};
+
+STATIC EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
+  TemporaryRamDone
+};
+
+STATIC 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
+  },
+};
+
+/** Temporary RAM migration function.
+
+  This function migrates the data from temporary RAM to permanent
+  memory.
+
+  @param[in]  PeiServices           PEI service
+  @param[in]  TemporaryMemoryBase   Temporary memory base address
+  @param[in]  PermanentMemoryBase   Permanent memory base address
+  @param[in]  CopySize              Size to copy
+
+**/
+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;
+  EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext;
+
+  DEBUG ((DEBUG_INFO,
+    "%a: Temp Mem Base:0x%Lx, Permanent Mem Base:0x%Lx, CopySize:0x%Lx\n",
+    __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
+  //
+  GetFirmwareContextPointer (&FirmwareContext);
+  FirmwareContext = (VOID *)FirmwareContext + (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+  SetFirmwareContextPointer (FirmwareContext);
+
+  //
+  // Relocate PEI Service **
+  //
+  FirmwareContext->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+  DEBUG ((DEBUG_INFO, "%a: OpenSBI Firmware Context is relocated to 0x%x\n", __FUNCTION__, FirmwareContext));
+  DEBUG ((DEBUG_INFO, "OpenSBI Firmware Context at 0x%x\n", FirmwareContext));
+  DEBUG ((DEBUG_INFO, "             PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable));
+
+  register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack);
+  asm volatile ("add sp, sp, a0"::"r"(a0):);
+  return EFI_SUCCESS;
+}
+
+/** Temprary RAM done function.
+
+**/
+EFI_STATUS EFIAPI TemporaryRamDone (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: 2nd time PEI core, temporary ram done.\n", __FUNCTION__));
+  return EFI_SUCCESS;
+}
+/** Return platform SEC PPI before PEI Core
+
+  @param[in,out]  ThisPpiList   Pointer to retrieve EFI_PEI_PPI_DESCRIPTOR.
+
+**/
+EFI_STATUS
+GetPlatformPrePeiCorePpiDescriptor (
+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **ThisPpiList
+)
+{
+  *ThisPpiList = mPrivateDispatchTable;
+  return EFI_SUCCESS;
+}
+

+ 43 - 0
Platform/StarFive/JH7110SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf

@@ -0,0 +1,43 @@
+## @file
+#  Library instance to to provide PPI before PEI Core
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = PlatformSecPpiLib
+  FILE_GUID                      = 8F8E049E-F193-427C-998E-1E8FE2612D94
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecPpiLib|PEI_CORE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+ PlatformSecPpiLib.c
+
+[Ppis]
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+  gEfiTemporaryRamDonePpiGuid    # PPI ALWAYS_PRODUCED
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  MemoryAllocationLib
+  PrintLib
+  RiscVFirmwareContextLib

+ 48 - 0
Platform/StarFive/JH7110SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S

@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+//
+// SiFive U5 Series 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 <RiscVImpl.h>
+#include <U5Clint.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

+ 36 - 0
Platform/StarFive/JH7110SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf

@@ -0,0 +1,36 @@
+## @file
+# RISC-V CPU lib to override timer mechanism for U5 series platform.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  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           = RISCV64
+#
+
+[Sources]
+
+[Sources.RISCV64]
+  RiscVPlatformTimerLib.S
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+
+

+ 39 - 0
Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/SerialIoLib.inf

@@ -0,0 +1,39 @@
+## @file
+#   Library instance for SerialIo library class
+#
+#  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = JH7110SerialPortLib
+  MODULE_UNI_FILE                = JH7110SerialPortLib.uni
+  FILE_GUID                      = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+[Packages]
+  MdePkg/MdePkg.dec
+  Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+  Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  RiscVOpensbiLib
+
+[FixedPcd]
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase
+  gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock
+
+[Sources]
+  SerialPortLib.c

+ 424 - 0
Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/SerialPortLib.c

@@ -0,0 +1,424 @@
+/** @file
+  UART Serial Port library functions
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/SerialPortLib.h>
+#include <Include/StarFiveUart.h>
+
+//---------------------------------------------
+// UART Register Offsets
+//---------------------------------------------
+
+#define UART_RBR_OFFSET		0	/* In:  Recieve Buffer Register */
+#define UART_THR_OFFSET		0	/* Out: Transmitter Holding Register */
+#define UART_DLL_OFFSET		0	/* Out: Divisor Latch Low */
+#define UART_IER_OFFSET		1	/* I/O: Interrupt Enable Register */
+#define UART_DLM_OFFSET		1	/* Out: Divisor Latch High */
+#define UART_FCR_OFFSET		2	/* Out: FIFO Control Register */
+#define UART_IIR_OFFSET		2	/* I/O: Interrupt Identification Register */
+#define UART_LCR_OFFSET		3	/* Out: Line Control Register */
+#define UART_MCR_OFFSET		4	/* Out: Modem Control Register */
+#define UART_LSR_OFFSET		5	/* In:  Line Status Register */
+#define UART_MSR_OFFSET		6	/* In:  Modem Status Register */
+#define UART_SCR_OFFSET		7	/* I/O: Scratch Register */
+#define UART_MDR1_OFFSET	8	/* I/O:  Mode Register */
+
+#define UART_LSR_FIFOE		0x80	/* Fifo error */
+#define UART_LSR_TEMT		0x40	/* Transmitter empty */
+#define UART_LSR_THRE		0x20	/* Transmit-hold-register empty */
+#define UART_LSR_BI		0x10	/* Break interrupt indicator */
+#define UART_LSR_FE		0x08	/* Frame error indicator */
+#define UART_LSR_PE		0x04	/* Parity error indicator */
+#define UART_LSR_OE		0x02	/* Overrun error indicator */
+#define UART_LSR_DR		0x01	/* Receiver data ready */
+#define UART_LSR_BRK_ERROR_BITS	0x1E	/* BI, FE, PE, OE bits */
+
+//---------------------------------------------
+// UART Settings
+//---------------------------------------------
+
+#define UART_BAUDRATE  115200
+#define SYS_CLK        FixedPcdGet32(PcdU5PlatformSystemClock)
+
+BOOLEAN Initiated = TRUE;
+
+/**
+  Get value from serial port register.
+
+  @param  RegIndex   Register index
+
+  @retval Vale returned from from serial port.
+
+**/
+
+#if 0
+
+#endif
+//static UINT32 uart8250_reg_width = 4;
+//static UINT32 uart8250_reg_shift = 2;
+UINT32 GetReg (
+  IN UINT32 RegIndex
+  )
+{
+  STATIC volatile UINT32 * const uart = (UINT32 *)FixedPcdGet32(PcdU5UartBase);
+
+  return readl ((volatile void *)(&uart[RegIndex]));
+}
+
+/**
+  Set serial port register.
+
+  @param RegIndex   Register index
+  @param Value      Value write to Register
+
+**/
+VOID SetReg (
+  IN UINT32 RegIndex,
+  IN UINT32 Value
+  )
+{
+  STATIC volatile UINT32 * const uart = (UINT32 *)FixedPcdGet32(PcdU5UartBase);
+
+  writel (Value, (volatile void *)(&uart[RegIndex]));
+}
+
+/**
+  Character output to serial port.
+
+  @param Ch        The character to serial port.
+
+**/
+VOID StarfiveUartPutChar (
+  IN UINT8 Ch
+  )
+{
+  while ((GetReg (UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
+
+  SetReg (UART_THR_OFFSET, Ch);
+}
+
+/**
+  Get character from serial port.
+
+  @retval character        The character from serial port.
+
+**/
+UINT32 StarfiveUartGetChar (VOID)
+{
+  UINT32 Ret;
+
+  Ret = GetReg (UART_LSR_OFFSET);
+  if (Ret & UART_LSR_DR) {
+    return GetReg(UART_RBR_OFFSET);
+  }
+  return -1;
+}
+/**
+  Find minimum divisor divides in_freq to max_target_hz;
+  Based on uart driver n SiFive FSBL.
+
+  f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1
+  The nearest integer solution requires rounding up as to not exceed max_target_hz.
+  div  = ceil(f_in / f_baud) - 1
+   = floor((f_in - 1 + f_baud) / f_baud) - 1
+  This should not overflow as long as (f_in - 1 + f_baud) does not exceed
+  2^32 - 1, which is unlikely since we represent frequencies in kHz.
+
+  @param Freq         The given clock to UART.
+  @param MaxTargetHZ  Target baudrate.
+
+**/
+#if 0
+UINT32
+UartMinClkDivisor (
+  IN UINT64 Freq,
+  IN UINT64 MaxTargetHZ
+  )
+{
+    UINT64 Quotient;
+
+    Quotient = (Freq + MaxTargetHZ - 1) / (MaxTargetHZ);
+    if (Quotient == 0) {
+        return 0;
+    } else {
+        return Quotient - 1;
+    }
+}
+#endif
+/**
+  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.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+#if 0
+  
+  UINT32 CurrentDivisor;
+
+  Divisor = UartMinClkDivisor (SYS_CLK / 2, UART_BAUDRATE);
+  if (Divisor == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  CurrentDivisor = GetReg(UART_REG_DIV);
+  if (Divisor != CurrentDivisor) {
+    uart8250_init(FixedPcdGet32(PcdU5UartBase),
+                             SYS_CLK/2, /* todo */
+                             UART_BAUDRATE,
+                             0, /* shift */
+                             4);
+  }
+#endif
+#if 0
+  UINT32 bdiv;
+
+  bdiv = (SYS_CLK + 8 * UART_BAUDRATE) / (16 * UART_BAUDRATE);
+  
+  /* Disable all interrupts */
+  SetReg(UART_IER_OFFSET, 0x00);
+  /* Enable DLAB */
+  SetReg(UART_LCR_OFFSET, 0x80);
+  
+  if (bdiv) {
+	  /* Set divisor low byte */
+	  SetReg(UART_DLL_OFFSET, bdiv & 0xff);
+	  /* Set divisor high byte */
+	  SetReg(UART_DLM_OFFSET, (bdiv >> 8) & 0xff);
+  }
+  
+  /* 8 bits, no parity, one stop bit */
+  SetReg(UART_LCR_OFFSET, 0x03);
+  /* Enable FIFO */
+  SetReg(UART_FCR_OFFSET, 0x01);
+  /* No modem control DTR RTS */
+  SetReg(UART_MCR_OFFSET, 0x00);
+  /* Clear line status */
+  GetReg(UART_LSR_OFFSET);
+  /* Read receive buffer */
+  GetReg(UART_RBR_OFFSET);
+  /* Set scratchpad */
+  SetReg(UART_SCR_OFFSET, 0x00);
+#endif
+  return EFI_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 Index;
+
+  if (Buffer == NULL || Initiated == FALSE) {
+    return 0;
+  }
+
+  for(Index = 0; Index < NumberOfBytes; Index ++) {
+    StarfiveUartPutChar (Buffer [Index]);
+  }
+
+  return Index;
+}
+
+/**
+  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 Index;
+
+  if (NULL == Buffer || Initiated == FALSE) {
+    return 0;
+  }
+
+  for (Index = 0; Index < NumberOfBytes; Index ++) {
+    Buffer [Index] = (UINT8)StarfiveUartGetChar ();
+  }
+
+  return Index;
+}
+
+/**
+  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
+  )
+{
+  UINT32 Ret;
+  Ret = GetReg (UART_LSR_OFFSET);
+  if ((Ret & UART_LSR_DR) == UART_LSR_DR)
+     return TRUE;
+#if 0
+  STATIC volatile UINT32 * const uart = (UINT32 *)FixedPcdGet32(PcdU5UartBase);
+  UINT32 IP;
+
+  if (Initiated == FALSE) {
+    return FALSE;
+  }
+  IP = MmioRead32 ((UINTN)(uart + UART_REG_IP));
+  if(IP & UART_IP_RXWM) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+#endif
+  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
+  )
+{
+  if (Initiated == FALSE) {
+    return EFI_NOT_READY;
+  }
+  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
+  )
+{
+  if (Initiated == FALSE) {
+    return EFI_NOT_READY;
+  }
+  *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
+  )
+{
+  if (Initiated == FALSE) {
+    return EFI_NOT_READY;
+  }
+  return RETURN_SUCCESS;
+}

+ 16 - 0
Platform/StarFive/JH7110SeriesPkg/Library/SerialIoLib/U5SerialPortLib.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."
+

+ 129 - 0
Platform/StarFive/JH7110SeriesPkg/Readme.md

@@ -0,0 +1,129 @@
+# Introduction of SiFive U5 Series Platforms
+U5SeriesPkg provides the common EDK2 libraries and drivers for SiFive U5 series
+platforms. Currently the supported platforms are Freedom U500 VC707 platform and
+Freedom U540 HiFive Unleashed platform.
+
+Both platforms are built with below common edk2 packages under edk2-platforms
+repository,
+- [**U5SeriesPkg**](https://github.com/tianocore/edk2-platforms/tree/master/Platform/SiFive/U5SeriesPkg)
+- [**RiscVPlatformPkg**](https://github.com/tianocore/edk2-platforms/tree/master/Platform/RISC-V/PlatformPkg)
+- [**RiscVProcessorPkg**](https://github.com/tianocore/edk2-platforms/tree/master/Silicon/RISC-V/ProcessorPkg)
+
+## U500 Platform
+This is a sample platform package used against to SiFive Freedom U500
+VC707 FPGA Dev Kit, please refer to "SiFive Freedom U500 VC707 FPGA Getting
+Started Guide" on https://www.sifive.com/documentation.
+The binary built from Platform/SiFive/U5SeriesPkg/FreedomU500VC707Board can run
+on U500 VC707 FPGA board.
+```
+build -a RISCV64 -t GCC5 -p Platform/SiFive/U5SeriesPkg/FreedomU500VC707Board/U500.dsc
+```
+
+## U540 Platform
+This is a sample platform package used for the SiFive Freedom U540 HiFive Unleashed
+development board, please refer to "SiFive Freedom U540-C000 Manual" on
+https://www.sifive.com. The binary built from
+Platform/SiFive/U5SeriesPkg/FreedomU540HiFiveUnleashedBoard/ can run on both
+hardware and [QEMU](https://git.qemu.org/?p=qemu.git;a=summary).
+It is confirmed that version 5.0 of QEMU can boot with this  firmware to EFI shell
+and Linux user space.
+```
+build -a RISCV64 -t GCC5 -p Platform/SiFive/U5SeriesPkg/FreedomU540HiFiveUnleashedBoard/U540.dsc
+```
+For running U540 edk2 binary on QEMU, use qemu-system-riscv64 under riscv64-softmmu
+to launch the binary with below parameters,
+
+```
+qemu-system-riscv64 -cpu sifive-u54 -machine sifive_u -bios U540.fd -m 2048 -nographic -smp cpus=5,maxcpus=5
+```
+
+## Download the Source Code
+```
+git clone https://github.com/tianocore/edk2.git
+git clone https://github.com/tianocore/edk2-platforms.git
+# Below to clone opensbi submodule.
+git submodule update --init
+```
+Refer to [Readme.md](https://github.com/tianocore/edk2-platforms/blob/master/Platform/RISC-V/PlatformPkg/Readme.md) for building RISC-V platforms.
+
+## Platform Status
+**FreedomU500VC707Board**
+Currently the binary built from U500 edk2 package can boot SiFive Freedom U500 VC707
+FPGA to EFI shell with console in/out enabled.
+
+**FreedomU540HiFiveUnleashedBoard**
+Currently the binary built from U540 edk2 package can boot SiFive Freedom U540 HiFive
+Unleashed to EFI shell with console in/out enabled and Linux kernel. Please refer to
+https://github.com/riscv/riscv-uefi-edk2-docs for booting to Linux kernel.
+
+## Supported Operating Systems
+Please refer to https://github.com/riscv/riscv-uefi-edk2-docs.
+
+## Known Issues and Limitations
+Only RISC-V RV64 is verified on this platform.
+
+## Related Materials
+- [RISC-V UEFI Documents](https://github.com/riscv/riscv-uefi-edk2-docs)
+- [RISC-V OpenSbi](https://github.com/riscv/opensbi)
+- [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)
+- [SiFive Freedom U540-C000 Manual](https://sifive.cdn.prismic.io/sifive%2F834354f0-08e6-423c-bf1f-0cb58ef14061_fu540-c000-v1.0.pdf)
+- [SiFive RISC-V Core Document](https://www.sifive.com/documentation)
+
+## U5SeriesPkg Libraries and Drivers
+### PeiCoreInfoHobLib
+This is the library to create RISC-V core characteristics for building up RISC-V
+related SMBIOS records to support a single boot loader  or OS image on all RISC-V
+platforms by discovering RISC-V hart configurations dynamically. This library leverage
+the silicon libraries provided in Silicon/SiFive.
+
+### RiscVPlatformTimerLib
+This is common U5 series platform timer library which has the platform-specific
+timer implementation.
+
+### SerialLib
+This is common U5 series platform serial port library.
+
+### TimerDxe
+This is common U5 series platform timer DXE driver which has the platform-specific
+timer implementation.
+
+## U500 Platform Libraries and Drivers
+### RiscVOpensbiPlatformLib
+In order to reduce the dependencies with RISC-V OpenSBI project
+(https://github.com/riscv/opensbi) and avoid duplicating code we use it, the
+implementation of RISC-V EDK2 platform is leveraging platform source code from OpenSBI
+code tree. The "platform.c" under OpenSbiPlatformLib is cloned from
+[RISC-V OpenSBI code tree](Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi)
+and built based on edk2 build environment.
+
+### PlatformPei
+This is the platform-implementation specific library which is executed in early PEI
+phase for U500 platform initialization.
+
+## U540 Platform Libraries and Drivers
+### RiscVOpensbiPlatformLib
+In order to reduce the dependencies with RISC-V OpenSBI project
+(https://github.com/riscv/opensbi) and fewer burdens to EDK2 build process, the
+implementation of RISC-V EDK2 platform is leveraging platform source code from
+OpenSBI code tree. The "platform.c" under OpenSbiPlatformLib is cloned from
+[RISC-V OpenSBI code tree](Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi)
+and built based on edk2build environment.
+
+### PlatformPei
+This is the platform-implementation specific library which is executed in early PEI
+phase for U540 platform initialization.
+
+## U5SeriesPkg Platform PCD settings
+
+| **PCD name** |**Usage**|
+|----------------|----------|
+|PcdU5PlatformSystemClock| U5 series platform system clock|
+|PcdNumberofU5Cores| Number of U5 core enabled on U5 series platform|
+|PcdE5MCSupported| Indicates whether the Monitor Core (E5) is supported on U5 series platform|
+|PcdU5UartBase|Platform serial port base address|
+
+
+## Platform Owners
+Chang, Abner <abner.chang@hpe.com>
+Chen, Gilbert <gilbert.chen@hpe.com>
+Schaefer, Daniel <daniel.schaefer@hpe.com>

+ 127 - 0
Platform/StarFive/JH7110SeriesPkg/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;
+}

+ 84 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf

@@ -0,0 +1,84 @@
+## @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>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  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           = RISCV64
+#
+
+[Sources]
+  FvbInfo.c
+  FwBlockService.c
+  FwBlockServiceDxe.c
+  RamFlash.c
+  RamFlashDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/RISC-V/PlatformPkg/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
+  gPcdProtocolGuid                              # SOMETIMES_CONSUMES
+  gEfiPcdProtocolGuid                           # CONSUMES
+  gGetPcdInfoProtocolGuid                       # SOMETIMES_CONSUMES
+  gEfiGetPcdInfoProtocolGuid                    # SOMETIMES_CONSUMES
+
+[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]
+  gEfiPcdProtocolGuid

+ 1117 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c

@@ -0,0 +1,1117 @@
+/**@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
+  }
+};
+
+/*++
+
+  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_STATUS
+GetFvbInstance (
+  IN  UINTN                               Instance,
+  IN  ESAL_FWB_GLOBAL                     *Global,
+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance
+)
+{
+  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)FwhRecord + FwhRecord->VolumeHeader.HeaderLength +
+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+      );
+    Instance--;
+  }
+
+  *FwhInstance = FwhRecord;
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+  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_STATUS
+FvbGetPhysicalAddress (
+  IN UINTN                                Instance,
+  OUT EFI_PHYSICAL_ADDRESS                *Address,
+  IN ESAL_FWB_GLOBAL                      *Global
+)
+{
+  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;
+}
+/*++
+
+  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_STATUS
+FvbGetVolumeAttributes (
+  IN UINTN                                Instance,
+  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global
+  )
+{
+  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;
+}
+
+/*++
+
+  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
+
+--*/
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                               Instance,
+  IN  EFI_LBA                             Lba,
+  OUT UINTN                               *LbaAddress,
+  OUT UINTN                               *LbaLength,
+  OUT UINTN                               *NumOfBlocks,
+  IN  ESAL_FWB_GLOBAL                     *Global
+  )
+{
+  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++;
+  }
+}
+/*++
+
+  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_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                                  Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2               *Attributes,
+  IN ESAL_FWB_GLOBAL                        *Global
+  )
+{
+  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;
+}
+/*++
+
+  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_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_PHYSICAL_ADDRESS                        *Address
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetPhysicalAddress (FvbDevice->Instance, Address,
+           mFvbModuleGlobal);
+}
+
+/*++
+
+  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_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN CONST EFI_LBA                                     Lba,
+  OUT UINTN                                       *BlockSize,
+  OUT UINTN                                       *NumOfBlocks
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetLbaAddress (
+          FvbDevice->Instance,
+          Lba,
+          NULL,
+          BlockSize,
+          NumOfBlocks,
+          mFvbModuleGlobal
+          );
+}
+
+/*++
+
+  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_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  OUT EFI_FVB_ATTRIBUTES_2                              *Attributes
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes,
+           mFvbModuleGlobal);
+}
+
+/*++
+
+  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_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2                           *Attributes
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes,
+           mFvbModuleGlobal);
+}
+
+/*++
+
+  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_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  )
+{
+  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;
+}
+
+/*++
+
+  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
+
+--*/
+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
+  )
+{
+  return RamFlashWrite (Lba, Offset, NumBytes, 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
+
+--*/
+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
+  )
+{
+  return RamFlashRead (Lba, Offset, NumBytes, Buffer);
+}
+
+/*++
+
+  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
+
+--*/
+EFI_STATUS
+ValidateFvHeader (
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
+  )
+{
+  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;
+}
+
+/*++
+
+  Routine Description:
+    This function does common initialization for FVB services
+
+  Arguments:
+
+  Returns:
+
+--*/
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  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
+  //
+  Status = PcdSet64S (
+    PcdFlashNvStorageVariableBase64,
+    (UINTN) PcdGet32 (PcdPlatformFlashNvStorageVariableBase)
+    );
+  ASSERT_EFI_ERROR (Status);
+  Status = PcdSet32S (
+    PcdFlashNvStorageFtwWorkingBase,
+    PcdGet32 (PcdPlatformFlashNvStorageFtwWorkingBase)
+    );
+  ASSERT_EFI_ERROR (Status);
+  Status = PcdSet32S (
+    PcdFlashNvStorageFtwSpareBase,
+    PcdGet32 (PcdPlatformFlashNvStorageFtwSpareBase)
+    );
+  ASSERT_EFI_ERROR (Status);
+
+  FwhInstance = (EFI_FW_VOL_INSTANCE *)
+    (
+      (UINTN) FwhInstance + FwVolHeader->HeaderLength +
+      (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+    );
+
+  //
+  // Module type specific hook.
+  //
+  InstallVirtualAddressChangeHandler ();
+  return EFI_SUCCESS;
+}

+ 187 - 0
Platform/StarFive/JH7110SeriesPkg/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 RAM based firmware volume block.
+
+**/
+
+#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

+ 150 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c

@@ -0,0 +1,150 @@
+/**@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);
+  }
+}
+
+/*++
+
+  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
+
+--*/
+STATIC
+VOID
+EFIAPI
+FvbVirtualAddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  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)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);
+}

+ 145 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c

@@ -0,0 +1,145 @@
+/** @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/IoLib.h>
+#include <Library/PcdLib.h>
+
+#include "RamFlash.h"
+
+VOID *mFlashBase;
+
+STATIC UINTN       mFdBlockSize = 0;
+STATIC UINTN       mFdBlockCount = 0;
+
+STATIC
+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
+  )
+{
+  UINT8  *Ptr;
+  UINTN  i;
+
+  //
+  // 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 (i = 0; i < *NumBytes; i++) {
+     MmioWrite8((UINTN)Ptr, Buffer[i]);
+     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;
+}

+ 85 - 0
Platform/StarFive/JH7110SeriesPkg/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 VOID *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

+ 20 - 0
Platform/StarFive/JH7110SeriesPkg/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);
+}

+ 311 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/Timer.c

@@ -0,0 +1,311 @@
+/** @file
+  RISC-V Timer Architectural Protocol for U5 series platform.
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Timer.h"
+#include <Library/RiscVEdk2SbiLib.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/riscv_io.h>
+#include <sbi/riscv_atomic.h>
+#include <U5Clint.h>
+
+BOOLEAN TimerHandlerReentry = FALSE;
+
+//
+// The handle onto which the Timer Architectural Protocol will be installed
+//
+STATIC 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.
+//
+STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction;
+
+//
+// The current period of the timer interrupt
+//
+STATIC UINT64 mTimerPeriod = 0;
+
+/**
+  U5 Series Timer 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;
+
+  if (TimerHandlerReentry) {
+    //
+    // MMode timer occurred when processing
+    // SMode timer handler.
+    //
+    RiscvTimer = RiscVReadMachineTimerInterface();
+    SbiSetTimer (RiscvTimer += mTimerPeriod);
+    csr_clear(CSR_SIP, MIP_STIP);
+    return;
+  }
+  TimerHandlerReentry = TRUE;
+
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  csr_clear(CSR_SIE, MIP_STIP); // Disable SMode timer int
+  csr_clear(CSR_SIP, MIP_STIP);
+  if (mTimerPeriod == 0) {
+    gBS->RestoreTPL (OriginalTPL);
+    csr_clear(CSR_SIE, MIP_STIP); // Disable SMode timer int
+    return;
+  }
+  if (mTimerNotifyFunction != NULL) {
+      mTimerNotifyFunction (mTimerPeriod);
+  }
+  RiscvTimer = RiscVReadMachineTimerInterface();
+  SbiSetTimer (RiscvTimer += mTimerPeriod);
+  gBS->RestoreTPL (OriginalTPL);
+  csr_set(CSR_SIE, MIP_STIP); // enable SMode timer int
+  TimerHandlerReentry = FALSE;
+}
+
+/**
+
+  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;
+    csr_clear(CSR_SIE, MIP_STIP); // disable timer int
+    return EFI_SUCCESS;
+  }
+
+  mTimerPeriod = TimerPeriod; // convert unit from 100ns to 1us
+  RiscvTimer = RiscVReadMachineTimerInterface();
+  SbiSetTimer(RiscvTimer + mTimerPeriod / 10);
+
+  mCpu->EnableInterrupt(mCpu);
+  csr_set(CSR_SIE, MIP_STIP); // enable timer int
+  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;
+}

+ 174 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/Timer.h

@@ -0,0 +1,174 @@
+/** @file
+  RISC-V Timer Architectural Protocol definitions for U5 Series platform,
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef U5_SERIES_TIMER_H_
+#define U5_SERIES_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

+ 14 - 0
Platform/StarFive/JH7110SeriesPkg/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."

+ 54 - 0
Platform/StarFive/JH7110SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf

@@ -0,0 +1,54 @@
+## @file
+# RISC-V Timer Arch protocol module for U5 Series platform
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  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
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+[Packages]
+  MdePkg/MdePkg.dec
+  Platform/StarFive/JH7110SeriesPkg/JH7110SeriesPkg.dec
+  Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  MachineModeTimerLib
+  RiscVCpuLib
+  RiscVEdk2SbiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Sources]
+  Timer.h
+  Timer.c
+
+[Protocols]
+  gEfiCpuArchProtocolGuid       ## CONSUMES
+  gEfiTimerArchProtocolGuid     ## PRODUCES
+
+[Pcd]
+  gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz
+
+[Depex]
+  gEfiCpuArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  TimerExtra.uni

+ 12 - 0
Platform/StarFive/JH7110SeriesPkg/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"