public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine
@ 2023-01-28 19:17 Sunil V L
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
                   ` (22 more replies)
  0 siblings, 23 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Abner Chang, Daniel Schaefer, Michael D Kinney, Liming Gao,
	Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Sami Mujawar, Leif Lindholm, Eric Dong, Ray Ni, Rahul Kumar,
	Zhiguang Liu, Anup Patel, Heinrich Schuchardt, Andrei Warkentin


REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add support for RISC-V qemu virt machine. Most of the changes are migrated from
edk2-platforms repo and added qemu specific libraries under OvmfPkg.

The series has passed CI tests (https://github.com/tianocore/edk2/pull/3962)

The series can be testes as per instructions @
https://github.com/vlsunil/riscv-uefi-edk2-docs/wiki/RISC-V-Qemu-Virt-support

Changes since V6:
	1) Took inspiration from IntelTdx and added all RISC-V qemu related libraries and
	   modules in OvmfPkg/RiscVVirt instead of directly under OvmfPkg/Library. Hoping for 
	   quicker review since now it shouldn't affect the existing OvmfPkg libraries/modules.
	2) Dropped migration of NvVarStoreFormattedLib for now to avoid MdeModulePkg changes.
	   Currently RISC-V Qemu doesn't support separate variable flash. So, it can be taken
	   as a separate activity in future when required.
	3) Rebased and new CI test request passed

Changes since V5:
	1) Avoided editing the existing INF files (as per feedback from Ray Ni). This reduced
	   several refactor patches.
	2) Moved to PEI less design (as per suggestion from Andrei Warkentin)
	3) Added PciCpuIO2Dxe driver in OvmfPkg.
	4) Removed APRIORI requirement in DSC/FDF infrastructure files. Now they 
	   are very similar to ArmVirtQemu.
	5) Addressed Heinrich's feedback.
	6) Rebased and added ack tags

Changes since V4:
	1) Rebased and added ACKs
	2) Dropped few patches related to VirtNorFlashDxe since they are already taken care by Ard.

Changes since V3:
	1) Addressed Abner's comments
	2) Changed folder name from Ia32_X64 to Ia32X64 as per latest guidelines.
	2) Rebased

Changes since V2:
	1) Fixed issues detected by CI
	2) Added an extra patch to fix up the consumers of NvVarStoreFormattedLib

Changes since V1:
	1) Added couple of patches from Ard to optimize the NorFlashDxe in Ovmf.
	   Note: There will be a separate patch series in future to update existing
	   consumers of NorFlashDxe driver.
	2) Migrated NvVarStoreFormattedLib from EmbeddedPkg to MdeModulePkg
	3) Created Null instance of the NorFlashPlatformLib library class
	4) Moved NorFlashPlatformLib.h from ArmPlatformPkg

These changes are available at: https://github.com/vlsunil/edk2/tree/RiscV64QemuVirt_v7

Cc: Abner Chang <abner.chang@amd.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Anup Patel <apatel@ventanamicro.com>
Cc: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Cc: Andrei Warkentin <andrei.warkentin@intel.com>

Sunil V L (20):
  MdePkg/Register: Add register definition header files for RISC-V
  MdePkg/BaseLib: RISC-V: Add few more helper functions
  MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions
  UefiCpuPkg: Add CpuTimerDxe module
  UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance
  UefiCpuPkg/CpuDxe: Add RISC-V instance
  UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
  EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
  ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg
  ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe
  OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library
  OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library
  OvmfPkg/RiscVVirt: Add ResetSystemLib library
  OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library
  OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  OvmfPkg/RiscVVirt: Add SEC module
  OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform
  Maintainers.txt: Add entry for OvmfPkg/RiscVVirt

 ArmVirtPkg/ArmVirtPkg.dec                                                       |    9 -
 EmbeddedPkg/EmbeddedPkg.dec                                                     |    3 +
 MdePkg/MdePkg.dec                                                               |    4 +
 OvmfPkg/OvmfPkg.dec                                                             |    7 +
 UefiCpuPkg/UefiCpuPkg.dec                                                       |    7 +
 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc                                             |  336 ++++++
 ArmVirtPkg/ArmVirtCloudHv.dsc                                                   |    2 +-
 ArmVirtPkg/ArmVirtQemu.dsc                                                      |    4 +-
 ArmVirtPkg/ArmVirtQemuKernel.dsc                                                |    2 +-
 MdePkg/MdePkg.dsc                                                               |    3 +
 ArmVirtPkg/ArmVirtQemu.dsc => OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc               |  276 ++---
 UefiCpuPkg/UefiCpuPkg.dsc                                                       |    6 +
 OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf                                             |  306 ++++++
 ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf                  |    2 +-
 ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf                            |    4 +-
 MdePkg/Library/BaseLib/BaseLib.inf                                              |    3 +
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf                              |   25 +
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf           |    3 +-
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf     |   75 ++
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf     |   23 +
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf                 |   38 +
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf     |   30 +
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf                                 |   48 +
 OvmfPkg/RiscVVirt/Sec/SecMain.inf                                               |   66 ++
 UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf                                             |   68 ++
 UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf                                          |   51 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf |   42 +
 UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf                       |   32 +
 MdePkg/Include/Library/BaseLib.h                                                |   50 +
 MdePkg/Include/Library/BaseRiscVSbiLib.h                                        |  127 +++
 MdePkg/Include/Register/RiscV64/RiscVEncoding.h                                 |  119 +++
 MdePkg/Include/Register/RiscV64/RiscVImpl.h                                     |   25 +
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h                   |   45 +
 OvmfPkg/RiscVVirt/Sec/SecMain.h                                                 |  102 ++
 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h                                              |  199 ++++
 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h                                          |  177 ++++
 UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h                                 |   34 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h      |  116 +++
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c                                |  227 +++++
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c             |    0
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c                   | 1078 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c                   |   77 ++
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c          |   65 ++
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c                       |  128 +++
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c       |   40 +
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c                                   |  557 ++++++++++
 OvmfPkg/RiscVVirt/Sec/Cpu.c                                                     |   33 +
 OvmfPkg/RiscVVirt/Sec/Memory.c                                                  |  263 +++++
 OvmfPkg/RiscVVirt/Sec/Platform.c                                                |   84 ++
 OvmfPkg/RiscVVirt/Sec/SecMain.c                                                 |  104 ++
 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c                                              |  365 +++++++
 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c                                          |  294 ++++++
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c      |  133 +++
 UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c                            |  199 ++++
 ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc                                            |    2 +-
 Maintainers.txt                                                                 |    4 +
 MdePkg/Library/BaseLib/RiscV64/CpuScratch.S                                     |   31 +
 MdePkg/Library/BaseLib/RiscV64/ReadTimer.S                                      |   23 +
 MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S                                 |   53 +-
 MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S                                       |   23 +
 OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc                                             |   41 +
 OvmfPkg/RiscVVirt/Sec/SecEntry.S                                                |   21 +
 OvmfPkg/RiscVVirt/VarStore.fdf.inc                                              |   79 ++
 UefiCpuPkg/CpuTimerDxe/CpuTimer.uni                                             |   14 +
 UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni                                        |   12 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S       |  105 ++
 UefiCpuPkg/UefiCpuPkg.ci.yaml                                                   |    1 +
 67 files changed, 6325 insertions(+), 200 deletions(-)
 create mode 100644 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
 copy ArmVirtPkg/ArmVirtQemu.dsc => OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc (66%)
 create mode 100644 OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
 create mode 100644 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
 rename {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf (89%)
 create mode 100644 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
 create mode 100644 OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
 create mode 100644 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
 create mode 100644 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
 create mode 100644 OvmfPkg/RiscVVirt/Sec/SecMain.inf
 create mode 100644 UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
 create mode 100644 UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
 create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
 create mode 100644 UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
 create mode 100644 MdePkg/Include/Library/BaseRiscVSbiLib.h
 create mode 100644 MdePkg/Include/Register/RiscV64/RiscVEncoding.h
 create mode 100644 MdePkg/Include/Register/RiscV64/RiscVImpl.h
 create mode 100644 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h
 create mode 100644 OvmfPkg/RiscVVirt/Sec/SecMain.h
 create mode 100644 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
 create mode 100644 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
 create mode 100644 UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
 create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h
 create mode 100644 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
 rename {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c (100%)
 create mode 100644 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c
 create mode 100644 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c
 create mode 100644 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
 create mode 100644 OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c
 create mode 100644 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c
 create mode 100644 OvmfPkg/RiscVVirt/Sec/Cpu.c
 create mode 100644 OvmfPkg/RiscVVirt/Sec/Memory.c
 create mode 100644 OvmfPkg/RiscVVirt/Sec/Platform.c
 create mode 100644 OvmfPkg/RiscVVirt/Sec/SecMain.c
 create mode 100644 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
 create mode 100644 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
 create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c
 create mode 100644 UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
 create mode 100644 MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
 create mode 100644 MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
 create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
 create mode 100644 OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc
 create mode 100644 OvmfPkg/RiscVVirt/Sec/SecEntry.S
 create mode 100644 OvmfPkg/RiscVVirt/VarStore.fdf.inc
 create mode 100644 UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
 create mode 100644 UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni
 create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S

-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 15:44   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:44   ` Michael D Kinney
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions Sunil V L
                   ` (21 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Daniel Schaefer, Michael D Kinney, Liming Gao, Zhiguang Liu,
	Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add register definitions and access routines for RISC-V. These
headers are leveraged from opensbi repo.

Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 119 ++++++++++++++++++++
 MdePkg/Include/Register/RiscV64/RiscVImpl.h     |  25 ++++
 2 files changed, 144 insertions(+)

diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
new file mode 100644
index 000000000000..5c2989b797bf
--- /dev/null
+++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
@@ -0,0 +1,119 @@
+/** @file
+  RISC-V CSR encodings
+
+  Copyright (c) 2019, Western Digital Corporation or its affiliates. All rights reserved.<BR>
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_ENCODING_H_
+#define RISCV_ENCODING_H_
+
+#define MSTATUS_SIE         0x00000002UL
+#define MSTATUS_MIE         0x00000008UL
+#define MSTATUS_SPIE_SHIFT  5
+#define MSTATUS_SPIE        (1UL << MSTATUS_SPIE_SHIFT)
+#define MSTATUS_UBE         0x00000040UL
+#define MSTATUS_MPIE        0x00000080UL
+#define MSTATUS_SPP_SHIFT   8
+#define MSTATUS_SPP         (1UL << MSTATUS_SPP_SHIFT)
+#define MSTATUS_MPP_SHIFT   11
+#define MSTATUS_MPP         (3UL << MSTATUS_MPP_SHIFT)
+
+#define SSTATUS_SIE         MSTATUS_SIE
+#define SSTATUS_SPIE_SHIFT  MSTATUS_SPIE_SHIFT
+#define SSTATUS_SPIE        MSTATUS_SPIE
+#define SSTATUS_SPP_SHIFT   MSTATUS_SPP_SHIFT
+#define SSTATUS_SPP         MSTATUS_SPP
+
+#define IRQ_S_SOFT    1
+#define IRQ_VS_SOFT   2
+#define IRQ_M_SOFT    3
+#define IRQ_S_TIMER   5
+#define IRQ_VS_TIMER  6
+#define IRQ_M_TIMER   7
+#define IRQ_S_EXT     9
+#define IRQ_VS_EXT    10
+#define IRQ_M_EXT     11
+#define IRQ_S_GEXT    12
+#define IRQ_PMU_OVF   13
+
+#define MIP_SSIP    (1UL << IRQ_S_SOFT)
+#define MIP_VSSIP   (1UL << IRQ_VS_SOFT)
+#define MIP_MSIP    (1UL << IRQ_M_SOFT)
+#define MIP_STIP    (1UL << IRQ_S_TIMER)
+#define MIP_VSTIP   (1UL << IRQ_VS_TIMER)
+#define MIP_MTIP    (1UL << IRQ_M_TIMER)
+#define MIP_SEIP    (1UL << IRQ_S_EXT)
+#define MIP_VSEIP   (1UL << IRQ_VS_EXT)
+#define MIP_MEIP    (1UL << IRQ_M_EXT)
+#define MIP_SGEIP   (1UL << IRQ_S_GEXT)
+#define MIP_LCOFIP  (1UL << IRQ_PMU_OVF)
+
+#define SIP_SSIP  MIP_SSIP
+#define SIP_STIP  MIP_STIP
+
+#define PRV_U  0UL
+#define PRV_S  1UL
+#define PRV_M  3UL
+
+#define SATP64_MODE  0xF000000000000000ULL
+#define SATP64_ASID  0x0FFFF00000000000ULL
+#define SATP64_PPN   0x00000FFFFFFFFFFFULL
+
+#define SATP_MODE_OFF   0UL
+#define SATP_MODE_SV32  1UL
+#define SATP_MODE_SV39  8UL
+#define SATP_MODE_SV48  9UL
+#define SATP_MODE_SV57  10UL
+#define SATP_MODE_SV64  11UL
+
+#define SATP_MODE  SATP64_MODE
+
+/* User Counters/Timers */
+#define CSR_CYCLE  0xc00
+#define CSR_TIME   0xc01
+
+/* Supervisor Trap Setup */
+#define CSR_SSTATUS  0x100
+#define CSR_SEDELEG  0x102
+#define CSR_SIDELEG  0x103
+#define CSR_SIE      0x104
+#define CSR_STVEC    0x105
+
+/* Supervisor Configuration */
+#define CSR_SENVCFG  0x10a
+
+/* Supervisor Trap Handling */
+#define CSR_SSCRATCH  0x140
+#define CSR_SEPC      0x141
+#define CSR_SCAUSE    0x142
+#define CSR_STVAL     0x143
+#define CSR_SIP       0x144
+
+/* Supervisor Protection and Translation */
+#define CSR_SATP  0x180
+
+/* Trap/Exception Causes */
+#define CAUSE_MISALIGNED_FETCH          0x0
+#define CAUSE_FETCH_ACCESS              0x1
+#define CAUSE_ILLEGAL_INSTRUCTION       0x2
+#define CAUSE_BREAKPOINT                0x3
+#define CAUSE_MISALIGNED_LOAD           0x4
+#define CAUSE_LOAD_ACCESS               0x5
+#define CAUSE_MISALIGNED_STORE          0x6
+#define CAUSE_STORE_ACCESS              0x7
+#define CAUSE_USER_ECALL                0x8
+#define CAUSE_SUPERVISOR_ECALL          0x9
+#define CAUSE_VIRTUAL_SUPERVISOR_ECALL  0xa
+#define CAUSE_MACHINE_ECALL             0xb
+#define CAUSE_FETCH_PAGE_FAULT          0xc
+#define CAUSE_LOAD_PAGE_FAULT           0xd
+#define CAUSE_STORE_PAGE_FAULT          0xf
+#define CAUSE_FETCH_GUEST_PAGE_FAULT    0x14
+#define CAUSE_LOAD_GUEST_PAGE_FAULT     0x15
+#define CAUSE_VIRTUAL_INST_FAULT        0x16
+#define CAUSE_STORE_GUEST_PAGE_FAULT    0x17
+
+#endif
diff --git a/MdePkg/Include/Register/RiscV64/RiscVImpl.h b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
new file mode 100644
index 000000000000..ee5c2ba60377
--- /dev/null
+++ b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
@@ -0,0 +1,25 @@
+/** @file
+  RISC-V package definitions.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_IMPL_H_
+#define RISCV_IMPL_H_
+
+#include <Register/RiscV64/RiscVEncoding.h>
+
+#define _ASM_FUNC(Name, Section)    \
+  .global   Name                  ; \
+  .section  #Section, "ax"        ; \
+  .type     Name, %function       ; \
+  .p2align  2                     ; \
+  Name:
+
+#define ASM_FUNC(Name)  _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
+#define RISCV_TIMER_COMPARE_BITS  32
+
+#endif
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 15:46   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:43   ` Michael D Kinney
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
                   ` (20 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Daniel Schaefer,
	Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Few of the basic helper functions required for any
RISC-V CPU were added in edk2-platforms. To support
qemu virt, they need to be added in BaseLib.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/Library/BaseLib/BaseLib.inf              |  3 ++
 MdePkg/Include/Library/BaseLib.h                | 50 ++++++++++++++++++
 MdePkg/Library/BaseLib/RiscV64/CpuScratch.S     | 31 ++++++++++++
 MdePkg/Library/BaseLib/RiscV64/ReadTimer.S      | 23 +++++++++
 MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 53 ++++++++++++++++++--
 MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S       | 23 +++++++++
 6 files changed, 179 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 9ed46a584a14..3a48492b1a01 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -401,6 +401,9 @@ [Sources.RISCV64]
   RiscV64/RiscVCpuPause.S           | GCC
   RiscV64/RiscVInterrupt.S          | GCC
   RiscV64/FlushCache.S              | GCC
+  RiscV64/CpuScratch.S              | GCC
+  RiscV64/ReadTimer.S               | GCC
+  RiscV64/RiscVMmu.S                | GCC
 
 [Sources.LOONGARCH64]
   Math64.c
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index f3f59f21c2ea..b4f4e45a1486 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -151,6 +151,56 @@ typedef struct {
 
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT  8
 
+VOID
+  RiscVSetSupervisorScratch (
+                             UINT64
+                             );
+
+UINT64
+RiscVGetSupervisorScratch (
+  VOID
+  );
+
+VOID
+  RiscVSetSupervisorStvec (
+                           UINT64
+                           );
+
+UINT64
+RiscVGetSupervisorStvec (
+  VOID
+  );
+
+UINT64
+RiscVGetSupervisorTrapCause (
+  VOID
+  );
+
+VOID
+  RiscVSetSupervisorAddressTranslationRegister (
+                                                UINT64
+                                                );
+
+UINT64
+RiscVReadTimer (
+  VOID
+  );
+
+VOID
+RiscVEnableTimerInterrupt (
+  VOID
+  );
+
+VOID
+RiscVDisableTimerInterrupt (
+  VOID
+  );
+
+VOID
+RiscVClearPendingTimerInterrupt (
+  VOID
+  );
+
 #endif // defined (MDE_CPU_RISCV64)
 
 #if defined (MDE_CPU_LOONGARCH64)
diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
new file mode 100644
index 000000000000..5492a500eb5e
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+//
+// CPU scratch register related functions for RISC-V
+//
+// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//------------------------------------------------------------------------------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Set Supervisor mode scratch.
+// @param a0 : Value set to Supervisor mode scratch
+//
+ASM_FUNC (RiscVSetSupervisorScratch)
+    csrw CSR_SSCRATCH, a0
+    ret
+
+//
+// Get Supervisor mode scratch.
+// @retval a0 : Value in Supervisor mode scratch
+//
+ASM_FUNC (RiscVGetSupervisorScratch)
+    csrr a0, CSR_SSCRATCH
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
new file mode 100644
index 000000000000..39a06efa51ef
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// Read CPU timer
+//
+// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//------------------------------------------------------------------------------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Read TIME CSR.
+// @retval a0 : 64-bit timer.
+//
+ASM_FUNC (RiscVReadTimer)
+    csrr a0, CSR_TIME
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
index 87b3468fc7fd..6a1b90a7e45c 100644
--- a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
@@ -8,13 +8,13 @@
 //
 //------------------------------------------------------------------------------
 
+#include <Register/RiscV64/RiscVImpl.h>
+
 ASM_GLOBAL ASM_PFX(RiscVDisableSupervisorModeInterrupts)
 ASM_GLOBAL ASM_PFX(RiscVEnableSupervisorModeInterrupt)
 ASM_GLOBAL ASM_PFX(RiscVGetSupervisorModeInterrupts)
 
-#define  SSTATUS_SIE                 0x00000002
-#define  CSR_SSTATUS                 0x100
-  #define  SSTATUS_SPP_BIT_POSITION  8
+#define  SSTATUS_SPP_BIT_POSITION  8
 
 //
 // This routine disables supervisor mode interrupt
@@ -53,11 +53,56 @@ InTrap:
   ret
 
 //
+// Set Supervisor mode trap vector.
+// @param a0 : Value set to Supervisor mode trap vector
+//
+ASM_FUNC (RiscVSetSupervisorStvec)
+    csrrw a1, CSR_STVEC, a0
+    ret
+
+//
+// Get Supervisor mode trap vector.
+// @retval a0 : Value in Supervisor mode trap vector
+//
+ASM_FUNC (RiscVGetSupervisorStvec)
+    csrr a0, CSR_STVEC
+    ret
+
+//
+// Get Supervisor trap cause CSR.
+//
+ASM_FUNC (RiscVGetSupervisorTrapCause)
+    csrrs a0, CSR_SCAUSE, 0
+    ret
+//
 // This routine returns supervisor mode interrupt
 // status.
 //
-ASM_PFX(RiscVGetSupervisorModeInterrupts):
+ASM_FUNC (RiscVGetSupervisorModeInterrupts)
   csrr a0, CSR_SSTATUS
   andi a0, a0, SSTATUS_SIE
   ret
 
+//
+// This routine disables supervisor mode timer interrupt
+//
+ASM_FUNC (RiscVDisableTimerInterrupt)
+    li   a0, SIP_STIP
+    csrc CSR_SIE, a0
+    ret
+
+//
+// This routine enables supervisor mode timer interrupt
+//
+ASM_FUNC (RiscVEnableTimerInterrupt)
+    li    a0, SIP_STIP
+    csrs CSR_SIE, a0
+    ret
+
+//
+// This routine clears pending supervisor mode timer interrupt
+//
+ASM_FUNC (RiscVClearPendingTimerInterrupt)
+    li   a0, SIP_STIP
+    csrc CSR_SIP, a0
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
new file mode 100644
index 000000000000..ac8f92f38aed
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// CPU scratch register related functions for RISC-V
+//
+// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//------------------------------------------------------------------------------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Set Supervisor Address Translation and
+// Protection Register.
+//
+ASM_FUNC (RiscVSetSupervisorAddressTranslationRegister)
+    csrw  CSR_SATP, a0
+    ret
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:45   ` Michael D Kinney
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions Sunil V L
                   ` (19 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This library is required to make SBI ecalls from the S-mode EDK2.
This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/MdePkg.dec                                  |   4 +
 MdePkg/MdePkg.dsc                                  |   3 +
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
 MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
 5 files changed, 386 insertions(+)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 3d08f20d15b0..ca2e4dcf815c 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Provides function to support TDX processing.
   TdxLib|Include/Library/TdxLib.h
 
+[LibraryClasses.RISCV64]
+  ##  @libraryclass  Provides function to make ecalls to SBI
+  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
+
 [Guids]
   #
   # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 32a852dc466e..0ac7618b4623 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
   MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
 
+[Components.RISCV64]
+  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
+
 [BuildOptions]
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
new file mode 100644
index 000000000000..d03132bf01c1
--- /dev/null
+++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
@@ -0,0 +1,25 @@
+## @file
+# RISC-V Library to call SBI ecalls
+#
+#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION         = 0x0001001b
+  BASE_NAME           = BaseRiscVSbiLib
+  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
+  MODULE_TYPE         = BASE
+  VERSION_STRING      = 1.0
+  LIBRARY_CLASS       = RiscVSbiLib
+
+[Sources]
+  BaseRiscVSbiLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
new file mode 100644
index 000000000000..3a3cbfb879f1
--- /dev/null
+++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
@@ -0,0 +1,127 @@
+/** @file
+  Library to call the RISC-V SBI ecalls
+
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Hart - Hardware Thread, similar to a CPU core
+
+  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
+
+**/
+
+#ifndef RISCV_SBI_LIB_H_
+#define RISCV_SBI_LIB_H_
+
+#include <Uefi.h>
+
+/* SBI Extension IDs */
+#define SBI_EXT_TIME  0x54494D45
+#define SBI_EXT_SRST  0x53525354
+
+/* SBI function IDs for TIME extension*/
+#define SBI_EXT_TIME_SET_TIMER  0x0
+
+/* SBI function IDs for SRST extension */
+#define SBI_EXT_SRST_RESET  0x0
+
+#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
+#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1
+#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
+
+#define SBI_SRST_RESET_REASON_NONE     0x0
+#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
+
+/* SBI return error codes */
+#define SBI_SUCCESS                0
+#define SBI_ERR_FAILED             -1
+#define SBI_ERR_NOT_SUPPORTED      -2
+#define SBI_ERR_INVALID_PARAM      -3
+#define SBI_ERR_DENIED             -4
+#define SBI_ERR_INVALID_ADDRESS    -5
+#define SBI_ERR_ALREADY_AVAILABLE  -6
+#define SBI_ERR_ALREADY_STARTED    -7
+#define SBI_ERR_ALREADY_STOPPED    -8
+
+#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
+
+typedef struct {
+  UINT64    BootHartId;
+  VOID      *PeiServiceTable;    // PEI Service table
+  VOID      *PrePiHobList;       // Pre PI Hob List
+  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
+} EFI_RISCV_FIRMWARE_CONTEXT;
+
+//
+// EDK2 OpenSBI firmware extension return status.
+//
+typedef struct {
+  UINTN    Error; ///< SBI status code
+  UINTN    Value; ///< Value returned
+} SBI_RET;
+
+VOID
+EFIAPI
+SbiSetTimer (
+  IN  UINT64  Time
+  );
+
+EFI_STATUS
+EFIAPI
+SbiSystemReset (
+  IN  UINTN  ResetType,
+  IN  UINTN  ResetReason
+  );
+
+/**
+  Get firmware context of the calling hart.
+
+  @param[out] FirmwareContext      The firmware context pointer.
+**/
+VOID
+EFIAPI
+GetFirmwareContext (
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
+  );
+
+/**
+  Set firmware context of the calling hart.
+
+  @param[in] FirmwareContext       The firmware context pointer.
+**/
+VOID
+EFIAPI
+SetFirmwareContext (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
+  );
+
+/**
+  Get pointer to OpenSBI Firmware Context
+
+  Get the pointer of firmware context.
+
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
+                                 Firmware Context.
+**/
+VOID
+EFIAPI
+GetFirmwareContextPointer (
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
+  );
+
+/**
+  Set pointer to OpenSBI Firmware Context
+
+  Set the pointer of firmware context.
+
+  @param    FirmwareContextPtr   Pointer to Firmware Context.
+**/
+VOID
+EFIAPI
+SetFirmwareContextPointer (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
+  );
+
+#endif
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
new file mode 100644
index 000000000000..15222a528753
--- /dev/null
+++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
@@ -0,0 +1,227 @@
+/** @file
+  Instance of the SBI ecall library.
+
+  It allows calling an SBI function via an ecall from S-Mode.
+
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+//
+// Maximum arguments for SBI ecall
+#define SBI_CALL_MAX_ARGS  6
+
+/**
+  Call SBI call using ecall instruction.
+
+  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
+
+  @param[in] ExtId    SBI extension ID.
+  @param[in] FuncId   SBI function ID.
+  @param[in] NumArgs  Number of arguments to pass to the ecall.
+  @param[in] ...      Argument list for the ecall.
+
+  @retval  Returns SBI_RET structure with value and error code.
+
+**/
+STATIC
+SBI_RET
+EFIAPI
+SbiCall (
+  IN  UINTN  ExtId,
+  IN  UINTN  FuncId,
+  IN  UINTN  NumArgs,
+  ...
+  )
+{
+  UINTN    I;
+  SBI_RET  Ret;
+  UINTN    Args[SBI_CALL_MAX_ARGS];
+  VA_LIST  ArgList;
+
+  VA_START (ArgList, NumArgs);
+
+  if (NumArgs > SBI_CALL_MAX_ARGS) {
+    Ret.Error = SBI_ERR_INVALID_PARAM;
+    Ret.Value = -1;
+    return Ret;
+  }
+
+  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
+    if (I < NumArgs) {
+      Args[I] = VA_ARG (ArgList, UINTN);
+    } else {
+      // Default to 0 for all arguments that are not given
+      Args[I] = 0;
+    }
+  }
+
+  VA_END (ArgList);
+
+  register UINTN  a0 asm ("a0") = Args[0];
+  register UINTN  a1 asm ("a1") = Args[1];
+  register UINTN  a2 asm ("a2") = Args[2];
+  register UINTN  a3 asm ("a3") = Args[3];
+  register UINTN  a4 asm ("a4") = Args[4];
+  register UINTN  a5 asm ("a5") = Args[5];
+  register UINTN  a6 asm ("a6") = (UINTN)(FuncId);
+  register UINTN  a7 asm ("a7") = (UINTN)(ExtId);
+
+  asm volatile ("ecall" \
+       : "+r" (a0), "+r" (a1) \
+       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
+       : "memory"); \
+  Ret.Error = a0;
+  Ret.Value = a1;
+  return Ret;
+}
+
+/**
+  Translate SBI error code to EFI status.
+
+  @param[in] SbiError   SBI error code
+  @retval EFI_STATUS
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+TranslateError (
+  IN  UINTN  SbiError
+  )
+{
+  switch (SbiError) {
+    case SBI_SUCCESS:
+      return EFI_SUCCESS;
+    case SBI_ERR_FAILED:
+      return EFI_DEVICE_ERROR;
+      break;
+    case SBI_ERR_NOT_SUPPORTED:
+      return EFI_UNSUPPORTED;
+      break;
+    case SBI_ERR_INVALID_PARAM:
+      return EFI_INVALID_PARAMETER;
+      break;
+    case SBI_ERR_DENIED:
+      return EFI_ACCESS_DENIED;
+      break;
+    case SBI_ERR_INVALID_ADDRESS:
+      return EFI_LOAD_ERROR;
+      break;
+    case SBI_ERR_ALREADY_AVAILABLE:
+      return EFI_ALREADY_STARTED;
+      break;
+    default:
+      //
+      // Reaches here only if SBI has defined a new error type
+      //
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+      break;
+  }
+}
+
+/**
+  Clear pending timer interrupt bit and set timer for next event after Time.
+
+  To clear the timer without scheduling a timer event, set Time to a
+  practically infinite value or mask the timer interrupt by clearing sie.STIE.
+
+  @param[in]  Time                 The time offset to the next scheduled timer interrupt.
+**/
+VOID
+EFIAPI
+SbiSetTimer (
+  IN  UINT64  Time
+  )
+{
+  SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);
+}
+
+EFI_STATUS
+EFIAPI
+SbiSystemReset (
+  IN  UINTN  ResetType,
+  IN  UINTN  ResetReason
+  )
+{
+  SBI_RET  Ret;
+
+  Ret = SbiCall (
+          SBI_EXT_SRST,
+          SBI_EXT_SRST_RESET,
+          2,
+          ResetType,
+          ResetReason
+          );
+
+  return TranslateError (Ret.Error);
+}
+
+/**
+  Get firmware context of the calling hart.
+
+  @param[out] FirmwareContext      The firmware context pointer.
+  @retval EFI_SUCCESS              The operation succeeds.
+**/
+VOID
+EFIAPI
+GetFirmwareContext (
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
+  )
+{
+  *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();
+}
+
+/**
+  Set firmware context of the calling hart.
+
+  @param[in] FirmwareContext       The firmware context pointer.
+**/
+VOID
+EFIAPI
+SetFirmwareContext (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
+  )
+{
+  RiscVSetSupervisorScratch ((UINT64)FirmwareContext);
+}
+
+/**
+  Get pointer to OpenSBI Firmware Context
+
+  Get the pointer of firmware context through OpenSBI FW Extension SBI.
+
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
+                                 Firmware Context.
+**/
+VOID
+EFIAPI
+GetFirmwareContextPointer (
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
+  )
+{
+  GetFirmwareContext (FirmwareContextPtr);
+}
+
+/**
+  Set the pointer to OpenSBI Firmware Context
+
+  Set the pointer of firmware context through OpenSBI FW Extension SBI.
+
+  @param    FirmwareContextPtr   Pointer to Firmware Context.
+**/
+VOID
+EFIAPI
+SetFirmwareContextPointer (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
+  )
+{
+  SetFirmwareContext (FirmwareContextPtr);
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (2 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  5:16   ` Ni, Ray
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
                   ` (18 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang, Heinrich Schuchardt

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RISC-V UEFI based platforms need to support RISCV_EFI_BOOT_PROTOCOL.
Add this protocol GUID definition and the header file required.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
---
 UefiCpuPkg/UefiCpuPkg.dec                       |  7 ++++
 UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h | 34 ++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index cff239d5283e..903ad52da91b 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -86,6 +86,13 @@ [Protocols]
   ## Include/Protocol/SmMonitorInit.h
   gEfiSmMonitorInitProtocolGuid  = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }}
 
+[Protocols.RISCV64]
+  #
+  # Protocols defined for RISC-V systems
+  #
+  ## Include/Protocol/RiscVBootProtocol.h
+  gRiscVEfiBootProtocolGuid  = { 0xccd15fec, 0x6f73, 0x4eec, { 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf }}
+
 #
 # [Error.gUefiCpuPkgTokenSpaceGuid]
 #   0x80000001 | Invalid value provided.
diff --git a/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
new file mode 100644
index 000000000000..ed223b852d34
--- /dev/null
+++ b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
@@ -0,0 +1,34 @@
+/** @file
+  RISC-V Boot Protocol mandatory for RISC-V UEFI platforms.
+
+  @par Revision Reference:
+  The protocol specification can be found at
+  https://github.com/riscv-non-isa/riscv-uefi
+
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_BOOT_PROTOCOL_H_
+#define RISCV_BOOT_PROTOCOL_H_
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL RISCV_EFI_BOOT_PROTOCOL;
+
+#define RISCV_EFI_BOOT_PROTOCOL_REVISION  0x00010000
+#define RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION \
+        RISCV_EFI_BOOT_PROTOCOL_REVISION
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_BOOT_HARTID)(
+  IN RISCV_EFI_BOOT_PROTOCOL   *This,
+  OUT UINTN                    *BootHartId
+  );
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL {
+  UINT64                 Revision;
+  EFI_GET_BOOT_HARTID    GetBootHartId;
+} RISCV_EFI_BOOT_PROTOCOL;
+
+#endif
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (3 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-08 18:02   ` [edk2-devel] " Michael D Kinney
                     ` (2 more replies)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance Sunil V L
                   ` (17 subsequent siblings)
  22 siblings, 3 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This DXE module initializes the timer interrupt handler
and installs the Arch Timer protocol.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                |   3 +
 UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf   |  51 ++++
 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h   | 177 ++++++++++++
 UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c   | 294 ++++++++++++++++++++
 UefiCpuPkg/CpuTimerDxe/CpuTimer.uni      |  14 +
 UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni |  12 +
 6 files changed, 551 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index f9a46089d2c7..96f6770281fe 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -195,5 +195,8 @@ [Components.IA32, Components.X64]
 [Components.X64]
   UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
 
+[Components.RISCV64]
+  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
new file mode 100644
index 000000000000..d7706328b591
--- /dev/null
+++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# Timer Arch protocol module
+#
+# 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                      = CpuTimerDxe
+  MODULE_UNI_FILE                = CpuTimer.uni
+  FILE_GUID                      = 055DDAC6-9142-4013-BF20-FC2E5BC325C9
+  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
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  CpuLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[LibraryClasses.RISCV64]
+  RiscVSbiLib
+
+[Sources.RISCV64]
+  RiscV64/Timer.h
+  RiscV64/Timer.c
+
+[Protocols]
+  gEfiCpuArchProtocolGuid       ## CONSUMES
+  gEfiTimerArchProtocolGuid     ## PRODUCES
+
+[Depex]
+  gEfiCpuArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  CpuTimerExtra.uni
diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
new file mode 100644
index 000000000000..586eb0cfadb4
--- /dev/null
+++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
@@ -0,0 +1,177 @@
+/** @file
+  RISC-V Timer Architectural Protocol definitions
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef TIMER_H_
+#define TIMER_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/Timer.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+//
+// RISC-V use 100us timer.
+// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units
+//
+#define DEFAULT_TIMER_TICK_DURATION  100000
+
+extern VOID
+RiscvSetTimerPeriod (
+  UINT32  TimerPeriod
+  );
+
+//
+// Function Prototypes
+//
+
+/**
+  Initialize the Timer Architectural Protocol driver
+
+  @param ImageHandle     ImageHandle of the loaded driver
+  @param SystemTable     Pointer to the System Table
+
+  @retval EFI_SUCCESS            Timer Architectural Protocol created
+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+;
+
+/**
+
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
+                         0 is returned, then the timer is currently disabled.
+
+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  OUT UINT64                  *TimerPeriod
+  )
+;
+
+/**
+
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+
+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+;
+
+#endif
diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
new file mode 100644
index 000000000000..db153f715e60
--- /dev/null
+++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
@@ -0,0 +1,294 @@
+/** @file
+  RISC-V Timer Architectural Protocol
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include "Timer.h"
+
+//
+// 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;
+
+/**
+  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;
+
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  if (mTimerNotifyFunction != NULL) {
+    mTimerNotifyFunction (mTimerPeriod);
+  }
+
+  RiscVDisableTimerInterrupt (); // Disable SMode timer int
+  RiscVClearPendingTimerInterrupt ();
+  if (mTimerPeriod == 0) {
+    gBS->RestoreTPL (OriginalTPL);
+    RiscVDisableTimerInterrupt (); // Disable SMode timer int
+    return;
+  }
+
+  RiscvTimer               = RiscVReadTimer ();
+  SbiSetTimer (RiscvTimer += mTimerPeriod);
+  gBS->RestoreTPL (OriginalTPL);
+  RiscVEnableTimerInterrupt (); // enable SMode timer int
+}
+
+/**
+
+  This function registers the handler NotifyFunction so it is called every time
+  the timer interrupt fires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
+  returned.  If the CPU does not support registering a timer interrupt handler,
+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+  is returned.
+
+  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction   The function to call when a timer interrupt fires.  This
+                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
+                          register a handler for the timer interrupt, so it can know
+                          how much time has passed.  This information is used to
+                          signal timer based events.  NULL will unregister the handler.
+
+  @retval        EFI_SUCCESS            The timer handler was registered.
+  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
+  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
+                                        registered.
+  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
+                                        previously registered.
+  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", NotifyFunction));
+  mTimerNotifyFunction = NotifyFunction;
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  UINT64  RiscvTimer;
+
+  DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));
+
+  if (TimerPeriod == 0) {
+    mTimerPeriod = 0;
+    RiscVDisableTimerInterrupt (); // Disable SMode timer int
+    return EFI_SUCCESS;
+  }
+
+  mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us
+  RiscvTimer   = RiscVReadTimer ();
+  SbiSetTimer (RiscvTimer + mTimerPeriod);
+
+  mCpu->EnableInterrupt (mCpu);
+  RiscVEnableTimerInterrupt (); // enable SMode 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;
+}
diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
new file mode 100644
index 000000000000..76de1f3f352a
--- /dev/null
+++ b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
@@ -0,0 +1,14 @@
+// /** @file
+//
+// 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 "Timer driver that provides Timer Arch protocol"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Timer driver that provides Timer Arch protocol."
diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni
new file mode 100644
index 000000000000..ceb93a7ce82f
--- /dev/null
+++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.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
+"Timer DXE Driver"
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (4 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-09  5:24   ` [edk2-devel] " Ni, Ray
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: " Sunil V L
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Abner Chang,
	Gerd Hoffmann

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add Cpu Exception Handler library for RISC-V. This is copied
from edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVExceptionLib

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                                                       |   1 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf |  42 +++++++
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h      | 116 +++++++++++++++++
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c      | 133 ++++++++++++++++++++
 UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S       | 105 ++++++++++++++++
 5 files changed, 397 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 96f6770281fe..251a8213f022 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -197,6 +197,7 @@ [Components.X64]
 
 [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+  UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
new file mode 100644
index 000000000000..82ca22c4bfec
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
@@ -0,0 +1,42 @@
+## @file
+# RISC-V CPU Exception Handler Library
+#
+# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseRiscV64CpuExceptionHandlerLib
+  MODULE_UNI_FILE                = BaseRiscV64CpuExceptionHandlerLib.uni
+  FILE_GUID                      = 6AB0D5FD-E615-45A3-9374-E284FB061FC9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CpuExceptionHandlerLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  RiscV64/SupervisorTrapHandler.S
+  RiscV64/CpuExceptionHandlerLib.c
+  RiscV64/CpuExceptionHandlerLib.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  SerialPortLib
+  PrintLib
+  SynchronizationLib
+  PeCoffGetEntryPointLib
+  MemoryAllocationLib
+  DebugLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h
new file mode 100644
index 000000000000..30f47e87552b
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h
@@ -0,0 +1,116 @@
+/** @file
+
+  RISC-V Exception Handler library definition file.
+
+  Copyright (c) 2019-2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_CPU_EXECPTION_HANDLER_LIB_H_
+#define RISCV_CPU_EXECPTION_HANDLER_LIB_H_
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  Trap Handler for S-mode
+
+**/
+VOID
+SupervisorModeTrap (
+  VOID
+  );
+
+//
+// Index of SMode trap register
+//
+#define SMODE_TRAP_REGS_zero     0
+#define SMODE_TRAP_REGS_ra       1
+#define SMODE_TRAP_REGS_sp       2
+#define SMODE_TRAP_REGS_gp       3
+#define SMODE_TRAP_REGS_tp       4
+#define SMODE_TRAP_REGS_t0       5
+#define SMODE_TRAP_REGS_t1       6
+#define SMODE_TRAP_REGS_t2       7
+#define SMODE_TRAP_REGS_s0       8
+#define SMODE_TRAP_REGS_s1       9
+#define SMODE_TRAP_REGS_a0       10
+#define SMODE_TRAP_REGS_a1       11
+#define SMODE_TRAP_REGS_a2       12
+#define SMODE_TRAP_REGS_a3       13
+#define SMODE_TRAP_REGS_a4       14
+#define SMODE_TRAP_REGS_a5       15
+#define SMODE_TRAP_REGS_a6       16
+#define SMODE_TRAP_REGS_a7       17
+#define SMODE_TRAP_REGS_s2       18
+#define SMODE_TRAP_REGS_s3       19
+#define SMODE_TRAP_REGS_s4       20
+#define SMODE_TRAP_REGS_s5       21
+#define SMODE_TRAP_REGS_s6       22
+#define SMODE_TRAP_REGS_s7       23
+#define SMODE_TRAP_REGS_s8       24
+#define SMODE_TRAP_REGS_s9       25
+#define SMODE_TRAP_REGS_s10      26
+#define SMODE_TRAP_REGS_s11      27
+#define SMODE_TRAP_REGS_t3       28
+#define SMODE_TRAP_REGS_t4       29
+#define SMODE_TRAP_REGS_t5       30
+#define SMODE_TRAP_REGS_t6       31
+#define SMODE_TRAP_REGS_sepc     32
+#define SMODE_TRAP_REGS_sstatus  33
+#define SMODE_TRAP_REGS_sie      34
+#define SMODE_TRAP_REGS_last     35
+
+#define SMODE_TRAP_REGS_OFFSET(x)  ((SMODE_TRAP_REGS_##x) * __SIZEOF_POINTER__)
+#define SMODE_TRAP_REGS_SIZE  SMODE_TRAP_REGS_OFFSET(last)
+
+#pragma pack(1)
+typedef struct {
+  //
+  // Below are follow the format of EFI_SYSTEM_CONTEXT
+  //
+  UINT64    zero;
+  UINT64    ra;
+  UINT64    sp;
+  UINT64    gp;
+  UINT64    tp;
+  UINT64    t0;
+  UINT64    t1;
+  UINT64    t2;
+  UINT64    s0;
+  UINT64    s1;
+  UINT64    a0;
+  UINT64    a1;
+  UINT64    a2;
+  UINT64    a3;
+  UINT64    a4;
+  UINT64    a5;
+  UINT64    a6;
+  UINT64    a7;
+  UINT64    s2;
+  UINT64    s3;
+  UINT64    s4;
+  UINT64    s5;
+  UINT64    s6;
+  UINT64    s7;
+  UINT64    s8;
+  UINT64    s9;
+  UINT64    s10;
+  UINT64    s11;
+  UINT64    t3;
+  UINT64    t4;
+  UINT64    t5;
+  UINT64    t6;
+  //
+  // Below are the additional information to
+  // EFI_SYSTEM_CONTEXT, private to supervisor mode trap
+  // and not public to EFI environment.
+  //
+  UINT64    sepc;
+  UINT64    sstatus;
+  UINT64    sie;
+} SMODE_TRAP_REGISTERS;
+#pragma pack()
+
+#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c
new file mode 100644
index 000000000000..f1ee7d236aec
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.c
@@ -0,0 +1,133 @@
+/** @file
+  RISC-V Exception Handler library implementation.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Register/RiscV64/RiscVEncoding.h>
+
+#include "CpuExceptionHandlerLib.h"
+
+STATIC EFI_CPU_INTERRUPT_HANDLER  mInterruptHandlers[2];
+
+/**
+  Initializes all CPU exceptions entries and provides the default exception handlers.
+
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+  @param[in]  VectorInfo    Pointer to reserved vector list.
+
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized
+                                with default exception handlers.
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+  @retval EFI_UNSUPPORTED       This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL
+  )
+{
+  RiscVSetSupervisorStvec ((UINT64)SupervisorModeTrap);
+  return EFI_SUCCESS;
+}
+
+/**
+  Registers a function to be called from the processor interrupt handler.
+
+  This function registers and enables the handler specified by InterruptHandler for a processor
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+  The installed handler is called once for each processor interrupt or exception.
+  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler
+                                will be uninstalled.
+
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was
+                                previously installed.
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+                                previously installed.
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,
+                                or this function is not supported.
+**/
+EFI_STATUS
+EFIAPI
+RegisterCpuInterruptHandler (
+  IN EFI_EXCEPTION_TYPE         InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Type:%x Handler: %x\n", __FUNCTION__, InterruptType, InterruptHandler));
+  mInterruptHandlers[InterruptType] = InterruptHandler;
+  return EFI_SUCCESS;
+}
+
+/**
+  Setup separate stacks for certain exception handlers.
+  If the input Buffer and BufferSize are both NULL, use global variable if possible.
+
+  @param[in]       Buffer        Point to buffer used to separate exception stack.
+  @param[in, out]  BufferSize    On input, it indicates the byte size of Buffer.
+                                 If the size is not enough, the return status will
+                                 be EFI_BUFFER_TOO_SMALL, and output BufferSize
+                                 will be the size it needs.
+
+  @retval EFI_SUCCESS             The stacks are assigned successfully.
+  @retval EFI_UNSUPPORTED         This function is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    This BufferSize is too small.
+**/
+EFI_STATUS
+EFIAPI
+InitializeSeparateExceptionStacks (
+  IN     VOID   *Buffer,
+  IN OUT UINTN  *BufferSize
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Supervisor mode trap handler.
+
+  @param[in]  SmodeTrapReg     Registers before trap occurred.
+
+**/
+VOID
+RiscVSupervisorModeTrapHandler (
+  SMODE_TRAP_REGISTERS  *SmodeTrapReg
+  )
+{
+  UINTN               SCause;
+  EFI_SYSTEM_CONTEXT  RiscVSystemContext;
+
+  RiscVSystemContext.SystemContextRiscV64 = (EFI_SYSTEM_CONTEXT_RISCV64 *)SmodeTrapReg;
+  //
+  // Check scasue register.
+  //
+  SCause = (UINTN)RiscVGetSupervisorTrapCause ();
+  if ((SCause & (1UL << (sizeof (UINTN) * 8- 1))) != 0) {
+    //
+    // This is interrupt event.
+    //
+    SCause &= ~(1UL << (sizeof (UINTN) * 8- 1));
+    if ((SCause == IRQ_S_TIMER) && (mInterruptHandlers[EXCEPT_RISCV_TIMER_INT] != NULL)) {
+      mInterruptHandlers[EXCEPT_RISCV_TIMER_INT](EXCEPT_RISCV_TIMER_INT, RiscVSystemContext);
+    }
+  }
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S
new file mode 100644
index 000000000000..649c4c5becf4
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandler.S
@@ -0,0 +1,105 @@
+/** @file
+  RISC-V Processor supervisor mode trap handler
+
+  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include "CpuExceptionHandlerLib.h"
+
+  .align 3
+  .section .entry, "ax", %progbits
+  .globl SupervisorModeTrap
+SupervisorModeTrap:
+  addi sp, sp, -SMODE_TRAP_REGS_SIZE
+
+  /* Save all general regisers except SP */
+  sd    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
+
+  csrr  t0, CSR_SSTATUS
+  and   t0, t0, (SSTATUS_SIE | SSTATUS_SPIE)
+  sd    t0, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
+  csrr  t0, CSR_SEPC
+  sd    t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
+  csrr  t0, CSR_SIE
+  sd    t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)
+  ld    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
+
+  sd    ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
+  sd    gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
+  sd    tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
+  sd    t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
+  sd    t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
+  sd    s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
+  sd    s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
+  sd    a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
+  sd    a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
+  sd    a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
+  sd    a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
+  sd    a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
+  sd    a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
+  sd    a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
+  sd    a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
+  sd    s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
+  sd    s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
+  sd    s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
+  sd    s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
+  sd    s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
+  sd    s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
+  sd    s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
+  sd    s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
+  sd    s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
+  sd    s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
+  sd    t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
+  sd    t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
+  sd    t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
+  sd    t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
+
+  /* Call to Supervisor mode trap handler in CpuExceptionHandlerLib.c */
+  call  RiscVSupervisorModeTrapHandler
+
+  /* Restore all general regisers except SP */
+  ld    ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
+  ld    gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
+  ld    tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
+  ld    t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
+  ld    s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
+  ld    s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
+  ld    a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
+  ld    a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
+  ld    a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
+  ld    a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
+  ld    a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
+  ld    a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
+  ld    a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
+  ld    a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
+  ld    s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
+  ld    s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
+  ld    s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
+  ld    s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
+  ld    s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
+  ld    s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
+  ld    s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
+  ld    s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
+  ld    s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
+  ld    s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
+  ld    t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
+  ld    t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
+  ld    t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
+  ld    t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
+
+  ld    t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
+  csrw  CSR_SEPC, t0
+  ld    t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)
+  csrw  CSR_SIE, t0
+  csrr  t0, CSR_SSTATUS
+  ld    t1, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
+  or    t0, t0, t1
+  csrw  CSR_SSTATUS, t0
+  ld    t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
+  ld    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
+  addi  sp, sp, SMODE_TRAP_REGS_SIZE
+  sret
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (5 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 15:58   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This is copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc           |   1 +
 UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf |  68 ++++
 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h  | 199 +++++++++++
 UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c  | 365 ++++++++++++++++++++
 4 files changed, 633 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 251a8213f022..8f2be6cd1b05 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -198,6 +198,7 @@ [Components.X64]
 [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
   UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
new file mode 100644
index 000000000000..5e590d03754f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
@@ -0,0 +1,68 @@
+## @file
+#  RISC-V CPU DXE module.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = CpuDxeRiscV64
+  MODULE_UNI_FILE                = CpuDxe.uni
+  FILE_GUID                      = BDEA19E2-778F-473C-BF82-5E38D6A27765
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeCpu
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CpuLib
+  DebugLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  CpuExceptionHandlerLib
+  HobLib
+  ReportStatusCodeLib
+  TimerLib
+  PeCoffGetEntryPointLib
+  RiscVSbiLib
+
+[Sources]
+  RiscV64/CpuDxe.c
+  RiscV64/CpuDxe.h
+
+[Protocols]
+  gEfiCpuArchProtocolGuid                       ## PRODUCES
+  gRiscVEfiBootProtocolGuid                     ## PRODUCES
+
+[Guids]
+  gIdleLoopEventGuid                            ## CONSUMES           ## Event
+
+[Ppis]
+  gEfiSecPlatformInformation2PpiGuid            ## UNDEFINED # HOB
+  gEfiSecPlatformInformationPpiGuid             ## UNDEFINED # HOB
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency             ## CONSUMES
+
+[Depex]
+  TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  CpuDxeExtra.uni
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
new file mode 100644
index 000000000000..49f4e119665a
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
@@ -0,0 +1,199 @@
+/** @file
+  RISC-V CPU DXE module header file.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_DXE_H_
+#define CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/RiscVBootProtocol.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+/**
+  Flush CPU data cache. If the instruction cache is fully coherent
+  with all DMA operations then function can just return EFI_SUCCESS.
+
+  @param  This              Protocol instance structure
+  @param  Start             Physical address to start flushing from.
+  @param  Length            Number of bytes to flush. Round up to chipset
+                            granularity.
+  @param  FlushType         Specifies the type of flush operation to perform.
+
+  @retval EFI_SUCCESS       If cache was flushed
+  @retval EFI_UNSUPPORTED   If flush type is not supported.
+  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   Start,
+  IN UINT64                 Length,
+  IN EFI_CPU_FLUSH_TYPE     FlushType
+  );
+
+/**
+  Enables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
+  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  );
+
+/**
+  Disables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
+  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  );
+
+/**
+  Return the state of interrupts.
+
+  @param  This                   Protocol instance structure
+  @param  State                  Pointer to the CPU's current interrupt state
+
+  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
+  @retval EFI_INVALID_PARAMETER  State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  OUT BOOLEAN                *State
+  );
+
+/**
+  Generates an INIT to the CPU.
+
+  @param  This              Protocol instance structure
+  @param  InitType          Type of CPU INIT to perform
+
+  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
+                            seen.
+  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
+  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_CPU_INIT_TYPE      InitType
+  );
+
+/**
+  Registers a function to be called from the CPU interrupt handler.
+
+  @param  This                   Protocol instance structure
+  @param  InterruptType          Defines which interrupt to hook. IA-32
+                                 valid range is 0x00 through 0xFF
+  @param  InterruptHandler       A pointer to a function of type
+                                 EFI_CPU_INTERRUPT_HANDLER that is called
+                                 when a processor interrupt occurs.  A null
+                                 pointer is an error condition.
+
+  @retval EFI_SUCCESS            If handler installed or uninstalled.
+  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
+                                 for InterruptType was previously installed.
+  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
+                                 InterruptType was not previously installed.
+  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
+                                 is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+  IN EFI_CPU_ARCH_PROTOCOL      *This,
+  IN EFI_EXCEPTION_TYPE         InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
+  );
+
+/**
+  Returns a timer value from one of the CPU's internal timers. There is no
+  inherent time interval between ticks but is a function of the CPU frequency.
+
+  @param  This                - Protocol instance structure.
+  @param  TimerIndex          - Specifies which CPU timer is requested.
+  @param  TimerValue          - Pointer to the returned timer value.
+  @param  TimerPeriod         - A pointer to the amount of time that passes
+                                in femtoseconds (10-15) for each increment
+                                of TimerValue. If TimerValue does not
+                                increment at a predictable rate, then 0 is
+                                returned.  The amount of time that has
+                                passed between two calls to GetTimerValue()
+                                can be calculated with the formula
+                                (TimerValue2 - TimerValue1) * TimerPeriod.
+                                This parameter is optional and may be NULL.
+
+  @retval EFI_SUCCESS           - If the CPU timer count was returned.
+  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
+  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
+  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  IN  UINT32                 TimerIndex,
+  OUT UINT64                 *TimerValue,
+  OUT UINT64                 *TimerPeriod OPTIONAL
+  );
+
+/**
+  Set memory cacheability attributes for given range of memeory.
+
+  @param  This                   Protocol instance structure
+  @param  BaseAddress            Specifies the start address of the
+                                 memory range
+  @param  Length                 Specifies the length of the memory range
+  @param  Attributes             The memory cacheability for the memory range
+
+  @retval EFI_SUCCESS            If the cacheability of that memory range is
+                                 set successfully
+  @retval EFI_UNSUPPORTED        If the desired operation cannot be done
+  @retval EFI_INVALID_PARAMETER  The input parameter is not correct,
+                                 such as Length = 0
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 Attributes
+  );
+
+#endif
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
new file mode 100644
index 000000000000..7551e0653603
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
@@ -0,0 +1,365 @@
+/** @file
+  RISC-V CPU DXE driver.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDxe.h"
+
+//
+// Global Variables
+//
+STATIC BOOLEAN           mInterruptState = FALSE;
+STATIC EFI_HANDLE        mCpuHandle      = NULL;
+STATIC UINTN             mBootHartId;
+RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol;
+
+/**
+  Get the boot hartid
+
+  @param  This                   Protocol instance structure
+  @param  BootHartId             Pointer to the Boot Hart ID variable
+
+  @retval EFI_SUCCESS            If BootHartId is returned
+  @retval EFI_INVALID_PARAMETER  Either "BootHartId" is NULL or "This" is not
+                                 a valid RISCV_EFI_BOOT_PROTOCOL instance.
+
+**/
+EFI_STATUS
+EFIAPI
+RiscvGetBootHartId (
+  IN RISCV_EFI_BOOT_PROTOCOL  *This,
+  OUT UINTN                   *BootHartId
+  )
+{
+  if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *BootHartId = mBootHartId;
+  return EFI_SUCCESS;
+}
+
+RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol = {
+  RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
+  RiscvGetBootHartId
+};
+
+EFI_CPU_ARCH_PROTOCOL  gCpu = {
+  CpuFlushCpuDataCache,
+  CpuEnableInterrupt,
+  CpuDisableInterrupt,
+  CpuGetInterruptState,
+  CpuInit,
+  CpuRegisterInterruptHandler,
+  CpuGetTimerValue,
+  CpuSetMemoryAttributes,
+  1,                          // NumberOfTimers
+  4                           // DmaBufferAlignment
+};
+
+//
+// CPU Arch Protocol Functions
+//
+
+/**
+  Flush CPU data cache. If the instruction cache is fully coherent
+  with all DMA operations then function can just return EFI_SUCCESS.
+
+  @param  This              Protocol instance structure
+  @param  Start             Physical address to start flushing from.
+  @param  Length            Number of bytes to flush. Round up to chipset
+                            granularity.
+  @param  FlushType         Specifies the type of flush operation to perform.
+
+  @retval EFI_SUCCESS       If cache was flushed
+  @retval EFI_UNSUPPORTED   If flush type is not supported.
+  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   Start,
+  IN UINT64                 Length,
+  IN EFI_CPU_FLUSH_TYPE     FlushType
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Enables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
+  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  )
+{
+  EnableInterrupts ();
+  mInterruptState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Disables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
+  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  )
+{
+  DisableInterrupts ();
+  mInterruptState = FALSE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Return the state of interrupts.
+
+  @param  This                   Protocol instance structure
+  @param  State                  Pointer to the CPU's current interrupt state
+
+  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
+  @retval EFI_INVALID_PARAMETER  State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  OUT BOOLEAN                *State
+  )
+{
+  if (State == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *State = mInterruptState;
+  return EFI_SUCCESS;
+}
+
+/**
+  Generates an INIT to the CPU.
+
+  @param  This              Protocol instance structure
+  @param  InitType          Type of CPU INIT to perform
+
+  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
+                            seen.
+  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
+  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_CPU_INIT_TYPE      InitType
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Registers a function to be called from the CPU interrupt handler.
+
+  @param  This                   Protocol instance structure
+  @param  InterruptType          Defines which interrupt to hook. IA-32
+                                 valid range is 0x00 through 0xFF
+  @param  InterruptHandler       A pointer to a function of type
+                                 EFI_CPU_INTERRUPT_HANDLER that is called
+                                 when a processor interrupt occurs.  A null
+                                 pointer is an error condition.
+
+  @retval EFI_SUCCESS            If handler installed or uninstalled.
+  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
+                                 for InterruptType was previously installed.
+  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
+                                 InterruptType was not previously installed.
+  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
+                                 is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+  IN EFI_CPU_ARCH_PROTOCOL      *This,
+  IN EFI_EXCEPTION_TYPE         InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
+  )
+{
+  return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
+}
+
+/**
+  Returns a timer value from one of the CPU's internal timers. There is no
+  inherent time interval between ticks but is a function of the CPU frequency.
+
+  @param  This                - Protocol instance structure.
+  @param  TimerIndex          - Specifies which CPU timer is requested.
+  @param  TimerValue          - Pointer to the returned timer value.
+  @param  TimerPeriod         - A pointer to the amount of time that passes
+                                in femtoseconds (10-15) for each increment
+                                of TimerValue. If TimerValue does not
+                                increment at a predictable rate, then 0 is
+                                returned.  The amount of time that has
+                                passed between two calls to GetTimerValue()
+                                can be calculated with the formula
+                                (TimerValue2 - TimerValue1) * TimerPeriod.
+                                This parameter is optional and may be NULL.
+
+  @retval EFI_SUCCESS           - If the CPU timer count was returned.
+  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
+  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
+  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  IN  UINT32                 TimerIndex,
+  OUT UINT64                 *TimerValue,
+  OUT UINT64                 *TimerPeriod OPTIONAL
+  )
+{
+  if (TimerValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TimerIndex != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerValue = (UINT64)RiscVReadTimer ();
+  if (TimerPeriod != NULL) {
+    *TimerPeriod = DivU64x32 (
+                     1000000000000000u,
+                     PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                     );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
+
+  This function modifies the attributes for the memory region specified by BaseAddress and
+  Length from their current attributes to the attributes specified by Attributes.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  BaseAddress      The physical address that is the start address of a memory region.
+  @param  Length           The size in bytes of the memory region.
+  @param  Attributes       The bit mask of attributes to set for the memory region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by
+                                BaseAddress and Length cannot be modified.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of attributes that
+                                cannot be set together.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
+                                the memory resource range.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory
+                                resource range specified by BaseAddress and Length.
+                                The bit mask of attributes is not support for the memory resource
+                                range specified by BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 Attributes
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Set memory attributes not supported yet\n", __FUNCTION__));
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the state information for the CPU Architectural Protocol.
+
+  @param ImageHandle     Image handle this driver.
+  @param SystemTable     Pointer to the System Table.
+
+  @retval EFI_SUCCESS           Thread can be successfully created
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Cannot create the thread
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  GetFirmwareContextPointer (&FirmwareContext);
+  ASSERT (FirmwareContext != NULL);
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n", __FUNCTION__, FirmwareContext));
+
+  mBootHartId = FirmwareContext->BootHartId;
+  DEBUG ((DEBUG_INFO, " %a: mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
+
+  InitializeCpuExceptionHandlers (NULL);
+
+  //
+  // Make sure interrupts are disabled
+  //
+  DisableInterrupts ();
+
+  //
+  // Install Boot protocol
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gRiscVEfiBootProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &gRiscvBootProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install CPU Architectural Protocol
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mCpuHandle,
+                  &gEfiCpuArchProtocolGuid,
+                  &gCpu,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (6 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: " Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-01-30 11:07   ` [edk2-devel] " dhaval
                     ` (2 more replies)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
                   ` (14 subsequent siblings)
  22 siblings, 3 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Abner Chang,
	Gerd Hoffmann

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                                 |   1 +
 UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf |  32 ++++
 UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c      | 199 ++++++++++++++++++++
 3 files changed, 232 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 8f2be6cd1b05..2df02bf75a35 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -199,6 +199,7 @@ [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
   UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
   UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+  UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
new file mode 100644
index 000000000000..c920e8e098b5
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
@@ -0,0 +1,32 @@
+## @file
+# RISC-V Base CPU Timer Library Instance
+#
+#  Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseRisV64CpuTimerLib
+  FILE_GUID                      = B635A600-EA24-4199-88E8-5761EEA96A51
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources]
+  RiscV64/CpuTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  DebugLib
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ## CONSUMES
diff --git a/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
new file mode 100644
index 000000000000..9c8efc0f3530
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
@@ -0,0 +1,199 @@
+/** @file
+  RISC-V instance of Timer Library.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+InternalRiscVTimerDelay (
+  IN UINT32  Delay
+  )
+{
+  UINT32  Ticks;
+  UINT32  Times;
+
+  Times  = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);
+  Delay &= ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = RiscVReadTimer () + Delay;
+    Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);
+    while (((Ticks - RiscVReadTimer ()) & (1 << (RISCV_TIMER_COMPARE_BITS - 1))) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN UINTN  MicroSeconds
+  )
+{
+  InternalRiscVTimerDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN UINTN  NanoSeconds
+  )
+{
+  InternalRiscVTimerDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance counter. The
+  counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)RiscVReadTimer ();
+}
+
+/**return
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64 *StartValue, OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 32 - 1;
+  }
+
+  return PcdGet64 (PcdCpuCoreCrystalClockFrequency);
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64  Ticks
+  )
+{
+  UINT64  NanoSeconds;
+  UINT32  Remainder;
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);
+
+  //
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
+  // will not overflow 64-bit.
+  //
+  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));
+
+  return NanoSeconds;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (7 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
                     ` (2 more replies)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V Sunil V L
                   ` (13 subsequent siblings)
  22 siblings, 3 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel; +Cc: Eric Dong, Ray Ni, Rahul Kumar, Gerd Hoffmann, Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RISC-V register names do not follow the EDK2 formatting.
So, add it to ignore list for now.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.ci.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml
index a377366798b0..953361ba0479 100644
--- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
+++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
@@ -27,6 +27,7 @@
         ],
         ## Both file path and directory path are accepted.
         "IgnoreFiles": [
+          "Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h"
         ]
     },
     "CompilerPlugin": {
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (8 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:51   ` Michael D Kinney
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
                   ` (12 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Ard Biesheuvel, Abner Chang, Daniel Schaefer

This PCD is required to be enabled so that PrePiLib
can be used in RISC-V.

Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 EmbeddedPkg/EmbeddedPkg.dec | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 341ef5e6a679..2965f01444e9 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -165,6 +165,9 @@ [PcdsFixedAtBuild.IA32]
 [PcdsFixedAtBuild.X64]
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
 
+[PcdsFixedAtBuild.RISCV64]
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+
 [PcdsFixedAtBuild.common, PcdsDynamic.common]
   #
   # Value to add to a host address to obtain a device address, using
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (9 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe Sunil V L
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This module is required by other architectures like RISC-V.
Hence, move this to OvmfPkg.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 ArmVirtPkg/ArmVirtPkg.dec                                             | 9 ---------
 OvmfPkg/OvmfPkg.dec                                                   | 7 +++++++
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf | 3 +--
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c   | 0
 4 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index 89d21ec3a364..4645c91a8375 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -34,8 +34,6 @@ [Guids.common]
   gEarly16550UartBaseAddressGuid   = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
   gArmVirtSystemMemorySizeGuid     = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
 
-  gArmVirtVariableGuid   = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
-
 [PcdsFeatureFlag]
   #
   # Feature Flag PCD that defines whether TPM2 support is enabled
@@ -69,10 +67,3 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
   # Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
   #
   gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
-
-[PcdsDynamic]
-  #
-  # Whether to force disable ACPI, regardless of the fw_cfg settings
-  # exposed by QEMU
-  #
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x00000003
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index a22eb246c625..e52602db5b79 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -157,6 +157,7 @@ [Guids]
   gVMMBootOrderGuid                     = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
   gUefiOvmfPkgTdxAcpiHobGuid            = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
   gEfiNonCcFvGuid                       = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
+  gOvmfVariableGuid                     = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
@@ -463,6 +464,12 @@ [PcdsDynamic, PcdsDynamicEx]
   #    2 - set by GOP Driver.
   gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource|0|UINT8|0x64
 
+  #
+  # Whether to force disable ACPI, regardless of the fw_cfg settings
+  # exposed by QEMU
+  #
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x69
+
 [PcdsFeatureFlag]
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
similarity index 89%
rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
index e900aa992661..85873f73b2eb 100644
--- a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+++ b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
@@ -19,7 +19,6 @@ [Sources]
   PlatformHasAcpiDtDxe.c
 
 [Packages]
-  ArmVirtPkg/ArmVirtPkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
@@ -38,7 +37,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   gEfiVariableArchProtocolGuid
diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
similarity index 100%
rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (10 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
@ 2023-01-28 19:17 ` Sunil V L
  2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Sunil V L
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:17 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

PlatformHasAcpiDtDxe is required by other architectures also.
Hence, it is moved to OvmfPkg. So, update the consumers of this
module with the new location.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 ArmVirtPkg/ArmVirtCloudHv.dsc                                  | 2 +-
 ArmVirtPkg/ArmVirtQemu.dsc                                     | 4 ++--
 ArmVirtPkg/ArmVirtQemuKernel.dsc                               | 2 +-
 ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf | 2 +-
 ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf           | 4 ++--
 ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc                           | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc
index 7ca7a391d9cf..c975e139a216 100644
--- a/ArmVirtPkg/ArmVirtCloudHv.dsc
+++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
@@ -198,7 +198,7 @@ [PcdsDynamicDefault.common]
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
 
 [PcdsDynamicHii]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
 
 ################################################################################
 #
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 0f1c6395488a..72a0cacab4a8 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -305,7 +305,7 @@ [PcdsPatchableInModule]
 !endif
 
 [PcdsDynamicHii]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
 
 !if $(TPM2_CONFIG_ENABLE) == TRUE
   gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
@@ -578,7 +578,7 @@ [Components.common]
   #
   # ACPI Support
   #
-  ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 [Components.AARCH64]
   MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index 807c85d48285..3cb9120e4e10 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -461,7 +461,7 @@ [Components.common]
   #
   # ACPI Support
   #
-  ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 [Components.AARCH64]
   MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {
diff --git a/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf b/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
index 4af06b2a6746..7cad40e11f33 100644
--- a/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
+++ b/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
@@ -36,7 +36,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   gEfiVariableArchProtocolGuid
diff --git a/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf b/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
index 1cf25780f830..c5bf798c3b2b 100644
--- a/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
+++ b/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
@@ -21,7 +21,7 @@ [Sources]
   KvmtoolPlatformDxe.c
 
 [Packages]
-  ArmVirtPkg/ArmVirtPkg.dec
+  OvmfPkg/OvmfPkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
@@ -37,7 +37,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   TRUE
diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index e06ca7424476..8a063bac04ac 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -141,7 +141,7 @@ [FV.FvMain]
   #
   # ACPI Support
   #
-  INF ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  INF OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 !if $(ARCH) == AARCH64
   INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
   INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (11 preceding siblings ...)
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library Sunil V L
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

RISC-V Qemu Virt platfform needs the PlatformBootManagerLib similar
to the one in ArmVirtPlatform. Add the library in OvmfPkg/RiscVVirt
leveraging the one from Arm.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   75 ++
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h               |   45 +
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c               | 1078 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c               |   77 ++
 4 files changed, 1275 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 000000000000..9d66c8110c53
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,75 @@
+## @file
+#  Implementation for PlatformBootManagerLib library class interfaces for RISC-V.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = DxeRiscV64PlatformBootManagerLib
+  FILE_GUID                      = 4FC87DC9-2666-49BB-9023-B5FAA1E9E732
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  PlatformBm.c
+  PlatformBm.h
+  QemuKernel.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  BootLogoLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  PcdLib
+  PlatformBmPrintScLib
+  QemuBootOrderLib
+  QemuLoadImageLib
+  ReportStatusCodeLib
+  TpmPlatformHierarchyLib
+  UefiBootManagerLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gEfiGlobalVariableGuid
+  gRootBridgesConnectedEventGroupGuid
+  gUefiShellFileGuid
+  gEfiTtyTermGuid
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gVirtioDeviceProtocolGuid
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h
new file mode 100644
index 000000000000..70c52d9832ca
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h
@@ -0,0 +1,45 @@
+/** @file
+  Head file for BDS Platform specific code
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_BM_H_
+#define _PLATFORM_BM_H_
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+  Download the kernel, the initial ramdisk, and the kernel command line from
+  QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two
+  image files, and load and start the kernel from it.
+
+  The kernel will be instructed via its command line to load the initrd from
+  the same Simple FileSystem.
+
+  @retval EFI_NOT_FOUND         Kernel image was not found.
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+  @retval EFI_PROTOCOL_ERROR    Unterminated kernel command line.
+
+  @return                       Error codes from any of the underlying
+                                functions. On success, the function doesn't
+                                return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+  VOID
+  );
+
+#endif // _PLATFORM_BM_H_
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c
new file mode 100644
index 000000000000..2559889638ad
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c
@@ -0,0 +1,1078 @@
+/** @file
+  Implementation for PlatformBootManagerLib library class interfaces.
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Virtio095.h>
+#include <Library/BootLogoLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformBmPrintScLib.h>
+#include <Library/QemuBootOrderLib.h>
+#include <Library/TpmPlatformHierarchyLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/VirtioDevice.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Guid/SerialPortLibVendor.h>
+#include <Guid/TtyTerm.h>
+
+#include "PlatformBm.h"
+
+#define DP_NODE_LEN(Type)  { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }
+
+#define VERSION_STRING_PREFIX  L"RISC-V EDK2 firmware version "
+
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH            SerialDxe;
+  UART_DEVICE_PATH              Uart;
+  VENDOR_DEFINED_DEVICE_PATH    TermType;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} PLATFORM_SERIAL_CONSOLE;
+#pragma pack ()
+
+STATIC PLATFORM_SERIAL_CONSOLE  mSerialConsole = {
+  //
+  // VENDOR_DEVICE_PATH SerialDxe
+  //
+  {
+    { HARDWARE_DEVICE_PATH,  HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },
+    EDKII_SERIAL_PORT_LIB_VENDOR_GUID
+  },
+
+  //
+  // UART_DEVICE_PATH Uart
+  //
+  {
+    { MESSAGING_DEVICE_PATH, MSG_UART_DP,  DP_NODE_LEN (UART_DEVICE_PATH)   },
+    0,                                      // Reserved
+    FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate
+    FixedPcdGet8 (PcdUartDefaultDataBits),  // DataBits
+    FixedPcdGet8 (PcdUartDefaultParity),    // Parity
+    FixedPcdGet8 (PcdUartDefaultStopBits)   // StopBits
+  },
+
+  //
+  // VENDOR_DEFINED_DEVICE_PATH TermType
+  //
+  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,
+      DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)
+    }
+    //
+    // Guid to be filled in dynamically
+    //
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+#pragma pack (1)
+typedef struct {
+  USB_CLASS_DEVICE_PATH       Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_USB_KEYBOARD;
+#pragma pack ()
+
+STATIC PLATFORM_USB_KEYBOARD  mUsbKeyboard = {
+  //
+  // USB_CLASS_DEVICE_PATH Keyboard
+  //
+  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,
+      DP_NODE_LEN (USB_CLASS_DEVICE_PATH)
+    },
+    0xFFFF, // VendorId: any
+    0xFFFF, // ProductId: any
+    3,      // DeviceClass: HID
+    1,      // DeviceSubClass: boot
+    1       // DeviceProtocol: keyboard
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+/**
+  Check if the handle satisfies a particular condition.
+
+  @param[in] Handle      The handle to check.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+
+  @retval TRUE   The condition is satisfied.
+  @retval FALSE  Otherwise. This includes the case when the condition could not
+                 be fully evaluated due to an error.
+**/
+typedef
+BOOLEAN
+(EFIAPI *FILTER_FUNCTION)(
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+/**
+  Process a handle.
+
+  @param[in] Handle      The handle to process.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+**/
+typedef
+VOID
+(EFIAPI *CALLBACK_FUNCTION)(
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+/**
+  Locate all handles that carry the specified protocol, filter them with a
+  callback function, and pass each handle that passes the filter to another
+  callback.
+
+  @param[in] ProtocolGuid  The protocol to look for.
+
+  @param[in] Filter        The filter function to pass each handle to. If this
+                           parameter is NULL, then all handles are processed.
+
+  @param[in] Process       The callback function to pass each handle to that
+                           clears the filter.
+**/
+STATIC
+VOID
+FilterAndProcess (
+  IN EFI_GUID           *ProtocolGuid,
+  IN FILTER_FUNCTION    Filter         OPTIONAL,
+  IN CALLBACK_FUNCTION  Process
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  *Handles;
+  UINTN       NoHandles;
+  UINTN       Idx;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  ProtocolGuid,
+                  NULL /* SearchKey */,
+                  &NoHandles,
+                  &Handles
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // This is not an error, just an informative condition.
+    //
+    DEBUG ((
+      DEBUG_VERBOSE,
+      "%a: %g: %r\n",
+      __FUNCTION__,
+      ProtocolGuid,
+      Status
+      ));
+    return;
+  }
+
+  ASSERT (NoHandles > 0);
+  for (Idx = 0; Idx < NoHandles; ++Idx) {
+    CHAR16         *DevicePathText;
+    STATIC CHAR16  Fallback[] = L"<device path unavailable>";
+
+    //
+    // The ConvertDevicePathToText() function handles NULL input transparently.
+    //
+    DevicePathText = ConvertDevicePathToText (
+                       DevicePathFromHandle (Handles[Idx]),
+                       FALSE, // DisplayOnly
+                       FALSE  // AllowShortcuts
+                       );
+    if (DevicePathText == NULL) {
+      DevicePathText = Fallback;
+    }
+
+    if ((Filter == NULL) || Filter (Handles[Idx], DevicePathText)) {
+      Process (Handles[Idx], DevicePathText);
+    }
+
+    if (DevicePathText != Fallback) {
+      FreePool (DevicePathText);
+    }
+  }
+
+  gBS->FreePool (Handles);
+}
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a PCI display device.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsPciDisplay (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  PCI_TYPE00           Pci;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // This is not an error worth reporting.
+    //
+    return FALSE;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0 /* Offset */,
+                        sizeof Pci / sizeof (UINT32),
+                        &Pci
+                        );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));
+    return FALSE;
+  }
+
+  return IS_PCI_DISPLAY (&Pci);
+}
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG device at
+  the VIRTIO_DEVICE_PROTOCOL level.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsVirtioRng (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS              Status;
+  VIRTIO_DEVICE_PROTOCOL  *VirtIo;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gVirtioDeviceProtocolGuid,
+                  (VOID **)&VirtIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return (BOOLEAN)(VirtIo->SubSystemDeviceId ==
+                   VIRTIO_SUBSYSTEM_ENTROPY_SOURCE);
+}
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG device at
+  the EFI_PCI_IO_PROTOCOL level.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsVirtioPciRng (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  UINT16               VendorId;
+  UINT16               DeviceId;
+  UINT8                RevisionId;
+  BOOLEAN              Virtio10;
+  UINT16               SubsystemId;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  //
+  // Read and check VendorId.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_VENDOR_ID_OFFSET,
+                        1,
+                        &VendorId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  if (VendorId != VIRTIO_VENDOR_ID) {
+    return FALSE;
+  }
+
+  //
+  // Read DeviceId and RevisionId.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_DEVICE_ID_OFFSET,
+                        1,
+                        &DeviceId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_REVISION_ID_OFFSET,
+                        1,
+                        &RevisionId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  //
+  // From DeviceId and RevisionId, determine whether the device is a
+  // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can
+  // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and
+  // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can
+  // only be sanity-checked, and SubsystemId will decide.
+  //
+  if ((DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) &&
+      (RevisionId >= 0x01))
+  {
+    Virtio10 = TRUE;
+  } else if ((DeviceId >= 0x1000) && (DeviceId <= 0x103F) && (RevisionId == 0x00)) {
+    Virtio10 = FALSE;
+  } else {
+    return FALSE;
+  }
+
+  //
+  // Read and check SubsystemId as dictated by Virtio10.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_SUBSYSTEM_ID_OFFSET,
+                        1,
+                        &SubsystemId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  if (Virtio10 && (SubsystemId >= 0x40)) {
+    return TRUE;
+  }
+
+  if (!Virtio10 && (SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {
+    return TRUE;
+  }
+
+  return FALSE;
+
+PciError:
+  DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));
+  return FALSE;
+}
+
+/**
+  This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking
+  the matching driver to produce all first-level child handles.
+**/
+STATIC
+VOID
+EFIAPI
+Connect (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->ConnectController (
+                  Handle, // ControllerHandle
+                  NULL,   // DriverImageHandle
+                  NULL,   // RemainingDevicePath -- produce all children
+                  FALSE   // Recursive
+                  );
+  DEBUG ((
+    EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
+    "%a: %s: %r\n",
+    __FUNCTION__,
+    ReportText,
+    Status
+    ));
+}
+
+/**
+  This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the
+  handle, and adds it to ConOut and ErrOut.
+**/
+STATIC
+VOID
+EFIAPI
+AddOutput (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  DevicePath = DevicePathFromHandle (Handle);
+  if (DevicePath == NULL) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: handle %p: device path not found\n",
+      __FUNCTION__,
+      ReportText,
+      Handle
+      ));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: adding to ConOut: %r\n",
+      __FUNCTION__,
+      ReportText,
+      Status
+      ));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: adding to ErrOut: %r\n",
+      __FUNCTION__,
+      ReportText,
+      Status
+      ));
+    return;
+  }
+
+  DEBUG ((
+    DEBUG_VERBOSE,
+    "%a: %s: added to ConOut and ErrOut\n",
+    __FUNCTION__,
+    ReportText
+    ));
+}
+
+STATIC
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID  *FileGuid,
+  CHAR16    *Description,
+  UINT32    Attributes
+  )
+{
+  EFI_STATUS                         Status;
+  INTN                               OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION       NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION       *BootOptions;
+  UINTN                              BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+  ASSERT (DevicePath != NULL);
+  DevicePath = AppendDevicePathNode (
+                 DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
+                 );
+  ASSERT (DevicePath != NULL);
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  ASSERT_EFI_ERROR (Status);
+  FreePool (DevicePath);
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount,
+                  LoadOptionTypeBoot
+                  );
+
+  OptionIndex = EfiBootManagerFindLoadOption (
+                  &NewOption,
+                  BootOptions,
+                  BootOptionCount
+                  );
+
+  if (OptionIndex == -1) {
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  EfiBootManagerFreeLoadOption (&NewOption);
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
+  whose device paths do not resolve exactly to an FvFile in the system.
+
+  This removes any boot options that point to binaries built into the firmware
+  and have become stale due to any of the following:
+  - FvMain's base address or size changed (historical),
+  - FvMain's FvNameGuid changed,
+  - the FILE_GUID of the pointed-to binary changed,
+  - the referenced binary is no longer built into the firmware.
+
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only
+  avoids exact duplicates.
+**/
+STATIC
+VOID
+RemoveStaleFvFileOptions (
+  VOID
+  )
+{
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions;
+  UINTN                         BootOptionCount;
+  UINTN                         Index;
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount,
+                  LoadOptionTypeBoot
+                  );
+
+  for (Index = 0; Index < BootOptionCount; ++Index) {
+    EFI_DEVICE_PATH_PROTOCOL  *Node1, *Node2, *SearchNode;
+    EFI_STATUS                Status;
+    EFI_HANDLE                FvHandle;
+
+    //
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+    // then keep the boot option.
+    //
+    Node1 = BootOptions[Index].FilePath;
+    if (!((DevicePathType (Node1) == HARDWARE_DEVICE_PATH) &&
+          (DevicePathSubType (Node1) == HW_MEMMAP_DP)) &&
+        !((DevicePathType (Node1) == MEDIA_DEVICE_PATH) &&
+          (DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)))
+    {
+      continue;
+    }
+
+    //
+    // If the second device path node is not FvFile(...), then keep the boot
+    // option.
+    //
+    Node2 = NextDevicePathNode (Node1);
+    if ((DevicePathType (Node2) != MEDIA_DEVICE_PATH) ||
+        (DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP))
+    {
+      continue;
+    }
+
+    //
+    // Locate the Firmware Volume2 protocol instance that is denoted by the
+    // boot option. If this lookup fails (i.e., the boot option references a
+    // firmware volume that doesn't exist), then we'll proceed to delete the
+    // boot option.
+    //
+    SearchNode = Node1;
+    Status     = gBS->LocateDevicePath (
+                        &gEfiFirmwareVolume2ProtocolGuid,
+                        &SearchNode,
+                        &FvHandle
+                        );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // The firmware volume was found; now let's see if it contains the FvFile
+      // identified by GUID.
+      //
+      EFI_FIRMWARE_VOLUME2_PROTOCOL      *FvProtocol;
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFileNode;
+      UINTN                              BufferSize;
+      EFI_FV_FILETYPE                    FoundType;
+      EFI_FV_FILE_ATTRIBUTES             FileAttributes;
+      UINT32                             AuthenticationStatus;
+
+      Status = gBS->HandleProtocol (
+                      FvHandle,
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **)&FvProtocol
+                      );
+      ASSERT_EFI_ERROR (Status);
+
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+      //
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+      // FileAttributes.
+      //
+      Status = FvProtocol->ReadFile (
+                             FvProtocol,
+                             &FvFileNode->FvFileName, // NameGuid
+                             NULL,                    // Buffer
+                             &BufferSize,
+                             &FoundType,
+                             &FileAttributes,
+                             &AuthenticationStatus
+                             );
+      if (!EFI_ERROR (Status)) {
+        //
+        // The FvFile was found. Keep the boot option.
+        //
+        continue;
+      }
+    }
+
+    //
+    // Delete the boot option.
+    //
+    Status = EfiBootManagerDeleteLoadOptionVariable (
+               BootOptions[Index].OptionNumber,
+               LoadOptionTypeBoot
+               );
+    DEBUG_CODE_BEGIN ();
+    CHAR16  *DevicePathString;
+
+    DevicePathString = ConvertDevicePathToText (
+                         BootOptions[Index].FilePath,
+                         FALSE,
+                         FALSE
+                         );
+    DEBUG ((
+      EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE,
+      "%a: removing stale Boot#%04x %s: %r\n",
+      __FUNCTION__,
+      (UINT32)BootOptions[Index].OptionNumber,
+      DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
+      Status
+      ));
+    if (DevicePathString != NULL) {
+      FreePool (DevicePathString);
+    }
+
+    DEBUG_CODE_END ();
+  }
+
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+STATIC
+VOID
+PlatformRegisterOptionsAndKeys (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Enter;
+  EFI_INPUT_KEY                 F2;
+  EFI_INPUT_KEY                 Esc;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  Status            = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Map F2 and ESC to Boot Manager Menu
+  //
+  F2.ScanCode     = SCAN_F2;
+  F2.UnicodeChar  = CHAR_NULL;
+  Esc.ScanCode    = SCAN_ESC;
+  Esc.UnicodeChar = CHAR_NULL;
+  Status          = EfiBootManagerGetBootManagerMenu (&BootOption);
+  ASSERT_EFI_ERROR (Status);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL,
+             (UINT16)BootOption.OptionNumber,
+             0,
+             &F2,
+             NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL,
+             (UINT16)BootOption.OptionNumber,
+             0,
+             &Esc,
+             NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+}
+
+//
+// BDS Platform Functions
+//
+
+/**
+  Do the platform init, can be customized by OEM/IBV
+  Possible things that can be done in PlatformBootManagerBeforeConsole:
+  > Update console variable: 1. include hot-plug devices;
+  >                          2. Clear ConIn and add SOL for AMT
+  > Register new Driver#### or Boot####
+  > Register new Key####: e.g.: F12
+  > Signal ReadyToLock event
+  > Authentication action: 1. connect Auth devices;
+  >                        2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  UINT16         FrontPageTimeout;
+  RETURN_STATUS  PcdStatus;
+  EFI_STATUS     Status;
+
+  //
+  // Signal EndOfDxe PI Event
+  //
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+  //
+  // Disable the TPM 2 platform hierarchy
+  //
+  ConfigureTpmPlatformHierarchy ();
+
+  //
+  // Dispatch deferred images after EndOfDxe event.
+  //
+  EfiBootManagerDispatchDeferredImages ();
+
+  //
+  // Locate the PCI root bridges and make the PCI bus driver connect each,
+  // non-recursively. This will produce a number of child handles with PciIo on
+  // them.
+  //
+  FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect);
+
+  //
+  // Signal the ACPI platform driver that it can download QEMU ACPI tables.
+  //
+  EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);
+
+  //
+  // Find all display class PCI devices (using the handles from the previous
+  // step), and connect them non-recursively. This should produce a number of
+  // child handles with GOPs on them.
+  //
+  FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect);
+
+  //
+  // Now add the device path of all handles with GOP on them to ConOut and
+  // ErrOut.
+  //
+  FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
+
+  //
+  // Add the hardcoded short-form USB keyboard device path to ConIn.
+  //
+  EfiBootManagerUpdateConsoleVariable (
+    ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard,
+    NULL
+    );
+
+  //
+  // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
+  //
+  CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
+
+  EfiBootManagerUpdateConsoleVariable (
+    ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+  EfiBootManagerUpdateConsoleVariable (
+    ConOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+  EfiBootManagerUpdateConsoleVariable (
+    ErrOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+
+  //
+  // Set the front page timeout from the QEMU configuration.
+  //
+  FrontPageTimeout = GetFrontPageTimeoutFromQemu ();
+  PcdStatus        = PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  //
+  // Reflect the PCD in the standard Timeout variable.
+  //
+  Status = gRT->SetVariable (
+                  EFI_TIME_OUT_VARIABLE_NAME,
+                  &gEfiGlobalVariableGuid,
+                  (EFI_VARIABLE_NON_VOLATILE |
+                   EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                   EFI_VARIABLE_RUNTIME_ACCESS),
+                  sizeof FrontPageTimeout,
+                  &FrontPageTimeout
+                  );
+  DEBUG ((
+    EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
+    "%a: SetVariable(%s, %u): %r\n",
+    __FUNCTION__,
+    EFI_TIME_OUT_VARIABLE_NAME,
+    FrontPageTimeout,
+    Status
+    ));
+
+  //
+  // Register platform-specific boot options and keyboard shortcuts.
+  //
+  PlatformRegisterOptionsAndKeys ();
+
+  //
+  // At this point, VIRTIO_DEVICE_PROTOCOL instances exist only for Virtio MMIO
+  // transports. Install EFI_RNG_PROTOCOL instances on Virtio MMIO RNG devices.
+  //
+  FilterAndProcess (&gVirtioDeviceProtocolGuid, IsVirtioRng, Connect);
+
+  //
+  // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL
+  // instances on Virtio PCI RNG devices.
+  //
+  FilterAndProcess (&gEfiPciIoProtocolGuid, IsVirtioPciRng, Connect);
+}
+
+/**
+  Do the platform specific action after the console is ready
+  Possible things that can be done in PlatformBootManagerAfterConsole:
+  > Console post action:
+    > Dynamically switch output mode from 100x31 to 80x25 for certain scenario
+    > Signal console ready platform customized event
+  > Run diagnostics like memory testing
+  > Connect certain devices
+  > Dispatch additional option roms
+  > Special boot: e.g.: USB boot, enter UI
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  RETURN_STATUS  Status;
+  UINTN          FirmwareVerLength;
+
+  FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString));
+  //
+  // Show the splash screen.
+  //
+  BootLogoEnableLogo ();
+
+  if (FirmwareVerLength > 0) {
+    Print (
+      VERSION_STRING_PREFIX L"%s\n",
+      PcdGetPtr (PcdFirmwareVersionString)
+      );
+  }
+
+  Print (L"Press ESCAPE within 10 seconds for boot options ");
+  //
+  // Process QEMU's -kernel command line option. The kernel booted this way
+  // will receive ACPI tables: in PlatformBootManagerBeforeConsole(), we
+  // connected any and all PCI root bridges, and then signaled the ACPI
+  // platform driver.
+  //
+  TryRunningQemuKernel ();
+
+  //
+  // Connect the purported boot devices.
+  //
+  Status = ConnectDevicesFromQemu ();
+  if (RETURN_ERROR (Status)) {
+    //
+    // Connect the rest of the devices.
+    //
+    EfiBootManagerConnectAll ();
+  }
+
+  //
+  // Enumerate all possible boot options, then filter and reorder them based on
+  // the QEMU configuration.
+  //
+  EfiBootManagerRefreshAllBootOption ();
+
+  //
+  // Register UEFI Shell
+  //
+  PlatformRegisterFvBootOption (
+    &gUefiShellFileGuid,
+    L"EFI Internal Shell",
+    LOAD_OPTION_ACTIVE
+    );
+
+  RemoveStaleFvFileOptions ();
+  SetBootOrderFromQemu ();
+
+  PlatformBmPrintScRegisterHandler ();
+}
+
+/**
+  This function is called each second during the boot manager waits the
+  timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16  TimeoutRemain
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  Black;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  White;
+  UINT16                               TimeoutInitial;
+
+  TimeoutInitial = PcdGet16 (PcdPlatformBootTimeOut);
+
+  //
+  // If PcdPlatformBootTimeOut is set to zero, then we consider
+  // that no progress update should be enacted.
+  //
+  if (TimeoutInitial == 0) {
+    return;
+  }
+
+  Black.Raw = 0x00000000;
+  White.Raw = 0x00FFFFFF;
+
+  BootLogoUpdateProgress (
+    White.Pixel,
+    Black.Pixel,
+    L"Start boot option",
+    White.Pixel,
+    (TimeoutInitial - TimeoutRemain) * 100 / TimeoutInitial,
+    0
+    );
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Key;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootManagerMenu;
+  UINTN                         Index;
+
+  //
+  // BootManagerMenu doesn't contain the correct information when return status
+  // is EFI_NOT_FOUND.
+  //
+  Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Normally BdsDxe does not print anything to the system console, but this is
+  // a last resort -- the end-user will likely not see any DEBUG messages
+  // logged in this situation.
+  //
+  // AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn
+  // here to see if it makes sense to request and wait for a keypress.
+  //
+  if (gST->ConIn != NULL) {
+    AsciiPrint (
+      "%a: No bootable option or device was found.\n"
+      "%a: Press any key to enter the Boot Manager Menu.\n",
+      gEfiCallerBaseName,
+      gEfiCallerBaseName
+      );
+    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
+    ASSERT_EFI_ERROR (Status);
+    ASSERT (Index == 0);
+
+    //
+    // Drain any queued keys.
+    //
+    while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {
+      //
+      // just throw away Key
+      //
+    }
+  }
+
+  for ( ; ;) {
+    EfiBootManagerBoot (&BootManagerMenu);
+  }
+}
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c
new file mode 100644
index 000000000000..736628174f4e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c
@@ -0,0 +1,77 @@
+/** @file
+  Try to load an EFI-stubbed RISC-V Linux kernel from QEMU's fw_cfg.
+
+  This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI
+  stub in the subject kernel is a hard requirement here.
+
+  Copyright (C) 2014-2016, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/QemuLoadImageLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+#include "PlatformBm.h"
+
+//
+// The entry point of the feature.
+//
+
+/**
+  Download the kernel, the initial ramdisk, and the kernel command line from
+  QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two
+  image files, and load and start the kernel from it.
+
+  The kernel will be instructed via its command line to load the initrd from
+  the same Simple FileSystem.
+
+  @retval EFI_NOT_FOUND         Kernel image was not found.
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+  @retval EFI_PROTOCOL_ERROR    Unterminated kernel command line.
+
+  @return                       Error codes from any of the underlying
+                                functions. On success, the function doesn't
+                                return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  KernelImageHandle;
+
+  Status = QemuLoadKernelImage (&KernelImageHandle);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event.
+  //
+  EfiSignalEventReadyToBoot ();
+
+  REPORT_STATUS_CODE (
+    EFI_PROGRESS_CODE,
+    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)
+    );
+
+  //
+  // Start the image.
+  //
+  Status = QemuStartKernelImage (&KernelImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: QemuStartKernelImage(): %r\n",
+      __FUNCTION__,
+      Status
+      ));
+  }
+
+  QemuUnloadKernelImage (KernelImageHandle);
+
+  return Status;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (12 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library Sunil V L
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

Add the PrePiHobListPointerLib required for RISC-V Qemu Virt machine
since it follows PEIless design.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf | 23 +++++++
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c      | 65 ++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
new file mode 100644
index 000000000000..c539682e8d0b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
@@ -0,0 +1,23 @@
+#/** @file
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PrePiHobListPointerLib
+  FILE_GUID                      = E3FAFC60-758C-471B-A333-FE704A4C11B4
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PrePiHobListPointerLib
+
+[Sources.RISCV64]
+  PrePiHobListPointer.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
new file mode 100644
index 000000000000..a58b7aae6bee
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
@@ -0,0 +1,65 @@
+/** @file
+*
+*  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+/**
+  Returns the pointer to the HOB list.
+
+  This function returns the pointer to first HOB in the list.
+
+  @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+PrePeiGetHobList (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return NULL;
+  }
+
+  return (VOID *)FirmwareContext->PrePiHobList;
+}
+
+/**
+  Updates the pointer to the HOB list.
+
+  @param  HobList       Hob list pointer to store
+
+**/
+EFI_STATUS
+EFIAPI
+PrePeiSetHobList (
+  IN  VOID  *HobList
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_NOT_READY;
+  }
+
+  FirmwareContext->PrePiHobList = HobList;
+  return EFI_SUCCESS;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (13 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library Sunil V L
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

RISC-V Qemu virt uses SBI calls to implement the reset.
Add the base class library.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf |  38 ++++++
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c       | 128 ++++++++++++++++++++
 2 files changed, 166 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
new file mode 100644
index 000000000000..c3fa6bd99b52
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
@@ -0,0 +1,38 @@
+## @file
+#  Base library instance for ResetSystem library class for RISC-V
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseResetSystemLib
+  FILE_GUID                      = AB45A200-769D-4C10-B0D6-5E1FF5EEBF31
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  ResetSystemLib.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  TimerLib
+  RiscVSbiLib
diff --git a/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 000000000000..14f7653aa8de
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,128 @@
+/** @file
+  Reset System Library functions for RISC-V
+
+  Copyright (c) 2021, Hewlett Packard Development LP. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+/**
+  This function causes a system-wide reset (cold reset), in which
+  all circuitry within the system returns to its initial state. This type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  If this function returns, it means that the system does not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  // Warm Reset via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_COLD_REBOOT, SBI_SRST_RESET_REASON_NONE);
+}
+
+/**
+  This function causes a system-wide initialization (warm reset), in which all processors
+  are set to their initial state. Pending cycles are not corrupted.
+
+  If this function returns, it means that the system does not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  // Warm Reset via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_WARM_REBOOT, SBI_SRST_RESET_REASON_NONE);
+}
+
+/**
+  This function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  If this function returns, it means that the system does not support shutdown reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  // Shut down via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_SHUTDOWN, SBI_SRST_RESET_REASON_NONE);
+}
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform. The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN  DataSize,
+  IN VOID   *ResetData
+  )
+{
+  //
+  // Can map to OpenSBI vendor or platform specific reset type.
+  //
+  return;
+}
+
+/**
+  The ResetSystem function resets the entire platform.
+
+  @param[in] ResetType      The type of reset to perform.
+  @param[in] ResetStatus    The status code for the reset.
+  @param[in] DataSize       The size, in bytes, of ResetData.
+  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+                            the data buffer starts with a Null-terminated string, optionally
+                            followed by additional binary data. The string is a description
+                            that the caller may use to further indicate the reason for the
+                            system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+  IN EFI_RESET_TYPE  ResetType,
+  IN EFI_STATUS      ResetStatus,
+  IN UINTN           DataSize,
+  IN VOID            *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+    case EfiResetWarm:
+      ResetWarm ();
+      break;
+
+    case EfiResetCold:
+      ResetCold ();
+      break;
+
+    case EfiResetShutdown:
+      ResetShutdown ();
+      return;
+
+    case EfiResetPlatformSpecific:
+      ResetPlatformSpecific (DataSize, ResetData);
+      return;
+
+    default:
+      return;
+  }
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (14 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:02   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Sunil V L
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

Qemu NOR flash driver needs this library. Add this
library for RISC-V leveraged from SbsaQemu.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf | 30 +++++++++++++++
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c   | 40 ++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
new file mode 100644
index 000000000000..4e87bd437380
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+#  Component description file for VirtNorFlashStaticLib module
+#
+#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = VirtNorFlashStaticLib
+  FILE_GUID                      = 064742F1-E531-4D7D-A154-22315889CC23
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = VirtNorFlashPlatformLib
+
+[Sources.common]
+  VirtNorFlashStaticLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
diff --git a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c
new file mode 100644
index 000000000000..fdc2ccb6294e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c
@@ -0,0 +1,40 @@
+/** @file
+
+ Copyright (c) 2019, Linaro Ltd. All rights reserved
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <Base.h>
+#include <PiDxe.h>
+#include <Library/VirtNorFlashPlatformLib.h>
+
+#define QEMU_NOR_BLOCK_SIZE  SIZE_256KB
+
+EFI_STATUS
+VirtNorFlashPlatformInitialization (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+VIRT_NOR_FLASH_DESCRIPTION  mNorFlashDevice =
+{
+  FixedPcdGet32 (PcdOvmfFdBaseAddress),
+  FixedPcdGet64 (PcdFlashNvStorageVariableBase),
+  FixedPcdGet32 (PcdOvmfFirmwareFdSize),
+  QEMU_NOR_BLOCK_SIZE
+};
+
+EFI_STATUS
+VirtNorFlashPlatformGetDevices (
+  OUT VIRT_NOR_FLASH_DESCRIPTION  **NorFlashDescriptions,
+  OUT UINT32                      *Count
+  )
+{
+  *NorFlashDescriptions = &mNorFlashDevice;
+  *Count                = 1;
+  return EFI_SUCCESS;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (15 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-01-30 10:12   ` [edk2-devel] " dhaval
  2023-02-06 16:02   ` Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module Sunil V L
                   ` (5 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL
to add the translation for IO access. This is copied from
ArmPciCpuIo2Dxe driver.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf |  48 ++
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c   | 557 ++++++++++++++++++++
 2 files changed, 605 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
new file mode 100644
index 000000000000..4f78cfa4067b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
@@ -0,0 +1,48 @@
+## @file
+#  Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciCpuIo2Dxe
+  FILE_GUID                      = 9BD3C765-2579-4CF0-9349-D77205565030
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PciCpuIo2Initialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  PciCpuIo2Dxe.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiBootServicesTableLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid                         ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c
new file mode 100644
index 000000000000..f3bf07e63141
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c
@@ -0,0 +1,557 @@
+/** @file
+  Produces the CPU I/O 2 Protocol.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Protocol/CpuIo2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define MAX_IO_PORT_ADDRESS  0xFFFF
+
+//
+// Handle for the CPU I/O 2 Protocol
+//
+STATIC EFI_HANDLE  mHandle = NULL;
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8  mInStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  0, // EfiCpuIoWidthFifoUint8
+  0, // EfiCpuIoWidthFifoUint16
+  0, // EfiCpuIoWidthFifoUint32
+  0, // EfiCpuIoWidthFifoUint64
+  1, // EfiCpuIoWidthFillUint8
+  2, // EfiCpuIoWidthFillUint16
+  4, // EfiCpuIoWidthFillUint32
+  8  // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8  mOutStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  1, // EfiCpuIoWidthFifoUint8
+  2, // EfiCpuIoWidthFifoUint16
+  4, // EfiCpuIoWidthFifoUint32
+  8, // EfiCpuIoWidthFifoUint64
+  0, // EfiCpuIoWidthFillUint8
+  0, // EfiCpuIoWidthFillUint16
+  0, // EfiCpuIoWidthFillUint32
+  0  // EfiCpuIoWidthFillUint64
+};
+
+/**
+  Check parameters to a CPU I/O 2 Protocol service request.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  @param[in] MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+  @param[in] Address        The base address of the I/O operation.
+  @param[in] Count          The number of I/O operations to perform. The number of
+                            bytes moved is Width size * Count, starting at Address.
+  @param[in] Buffer         For read operations, the destination buffer to store the results.
+                            For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+CpuIoCheckParameter (
+  IN BOOLEAN                    MmioOperation,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  UINT64  MaxCount;
+  UINT64  Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the access,
+  // so treat Count as 1
+  //
+  if ((Width >= EfiCpuIoWidthFifoUint8) && (Width <= EfiCpuIoWidthFifoUint64)) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Address is aligned
+  //
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check to see if any address associated with this transfer exceeds the maximum
+  // allowed address.  The maximum address implied by the parameters passed in is
+  // Address + Size * Count.  If the following condition is met, then the transfer
+  // is not supported.
+  //
+  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+  //
+  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
+  // can also be the maximum integer value supported by the CPU, this range
+  // check must be adjusted to avoid all overflow conditions.
+  //
+  // The following form of the range check is equivalent but assumes that
+  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+  //
+  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+  if (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check to see if Buffer is aligned
+  //
+  if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width])  - 1))) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Address += PcdGet64 (PcdPciIoTranslation);
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller is responsible
+  for satisfying any alignment and I/O width restrictions that a PI System on a
+  platform might require. For example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
+  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+  incremented for each of the Count operations that is performed. The read or
+  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  //
+  // Make sure the parameters are valid
+  //
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Address += PcdGet64 (PcdPciIoTranslation);
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// CPU I/O 2 Protocol instance
+//
+STATIC EFI_CPU_IO2_PROTOCOL  mCpuIo2 = {
+  {
+    CpuMemoryServiceRead,
+    CpuMemoryServiceWrite
+  },
+  {
+    CpuIoServiceRead,
+    CpuIoServiceWrite
+  }
+};
+
+/**
+  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCpuIo2Initialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mHandle,
+                  &gEfiCpuIo2ProtocolGuid,
+                  &mCpuIo2,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (16 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-01-30  5:17   ` [edk2-devel] " dhaval
  2023-02-06 16:03   ` Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform Sunil V L
                   ` (4 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

Add the SEC module for RISC-V Qemu virt machine support.
It uses the PEI less design.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Sec/SecMain.inf |  66 +++++
 OvmfPkg/RiscVVirt/Sec/SecMain.h   | 102 ++++++++
 OvmfPkg/RiscVVirt/Sec/Cpu.c       |  33 +++
 OvmfPkg/RiscVVirt/Sec/Memory.c    | 263 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/Sec/Platform.c  |  84 +++++++
 OvmfPkg/RiscVVirt/Sec/SecMain.c   | 104 ++++++++
 OvmfPkg/RiscVVirt/Sec/SecEntry.S  |  21 ++
 7 files changed, 673 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.inf b/OvmfPkg/RiscVVirt/Sec/SecMain.inf
new file mode 100644
index 000000000000..aed35d3af596
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.inf
@@ -0,0 +1,66 @@
+## @file
+#  SEC Driver for RISC-V
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SecMainRiscV64
+  FILE_GUID                      = 16740C0A-AA84-4F62-A06D-AE328057AE07
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  SecEntry.S
+  SecMain.c
+  SecMain.h
+  Cpu.c
+  Memory.c
+  Platform.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  PcdLib
+  IoLib
+  PeCoffLib
+  LzmaDecompressLib
+  RiscVSbiLib
+  PrePiLib
+  FdtLib
+  MemoryAllocationLib
+  HobLib
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
+  gEfiTemporaryRamDonePpiGuid                   ## PRODUCES
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+
+[Guids]
+  gFdtHobGuid
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.h b/OvmfPkg/RiscVVirt/Sec/SecMain.h
new file mode 100644
index 000000000000..83a8058efe40
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.h
@@ -0,0 +1,102 @@
+/** @file
+  Master header file for SecCore.
+
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SEC_MAIN_H_
+#define SEC_MAIN_H_
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PlatformInitLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+  @param SizeOfRam           Size of the temporary memory available for use.
+  @param TempRamBase         Base address of temporary ram
+  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartup (
+  IN  UINTN  BootHartId,
+  IN  VOID   *DeviceTreeAddress
+  );
+
+/**
+  Auto-generated function that calls the library constructors for all of the module's
+  dependent libraries.  This function must be called by the SEC Core once a stack has
+  been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+  VOID
+  );
+
+/**
+  Perform Platform PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPeimInitialization (
+  VOID
+  );
+
+/**
+  Perform Memory PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryPeimInitialization (
+  VOID
+  );
+
+/**
+  Perform CPU PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+CpuPeimInitialization (
+  VOID
+  );
+
+#endif
diff --git a/OvmfPkg/RiscVVirt/Sec/Cpu.c b/OvmfPkg/RiscVVirt/Sec/Cpu.c
new file mode 100644
index 000000000000..2c16df697e37
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Cpu.c
@@ -0,0 +1,33 @@
+/** @file
+The library call to pass the device tree to DXE via HOB.
+
+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 <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+/**
+  Cpu Peim initialization.
+
+**/
+EFI_STATUS
+CpuPeimInitialization (
+  VOID
+  )
+{
+  //
+  // for MMU type >= sv39
+  //
+  BuildCpuHob (56, 32);
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Sec/Memory.c
new file mode 100644
index 000000000000..70935b07b56b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Memory.c
@@ -0,0 +1,263 @@
+/** @file
+  Memory Detection for Virtual Machines.
+
+  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Register/RiscV64/RiscVEncoding.h>
+#include <Library/PrePiLib.h>
+#include <libfdt.h>
+#include <Guid/FdtHob.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+/**
+  Build reserved memory range resource HOB.
+
+  @param  MemoryBase     Reserved memory range base address.
+  @param  MemorySize     Reserved memory range size.
+
+**/
+STATIC
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+/**
+  Create memory range resource HOB using the memory base
+  address and size.
+
+  @param  MemoryBase     Memory range base address.
+  @param  MemorySize     Memory range size.
+
+**/
+STATIC
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+/**
+  Create memory range resource HOB using memory base
+  address and top address of the memory range.
+
+  @param  MemoryBase     Memory range base address.
+  @param  MemoryLimit    Memory range size.
+
+**/
+STATIC
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  EFI_PHYSICAL_ADDRESS  MemoryLimit
+  )
+{
+  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+/**
+  Configure MMU
+**/
+STATIC
+VOID
+InitMmu (
+  )
+{
+  //
+  // Set supervisor translation mode to Bare mode
+  //
+  RiscVSetSupervisorAddressTranslationRegister ((UINT64)SATP_MODE_OFF << 60);
+  DEBUG ((DEBUG_INFO, "%a: Set Supervisor address mode to bare-metal mode.\n", __FUNCTION__));
+}
+
+/**
+  Publish system RAM and reserve memory regions.
+
+**/
+STATIC
+VOID
+InitializeRamRegions (
+  EFI_PHYSICAL_ADDRESS  SystemMemoryBase,
+  UINT64                SystemMemorySize,
+  EFI_PHYSICAL_ADDRESS  MmodeResvBase,
+  UINT64                MmodeResvSize
+  )
+{
+  /*
+   * M-mode FW can be loaded anywhere in memory but should not overlap
+   * with the EDK2. This can happen if some other boot code loads the
+   * M-mode firmware.
+   *
+   * The M-mode firmware memory should be marked as reserved memory
+   * so that OS doesn't use it.
+   */
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: M-mode FW Memory Start:0x%lx End:0x%lx\n",
+    __FUNCTION__,
+    MmodeResvBase,
+    MmodeResvBase + MmodeResvSize
+    ));
+  AddReservedMemoryBaseSizeHob (MmodeResvBase, MmodeResvSize);
+
+  if (MmodeResvBase > SystemMemoryBase) {
+    AddMemoryRangeHob (SystemMemoryBase, MmodeResvBase);
+  }
+
+  AddMemoryRangeHob (
+    MmodeResvBase + MmodeResvSize,
+    SystemMemoryBase + SystemMemorySize
+    );
+}
+
+/**
+  Initialize memory hob based on the DTB information.
+
+  @return EFI_SUCCESS     The memory hob added successfully.
+
+**/
+EFI_STATUS
+MemoryPeimInitialization (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+  CONST UINT64                *RegProp;
+  CONST CHAR8                 *Type;
+  UINT64                      CurBase, CurSize;
+  INT32                       Node, Prev;
+  INT32                       Len;
+  VOID                        *FdtPointer;
+  EFI_PHYSICAL_ADDRESS        MmodeResvBase;
+  UINT64                      MmodeResvSize;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
+  if (FdtPointer == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  /* try to locate the reserved memory opensbi node */
+  Node = fdt_path_offset (FdtPointer, "/reserved-memory/mmode_resv0");
+  if (Node >= 0) {
+    RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);
+    if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
+      MmodeResvBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+      MmodeResvSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+    }
+  }
+
+  // Look for the lowest memory node
+  for (Prev = 0; ; Prev = Node) {
+    Node = fdt_next_node (FdtPointer, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    // Check for memory node
+    Type = fdt_getprop (FdtPointer, Node, "device_type", &Len);
+    if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
+      // Get the 'reg' property of this node. For now, we will assume
+      // two 8 byte quantities for base and size, respectively.
+      RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);
+      if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
+        CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+        CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+
+        DEBUG ((
+          DEBUG_INFO,
+          "%a: System RAM @ 0x%lx - 0x%lx\n",
+          __FUNCTION__,
+          CurBase,
+          CurBase + CurSize - 1
+          ));
+
+        if ((MmodeResvBase >= CurBase) && ((MmodeResvBase + MmodeResvSize) <= (CurBase + CurSize))) {
+          InitializeRamRegions (
+            CurBase,
+            CurSize,
+            MmodeResvBase,
+            MmodeResvSize
+            );
+        } else {
+          AddMemoryBaseSizeHob (CurBase, CurSize);
+        }
+      } else {
+        DEBUG ((
+          DEBUG_ERROR,
+          "%a: Failed to parse FDT memory node\n",
+          __FUNCTION__
+          ));
+      }
+    }
+  }
+
+  InitMmu ();
+
+  BuildMemoryTypeInformationHob ();
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/Platform.c b/OvmfPkg/RiscVVirt/Sec/Platform.c
new file mode 100644
index 000000000000..e8fd126cf800
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Platform.c
@@ -0,0 +1,84 @@
+/** @file
+The library call to pass the device tree to DXE via HOB.
+
+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 <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/PcdLib.h>
+#include <Include/Library/PrePiLib.h>
+#include <libfdt.h>
+#include <Guid/FdtHob.h>
+
+/**
+  @retval EFI_SUCCESS            The address of FDT is passed in HOB.
+          EFI_UNSUPPORTED        Can't locate FDT.
+**/
+EFI_STATUS
+EFIAPI
+PlatformPeimInitialization (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+  VOID                        *FdtPointer;
+  VOID                        *Base;
+  VOID                        *NewBase;
+  UINTN                       FdtSize;
+  UINTN                       FdtPages;
+  UINT64                      *FdtHobData;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
+  if (FdtPointer == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a: Build FDT HOB - FDT at address: 0x%x \n", __FUNCTION__, FdtPointer));
+  Base = FdtPointer;
+  if (fdt_check_header (Base) != 0) {
+    DEBUG ((DEBUG_ERROR, "%a: Corrupted DTB\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtSize  = fdt_totalsize (Base);
+  FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
+  NewBase  = AllocatePages (FdtPages);
+  if (NewBase == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Could not allocate memory for DTB\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
+
+  FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
+  if (FdtHobData == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Could not build FDT Hob\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  *FdtHobData = (UINTN)NewBase;
+
+  BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.c b/OvmfPkg/RiscVVirt/Sec/SecMain.c
new file mode 100644
index 000000000000..054e49ef0c1e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.c
@@ -0,0 +1,104 @@
+/** @file
+  RISC-V SEC phase module for Qemu Virt.
+
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecMain.h"
+
+STATIC
+EFI_STATUS
+EFIAPI
+SecInitializePlatform (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  MemoryPeimInitialization ();
+
+  CpuPeimInitialization ();
+
+  // Set the Boot Mode
+  SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+
+  Status = PlatformPeimInitialization ();
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+
+  @param[in]  BootHartId         Hardware thread ID of boot hart.
+  @param[in]  DeviceTreeAddress  Pointer to Device Tree (DTB)
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartup (
+  IN  UINTN  BootHartId,
+  IN  VOID   *DeviceTreeAddress
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *HobList;
+  EFI_RISCV_FIRMWARE_CONTEXT  FirmwareContext;
+  EFI_STATUS                  Status;
+  UINT64                      UefiMemoryBase;
+  UINT64                      StackBase;
+
+  //
+  // Report Status Code to indicate entering SEC core
+  //
+  DEBUG ((
+    DEBUG_INFO,
+    "%a() BootHartId: 0x%x, DeviceTreeAddress=0x%x\n",
+    __FUNCTION__,
+    BootHartId,
+    DeviceTreeAddress
+    ));
+
+  FirmwareContext.BootHartId          = BootHartId;
+  FirmwareContext.FlattenedDeviceTree = (UINT64)DeviceTreeAddress;
+  SetFirmwareContextPointer (&FirmwareContext);
+
+  StackBase      = (UINT64)FixedPcdGet32 (PcdOvmfSecPeiTempRamBase);
+  UefiMemoryBase = StackBase +  FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SIZE_32MB;
+
+  // Declare the PI/UEFI memory region
+  HobList = HobConstructor (
+              (VOID *)UefiMemoryBase,
+              SIZE_32MB,
+              (VOID *)UefiMemoryBase,
+              (VOID *)StackBase // The top of the UEFI Memory is reserved for the stacks
+              );
+  PrePeiSetHobList (HobList);
+
+  SecInitializePlatform ();
+
+  //
+  // Process all libraries constructor function linked to SecMain.
+  //
+  ProcessLibraryConstructorList ();
+
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+  Status = DecompressFirstFv ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Load the DXE Core and transfer control to it
+  Status = LoadDxeCoreFromFv (NULL, 0);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Should not come here.
+  //
+  UNREACHABLE ();
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecEntry.S b/OvmfPkg/RiscVVirt/Sec/SecEntry.S
new file mode 100644
index 000000000000..e919a3cb0e80
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecEntry.S
@@ -0,0 +1,21 @@
+/*
+  Copyright (c) 2022 Ventana Micro Systems Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ */
+
+#include "SecMain.h"
+
+.text
+.align 3
+
+ASM_FUNC (_ModuleEntryPoint)
+  /* Use Temp memory as the stack for calling to C code */
+  li    a4, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)
+  li    a5, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)
+
+  /* Use Temp memory as the stack for calling to C code */
+  add   sp, a4, a5
+
+  call SecStartup
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (17 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:03   ` [edk2-devel] " Andrei Warkentin
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt Sunil V L
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Abner Chang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add infrastructure files to build edk2 for RISC-V qemu virt machine.

- It follows PEI less design.
- EDK2 for qemu virt is booted in S-mode as a payload for M-mode FW
- Leveraged from ArmVirtQemu

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 336 +++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 509 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf | 306 ++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc |  41 ++
 OvmfPkg/RiscVVirt/VarStore.fdf.inc  |  79 +++
 5 files changed, 1271 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
new file mode 100644
index 000000000000..526da0f7e6e9
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
@@ -0,0 +1,336 @@
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+#  Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. All rights reserved.
+#  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+#  Copyright (c) Microsoft Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+[Defines]
+  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000047
+
+[LibraryClasses.common]
+!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
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+
+  #
+  # Ramdisk Requirements
+  #
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
+  # Allow dynamic PCDs
+  #
+
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  # Networking Requirements
+!include NetworkPkg/NetworkLibs.dsc.inc
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
+!endif
+
+
+  # Add support for GCC stack protector
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+  # RISC-V Architectural Libraries
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+  RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
+  PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  ResetSystemLib|OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
+
+  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
+
+  # Flattened Device Tree (FDT) access library
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+  # PCI Libraries
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
+  PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
+  PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
+  DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+
+  # USB Libraries
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  #
+  # CryptoPkg libraries needed by multiple firmware features
+  #
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!else
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+!endif
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
+  #
+  # Secure Boot dependencies
+  #
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
+
+  # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
+  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+!else
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+  VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+  PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+[PcdsFeatureFlag]
+  #
+  # Activate AcpiSdtProtocol
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(DEBUG_ON_SERIAL_PORT) != TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  #  DEBUG_INFO      0x00000040  // Informational debug messages
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNP Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // LoadFile
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                              // significantly impact boot performance
+  #  DEBUG_ERROR     0x80000000  // Error
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
+!endif
+
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragments for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|600
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1500
+!else
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|300
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|150
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1000
+!endif
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|6000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  #
+  # Enable strict image permissions for all images. (This applies
+  # only to images that were built with >= 4 KB section alignment.)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
+
+  #
+  # Enable NX memory protection for all non-code regions, including OEM and OS
+  # reserved ones, with the exception of LoaderData regions, of which OS loaders
+  # (i.e., GRUB) may assume that its contents are executable.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
+
+[Components.common]
+  #
+  # Ramdisk support
+  #
+  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  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
+!if $(ACPIVIEW_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+!endif
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+!endif
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+  #
+  # ACPI Support
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
+    <LibraryClasses>
+      NULL|EmbeddedPkg/Library/PlatformHasAcpiLib/PlatformHasAcpiLib.inf
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
new file mode 100644
index 000000000000..17fd64a1a8d4
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -0,0 +1,509 @@
+## @file
+#  RISC-V EFI on RiscVVirtQem platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. 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                  = RiscVVirtQemu
+  PLATFORM_GUID                  = 39DADB39-1B21-4867-838E-830B6149B9E0
+  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               = OvmfPkg/RiscVVirt/RiscVVirtQemu.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 TTY_TERMINAL            = FALSE
+  DEFINE SECURE_BOOT_ENABLE      = FALSE
+  DEFINE TPM2_ENABLE             = FALSE
+  DEFINE TPM2_CONFIG_ENABLE      = FALSE
+  DEFINE DEBUG_ON_SERIAL_PORT    = TRUE
+
+  #
+  # Network definition
+  #
+  DEFINE NETWORK_IP6_ENABLE             = FALSE
+  DEFINE NETWORK_HTTP_BOOT_ENABLE       = FALSE
+  DEFINE NETWORK_SNP_ENABLE             = FALSE
+  DEFINE NETWORK_TLS_ENABLE             = FALSE
+  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
+  DEFINE NETWORK_ISCSI_ENABLE           = FALSE
+
+!if $(NETWORK_SNP_ENABLE) == TRUE
+  !error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
+!endif
+
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  GCC:*_*_RISCV64_GENFW_FLAGS    = --keepexceptiontable
+!endif
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:  *_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+  MSFT: *_*_*_DLINK_FLAGS = /ALIGN:4096
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+!include NetworkPkg/NetworkDefines.dsc.inc
+
+!include OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses.common]
+  # Virtio Support
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
+  VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
+  QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
+  QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
+
+  TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
+  VirtNorFlashPlatformLib|OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+  QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
+  PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
+  PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+
+!if $(TPM2_ENABLE) == TRUE
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf
+!endif
+
+[LibraryClasses.common.DXE_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
+
+!if $(TPM2_ENABLE) == TRUE
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
+
+#!include NetworkPkg/NetworkBuildOptions.dsc.inc
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag.common]
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|TRUE
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  #
+  # The cumulative and individual VOLATILE variable size limits should be set
+  # high enough for accommodating several and/or large CA certificates.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+!endif
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"2.7"
+
+  # Serial Port
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x10000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|9600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|3686400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1
+
+  #
+  # Network Pcds
+  #
+!include NetworkPkg/NetworkPcds.dsc.inc
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  #
+  # The maximum physical I/O addressability of the processor, set with
+  # BuildCpuHob().
+  #
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
+
+  #
+  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
+
+!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
+
+  gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x02
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
+
+[PcdsDynamicDefault.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
+  ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI
+  #  enumeration to complete before installing ACPI tables.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
+
+  # set PcdPciExpressBaseAddress to MAX_UINT64, which signifies that this
+  # PCD and PcdPciDisableBusEnumeration above have not been assigned yet
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xFFFFFFFFFFFFFFFF
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation|0x0
+
+  #
+  # Set video resolution for boot options and for text setup.
+  # PlatformDxe can set the former at runtime.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1280
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0
+
+  #
+  # SMBIOS entry point version
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0300
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+
+  #
+  # IPv4 and IPv6 PXE Boot support.
+  #
+  gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
+  gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+
+  #
+  # TPM2 support
+  #
+!if $(TPM2_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
+!else
+[PcdsPatchableInModule]
+  # make this PCD patchable instead of dynamic when TPM support is not enabled
+  # this permits setting the PCD in unreachable code without pulling in dynamic PCD support
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
+!endif
+
+[PcdsDynamicHii]
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
+
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+
+[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
+!if $(TPM2_ENABLE) == TRUE
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+!else
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!endif
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+
+  #
+  # SEC Phase modules
+  #
+  OvmfPkg/RiscVVirt/Sec/SecMain.inf {
+    <LibraryClasses>
+      ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+      LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+      HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+      PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+      MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
+   <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  #
+  # Architectural Protocols
+  #
+  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!if $(TPM2_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+!else
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # Status Code Routing
+  #
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+  #
+  # Platform Driver
+  #
+  OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.inf
+  EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  }
+  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
+  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  }
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Logo/LogoDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
+  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierLibNull.inf
+  }
+
+  #
+  # Networking stack
+  #
+!include NetworkPkg/NetworkComponents.dsc.inc
+
+  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
+  }
+
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
+  }
+!endif
+
+  #
+  # SCSI Bus and Disk Driver
+  #
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  #
+  # NVME Driver
+  #
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+  }
+  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+  #
+  # PCI support
+  #
+  OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
+  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+  OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+  #
+  # Video support
+  #
+  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+  OvmfPkg/PlatformDxe/Platform.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
+
+  #
+  # TPM2 support
+  #
+!if $(TPM2_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
+    <LibraryClasses>
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+  }
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+  #
+  # ACPI Support
+  #
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
new file mode 100644
index 000000000000..3c6e1819d9e9
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
@@ -0,0 +1,306 @@
+# @file
+#  Flash definition file on RiscVVirt RISC-V platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Platform definitions
+#
+
+!include RiscVVirt.fdf.inc
+
+################################################################################
+[FD.RISCV_VIRT]
+BaseAddress   = $(FW_BASE_ADDRESS)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size          = $(FW_SIZE)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(FW_BLOCKS)
+
+0x00000000|$(CODE_SIZE)
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+FV = FVMAIN_COMPACT
+
+!include VarStore.fdf.inc
+################################################################################
+
+[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
+
+#
+# DXE Phase modules
+#
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.inf
+INF  EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf
+INF  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
+
+#
+# PI DXE Drivers producing Architectural Protocols (EFI Services)
+#
+INF  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.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/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+INF  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+#
+# Multiple Console IO support
+#
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+# RISC-V Core Drivers
+INF  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+INF  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+#
+# FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+#
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+INF  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+#
+# Status Code Routing
+#
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+#
+# Platform Driver
+#
+INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+INF  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+INF  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+INF  ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
+INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
+
+#
+# Bds
+#
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Application/UiApp/UiApp.inf
+INF  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+
+#
+# Networking stack
+#
+!include NetworkPkg/Network.fdf.inc
+
+#
+# SCSI Bus and Disk Driver
+#
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+#
+# NVME Driver
+#
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+#
+# SMBIOS Support
+#
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+#
+# ACPI Support
+#
+INF  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+#
+# PCI support
+#
+INF  OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+INF  OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+#
+# Video support
+#
+INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+INF  OvmfPkg/PlatformDxe/Platform.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
+
+#
+# TianoCore logo (splash screen)
+#
+INF  MdeModulePkg/Logo/LogoDxe.inf
+
+#
+# Ramdisk support
+#
+INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+#INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.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
+
+INF OvmfPkg/RiscVVirt/Sec/SecMain.inf
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+     SECTION FV_IMAGE = DXEFV
+   }
+ }
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32     PE32   Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32     PE32   Align=4K         $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align = 4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32  Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32   Align=4K   |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32     PE32   Align=4K   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32  Align=4K  |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc
new file mode 100644
index 000000000000..b0a1c3293f33
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc
@@ -0,0 +1,41 @@
+## @file
+#  Definitions of Flash definition file on RiscVVirt RISC-V platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+DEFINE BLOCK_SIZE                  = 0x1000
+
+DEFINE PFLASH1_BASE                = 0x22000000
+
+DEFINE FW_BASE_ADDRESS             = $(PFLASH1_BASE)
+DEFINE FW_SIZE                     = 0x00800000
+DEFINE FW_BLOCKS                   = 0x800
+
+DEFINE CODE_BASE_ADDRESS           = $(FW_BASE_ADDRESS)
+DEFINE CODE_SIZE                   = 0x00740000
+DEFINE CODE_BLOCKS                 = 0x740
+
+DEFINE VARS_SIZE                    = 0x000C0000
+DEFINE VARS_BLOCK_SIZE              = 0x40000
+DEFINE VARS_BLOCKS                  = 0x3
+
+#
+# EFI Variable memory region.
+# The total size of EFI Variable FD must include
+# all of sub regions of EFI Variable
+#
+DEFINE VARS_OFFSET                   = $(CODE_SIZE)
+DEFINE VARS_LIVE_SIZE                = 0x00040000
+DEFINE VARS_FTW_WORKING_OFFSET       = $(VARS_OFFSET) + $(VARS_LIVE_SIZE)
+DEFINE VARS_FTW_WORKING_SIZE         = 0x00040000
+DEFINE VARS_FTW_SPARE_OFFSET         = $(VARS_FTW_WORKING_OFFSET) + $(VARS_FTW_WORKING_SIZE)
+DEFINE VARS_FTW_SPARE_SIZE           = 0x00040000
+
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency = 10000000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase = 0x83FF0000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize = 0x00010000
diff --git a/OvmfPkg/RiscVVirt/VarStore.fdf.inc b/OvmfPkg/RiscVVirt/VarStore.fdf.inc
new file mode 100644
index 000000000000..30b170d77997
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/VarStore.fdf.inc
@@ -0,0 +1,79 @@
+## @file
+#  FDF include file with Layout Regions that define an empty variable store.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#  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_LIVE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|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: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3FFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xFF, 0x03, 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)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|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)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#
+#NV_FTW_SPARE
-- 
2.38.0


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

* [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
                   ` (18 preceding siblings ...)
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform Sunil V L
@ 2023-01-28 19:18 ` Sunil V L
  2023-02-06 16:04   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:51   ` Michael D Kinney
       [not found] ` <173E8F29CD0D02D8.27165@groups.io>
                   ` (2 subsequent siblings)
  22 siblings, 2 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-28 19:18 UTC (permalink / raw)
  To: devel; +Cc: Andrew Fish, Leif Lindholm, Michael D Kinney

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RiscVVirt is created to support EDK2 for RISC-V qemu
virt machine platform. Add maintainer entries.

Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 Maintainers.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index 68f603b48398..fdb27c39b152 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -539,6 +539,10 @@ F: OvmfPkg/XenResetVector/
 R: Anthony Perard <anthony.perard@citrix.com> [tperard]
 R: Julien Grall <julien@xen.org> [jgrall]
 
+OvmfPkg: RISC-V Qemu Virt Platform
+F: OvmfPkg/RiscVVirt
+R: Sunil V L <sunilvl@ventanamicro.com> [vlsunil]
+
 PcAtChipsetPkg
 F: PcAtChipsetPkg/
 W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
-- 
2.38.0


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module Sunil V L
@ 2023-01-30  5:17   ` dhaval
  2023-01-30  6:00     ` Sunil V L
  2023-02-06 16:03   ` Andrei Warkentin
  1 sibling, 1 reply; 80+ messages in thread
From: dhaval @ 2023-01-30  5:17 UTC (permalink / raw)
  To: Sunil V L, devel

[-- Attachment #1: Type: text/plain, Size: 186 bytes --]

BuildCpuHob (56, 32);
Can we find a better programmatic way of doing this? SATP register could be on method, or PCD? Also would help if you can clarify how we arrive at this value 56.

[-- Attachment #2: Type: text/html, Size: 234 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module
  2023-01-30  5:17   ` [edk2-devel] " dhaval
@ 2023-01-30  6:00     ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-30  6:00 UTC (permalink / raw)
  To: dhaval, devel

[-- Attachment #1: Type: text/plain, Size: 853 bytes --]

Hi Dhaval,

In general, I didn't not want to add many extra code/design  as part of 
this series to keep it simple  refactor and port from edk2-platforms 
patches. We are the first one to do this type of refactoring work and 
hence not easy to convince people. So, I am still keeping many things 
hardcoded as in edk2-platforms. Once this series gets merged, next set 
of patches will be mostly within RISC-V code which will be much easier 
to upstream.

Irrespective of SATP (>= sv39), the physical address space is 56 bits as 
per the priv spec. We don't plan to support RV32 with edk2 anyway.

Thanks

Sunil

On 30/01/23 10:47, dhaval@rivosinc.com wrote:
> BuildCpuHob (56, 32); Can we find a better programmatic way of doing 
> this? SATP register could be on method, or PCD? Also would help if you 
> can clarify how we arrive at this value 56. 

[-- Attachment #2: Type: text/html, Size: 1444 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Sunil V L
@ 2023-01-30 10:12   ` dhaval
  2023-01-30 13:05     ` Sunil V L
  2023-02-06 16:02   ` Andrei Warkentin
  1 sibling, 1 reply; 80+ messages in thread
From: dhaval @ 2023-01-30 10:12 UTC (permalink / raw)
  To: Sunil V L, devel

[-- Attachment #1: Type: text/plain, Size: 358 bytes --]

What I see in the current implementation is:

* UEFICpuPkg implements gEfiCpuIo2ProtocolGuid which does not seem to be generic.
* ARMPkg implements it which seems similar to what RV needs.

Do we really expect this to be platform specific implementation and hence it should be in respective platform folders? Neither x86/ARM seem to follow this model?

[-- Attachment #2: Type: text/html, Size: 393 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
@ 2023-01-30 11:07   ` dhaval
  2023-01-30 13:08     ` Sunil V L
  2023-02-06 16:00   ` Andrei Warkentin
  2023-02-09  5:37   ` Ni, Ray
  2 siblings, 1 reply; 80+ messages in thread
From: dhaval @ 2023-01-30 11:07 UTC (permalink / raw)
  To: Sunil V L, devel

[-- Attachment #1: Type: text/plain, Size: 137 bytes --]

Wonder if it will be better to use single inf file (inside CPUTimerLib) with
SOURCES.RISCV64 or current implementation is recommended?

[-- Attachment #2: Type: text/html, Size: 320 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  2023-01-30 10:12   ` [edk2-devel] " dhaval
@ 2023-01-30 13:05     ` Sunil V L
  2023-01-30 14:33       ` dhaval
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-30 13:05 UTC (permalink / raw)
  To: dhaval; +Cc: devel

On Mon, Jan 30, 2023 at 02:12:58AM -0800, dhaval@rivosinc.com wrote:
> What I see in the current implementation is:
> 
> * UEFICpuPkg implements gEfiCpuIo2ProtocolGuid which does not seem to be generic.
> * ARMPkg implements it which seems similar to what RV needs.
> 
Yes, this is exact copy of the ArmPkg version. I guess Loongarch also will need the same.

> Do we really expect this to be platform specific implementation and hence it should be in respective platform folders? Neither x86/ARM seem to follow this model?

Correct. Both real and virtual platforms would need it. But adding
inside UefiCpuPkg/CpuI02Dxe looked bit messy which needs bit more
discussion and not sure whether it is a good idea to create parallel to
CpuIo2Dxe. So, I thought it is better to add it in RiscVVirt for now
instead of delaying the virt support even further. Let us take that as a
separate activity after this series with inputs from different CPU
architectures.

Thanks
Sunil



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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  2023-01-30 11:07   ` [edk2-devel] " dhaval
@ 2023-01-30 13:08     ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-01-30 13:08 UTC (permalink / raw)
  To: dhaval; +Cc: devel

On Mon, Jan 30, 2023 at 03:07:22AM -0800, dhaval@rivosinc.com wrote:
> Wonder if it will be better to use single inf file (inside CPUTimerLib) with
> SOURCES.RISCV64 or current implementation is recommended?

Yes, this is as per recommendation from Ray.

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg
       [not found] ` <173E8F29CD0D02D8.27165@groups.io>
@ 2023-01-30 13:43   ` Sunil V L
  2023-02-03 12:29     ` Ard Biesheuvel
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-01-30 13:43 UTC (permalink / raw)
  To: devel, Ard Biesheuvel, Leif Lindholm
  Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

Hi Ard, Leif,

Do you see any issues with this migration?

Thanks!
Sunil

On Sun, Jan 29, 2023 at 12:47:58AM +0530, Sunil V L via groups.io wrote:
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This module is required by other architectures like RISC-V.
> Hence, move this to OvmfPkg.
> 
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> ---
>  ArmVirtPkg/ArmVirtPkg.dec                                             | 9 ---------
>  OvmfPkg/OvmfPkg.dec                                                   | 7 +++++++
>  {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf | 3 +--
>  {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c   | 0
>  4 files changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
> index 89d21ec3a364..4645c91a8375 100644
> --- a/ArmVirtPkg/ArmVirtPkg.dec
> +++ b/ArmVirtPkg/ArmVirtPkg.dec
> @@ -34,8 +34,6 @@ [Guids.common]
>    gEarly16550UartBaseAddressGuid   = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
>    gArmVirtSystemMemorySizeGuid     = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
>  
> -  gArmVirtVariableGuid   = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
> -
>  [PcdsFeatureFlag]
>    #
>    # Feature Flag PCD that defines whether TPM2 support is enabled
> @@ -69,10 +67,3 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
>    # Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
>    #
>    gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
> -
> -[PcdsDynamic]
> -  #
> -  # Whether to force disable ACPI, regardless of the fw_cfg settings
> -  # exposed by QEMU
> -  #
> -  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x00000003
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index a22eb246c625..e52602db5b79 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -157,6 +157,7 @@ [Guids]
>    gVMMBootOrderGuid                     = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
>    gUefiOvmfPkgTdxAcpiHobGuid            = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
>    gEfiNonCcFvGuid                       = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
> +  gOvmfVariableGuid                     = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
>  
>  [Ppis]
>    # PPI whose presence in the PPI database signals that the TPM base address
> @@ -463,6 +464,12 @@ [PcdsDynamic, PcdsDynamicEx]
>    #    2 - set by GOP Driver.
>    gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource|0|UINT8|0x64
>  
> +  #
> +  # Whether to force disable ACPI, regardless of the fw_cfg settings
> +  # exposed by QEMU
> +  #
> +  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x69
> +
>  [PcdsFeatureFlag]
>    gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
>    gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
> diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> similarity index 89%
> rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> index e900aa992661..85873f73b2eb 100644
> --- a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> +++ b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> @@ -19,7 +19,6 @@ [Sources]
>    PlatformHasAcpiDtDxe.c
>  
>  [Packages]
> -  ArmVirtPkg/ArmVirtPkg.dec
>    EmbeddedPkg/EmbeddedPkg.dec
>    MdeModulePkg/MdeModulePkg.dec
>    MdePkg/MdePkg.dec
> @@ -38,7 +37,7 @@ [Guids]
>    gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
>  
>  [Pcd]
> -  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
> +  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
>  
>  [Depex]
>    gEfiVariableArchProtocolGuid
> diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> similarity index 100%
> rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> -- 
> 2.38.0
> 
> 
> 
> 
> 
> 

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  2023-01-30 13:05     ` Sunil V L
@ 2023-01-30 14:33       ` dhaval
  0 siblings, 0 replies; 80+ messages in thread
From: dhaval @ 2023-01-30 14:33 UTC (permalink / raw)
  To: Sunil V L; +Cc: devel

[-- Attachment #1: Type: text/plain, Size: 1275 bytes --]

Okay. So I am fine with that stepped approach- let us please make a list of
such items that we are deciding on doing in the next version so that we can
track them?

On Mon, Jan 30, 2023 at 6:35 PM Sunil V L <sunilvl@ventanamicro.com> wrote:

> On Mon, Jan 30, 2023 at 02:12:58AM -0800, dhaval@rivosinc.com wrote:
> > What I see in the current implementation is:
> >
> > * UEFICpuPkg implements gEfiCpuIo2ProtocolGuid which does not seem to be
> generic.
> > * ARMPkg implements it which seems similar to what RV needs.
> >
> Yes, this is exact copy of the ArmPkg version. I guess Loongarch also will
> need the same.
>
> > Do we really expect this to be platform specific implementation and
> hence it should be in respective platform folders? Neither x86/ARM seem to
> follow this model?
>
> Correct. Both real and virtual platforms would need it. But adding
> inside UefiCpuPkg/CpuI02Dxe looked bit messy which needs bit more
> discussion and not sure whether it is a good idea to create parallel to
> CpuIo2Dxe. So, I thought it is better to add it in RiscVVirt for now
> instead of delaying the virt support even further. Let us take that as a
> separate activity after this series with inputs from different CPU
> architectures.
>
> Thanks
> Sunil
>
>
>

-- 
Thanks!
=D

[-- Attachment #2: Type: text/html, Size: 1805 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
       [not found] ` <173E8F254E9BED62.27165@groups.io>
@ 2023-02-02 14:35   ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-02 14:35 UTC (permalink / raw)
  To: Michael D Kinney
  Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Abner Chang, devel

Hi Mike,

I know you are pretty busy. But I need your help. As we discussed in the
tianocore design meeting last year and as per your recommendation 
(https://edk2.groups.io/g/devel/message/85481), these changes in MdePkg
are done. Abner has helped to review from RISC-V perspective. If you
could ACK these patches from MdePkg structure/policy perspective atleast,
it will be very helpful.

Thanks!
Sunil

On Sun, Jan 29, 2023 at 12:47:50AM +0530, Sunil V L via groups.io wrote:
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This library is required to make SBI ecalls from the S-mode EDK2.
> This is mostly copied from
> edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib
> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  MdePkg/MdePkg.dec                                  |   4 +
>  MdePkg/MdePkg.dsc                                  |   3 +
>  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
>  MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
>  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
>  5 files changed, 386 insertions(+)
> 
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 3d08f20d15b0..ca2e4dcf815c 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
>    ##  @libraryclass  Provides function to support TDX processing.
>    TdxLib|Include/Library/TdxLib.h
>  
> +[LibraryClasses.RISCV64]
> +  ##  @libraryclass  Provides function to make ecalls to SBI
> +  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
> +
>  [Guids]
>    #
>    # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
> diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
> index 32a852dc466e..0ac7618b4623 100644
> --- a/MdePkg/MdePkg.dsc
> +++ b/MdePkg/MdePkg.dsc
> @@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
>    MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>    MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
>  
> +[Components.RISCV64]
> +  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> +
>  [BuildOptions]
> diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> new file mode 100644
> index 000000000000..d03132bf01c1
> --- /dev/null
> +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> @@ -0,0 +1,25 @@
> +## @file
> +# RISC-V Library to call SBI ecalls
> +#
> +#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION         = 0x0001001b
> +  BASE_NAME           = BaseRiscVSbiLib
> +  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
> +  MODULE_TYPE         = BASE
> +  VERSION_STRING      = 1.0
> +  LIBRARY_CLASS       = RiscVSbiLib
> +
> +[Sources]
> +  BaseRiscVSbiLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> new file mode 100644
> index 000000000000..3a3cbfb879f1
> --- /dev/null
> +++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> @@ -0,0 +1,127 @@
> +/** @file
> +  Library to call the RISC-V SBI ecalls
> +
> +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Hart - Hardware Thread, similar to a CPU core
> +
> +  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
> +
> +**/
> +
> +#ifndef RISCV_SBI_LIB_H_
> +#define RISCV_SBI_LIB_H_
> +
> +#include <Uefi.h>
> +
> +/* SBI Extension IDs */
> +#define SBI_EXT_TIME  0x54494D45
> +#define SBI_EXT_SRST  0x53525354
> +
> +/* SBI function IDs for TIME extension*/
> +#define SBI_EXT_TIME_SET_TIMER  0x0
> +
> +/* SBI function IDs for SRST extension */
> +#define SBI_EXT_SRST_RESET  0x0
> +
> +#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
> +#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1
> +#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
> +
> +#define SBI_SRST_RESET_REASON_NONE     0x0
> +#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
> +
> +/* SBI return error codes */
> +#define SBI_SUCCESS                0
> +#define SBI_ERR_FAILED             -1
> +#define SBI_ERR_NOT_SUPPORTED      -2
> +#define SBI_ERR_INVALID_PARAM      -3
> +#define SBI_ERR_DENIED             -4
> +#define SBI_ERR_INVALID_ADDRESS    -5
> +#define SBI_ERR_ALREADY_AVAILABLE  -6
> +#define SBI_ERR_ALREADY_STARTED    -7
> +#define SBI_ERR_ALREADY_STOPPED    -8
> +
> +#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
> +
> +typedef struct {
> +  UINT64    BootHartId;
> +  VOID      *PeiServiceTable;    // PEI Service table
> +  VOID      *PrePiHobList;       // Pre PI Hob List
> +  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
> +} EFI_RISCV_FIRMWARE_CONTEXT;
> +
> +//
> +// EDK2 OpenSBI firmware extension return status.
> +//
> +typedef struct {
> +  UINTN    Error; ///< SBI status code
> +  UINTN    Value; ///< Value returned
> +} SBI_RET;
> +
> +VOID
> +EFIAPI
> +SbiSetTimer (
> +  IN  UINT64  Time
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SbiSystemReset (
> +  IN  UINTN  ResetType,
> +  IN  UINTN  ResetReason
> +  );
> +
> +/**
> +  Get firmware context of the calling hart.
> +
> +  @param[out] FirmwareContext      The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContext (
> +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> +  );
> +
> +/**
> +  Set firmware context of the calling hart.
> +
> +  @param[in] FirmwareContext       The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContext (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> +  );
> +
> +/**
> +  Get pointer to OpenSBI Firmware Context
> +
> +  Get the pointer of firmware context.
> +
> +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> +                                 Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContextPointer (
> +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> +  );
> +
> +/**
> +  Set pointer to OpenSBI Firmware Context
> +
> +  Set the pointer of firmware context.
> +
> +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContextPointer (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> +  );
> +
> +#endif
> diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> new file mode 100644
> index 000000000000..15222a528753
> --- /dev/null
> +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> @@ -0,0 +1,227 @@
> +/** @file
> +  Instance of the SBI ecall library.
> +
> +  It allows calling an SBI function via an ecall from S-Mode.
> +
> +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseRiscVSbiLib.h>
> +
> +//
> +// Maximum arguments for SBI ecall
> +#define SBI_CALL_MAX_ARGS  6
> +
> +/**
> +  Call SBI call using ecall instruction.
> +
> +  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
> +
> +  @param[in] ExtId    SBI extension ID.
> +  @param[in] FuncId   SBI function ID.
> +  @param[in] NumArgs  Number of arguments to pass to the ecall.
> +  @param[in] ...      Argument list for the ecall.
> +
> +  @retval  Returns SBI_RET structure with value and error code.
> +
> +**/
> +STATIC
> +SBI_RET
> +EFIAPI
> +SbiCall (
> +  IN  UINTN  ExtId,
> +  IN  UINTN  FuncId,
> +  IN  UINTN  NumArgs,
> +  ...
> +  )
> +{
> +  UINTN    I;
> +  SBI_RET  Ret;
> +  UINTN    Args[SBI_CALL_MAX_ARGS];
> +  VA_LIST  ArgList;
> +
> +  VA_START (ArgList, NumArgs);
> +
> +  if (NumArgs > SBI_CALL_MAX_ARGS) {
> +    Ret.Error = SBI_ERR_INVALID_PARAM;
> +    Ret.Value = -1;
> +    return Ret;
> +  }
> +
> +  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
> +    if (I < NumArgs) {
> +      Args[I] = VA_ARG (ArgList, UINTN);
> +    } else {
> +      // Default to 0 for all arguments that are not given
> +      Args[I] = 0;
> +    }
> +  }
> +
> +  VA_END (ArgList);
> +
> +  register UINTN  a0 asm ("a0") = Args[0];
> +  register UINTN  a1 asm ("a1") = Args[1];
> +  register UINTN  a2 asm ("a2") = Args[2];
> +  register UINTN  a3 asm ("a3") = Args[3];
> +  register UINTN  a4 asm ("a4") = Args[4];
> +  register UINTN  a5 asm ("a5") = Args[5];
> +  register UINTN  a6 asm ("a6") = (UINTN)(FuncId);
> +  register UINTN  a7 asm ("a7") = (UINTN)(ExtId);
> +
> +  asm volatile ("ecall" \
> +       : "+r" (a0), "+r" (a1) \
> +       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
> +       : "memory"); \
> +  Ret.Error = a0;
> +  Ret.Value = a1;
> +  return Ret;
> +}
> +
> +/**
> +  Translate SBI error code to EFI status.
> +
> +  @param[in] SbiError   SBI error code
> +  @retval EFI_STATUS
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +TranslateError (
> +  IN  UINTN  SbiError
> +  )
> +{
> +  switch (SbiError) {
> +    case SBI_SUCCESS:
> +      return EFI_SUCCESS;
> +    case SBI_ERR_FAILED:
> +      return EFI_DEVICE_ERROR;
> +      break;
> +    case SBI_ERR_NOT_SUPPORTED:
> +      return EFI_UNSUPPORTED;
> +      break;
> +    case SBI_ERR_INVALID_PARAM:
> +      return EFI_INVALID_PARAMETER;
> +      break;
> +    case SBI_ERR_DENIED:
> +      return EFI_ACCESS_DENIED;
> +      break;
> +    case SBI_ERR_INVALID_ADDRESS:
> +      return EFI_LOAD_ERROR;
> +      break;
> +    case SBI_ERR_ALREADY_AVAILABLE:
> +      return EFI_ALREADY_STARTED;
> +      break;
> +    default:
> +      //
> +      // Reaches here only if SBI has defined a new error type
> +      //
> +      ASSERT (FALSE);
> +      return EFI_UNSUPPORTED;
> +      break;
> +  }
> +}
> +
> +/**
> +  Clear pending timer interrupt bit and set timer for next event after Time.
> +
> +  To clear the timer without scheduling a timer event, set Time to a
> +  practically infinite value or mask the timer interrupt by clearing sie.STIE.
> +
> +  @param[in]  Time                 The time offset to the next scheduled timer interrupt.
> +**/
> +VOID
> +EFIAPI
> +SbiSetTimer (
> +  IN  UINT64  Time
> +  )
> +{
> +  SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SbiSystemReset (
> +  IN  UINTN  ResetType,
> +  IN  UINTN  ResetReason
> +  )
> +{
> +  SBI_RET  Ret;
> +
> +  Ret = SbiCall (
> +          SBI_EXT_SRST,
> +          SBI_EXT_SRST_RESET,
> +          2,
> +          ResetType,
> +          ResetReason
> +          );
> +
> +  return TranslateError (Ret.Error);
> +}
> +
> +/**
> +  Get firmware context of the calling hart.
> +
> +  @param[out] FirmwareContext      The firmware context pointer.
> +  @retval EFI_SUCCESS              The operation succeeds.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContext (
> +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> +  )
> +{
> +  *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();
> +}
> +
> +/**
> +  Set firmware context of the calling hart.
> +
> +  @param[in] FirmwareContext       The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContext (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> +  )
> +{
> +  RiscVSetSupervisorScratch ((UINT64)FirmwareContext);
> +}
> +
> +/**
> +  Get pointer to OpenSBI Firmware Context
> +
> +  Get the pointer of firmware context through OpenSBI FW Extension SBI.
> +
> +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> +                                 Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContextPointer (
> +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> +  )
> +{
> +  GetFirmwareContext (FirmwareContextPtr);
> +}
> +
> +/**
> +  Set the pointer to OpenSBI Firmware Context
> +
> +  Set the pointer of firmware context through OpenSBI FW Extension SBI.
> +
> +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContextPointer (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> +  )
> +{
> +  SetFirmwareContext (FirmwareContextPtr);
> +}
> -- 
> 2.38.0
> 
> 
> 
> 
> 
> 

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
       [not found] ` <173E8F293E682CB4.27165@groups.io>
@ 2023-02-03  9:46   ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-03  9:46 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Ard Biesheuvel, Abner Chang, Daniel Schaefer

Hi Ard, Leif,

Irrespective of refactoring gets accepted or not, this change is
necessary for RISC-V. This is a simple change and it will be great if
you could merge before freeze window starts.

In fact, I don't know why this PCD PcdPrePiCpuIoSize is required in
PrePiLib.inf since it is not used in the library. So, it should work
if it gets removed from PrePiLib.inf. Any of these two solutions will allow
us to use the library for RISC-V.

Thanks!
Sunil

On Sun, Jan 29, 2023 at 12:47:57AM +0530, Sunil V L via groups.io wrote:
> This PCD is required to be enabled so that PrePiLib
> can be used in RISC-V.
> 
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> ---
>  EmbeddedPkg/EmbeddedPkg.dec | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
> index 341ef5e6a679..2965f01444e9 100644
> --- a/EmbeddedPkg/EmbeddedPkg.dec
> +++ b/EmbeddedPkg/EmbeddedPkg.dec
> @@ -165,6 +165,9 @@ [PcdsFixedAtBuild.IA32]
>  [PcdsFixedAtBuild.X64]
>    gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
>  
> +[PcdsFixedAtBuild.RISCV64]
> +  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
> +
>  [PcdsFixedAtBuild.common, PcdsDynamic.common]
>    #
>    # Value to add to a host address to obtain a device address, using
> -- 
> 2.38.0
> 
> 
> 
> 
> 
> 

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg
  2023-01-30 13:43   ` [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
@ 2023-02-03 12:29     ` Ard Biesheuvel
  0 siblings, 0 replies; 80+ messages in thread
From: Ard Biesheuvel @ 2023-02-03 12:29 UTC (permalink / raw)
  To: Sunil V L
  Cc: devel, Leif Lindholm, Ard Biesheuvel, Jiewen Yao, Jordan Justen,
	Gerd Hoffmann

On Mon, 30 Jan 2023 at 14:44, Sunil V L <sunilvl@ventanamicro.com> wrote:
>
> Hi Ard, Leif,
>
> Do you see any issues with this migration?
>
> Thanks!
> Sunil
>
> On Sun, Jan 29, 2023 at 12:47:58AM +0530, Sunil V L via groups.io wrote:
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> >
> > This module is required by other architectures like RISC-V.
> > Hence, move this to OvmfPkg.
> >
> > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>

Acked-by: Ard Biesheuvel <ardb@kernel.org>

> > ---
> >  ArmVirtPkg/ArmVirtPkg.dec                                             | 9 ---------
> >  OvmfPkg/OvmfPkg.dec                                                   | 7 +++++++
> >  {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf | 3 +--
> >  {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c   | 0
> >  4 files changed, 8 insertions(+), 11 deletions(-)
> >
> > diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
> > index 89d21ec3a364..4645c91a8375 100644
> > --- a/ArmVirtPkg/ArmVirtPkg.dec
> > +++ b/ArmVirtPkg/ArmVirtPkg.dec
> > @@ -34,8 +34,6 @@ [Guids.common]
> >    gEarly16550UartBaseAddressGuid   = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
> >    gArmVirtSystemMemorySizeGuid     = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
> >
> > -  gArmVirtVariableGuid   = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
> > -
> >  [PcdsFeatureFlag]
> >    #
> >    # Feature Flag PCD that defines whether TPM2 support is enabled
> > @@ -69,10 +67,3 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
> >    # Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
> >    #
> >    gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
> > -
> > -[PcdsDynamic]
> > -  #
> > -  # Whether to force disable ACPI, regardless of the fw_cfg settings
> > -  # exposed by QEMU
> > -  #
> > -  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x00000003
> > diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> > index a22eb246c625..e52602db5b79 100644
> > --- a/OvmfPkg/OvmfPkg.dec
> > +++ b/OvmfPkg/OvmfPkg.dec
> > @@ -157,6 +157,7 @@ [Guids]
> >    gVMMBootOrderGuid                     = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
> >    gUefiOvmfPkgTdxAcpiHobGuid            = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
> >    gEfiNonCcFvGuid                       = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
> > +  gOvmfVariableGuid                     = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
> >
> >  [Ppis]
> >    # PPI whose presence in the PPI database signals that the TPM base address
> > @@ -463,6 +464,12 @@ [PcdsDynamic, PcdsDynamicEx]
> >    #    2 - set by GOP Driver.
> >    gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource|0|UINT8|0x64
> >
> > +  #
> > +  # Whether to force disable ACPI, regardless of the fw_cfg settings
> > +  # exposed by QEMU
> > +  #
> > +  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x69
> > +
> >  [PcdsFeatureFlag]
> >    gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
> >    gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
> > diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> > similarity index 89%
> > rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> > rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> > index e900aa992661..85873f73b2eb 100644
> > --- a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> > +++ b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
> > @@ -19,7 +19,6 @@ [Sources]
> >    PlatformHasAcpiDtDxe.c
> >
> >  [Packages]
> > -  ArmVirtPkg/ArmVirtPkg.dec
> >    EmbeddedPkg/EmbeddedPkg.dec
> >    MdeModulePkg/MdeModulePkg.dec
> >    MdePkg/MdePkg.dec
> > @@ -38,7 +37,7 @@ [Guids]
> >    gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
> >
> >  [Pcd]
> > -  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
> > +  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
> >
> >  [Depex]
> >    gEfiVariableArchProtocolGuid
> > diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> > similarity index 100%
> > rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> > rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
> > --
> > 2.38.0
> >
> >
> >
> > 
> >
> >

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
@ 2023-02-06 15:44   ` Andrei Warkentin
  2023-02-09  1:44   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 15:44 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Daniel Schaefer, Kinney, Michael D, Gao, Liming, Liu, Zhiguang,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Daniel Schaefer <git@danielschaefer.me>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add register definitions and access routines for RISC-V. These headers are leveraged from opensbi repo.

Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 119 ++++++++++++++++++++
 MdePkg/Include/Register/RiscV64/RiscVImpl.h     |  25 ++++
 2 files changed, 144 insertions(+)

diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
new file mode 100644
index 000000000000..5c2989b797bf
--- /dev/null
+++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
@@ -0,0 +1,119 @@
+/** @file
+  RISC-V CSR encodings
+
+  Copyright (c) 2019, Western Digital Corporation or its affiliates. 
+ All rights reserved.<BR>  Copyright (c) 2022, Ventana Micro Systems 
+ Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_ENCODING_H_
+#define RISCV_ENCODING_H_
+
+#define MSTATUS_SIE         0x00000002UL
+#define MSTATUS_MIE         0x00000008UL
+#define MSTATUS_SPIE_SHIFT  5
+#define MSTATUS_SPIE        (1UL << MSTATUS_SPIE_SHIFT)
+#define MSTATUS_UBE         0x00000040UL
+#define MSTATUS_MPIE        0x00000080UL
+#define MSTATUS_SPP_SHIFT   8
+#define MSTATUS_SPP         (1UL << MSTATUS_SPP_SHIFT)
+#define MSTATUS_MPP_SHIFT   11
+#define MSTATUS_MPP         (3UL << MSTATUS_MPP_SHIFT)
+
+#define SSTATUS_SIE         MSTATUS_SIE
+#define SSTATUS_SPIE_SHIFT  MSTATUS_SPIE_SHIFT
+#define SSTATUS_SPIE        MSTATUS_SPIE
+#define SSTATUS_SPP_SHIFT   MSTATUS_SPP_SHIFT
+#define SSTATUS_SPP         MSTATUS_SPP
+
+#define IRQ_S_SOFT    1
+#define IRQ_VS_SOFT   2
+#define IRQ_M_SOFT    3
+#define IRQ_S_TIMER   5
+#define IRQ_VS_TIMER  6
+#define IRQ_M_TIMER   7
+#define IRQ_S_EXT     9
+#define IRQ_VS_EXT    10
+#define IRQ_M_EXT     11
+#define IRQ_S_GEXT    12
+#define IRQ_PMU_OVF   13
+
+#define MIP_SSIP    (1UL << IRQ_S_SOFT)
+#define MIP_VSSIP   (1UL << IRQ_VS_SOFT)
+#define MIP_MSIP    (1UL << IRQ_M_SOFT)
+#define MIP_STIP    (1UL << IRQ_S_TIMER)
+#define MIP_VSTIP   (1UL << IRQ_VS_TIMER)
+#define MIP_MTIP    (1UL << IRQ_M_TIMER)
+#define MIP_SEIP    (1UL << IRQ_S_EXT)
+#define MIP_VSEIP   (1UL << IRQ_VS_EXT)
+#define MIP_MEIP    (1UL << IRQ_M_EXT)
+#define MIP_SGEIP   (1UL << IRQ_S_GEXT)
+#define MIP_LCOFIP  (1UL << IRQ_PMU_OVF)
+
+#define SIP_SSIP  MIP_SSIP
+#define SIP_STIP  MIP_STIP
+
+#define PRV_U  0UL
+#define PRV_S  1UL
+#define PRV_M  3UL
+
+#define SATP64_MODE  0xF000000000000000ULL #define SATP64_ASID  
+0x0FFFF00000000000ULL
+#define SATP64_PPN   0x00000FFFFFFFFFFFULL
+
+#define SATP_MODE_OFF   0UL
+#define SATP_MODE_SV32  1UL
+#define SATP_MODE_SV39  8UL
+#define SATP_MODE_SV48  9UL
+#define SATP_MODE_SV57  10UL
+#define SATP_MODE_SV64  11UL
+
+#define SATP_MODE  SATP64_MODE
+
+/* User Counters/Timers */
+#define CSR_CYCLE  0xc00
+#define CSR_TIME   0xc01
+
+/* Supervisor Trap Setup */
+#define CSR_SSTATUS  0x100
+#define CSR_SEDELEG  0x102
+#define CSR_SIDELEG  0x103
+#define CSR_SIE      0x104
+#define CSR_STVEC    0x105
+
+/* Supervisor Configuration */
+#define CSR_SENVCFG  0x10a
+
+/* Supervisor Trap Handling */
+#define CSR_SSCRATCH  0x140
+#define CSR_SEPC      0x141
+#define CSR_SCAUSE    0x142
+#define CSR_STVAL     0x143
+#define CSR_SIP       0x144
+
+/* Supervisor Protection and Translation */ #define CSR_SATP  0x180
+
+/* Trap/Exception Causes */
+#define CAUSE_MISALIGNED_FETCH          0x0
+#define CAUSE_FETCH_ACCESS              0x1
+#define CAUSE_ILLEGAL_INSTRUCTION       0x2
+#define CAUSE_BREAKPOINT                0x3
+#define CAUSE_MISALIGNED_LOAD           0x4
+#define CAUSE_LOAD_ACCESS               0x5
+#define CAUSE_MISALIGNED_STORE          0x6
+#define CAUSE_STORE_ACCESS              0x7
+#define CAUSE_USER_ECALL                0x8
+#define CAUSE_SUPERVISOR_ECALL          0x9
+#define CAUSE_VIRTUAL_SUPERVISOR_ECALL  0xa
+#define CAUSE_MACHINE_ECALL             0xb
+#define CAUSE_FETCH_PAGE_FAULT          0xc
+#define CAUSE_LOAD_PAGE_FAULT           0xd
+#define CAUSE_STORE_PAGE_FAULT          0xf
+#define CAUSE_FETCH_GUEST_PAGE_FAULT    0x14
+#define CAUSE_LOAD_GUEST_PAGE_FAULT     0x15
+#define CAUSE_VIRTUAL_INST_FAULT        0x16
+#define CAUSE_STORE_GUEST_PAGE_FAULT    0x17
+
+#endif
diff --git a/MdePkg/Include/Register/RiscV64/RiscVImpl.h b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
new file mode 100644
index 000000000000..ee5c2ba60377
--- /dev/null
+++ b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
@@ -0,0 +1,25 @@
+/** @file
+  RISC-V package definitions.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
+ All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_IMPL_H_
+#define RISCV_IMPL_H_
+
+#include <Register/RiscV64/RiscVEncoding.h>
+
+#define _ASM_FUNC(Name, Section)    \
+  .global   Name                  ; \
+  .section  #Section, "ax"        ; \
+  .type     Name, %function       ; \
+  .p2align  2                     ; \
+  Name:
+
+#define ASM_FUNC(Name)  _ASM_FUNC(ASM_PFX(Name), .text. ## Name) 
+#define RISCV_TIMER_COMPARE_BITS  32
+
+#endif
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions Sunil V L
@ 2023-02-06 15:46   ` Andrei Warkentin
  2023-02-09  1:43   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 15:46 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Few of the basic helper functions required for any RISC-V CPU were added in edk2-platforms. To support qemu virt, they need to be added in BaseLib.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/Library/BaseLib/BaseLib.inf              |  3 ++
 MdePkg/Include/Library/BaseLib.h                | 50 ++++++++++++++++++
 MdePkg/Library/BaseLib/RiscV64/CpuScratch.S     | 31 ++++++++++++
 MdePkg/Library/BaseLib/RiscV64/ReadTimer.S      | 23 +++++++++
 MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 53 ++++++++++++++++++--
 MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S       | 23 +++++++++
 6 files changed, 179 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 9ed46a584a14..3a48492b1a01 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -401,6 +401,9 @@ [Sources.RISCV64]
   RiscV64/RiscVCpuPause.S           | GCC
   RiscV64/RiscVInterrupt.S          | GCC
   RiscV64/FlushCache.S              | GCC
+  RiscV64/CpuScratch.S              | GCC
+  RiscV64/ReadTimer.S               | GCC
+  RiscV64/RiscVMmu.S                | GCC
 
 [Sources.LOONGARCH64]
   Math64.c
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index f3f59f21c2ea..b4f4e45a1486 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -151,6 +151,56 @@ typedef struct {
 
 #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT  8
 
+VOID
+  RiscVSetSupervisorScratch (
+                             UINT64
+                             );
+
+UINT64
+RiscVGetSupervisorScratch (
+  VOID
+  );
+
+VOID
+  RiscVSetSupervisorStvec (
+                           UINT64
+                           );
+
+UINT64
+RiscVGetSupervisorStvec (
+  VOID
+  );
+
+UINT64
+RiscVGetSupervisorTrapCause (
+  VOID
+  );
+
+VOID
+  RiscVSetSupervisorAddressTranslationRegister (
+                                                UINT64
+                                                );
+
+UINT64
+RiscVReadTimer (
+  VOID
+  );
+
+VOID
+RiscVEnableTimerInterrupt (
+  VOID
+  );
+
+VOID
+RiscVDisableTimerInterrupt (
+  VOID
+  );
+
+VOID
+RiscVClearPendingTimerInterrupt (
+  VOID
+  );
+
 #endif // defined (MDE_CPU_RISCV64)
 
 #if defined (MDE_CPU_LOONGARCH64)
diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
new file mode 100644
index 000000000000..5492a500eb5e
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
@@ -0,0 +1,31 @@
+//---------------------------------------------------------------------
+---------
+//
+// CPU scratch register related functions for RISC-V // // Copyright 
+(c) 2020, Hewlett Packard Enterprise Development LP. All rights 
+reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent //
+//---------------------------------------------------------------------
+---------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Set Supervisor mode scratch.
+// @param a0 : Value set to Supervisor mode scratch // ASM_FUNC 
+(RiscVSetSupervisorScratch)
+    csrw CSR_SSCRATCH, a0
+    ret
+
+//
+// Get Supervisor mode scratch.
+// @retval a0 : Value in Supervisor mode scratch // ASM_FUNC 
+(RiscVGetSupervisorScratch)
+    csrr a0, CSR_SSCRATCH
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
new file mode 100644
index 000000000000..39a06efa51ef
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
@@ -0,0 +1,23 @@
+//---------------------------------------------------------------------
+---------
+//
+// Read CPU timer
+//
+// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All 
+rights reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent 
+//
+//---------------------------------------------------------------------
+---------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Read TIME CSR.
+// @retval a0 : 64-bit timer.
+//
+ASM_FUNC (RiscVReadTimer)
+    csrr a0, CSR_TIME
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
index 87b3468fc7fd..6a1b90a7e45c 100644
--- a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
@@ -8,13 +8,13 @@
 //
 //------------------------------------------------------------------------------
 
+#include <Register/RiscV64/RiscVImpl.h>
+
 ASM_GLOBAL ASM_PFX(RiscVDisableSupervisorModeInterrupts)
 ASM_GLOBAL ASM_PFX(RiscVEnableSupervisorModeInterrupt)
 ASM_GLOBAL ASM_PFX(RiscVGetSupervisorModeInterrupts)
 
-#define  SSTATUS_SIE                 0x00000002
-#define  CSR_SSTATUS                 0x100
-  #define  SSTATUS_SPP_BIT_POSITION  8
+#define  SSTATUS_SPP_BIT_POSITION  8
 
 //
 // This routine disables supervisor mode interrupt @@ -53,11 +53,56 @@ InTrap:
   ret
 
 //
+// Set Supervisor mode trap vector.
+// @param a0 : Value set to Supervisor mode trap vector // ASM_FUNC 
+(RiscVSetSupervisorStvec)
+    csrrw a1, CSR_STVEC, a0
+    ret
+
+//
+// Get Supervisor mode trap vector.
+// @retval a0 : Value in Supervisor mode trap vector // ASM_FUNC 
+(RiscVGetSupervisorStvec)
+    csrr a0, CSR_STVEC
+    ret
+
+//
+// Get Supervisor trap cause CSR.
+//
+ASM_FUNC (RiscVGetSupervisorTrapCause)
+    csrrs a0, CSR_SCAUSE, 0
+    ret
+//
 // This routine returns supervisor mode interrupt  // status.
 //
-ASM_PFX(RiscVGetSupervisorModeInterrupts):
+ASM_FUNC (RiscVGetSupervisorModeInterrupts)
   csrr a0, CSR_SSTATUS
   andi a0, a0, SSTATUS_SIE
   ret
 
+//
+// This routine disables supervisor mode timer interrupt // ASM_FUNC 
+(RiscVDisableTimerInterrupt)
+    li   a0, SIP_STIP
+    csrc CSR_SIE, a0
+    ret
+
+//
+// This routine enables supervisor mode timer interrupt // ASM_FUNC 
+(RiscVEnableTimerInterrupt)
+    li    a0, SIP_STIP
+    csrs CSR_SIE, a0
+    ret
+
+//
+// This routine clears pending supervisor mode timer interrupt // 
+ASM_FUNC (RiscVClearPendingTimerInterrupt)
+    li   a0, SIP_STIP
+    csrc CSR_SIP, a0
+    ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
new file mode 100644
index 000000000000..ac8f92f38aed
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
@@ -0,0 +1,23 @@
+//---------------------------------------------------------------------
+---------
+//
+// CPU scratch register related functions for RISC-V // // Copyright 
+(c) 2020, Hewlett Packard Enterprise Development LP. All rights 
+reserved.<BR> // // SPDX-License-Identifier: BSD-2-Clause-Patent //
+//---------------------------------------------------------------------
+---------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.data
+.align 3
+.section .text
+
+//
+// Set Supervisor Address Translation and // Protection Register.
+//
+ASM_FUNC (RiscVSetSupervisorAddressTranslationRegister)
+    csrw  CSR_SATP, a0
+    ret
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
@ 2023-02-06 15:47   ` Andrei Warkentin
  2023-02-09  1:45   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 15:47 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Kinney, Michael D, Gao, Liming, Liu, Zhiguang, Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This library is required to make SBI ecalls from the S-mode EDK2.
This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 MdePkg/MdePkg.dec                                  |   4 +
 MdePkg/MdePkg.dsc                                  |   3 +
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
 MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
 MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
 5 files changed, 386 insertions(+)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 3d08f20d15b0..ca2e4dcf815c 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Provides function to support TDX processing.
   TdxLib|Include/Library/TdxLib.h
 
+[LibraryClasses.RISCV64]
+  ##  @libraryclass  Provides function to make ecalls to SBI
+  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
+
 [Guids]
   #
   # GUID defined in UEFI2.1/UEFI2.0/EFI1.1 diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 32a852dc466e..0ac7618b4623 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
   MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
 
+[Components.RISCV64]
+  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
+
 [BuildOptions]
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
new file mode 100644
index 000000000000..d03132bf01c1
--- /dev/null
+++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
@@ -0,0 +1,25 @@
+## @file
+# RISC-V Library to call SBI ecalls
+#
+#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All 
+rights reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent 
+# ##
+
+[Defines]
+  INF_VERSION         = 0x0001001b
+  BASE_NAME           = BaseRiscVSbiLib
+  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
+  MODULE_TYPE         = BASE
+  VERSION_STRING      = 1.0
+  LIBRARY_CLASS       = RiscVSbiLib
+
+[Sources]
+  BaseRiscVSbiLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
new file mode 100644
index 000000000000..3a3cbfb879f1
--- /dev/null
+++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
@@ -0,0 +1,127 @@
+/** @file
+  Library to call the RISC-V SBI ecalls
+
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights 
+ reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Hart - Hardware Thread, similar to a CPU core
+
+  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
+
+**/
+
+#ifndef RISCV_SBI_LIB_H_
+#define RISCV_SBI_LIB_H_
+
+#include <Uefi.h>
+
+/* SBI Extension IDs */
+#define SBI_EXT_TIME  0x54494D45
+#define SBI_EXT_SRST  0x53525354
+
+/* SBI function IDs for TIME extension*/ #define SBI_EXT_TIME_SET_TIMER  
+0x0
+
+/* SBI function IDs for SRST extension */ #define SBI_EXT_SRST_RESET  
+0x0
+
+#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
+#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1 #define 
+SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
+
+#define SBI_SRST_RESET_REASON_NONE     0x0
+#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
+
+/* SBI return error codes */
+#define SBI_SUCCESS                0
+#define SBI_ERR_FAILED             -1
+#define SBI_ERR_NOT_SUPPORTED      -2
+#define SBI_ERR_INVALID_PARAM      -3
+#define SBI_ERR_DENIED             -4
+#define SBI_ERR_INVALID_ADDRESS    -5
+#define SBI_ERR_ALREADY_AVAILABLE  -6
+#define SBI_ERR_ALREADY_STARTED    -7
+#define SBI_ERR_ALREADY_STOPPED    -8
+
+#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
+
+typedef struct {
+  UINT64    BootHartId;
+  VOID      *PeiServiceTable;    // PEI Service table
+  VOID      *PrePiHobList;       // Pre PI Hob List
+  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
+} EFI_RISCV_FIRMWARE_CONTEXT;
+
+//
+// EDK2 OpenSBI firmware extension return status.
+//
+typedef struct {
+  UINTN    Error; ///< SBI status code
+  UINTN    Value; ///< Value returned
+} SBI_RET;
+
+VOID
+EFIAPI
+SbiSetTimer (
+  IN  UINT64  Time
+  );
+
+EFI_STATUS
+EFIAPI
+SbiSystemReset (
+  IN  UINTN  ResetType,
+  IN  UINTN  ResetReason
+  );
+
+/**
+  Get firmware context of the calling hart.
+
+  @param[out] FirmwareContext      The firmware context pointer.
+**/
+VOID
+EFIAPI
+GetFirmwareContext (
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
+  );
+
+/**
+  Set firmware context of the calling hart.
+
+  @param[in] FirmwareContext       The firmware context pointer.
+**/
+VOID
+EFIAPI
+SetFirmwareContext (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
+  );
+
+/**
+  Get pointer to OpenSBI Firmware Context
+
+  Get the pointer of firmware context.
+
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
+                                 Firmware Context.
+**/
+VOID
+EFIAPI
+GetFirmwareContextPointer (
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
+  );
+
+/**
+  Set pointer to OpenSBI Firmware Context
+
+  Set the pointer of firmware context.
+
+  @param    FirmwareContextPtr   Pointer to Firmware Context.
+**/
+VOID
+EFIAPI
+SetFirmwareContextPointer (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
+  );
+
+#endif
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
new file mode 100644
index 000000000000..15222a528753
--- /dev/null
+++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
@@ -0,0 +1,227 @@
+/** @file
+  Instance of the SBI ecall library.
+
+  It allows calling an SBI function via an ecall from S-Mode.
+
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights 
+ reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+//
+// Maximum arguments for SBI ecall
+#define SBI_CALL_MAX_ARGS  6
+
+/**
+  Call SBI call using ecall instruction.
+
+  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
+
+  @param[in] ExtId    SBI extension ID.
+  @param[in] FuncId   SBI function ID.
+  @param[in] NumArgs  Number of arguments to pass to the ecall.
+  @param[in] ...      Argument list for the ecall.
+
+  @retval  Returns SBI_RET structure with value and error code.
+
+**/
+STATIC
+SBI_RET
+EFIAPI
+SbiCall (
+  IN  UINTN  ExtId,
+  IN  UINTN  FuncId,
+  IN  UINTN  NumArgs,
+  ...
+  )
+{
+  UINTN    I;
+  SBI_RET  Ret;
+  UINTN    Args[SBI_CALL_MAX_ARGS];
+  VA_LIST  ArgList;
+
+  VA_START (ArgList, NumArgs);
+
+  if (NumArgs > SBI_CALL_MAX_ARGS) {
+    Ret.Error = SBI_ERR_INVALID_PARAM;
+    Ret.Value = -1;
+    return Ret;
+  }
+
+  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
+    if (I < NumArgs) {
+      Args[I] = VA_ARG (ArgList, UINTN);
+    } else {
+      // Default to 0 for all arguments that are not given
+      Args[I] = 0;
+    }
+  }
+
+  VA_END (ArgList);
+
+  register UINTN  a0 asm ("a0") = Args[0];  register UINTN  a1 asm 
+ ("a1") = Args[1];  register UINTN  a2 asm ("a2") = Args[2];  register 
+ UINTN  a3 asm ("a3") = Args[3];  register UINTN  a4 asm ("a4") = 
+ Args[4];  register UINTN  a5 asm ("a5") = Args[5];  register UINTN  a6 
+ asm ("a6") = (UINTN)(FuncId);  register UINTN  a7 asm ("a7") = 
+ (UINTN)(ExtId);
+
+  asm volatile ("ecall" \
+       : "+r" (a0), "+r" (a1) \
+       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
+       : "memory"); \
+  Ret.Error = a0;
+  Ret.Value = a1;
+  return Ret;
+}
+
+/**
+  Translate SBI error code to EFI status.
+
+  @param[in] SbiError   SBI error code
+  @retval EFI_STATUS
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+TranslateError (
+  IN  UINTN  SbiError
+  )
+{
+  switch (SbiError) {
+    case SBI_SUCCESS:
+      return EFI_SUCCESS;
+    case SBI_ERR_FAILED:
+      return EFI_DEVICE_ERROR;
+      break;
+    case SBI_ERR_NOT_SUPPORTED:
+      return EFI_UNSUPPORTED;
+      break;
+    case SBI_ERR_INVALID_PARAM:
+      return EFI_INVALID_PARAMETER;
+      break;
+    case SBI_ERR_DENIED:
+      return EFI_ACCESS_DENIED;
+      break;
+    case SBI_ERR_INVALID_ADDRESS:
+      return EFI_LOAD_ERROR;
+      break;
+    case SBI_ERR_ALREADY_AVAILABLE:
+      return EFI_ALREADY_STARTED;
+      break;
+    default:
+      //
+      // Reaches here only if SBI has defined a new error type
+      //
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+      break;
+  }
+}
+
+/**
+  Clear pending timer interrupt bit and set timer for next event after Time.
+
+  To clear the timer without scheduling a timer event, set Time to a  
+ practically infinite value or mask the timer interrupt by clearing sie.STIE.
+
+  @param[in]  Time                 The time offset to the next scheduled timer interrupt.
+**/
+VOID
+EFIAPI
+SbiSetTimer (
+  IN  UINT64  Time
+  )
+{
+  SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time); }
+
+EFI_STATUS
+EFIAPI
+SbiSystemReset (
+  IN  UINTN  ResetType,
+  IN  UINTN  ResetReason
+  )
+{
+  SBI_RET  Ret;
+
+  Ret = SbiCall (
+          SBI_EXT_SRST,
+          SBI_EXT_SRST_RESET,
+          2,
+          ResetType,
+          ResetReason
+          );
+
+  return TranslateError (Ret.Error);
+}
+
+/**
+  Get firmware context of the calling hart.
+
+  @param[out] FirmwareContext      The firmware context pointer.
+  @retval EFI_SUCCESS              The operation succeeds.
+**/
+VOID
+EFIAPI
+GetFirmwareContext (
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
+  )
+{
+  *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT 
+*)RiscVGetSupervisorScratch (); }
+
+/**
+  Set firmware context of the calling hart.
+
+  @param[in] FirmwareContext       The firmware context pointer.
+**/
+VOID
+EFIAPI
+SetFirmwareContext (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
+  )
+{
+  RiscVSetSupervisorScratch ((UINT64)FirmwareContext); }
+
+/**
+  Get pointer to OpenSBI Firmware Context
+
+  Get the pointer of firmware context through OpenSBI FW Extension SBI.
+
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
+                                 Firmware Context.
+**/
+VOID
+EFIAPI
+GetFirmwareContextPointer (
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
+  )
+{
+  GetFirmwareContext (FirmwareContextPtr); }
+
+/**
+  Set the pointer to OpenSBI Firmware Context
+
+  Set the pointer of firmware context through OpenSBI FW Extension SBI.
+
+  @param    FirmwareContextPtr   Pointer to Firmware Context.
+**/
+VOID
+EFIAPI
+SetFirmwareContextPointer (
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
+  )
+{
+  SetFirmwareContext (FirmwareContextPtr); }
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions Sunil V L
@ 2023-02-06 15:47   ` Andrei Warkentin
  2023-02-09  5:16   ` Ni, Ray
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 15:47 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Daniel Schaefer,
	Gerd Hoffmann, Abner Chang, Heinrich Schuchardt

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>; Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RISC-V UEFI based platforms need to support RISCV_EFI_BOOT_PROTOCOL.
Add this protocol GUID definition and the header file required.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
---
 UefiCpuPkg/UefiCpuPkg.dec                       |  7 ++++
 UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h | 34 ++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index cff239d5283e..903ad52da91b 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -86,6 +86,13 @@ [Protocols]
   ## Include/Protocol/SmMonitorInit.h
   gEfiSmMonitorInitProtocolGuid  = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }}
 
+[Protocols.RISCV64]
+  #
+  # Protocols defined for RISC-V systems
+  #
+  ## Include/Protocol/RiscVBootProtocol.h
+  gRiscVEfiBootProtocolGuid  = { 0xccd15fec, 0x6f73, 0x4eec, { 0x83, 
+0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf }}
+
 #
 # [Error.gUefiCpuPkgTokenSpaceGuid]
 #   0x80000001 | Invalid value provided.
diff --git a/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
new file mode 100644
index 000000000000..ed223b852d34
--- /dev/null
+++ b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
@@ -0,0 +1,34 @@
+/** @file
+  RISC-V Boot Protocol mandatory for RISC-V UEFI platforms.
+
+  @par Revision Reference:
+  The protocol specification can be found at  
+ https://github.com/riscv-non-isa/riscv-uefi
+
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
+ reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_BOOT_PROTOCOL_H_
+#define RISCV_BOOT_PROTOCOL_H_
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL RISCV_EFI_BOOT_PROTOCOL;
+
+#define RISCV_EFI_BOOT_PROTOCOL_REVISION  0x00010000 #define 
+RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION \
+        RISCV_EFI_BOOT_PROTOCOL_REVISION
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_BOOT_HARTID)(
+  IN RISCV_EFI_BOOT_PROTOCOL   *This,
+  OUT UINTN                    *BootHartId
+  );
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL {
+  UINT64                 Revision;
+  EFI_GET_BOOT_HARTID    GetBootHartId;
+} RISCV_EFI_BOOT_PROTOCOL;
+
+#endif
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: " Sunil V L
@ 2023-02-06 15:58   ` Andrei Warkentin
  2023-02-08  5:05     ` Sunil V L
  0 siblings, 1 reply; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 15:58 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Daniel Schaefer,
	Gerd Hoffmann, Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This is copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc           |   1 +
 UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf |  68 ++++  UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h  | 199 +++++++++++  UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c  | 365 ++++++++++++++++++++
 4 files changed, 633 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 251a8213f022..8f2be6cd1b05 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -198,6 +198,7 @@ [Components.X64]
 [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
   UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
new file mode 100644
index 000000000000..5e590d03754f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
@@ -0,0 +1,68 @@
+## @file
+#  RISC-V CPU DXE module.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
+reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = CpuDxeRiscV64
+  MODULE_UNI_FILE                = CpuDxe.uni
+  FILE_GUID                      = BDEA19E2-778F-473C-BF82-5E38D6A27765
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeCpu
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CpuLib
+  DebugLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  CpuExceptionHandlerLib
+  HobLib
+  ReportStatusCodeLib
+  TimerLib
+  PeCoffGetEntryPointLib
+  RiscVSbiLib
+
+[Sources]
+  RiscV64/CpuDxe.c
+  RiscV64/CpuDxe.h
+
+[Protocols]
+  gEfiCpuArchProtocolGuid                       ## PRODUCES
+  gRiscVEfiBootProtocolGuid                     ## PRODUCES
+
+[Guids]
+  gIdleLoopEventGuid                            ## CONSUMES           ## Event
+
+[Ppis]
+  gEfiSecPlatformInformation2PpiGuid            ## UNDEFINED # HOB
+  gEfiSecPlatformInformationPpiGuid             ## UNDEFINED # HOB
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency             ## CONSUMES
+
+[Depex]
+  TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  CpuDxeExtra.uni
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
new file mode 100644
index 000000000000..49f4e119665a
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
@@ -0,0 +1,199 @@
+/** @file
+  RISC-V CPU DXE module header file.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
+ All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_DXE_H_
+#define CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/RiscVBootProtocol.h> #include 
+<Library/BaseRiscVSbiLib.h> #include <Library/BaseLib.h> #include 
+<Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+/**
+  Flush CPU data cache. If the instruction cache is fully coherent
+  with all DMA operations then function can just return EFI_SUCCESS.
+
+  @param  This              Protocol instance structure
+  @param  Start             Physical address to start flushing from.
+  @param  Length            Number of bytes to flush. Round up to chipset
+                            granularity.
+  @param  FlushType         Specifies the type of flush operation to perform.
+
+  @retval EFI_SUCCESS       If cache was flushed
+  @retval EFI_UNSUPPORTED   If flush type is not supported.
+  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   Start,
+  IN UINT64                 Length,
+  IN EFI_CPU_FLUSH_TYPE     FlushType
+  );
+
+/**
+  Enables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
+  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  );
+
+/**
+  Disables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
+  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  );
+
+/**
+  Return the state of interrupts.
+
+  @param  This                   Protocol instance structure
+  @param  State                  Pointer to the CPU's current interrupt state
+
+  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
+  @retval EFI_INVALID_PARAMETER  State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  OUT BOOLEAN                *State
+  );
+
+/**
+  Generates an INIT to the CPU.
+
+  @param  This              Protocol instance structure
+  @param  InitType          Type of CPU INIT to perform
+
+  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
+                            seen.
+  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
+  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_CPU_INIT_TYPE      InitType
+  );
+
+/**
+  Registers a function to be called from the CPU interrupt handler.
+
+  @param  This                   Protocol instance structure
+  @param  InterruptType          Defines which interrupt to hook. IA-32
+                                 valid range is 0x00 through 0xFF
+  @param  InterruptHandler       A pointer to a function of type
+                                 EFI_CPU_INTERRUPT_HANDLER that is called
+                                 when a processor interrupt occurs.  A null
+                                 pointer is an error condition.
+
+  @retval EFI_SUCCESS            If handler installed or uninstalled.
+  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
+                                 for InterruptType was previously installed.
+  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
+                                 InterruptType was not previously installed.
+  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
+                                 is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+  IN EFI_CPU_ARCH_PROTOCOL      *This,
+  IN EFI_EXCEPTION_TYPE         InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
+  );
+
+/**
+  Returns a timer value from one of the CPU's internal timers. There is 
+no
+  inherent time interval between ticks but is a function of the CPU frequency.
+
+  @param  This                - Protocol instance structure.
+  @param  TimerIndex          - Specifies which CPU timer is requested.
+  @param  TimerValue          - Pointer to the returned timer value.
+  @param  TimerPeriod         - A pointer to the amount of time that passes
+                                in femtoseconds (10-15) for each increment
+                                of TimerValue. If TimerValue does not
+                                increment at a predictable rate, then 0 is
+                                returned.  The amount of time that has
+                                passed between two calls to GetTimerValue()
+                                can be calculated with the formula
+                                (TimerValue2 - TimerValue1) * TimerPeriod.
+                                This parameter is optional and may be NULL.
+
+  @retval EFI_SUCCESS           - If the CPU timer count was returned.
+  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
+  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
+  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  IN  UINT32                 TimerIndex,
+  OUT UINT64                 *TimerValue,
+  OUT UINT64                 *TimerPeriod OPTIONAL
+  );
+
+/**
+  Set memory cacheability attributes for given range of memeory.
+
+  @param  This                   Protocol instance structure
+  @param  BaseAddress            Specifies the start address of the
+                                 memory range
+  @param  Length                 Specifies the length of the memory range
+  @param  Attributes             The memory cacheability for the memory range
+
+  @retval EFI_SUCCESS            If the cacheability of that memory range is
+                                 set successfully
+  @retval EFI_UNSUPPORTED        If the desired operation cannot be done
+  @retval EFI_INVALID_PARAMETER  The input parameter is not correct,
+                                 such as Length = 0
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 Attributes
+  );
+
+#endif
diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
new file mode 100644
index 000000000000..7551e0653603
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
@@ -0,0 +1,365 @@
+/** @file
+  RISC-V CPU DXE driver.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
+ All rights reserved.<BR>  Copyright (c) 2022, Ventana Micro Systems 
+ Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDxe.h"
+
+//
+// Global Variables
+//
+STATIC BOOLEAN           mInterruptState = FALSE;
+STATIC EFI_HANDLE        mCpuHandle      = NULL;
+STATIC UINTN             mBootHartId;
+RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol;
+
+/**
+  Get the boot hartid
+
+  @param  This                   Protocol instance structure
+  @param  BootHartId             Pointer to the Boot Hart ID variable
+
+  @retval EFI_SUCCESS            If BootHartId is returned
+  @retval EFI_INVALID_PARAMETER  Either "BootHartId" is NULL or "This" is not
+                                 a valid RISCV_EFI_BOOT_PROTOCOL instance.
+
+**/
+EFI_STATUS
+EFIAPI
+RiscvGetBootHartId (
+  IN RISCV_EFI_BOOT_PROTOCOL  *This,
+  OUT UINTN                   *BootHartId
+  )
+{
+  if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *BootHartId = mBootHartId;
+  return EFI_SUCCESS;
+}
+
+RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol = {
+  RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
+  RiscvGetBootHartId
+};
+
+EFI_CPU_ARCH_PROTOCOL  gCpu = {
+  CpuFlushCpuDataCache,
+  CpuEnableInterrupt,
+  CpuDisableInterrupt,
+  CpuGetInterruptState,
+  CpuInit,
+  CpuRegisterInterruptHandler,
+  CpuGetTimerValue,
+  CpuSetMemoryAttributes,
+  1,                          // NumberOfTimers
+  4                           // DmaBufferAlignment
+};
+
+//
+// CPU Arch Protocol Functions
+//
+
+/**
+  Flush CPU data cache. If the instruction cache is fully coherent
+  with all DMA operations then function can just return EFI_SUCCESS.
+
+  @param  This              Protocol instance structure
+  @param  Start             Physical address to start flushing from.
+  @param  Length            Number of bytes to flush. Round up to chipset
+                            granularity.
+  @param  FlushType         Specifies the type of flush operation to perform.
+
+  @retval EFI_SUCCESS       If cache was flushed
+  @retval EFI_UNSUPPORTED   If flush type is not supported.
+  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   Start,
+  IN UINT64                 Length,
+  IN EFI_CPU_FLUSH_TYPE     FlushType
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Enables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
+  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  )
+{
+  EnableInterrupts ();
+  mInterruptState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Disables CPU interrupts.
+
+  @param  This              Protocol instance structure
+
+  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
+  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL  *This
+  )
+{
+  DisableInterrupts ();
+  mInterruptState = FALSE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Return the state of interrupts.
+
+  @param  This                   Protocol instance structure
+  @param  State                  Pointer to the CPU's current interrupt state
+
+  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
+  @retval EFI_INVALID_PARAMETER  State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  OUT BOOLEAN                *State
+  )
+{
+  if (State == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *State = mInterruptState;
+  return EFI_SUCCESS;
+}
+
+/**
+  Generates an INIT to the CPU.
+
+  @param  This              Protocol instance structure
+  @param  InitType          Type of CPU INIT to perform
+
+  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
+                            seen.
+  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
+  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_CPU_INIT_TYPE      InitType
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Registers a function to be called from the CPU interrupt handler.
+
+  @param  This                   Protocol instance structure
+  @param  InterruptType          Defines which interrupt to hook. IA-32
+                                 valid range is 0x00 through 0xFF
+  @param  InterruptHandler       A pointer to a function of type
+                                 EFI_CPU_INTERRUPT_HANDLER that is called
+                                 when a processor interrupt occurs.  A null
+                                 pointer is an error condition.
+
+  @retval EFI_SUCCESS            If handler installed or uninstalled.
+  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
+                                 for InterruptType was previously installed.
+  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
+                                 InterruptType was not previously installed.
+  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
+                                 is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+  IN EFI_CPU_ARCH_PROTOCOL      *This,
+  IN EFI_EXCEPTION_TYPE         InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
+  )
+{
+  return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); 
+}
+
+/**
+  Returns a timer value from one of the CPU's internal timers. There is 
+no
+  inherent time interval between ticks but is a function of the CPU frequency.
+
+  @param  This                - Protocol instance structure.
+  @param  TimerIndex          - Specifies which CPU timer is requested.
+  @param  TimerValue          - Pointer to the returned timer value.
+  @param  TimerPeriod         - A pointer to the amount of time that passes
+                                in femtoseconds (10-15) for each increment
+                                of TimerValue. If TimerValue does not
+                                increment at a predictable rate, then 0 is
+                                returned.  The amount of time that has
+                                passed between two calls to GetTimerValue()
+                                can be calculated with the formula
+                                (TimerValue2 - TimerValue1) * TimerPeriod.
+                                This parameter is optional and may be NULL.
+
+  @retval EFI_SUCCESS           - If the CPU timer count was returned.
+  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
+  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
+  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+  IN  EFI_CPU_ARCH_PROTOCOL  *This,
+  IN  UINT32                 TimerIndex,
+  OUT UINT64                 *TimerValue,
+  OUT UINT64                 *TimerPeriod OPTIONAL
+  )
+{
+  if (TimerValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TimerIndex != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerValue = (UINT64)RiscVReadTimer ();  if (TimerPeriod != NULL) {
+    *TimerPeriod = DivU64x32 (
+                     1000000000000000u,
+                     PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                     );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
+
+  This function modifies the attributes for the memory region specified 
+ by BaseAddress and  Length from their current attributes to the attributes specified by Attributes.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  BaseAddress      The physical address that is the start address of a memory region.
+  @param  Length           The size in bytes of the memory region.
+  @param  Attributes       The bit mask of attributes to set for the memory region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by
+                                BaseAddress and Length cannot be modified.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of attributes that
+                                cannot be set together.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
+                                the memory resource range.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory
+                                resource range specified by BaseAddress and Length.
+                                The bit mask of attributes is not support for the memory resource
+                                range specified by BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+  IN EFI_CPU_ARCH_PROTOCOL  *This,
+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 Attributes
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Set memory attributes not supported yet\n", 
+__FUNCTION__));
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the state information for the CPU Architectural Protocol.
+
+  @param ImageHandle     Image handle this driver.
+  @param SystemTable     Pointer to the System Table.
+
+  @retval EFI_SUCCESS           Thread can be successfully created
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Cannot create the thread
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  GetFirmwareContextPointer (&FirmwareContext);  ASSERT 
+ (FirmwareContext != NULL);  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n", 
+ __FUNCTION__, FirmwareContext));
+
+  mBootHartId = FirmwareContext->BootHartId;  DEBUG ((DEBUG_INFO, " %a: 
+ mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
+
+  InitializeCpuExceptionHandlers (NULL);
+
+  //
+  // Make sure interrupts are disabled
+  //
+  DisableInterrupts ();
+
+  //
+  // Install Boot protocol
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gRiscVEfiBootProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &gRiscvBootProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install CPU Architectural Protocol
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mCpuHandle,
+                  &gEfiCpuArchProtocolGuid,
+                  &gCpu,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
  2023-01-30 11:07   ` [edk2-devel] " dhaval
@ 2023-02-06 16:00   ` Andrei Warkentin
  2023-02-09  5:37   ` Ni, Ray
  2 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:00 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Daniel Schaefer, Abner Chang,
	Gerd Hoffmann

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>; Gerd Hoffmann <kraxel@redhat.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                                 |   1 +
 UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf |  32 ++++
 UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c      | 199 ++++++++++++++++++++
 3 files changed, 232 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 8f2be6cd1b05..2df02bf75a35 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -199,6 +199,7 @@ [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
   UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
   UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+  UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
new file mode 100644
index 000000000000..c920e8e098b5
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
@@ -0,0 +1,32 @@
+## @file
+# RISC-V Base CPU Timer Library Instance # #  Copyright (c) 2016 - 
+2019, Hewlett Packard Enterprise Development LP. All rights 
+reserved.<BR> #  Copyright (c) 2022, Ventana Micro Systems Inc. All 
+rights reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent 
+# ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseRisV64CpuTimerLib
+  FILE_GUID                      = B635A600-EA24-4199-88E8-5761EEA96A51
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources]
+  RiscV64/CpuTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  DebugLib
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ## 
+CONSUMES
diff --git a/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
new file mode 100644
index 000000000000..9c8efc0f3530
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
@@ -0,0 +1,199 @@
+/** @file
+  RISC-V instance of Timer Library.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
+ All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked 
+ by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+InternalRiscVTimerDelay (
+  IN UINT32  Delay
+  )
+{
+  UINT32  Ticks;
+  UINT32  Times;
+
+  Times  = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);
+  Delay &= ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = RiscVReadTimer () + Delay;
+    Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);
+    while (((Ticks - RiscVReadTimer ()) & (1 << (RISCV_TIMER_COMPARE_BITS - 1))) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN UINTN  MicroSeconds
+  )
+{
+  InternalRiscVTimerDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN UINTN  NanoSeconds
+  )
+{
+  InternalRiscVTimerDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance 
+ counter. The  counter can either count up by 1 or count down by 1. If 
+ the physical  performance counter counts by a larger increment, then 
+ the counter values  must be translated. The properties of the counter 
+ can be retrieved from  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)RiscVReadTimer ();
+}
+
+/**return
+  Retrieves the 64-bit frequency in Hz and the range of performance 
+counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance 
+ counter starts  with immediately after is it rolls over is returned in 
+ StartValue. If  EndValue is not NULL, then the value that the 
+ performance counter end with  immediately before it rolls over is 
+ returned in EndValue. The 64-bit  frequency of the performance counter 
+ in Hz is always returned. If StartValue  is less than EndValue, then 
+ the performance counter counts up. If StartValue  is greater than 
+ EndValue, then the performance counter counts down. For  example, a 
+ 64-bit free running counter that counts up would have a StartValue  of 
+ 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64 *StartValue, OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 32 - 1;
+  }
+
+  return PcdGet64 (PcdCpuCoreCrystalClockFrequency);
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance 
+ counter to  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64  Ticks
+  )
+{
+  UINT64  NanoSeconds;
+  UINT32  Remainder;
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 
+ (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);
+
+  //
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then 
+ (Remainder * 1,000,000,000)  // will not overflow 64-bit.
+  //
+  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 
+ 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));
+
+  return NanoSeconds;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
@ 2023-02-06 16:00   ` Andrei Warkentin
  2023-02-09  1:50   ` Michael D Kinney
  2023-02-09  5:38   ` Ni, Ray
  2 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:00 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Gerd Hoffmann, Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RISC-V register names do not follow the EDK2 formatting.
So, add it to ignore list for now.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.ci.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml index a377366798b0..953361ba0479 100644
--- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
+++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
@@ -27,6 +27,7 @@
         ],
         ## Both file path and directory path are accepted.
         "IgnoreFiles": [
+          "Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h"
         ]
     },
     "CompilerPlugin": {
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V Sunil V L
@ 2023-02-06 16:00   ` Andrei Warkentin
  2023-02-09  1:51   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:00 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Leif Lindholm, Ard Biesheuvel, Abner Chang, Daniel Schaefer

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Leif Lindholm <quic_llindhol@quicinc.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>; Abner Chang <abner.chang@amd.com>; Daniel Schaefer <git@danielschaefer.me>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V

This PCD is required to be enabled so that PrePiLib can be used in RISC-V.

Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 EmbeddedPkg/EmbeddedPkg.dec | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 341ef5e6a679..2965f01444e9 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -165,6 +165,9 @@ [PcdsFixedAtBuild.IA32]  [PcdsFixedAtBuild.X64]
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
 
+[PcdsFixedAtBuild.RISCV64]
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+
 [PcdsFixedAtBuild.common, PcdsDynamic.common]
   #
   # Value to add to a host address to obtain a device address, using
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
@ 2023-02-06 16:01   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:01 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This module is required by other architectures like RISC-V.
Hence, move this to OvmfPkg.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 ArmVirtPkg/ArmVirtPkg.dec                                             | 9 ---------
 OvmfPkg/OvmfPkg.dec                                                   | 7 +++++++
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf | 3 +--
 {ArmVirtPkg => OvmfPkg}/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c   | 0
 4 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec index 89d21ec3a364..4645c91a8375 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -34,8 +34,6 @@ [Guids.common]
   gEarly16550UartBaseAddressGuid   = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
   gArmVirtSystemMemorySizeGuid     = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
 
-  gArmVirtVariableGuid   = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
-
 [PcdsFeatureFlag]
   #
   # Feature Flag PCD that defines whether TPM2 support is enabled @@ -69,10 +67,3 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
   # Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
   #
   gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
-
-[PcdsDynamic]
-  #
-  # Whether to force disable ACPI, regardless of the fw_cfg settings
-  # exposed by QEMU
-  #
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x00000003
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index a22eb246c625..e52602db5b79 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -157,6 +157,7 @@ [Guids]
   gVMMBootOrderGuid                     = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
   gUefiOvmfPkgTdxAcpiHobGuid            = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
   gEfiNonCcFvGuid                       = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
+  gOvmfVariableGuid                     = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address @@ -463,6 +464,12 @@ [PcdsDynamic, PcdsDynamicEx]
   #    2 - set by GOP Driver.
   gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource|0|UINT8|0x64
 
+  #
+  # Whether to force disable ACPI, regardless of the fw_cfg settings  # 
+ exposed by QEMU  #
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x69
+
 [PcdsFeatureFlag]
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
similarity index 89%
rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
index e900aa992661..85873f73b2eb 100644
--- a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+++ b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
@@ -19,7 +19,6 @@ [Sources]
   PlatformHasAcpiDtDxe.c
 
 [Packages]
-  ArmVirtPkg/ArmVirtPkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
@@ -38,7 +37,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   gEfiVariableArchProtocolGuid
diff --git a/ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c b/OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
similarity index 100%
rename from ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
rename to OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.c
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe Sunil V L
@ 2023-02-06 16:01   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:01 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Leif Lindholm <quic_llindhol@quicinc.com>; Sami Mujawar <sami.mujawar@arm.com>; Gerd Hoffmann <kraxel@redhat.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

PlatformHasAcpiDtDxe is required by other architectures also.
Hence, it is moved to OvmfPkg. So, update the consumers of this module with the new location.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 ArmVirtPkg/ArmVirtCloudHv.dsc                                  | 2 +-
 ArmVirtPkg/ArmVirtQemu.dsc                                     | 4 ++--
 ArmVirtPkg/ArmVirtQemuKernel.dsc                               | 2 +-
 ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf | 2 +-
 ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf           | 4 ++--
 ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc                           | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index 7ca7a391d9cf..c975e139a216 100644
--- a/ArmVirtPkg/ArmVirtCloudHv.dsc
+++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
@@ -198,7 +198,7 @@ [PcdsDynamicDefault.common]
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
 
 [PcdsDynamicHii]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
+  
+ gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariable
+ Guid|0x0|FALSE|NV,BS
 
 ################################################################################
 #
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 0f1c6395488a..72a0cacab4a8 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -305,7 +305,7 @@ [PcdsPatchableInModule]  !endif
 
 [PcdsDynamicHii]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
+  
+ gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariable
+ Guid|0x0|FALSE|NV,BS
 
 !if $(TPM2_CONFIG_ENABLE) == TRUE
   gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
@@ -578,7 +578,7 @@ [Components.common]
   #
   # ACPI Support
   #
-  ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 [Components.AARCH64]
   MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf { diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index 807c85d48285..3cb9120e4e10 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -461,7 +461,7 @@ [Components.common]
   #
   # ACPI Support
   #
-  ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 [Components.AARCH64]
   MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf { diff --git a/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf b/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
index 4af06b2a6746..7cad40e11f33 100644
--- a/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
+++ b/ArmVirtPkg/CloudHvPlatformHasAcpiDtDxe/CloudHvHasAcpiDtDxe.inf
@@ -36,7 +36,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   gEfiVariableArchProtocolGuid
diff --git a/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf b/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
index 1cf25780f830..c5bf798c3b2b 100644
--- a/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
+++ b/ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
@@ -21,7 +21,7 @@ [Sources]
   KvmtoolPlatformDxe.c
 
 [Packages]
-  ArmVirtPkg/ArmVirtPkg.dec
+  OvmfPkg/OvmfPkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
@@ -37,7 +37,7 @@ [Guids]
   gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
 
 [Pcd]
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
 
 [Depex]
   TRUE
diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index e06ca7424476..8a063bac04ac 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -141,7 +141,7 @@ [FV.FvMain]
   #
   # ACPI Support
   #
-  INF ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  INF OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
 !if $(ARCH) == AARCH64
   INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
   INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Sunil V L
@ 2023-02-06 16:01   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:01 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library

RISC-V Qemu Virt platfform needs the PlatformBootManagerLib similar to the one in ArmVirtPlatform. Add the library in OvmfPkg/RiscVVirt leveraging the one from Arm.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   75 ++
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h               |   45 +
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c               | 1078 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c               |   77 ++
 4 files changed, 1275 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 000000000000..9d66c8110c53
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManag
+++ erLib.inf
@@ -0,0 +1,75 @@
+## @file
+#  Implementation for PlatformBootManagerLib library class interfaces for RISC-V.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
+reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = DxeRiscV64PlatformBootManagerLib
+  FILE_GUID                      = 4FC87DC9-2666-49BB-9023-B5FAA1E9E732
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  PlatformBm.c
+  PlatformBm.h
+  QemuKernel.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  BootLogoLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  PcdLib
+  PlatformBmPrintScLib
+  QemuBootOrderLib
+  QemuLoadImageLib
+  ReportStatusCodeLib
+  TpmPlatformHierarchyLib
+  UefiBootManagerLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gEfiGlobalVariableGuid
+  gRootBridgesConnectedEventGroupGuid
+  gUefiShellFileGuid
+  gEfiTtyTermGuid
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gVirtioDeviceProtocolGuid
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h
new file mode 100644
index 000000000000..70c52d9832ca
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h
@@ -0,0 +1,45 @@
+/** @file
+  Head file for BDS Platform specific code
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2004 - 2008, Intel Corporation. All rights 
+ reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_BM_H_
+#define _PLATFORM_BM_H_
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h> #include 
+<Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+  Download the kernel, the initial ramdisk, and the kernel command line 
+from
+  QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the 
+two
+  image files, and load and start the kernel from it.
+
+  The kernel will be instructed via its command line to load the initrd 
+ from  the same Simple FileSystem.
+
+  @retval EFI_NOT_FOUND         Kernel image was not found.
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+  @retval EFI_PROTOCOL_ERROR    Unterminated kernel command line.
+
+  @return                       Error codes from any of the underlying
+                                functions. On success, the function doesn't
+                                return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+  VOID
+  );
+
+#endif // _PLATFORM_BM_H_
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c
new file mode 100644
index 000000000000..2559889638ad
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c
@@ -0,0 +1,1078 @@
+/** @file
+  Implementation for PlatformBootManagerLib library class interfaces.
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>  Copyright (c) 
+ 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Virtio095.h> #include 
+<Library/BootLogoLib.h> #include <Library/DevicePathLib.h> #include 
+<Library/PcdLib.h> #include <Library/PlatformBmPrintScLib.h> #include 
+<Library/QemuBootOrderLib.h> #include 
+<Library/TpmPlatformHierarchyLib.h>
+#include <Library/UefiBootManagerLib.h> #include 
+<Protocol/DevicePath.h> #include <Protocol/FirmwareVolume2.h> #include 
+<Protocol/GraphicsOutput.h> #include <Protocol/LoadedImage.h> #include 
+<Protocol/PciIo.h> #include <Protocol/PciRootBridgeIo.h> #include 
+<Protocol/VirtioDevice.h> #include <Guid/EventGroup.h> #include 
+<Guid/GlobalVariable.h> #include 
+<Guid/RootBridgesConnectedEventGroup.h>
+#include <Guid/SerialPortLibVendor.h>
+#include <Guid/TtyTerm.h>
+
+#include "PlatformBm.h"
+
+#define DP_NODE_LEN(Type)  { (UINT8)sizeof (Type), (UINT8)(sizeof 
+(Type) >> 8) }
+
+#define VERSION_STRING_PREFIX  L"RISC-V EDK2 firmware version "
+
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH            SerialDxe;
+  UART_DEVICE_PATH              Uart;
+  VENDOR_DEFINED_DEVICE_PATH    TermType;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} PLATFORM_SERIAL_CONSOLE;
+#pragma pack ()
+
+STATIC PLATFORM_SERIAL_CONSOLE  mSerialConsole = {
+  //
+  // VENDOR_DEVICE_PATH SerialDxe
+  //
+  {
+    { HARDWARE_DEVICE_PATH,  HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },
+    EDKII_SERIAL_PORT_LIB_VENDOR_GUID
+  },
+
+  //
+  // UART_DEVICE_PATH Uart
+  //
+  {
+    { MESSAGING_DEVICE_PATH, MSG_UART_DP,  DP_NODE_LEN (UART_DEVICE_PATH)   },
+    0,                                      // Reserved
+    FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate
+    FixedPcdGet8 (PcdUartDefaultDataBits),  // DataBits
+    FixedPcdGet8 (PcdUartDefaultParity),    // Parity
+    FixedPcdGet8 (PcdUartDefaultStopBits)   // StopBits
+  },
+
+  //
+  // VENDOR_DEFINED_DEVICE_PATH TermType  //  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,
+      DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)
+    }
+    //
+    // Guid to be filled in dynamically
+    //
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+#pragma pack (1)
+typedef struct {
+  USB_CLASS_DEVICE_PATH       Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_USB_KEYBOARD;
+#pragma pack ()
+
+STATIC PLATFORM_USB_KEYBOARD  mUsbKeyboard = {
+  //
+  // USB_CLASS_DEVICE_PATH Keyboard
+  //
+  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,
+      DP_NODE_LEN (USB_CLASS_DEVICE_PATH)
+    },
+    0xFFFF, // VendorId: any
+    0xFFFF, // ProductId: any
+    3,      // DeviceClass: HID
+    1,      // DeviceSubClass: boot
+    1       // DeviceProtocol: keyboard
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+/**
+  Check if the handle satisfies a particular condition.
+
+  @param[in] Handle      The handle to check.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+
+  @retval TRUE   The condition is satisfied.
+  @retval FALSE  Otherwise. This includes the case when the condition could not
+                 be fully evaluated due to an error.
+**/
+typedef
+BOOLEAN
+(EFIAPI *FILTER_FUNCTION)(
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+/**
+  Process a handle.
+
+  @param[in] Handle      The handle to process.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+**/
+typedef
+VOID
+(EFIAPI *CALLBACK_FUNCTION)(
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+/**
+  Locate all handles that carry the specified protocol, filter them 
+with a
+  callback function, and pass each handle that passes the filter to 
+another
+  callback.
+
+  @param[in] ProtocolGuid  The protocol to look for.
+
+  @param[in] Filter        The filter function to pass each handle to. If this
+                           parameter is NULL, then all handles are processed.
+
+  @param[in] Process       The callback function to pass each handle to that
+                           clears the filter.
+**/
+STATIC
+VOID
+FilterAndProcess (
+  IN EFI_GUID           *ProtocolGuid,
+  IN FILTER_FUNCTION    Filter         OPTIONAL,
+  IN CALLBACK_FUNCTION  Process
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  *Handles;
+  UINTN       NoHandles;
+  UINTN       Idx;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  ProtocolGuid,
+                  NULL /* SearchKey */,
+                  &NoHandles,
+                  &Handles
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // This is not an error, just an informative condition.
+    //
+    DEBUG ((
+      DEBUG_VERBOSE,
+      "%a: %g: %r\n",
+      __FUNCTION__,
+      ProtocolGuid,
+      Status
+      ));
+    return;
+  }
+
+  ASSERT (NoHandles > 0);
+  for (Idx = 0; Idx < NoHandles; ++Idx) {
+    CHAR16         *DevicePathText;
+    STATIC CHAR16  Fallback[] = L"<device path unavailable>";
+
+    //
+    // The ConvertDevicePathToText() function handles NULL input transparently.
+    //
+    DevicePathText = ConvertDevicePathToText (
+                       DevicePathFromHandle (Handles[Idx]),
+                       FALSE, // DisplayOnly
+                       FALSE  // AllowShortcuts
+                       );
+    if (DevicePathText == NULL) {
+      DevicePathText = Fallback;
+    }
+
+    if ((Filter == NULL) || Filter (Handles[Idx], DevicePathText)) {
+      Process (Handles[Idx], DevicePathText);
+    }
+
+    if (DevicePathText != Fallback) {
+      FreePool (DevicePathText);
+    }
+  }
+
+  gBS->FreePool (Handles);
+}
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a PCI display device.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsPciDisplay (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  PCI_TYPE00           Pci;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // This is not an error worth reporting.
+    //
+    return FALSE;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0 /* Offset */,
+                        sizeof Pci / sizeof (UINT32),
+                        &Pci
+                        );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));
+    return FALSE;
+  }
+
+  return IS_PCI_DISPLAY (&Pci);
+}
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG 
+device at
+  the VIRTIO_DEVICE_PROTOCOL level.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsVirtioRng (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS              Status;
+  VIRTIO_DEVICE_PROTOCOL  *VirtIo;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gVirtioDeviceProtocolGuid,
+                  (VOID **)&VirtIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return (BOOLEAN)(VirtIo->SubSystemDeviceId ==
+                   VIRTIO_SUBSYSTEM_ENTROPY_SOURCE); }
+
+/**
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG 
+device at
+  the EFI_PCI_IO_PROTOCOL level.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsVirtioPciRng (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  UINT16               VendorId;
+  UINT16               DeviceId;
+  UINT8                RevisionId;
+  BOOLEAN              Virtio10;
+  UINT16               SubsystemId;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  //
+  // Read and check VendorId.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_VENDOR_ID_OFFSET,
+                        1,
+                        &VendorId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  if (VendorId != VIRTIO_VENDOR_ID) {
+    return FALSE;
+  }
+
+  //
+  // Read DeviceId and RevisionId.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_DEVICE_ID_OFFSET,
+                        1,
+                        &DeviceId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_REVISION_ID_OFFSET,
+                        1,
+                        &RevisionId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  //
+  // From DeviceId and RevisionId, determine whether the device is a  
+ // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can  
+ // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and  
+ // SubsystemId will only play a sanity-check role. Otherwise, DeviceId 
+ can  // only be sanity-checked, and SubsystemId will decide.
+  //
+  if ((DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) &&
+      (RevisionId >= 0x01))
+  {
+    Virtio10 = TRUE;
+  } else if ((DeviceId >= 0x1000) && (DeviceId <= 0x103F) && (RevisionId == 0x00)) {
+    Virtio10 = FALSE;
+  } else {
+    return FALSE;
+  }
+
+  //
+  // Read and check SubsystemId as dictated by Virtio10.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PCI_SUBSYSTEM_ID_OFFSET,
+                        1,
+                        &SubsystemId
+                        );
+  if (EFI_ERROR (Status)) {
+    goto PciError;
+  }
+
+  if (Virtio10 && (SubsystemId >= 0x40)) {
+    return TRUE;
+  }
+
+  if (!Virtio10 && (SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {
+    return TRUE;
+  }
+
+  return FALSE;
+
+PciError:
+  DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, 
+Status));
+  return FALSE;
+}
+
+/**
+  This CALLBACK_FUNCTION attempts to connect a handle non-recursively, 
+asking
+  the matching driver to produce all first-level child handles.
+**/
+STATIC
+VOID
+EFIAPI
+Connect (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->ConnectController (
+                  Handle, // ControllerHandle
+                  NULL,   // DriverImageHandle
+                  NULL,   // RemainingDevicePath -- produce all children
+                  FALSE   // Recursive
+                  );
+  DEBUG ((
+    EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
+    "%a: %s: %r\n",
+    __FUNCTION__,
+    ReportText,
+    Status
+    ));
+}
+
+/**
+  This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from 
+the
+  handle, and adds it to ConOut and ErrOut.
+**/
+STATIC
+VOID
+EFIAPI
+AddOutput (
+  IN EFI_HANDLE    Handle,
+  IN CONST CHAR16  *ReportText
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  DevicePath = DevicePathFromHandle (Handle);  if (DevicePath == NULL) 
+ {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: handle %p: device path not found\n",
+      __FUNCTION__,
+      ReportText,
+      Handle
+      ));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, 
+ NULL);  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: adding to ConOut: %r\n",
+      __FUNCTION__,
+      ReportText,
+      Status
+      ));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, 
+ NULL);  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: %s: adding to ErrOut: %r\n",
+      __FUNCTION__,
+      ReportText,
+      Status
+      ));
+    return;
+  }
+
+  DEBUG ((
+    DEBUG_VERBOSE,
+    "%a: %s: added to ConOut and ErrOut\n",
+    __FUNCTION__,
+    ReportText
+    ));
+}
+
+STATIC
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID  *FileGuid,
+  CHAR16    *Description,
+  UINT32    Attributes
+  )
+{
+  EFI_STATUS                         Status;
+  INTN                               OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION       NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION       *BootOptions;
+  UINTN                              BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);  DevicePath = 
+ DevicePathFromHandle (LoadedImage->DeviceHandle);  ASSERT (DevicePath 
+ != NULL);  DevicePath = AppendDevicePathNode (
+                 DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
+                 );
+  ASSERT (DevicePath != NULL);
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  ASSERT_EFI_ERROR (Status);
+  FreePool (DevicePath);
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount,
+                  LoadOptionTypeBoot
+                  );
+
+  OptionIndex = EfiBootManagerFindLoadOption (
+                  &NewOption,
+                  BootOptions,
+                  BootOptionCount
+                  );
+
+  if (OptionIndex == -1) {
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  EfiBootManagerFreeLoadOption (&NewOption);
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); }
+
+/**
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot 
+options
+  whose device paths do not resolve exactly to an FvFile in the system.
+
+  This removes any boot options that point to binaries built into the 
+ firmware  and have become stale due to any of the following:
+  - FvMain's base address or size changed (historical),
+  - FvMain's FvNameGuid changed,
+  - the FILE_GUID of the pointed-to binary changed,
+  - the referenced binary is no longer built into the firmware.
+
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() 
+only
+  avoids exact duplicates.
+**/
+STATIC
+VOID
+RemoveStaleFvFileOptions (
+  VOID
+  )
+{
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions;
+  UINTN                         BootOptionCount;
+  UINTN                         Index;
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount,
+                  LoadOptionTypeBoot
+                  );
+
+  for (Index = 0; Index < BootOptionCount; ++Index) {
+    EFI_DEVICE_PATH_PROTOCOL  *Node1, *Node2, *SearchNode;
+    EFI_STATUS                Status;
+    EFI_HANDLE                FvHandle;
+
+    //
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+    // then keep the boot option.
+    //
+    Node1 = BootOptions[Index].FilePath;
+    if (!((DevicePathType (Node1) == HARDWARE_DEVICE_PATH) &&
+          (DevicePathSubType (Node1) == HW_MEMMAP_DP)) &&
+        !((DevicePathType (Node1) == MEDIA_DEVICE_PATH) &&
+          (DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)))
+    {
+      continue;
+    }
+
+    //
+    // If the second device path node is not FvFile(...), then keep the boot
+    // option.
+    //
+    Node2 = NextDevicePathNode (Node1);
+    if ((DevicePathType (Node2) != MEDIA_DEVICE_PATH) ||
+        (DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP))
+    {
+      continue;
+    }
+
+    //
+    // Locate the Firmware Volume2 protocol instance that is denoted by the
+    // boot option. If this lookup fails (i.e., the boot option references a
+    // firmware volume that doesn't exist), then we'll proceed to delete the
+    // boot option.
+    //
+    SearchNode = Node1;
+    Status     = gBS->LocateDevicePath (
+                        &gEfiFirmwareVolume2ProtocolGuid,
+                        &SearchNode,
+                        &FvHandle
+                        );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // The firmware volume was found; now let's see if it contains the FvFile
+      // identified by GUID.
+      //
+      EFI_FIRMWARE_VOLUME2_PROTOCOL      *FvProtocol;
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFileNode;
+      UINTN                              BufferSize;
+      EFI_FV_FILETYPE                    FoundType;
+      EFI_FV_FILE_ATTRIBUTES             FileAttributes;
+      UINT32                             AuthenticationStatus;
+
+      Status = gBS->HandleProtocol (
+                      FvHandle,
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **)&FvProtocol
+                      );
+      ASSERT_EFI_ERROR (Status);
+
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+      //
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+      // FileAttributes.
+      //
+      Status = FvProtocol->ReadFile (
+                             FvProtocol,
+                             &FvFileNode->FvFileName, // NameGuid
+                             NULL,                    // Buffer
+                             &BufferSize,
+                             &FoundType,
+                             &FileAttributes,
+                             &AuthenticationStatus
+                             );
+      if (!EFI_ERROR (Status)) {
+        //
+        // The FvFile was found. Keep the boot option.
+        //
+        continue;
+      }
+    }
+
+    //
+    // Delete the boot option.
+    //
+    Status = EfiBootManagerDeleteLoadOptionVariable (
+               BootOptions[Index].OptionNumber,
+               LoadOptionTypeBoot
+               );
+    DEBUG_CODE_BEGIN ();
+    CHAR16  *DevicePathString;
+
+    DevicePathString = ConvertDevicePathToText (
+                         BootOptions[Index].FilePath,
+                         FALSE,
+                         FALSE
+                         );
+    DEBUG ((
+      EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE,
+      "%a: removing stale Boot#%04x %s: %r\n",
+      __FUNCTION__,
+      (UINT32)BootOptions[Index].OptionNumber,
+      DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
+      Status
+      ));
+    if (DevicePathString != NULL) {
+      FreePool (DevicePathString);
+    }
+
+    DEBUG_CODE_END ();
+  }
+
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); }
+
+STATIC
+VOID
+PlatformRegisterOptionsAndKeys (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Enter;
+  EFI_INPUT_KEY                 F2;
+  EFI_INPUT_KEY                 Esc;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  Status            = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Map F2 and ESC to Boot Manager Menu
+  //
+  F2.ScanCode     = SCAN_F2;
+  F2.UnicodeChar  = CHAR_NULL;
+  Esc.ScanCode    = SCAN_ESC;
+  Esc.UnicodeChar = CHAR_NULL;
+  Status          = EfiBootManagerGetBootManagerMenu (&BootOption);
+  ASSERT_EFI_ERROR (Status);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL,
+             (UINT16)BootOption.OptionNumber,
+             0,
+             &F2,
+             NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL,
+             (UINT16)BootOption.OptionNumber,
+             0,
+             &Esc,
+             NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); }
+
+//
+// BDS Platform Functions
+//
+
+/**
+  Do the platform init, can be customized by OEM/IBV
+  Possible things that can be done in PlatformBootManagerBeforeConsole:
+  > Update console variable: 1. include hot-plug devices;
+  >                          2. Clear ConIn and add SOL for AMT
+  > Register new Driver#### or Boot####
+  > Register new Key####: e.g.: F12
+  > Signal ReadyToLock event
+  > Authentication action: 1. connect Auth devices;
+  >                        2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  UINT16         FrontPageTimeout;
+  RETURN_STATUS  PcdStatus;
+  EFI_STATUS     Status;
+
+  //
+  // Signal EndOfDxe PI Event
+  //
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+  //
+  // Disable the TPM 2 platform hierarchy  //  
+ ConfigureTpmPlatformHierarchy ();
+
+  //
+  // Dispatch deferred images after EndOfDxe event.
+  //
+  EfiBootManagerDispatchDeferredImages ();
+
+  //
+  // Locate the PCI root bridges and make the PCI bus driver connect 
+ each,  // non-recursively. This will produce a number of child handles 
+ with PciIo on  // them.
+  //
+  FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect);
+
+  //
+  // Signal the ACPI platform driver that it can download QEMU ACPI tables.
+  //
+  EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);
+
+  //
+  // Find all display class PCI devices (using the handles from the 
+ previous  // step), and connect them non-recursively. This should 
+ produce a number of  // child handles with GOPs on them.
+  //
+  FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect);
+
+  //
+  // Now add the device path of all handles with GOP on them to ConOut 
+ and  // ErrOut.
+  //
+  FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
+
+  //
+  // Add the hardcoded short-form USB keyboard device path to ConIn.
+  //
+  EfiBootManagerUpdateConsoleVariable (
+    ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard,
+    NULL
+    );
+
+  //
+  // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
+  //
+  CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
+
+  EfiBootManagerUpdateConsoleVariable (
+    ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+  EfiBootManagerUpdateConsoleVariable (
+    ConOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+  EfiBootManagerUpdateConsoleVariable (
+    ErrOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole,
+    NULL
+    );
+
+  //
+  // Set the front page timeout from the QEMU configuration.
+  //
+  FrontPageTimeout = GetFrontPageTimeoutFromQemu ();
+  PcdStatus        = PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  //
+  // Reflect the PCD in the standard Timeout variable.
+  //
+  Status = gRT->SetVariable (
+                  EFI_TIME_OUT_VARIABLE_NAME,
+                  &gEfiGlobalVariableGuid,
+                  (EFI_VARIABLE_NON_VOLATILE |
+                   EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                   EFI_VARIABLE_RUNTIME_ACCESS),
+                  sizeof FrontPageTimeout,
+                  &FrontPageTimeout
+                  );
+  DEBUG ((
+    EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
+    "%a: SetVariable(%s, %u): %r\n",
+    __FUNCTION__,
+    EFI_TIME_OUT_VARIABLE_NAME,
+    FrontPageTimeout,
+    Status
+    ));
+
+  //
+  // Register platform-specific boot options and keyboard shortcuts.
+  //
+  PlatformRegisterOptionsAndKeys ();
+
+  //
+  // At this point, VIRTIO_DEVICE_PROTOCOL instances exist only for 
+ Virtio MMIO  // transports. Install EFI_RNG_PROTOCOL instances on Virtio MMIO RNG devices.
+  //
+  FilterAndProcess (&gVirtioDeviceProtocolGuid, IsVirtioRng, Connect);
+
+  //
+  // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) 
+EFI_RNG_PROTOCOL
+  // instances on Virtio PCI RNG devices.
+  //
+  FilterAndProcess (&gEfiPciIoProtocolGuid, IsVirtioPciRng, Connect); }
+
+/**
+  Do the platform specific action after the console is ready
+  Possible things that can be done in PlatformBootManagerAfterConsole:
+  > Console post action:
+    > Dynamically switch output mode from 100x31 to 80x25 for certain scenario
+    > Signal console ready platform customized event
+  > Run diagnostics like memory testing
+  > Connect certain devices
+  > Dispatch additional option roms
+  > Special boot: e.g.: USB boot, enter UI **/ VOID EFIAPI 
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  RETURN_STATUS  Status;
+  UINTN          FirmwareVerLength;
+
+  FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString));  
+ //  // Show the splash screen.
+  //
+  BootLogoEnableLogo ();
+
+  if (FirmwareVerLength > 0) {
+    Print (
+      VERSION_STRING_PREFIX L"%s\n",
+      PcdGetPtr (PcdFirmwareVersionString)
+      );
+  }
+
+  Print (L"Press ESCAPE within 10 seconds for boot options ");  //  // 
+ Process QEMU's -kernel command line option. The kernel booted this way  
+ // will receive ACPI tables: in PlatformBootManagerBeforeConsole(), we  
+ // connected any and all PCI root bridges, and then signaled the ACPI  
+ // platform driver.
+  //
+  TryRunningQemuKernel ();
+
+  //
+  // Connect the purported boot devices.
+  //
+  Status = ConnectDevicesFromQemu ();
+  if (RETURN_ERROR (Status)) {
+    //
+    // Connect the rest of the devices.
+    //
+    EfiBootManagerConnectAll ();
+  }
+
+  //
+  // Enumerate all possible boot options, then filter and reorder them 
+ based on  // the QEMU configuration.
+  //
+  EfiBootManagerRefreshAllBootOption ();
+
+  //
+  // Register UEFI Shell
+  //
+  PlatformRegisterFvBootOption (
+    &gUefiShellFileGuid,
+    L"EFI Internal Shell",
+    LOAD_OPTION_ACTIVE
+    );
+
+  RemoveStaleFvFileOptions ();
+  SetBootOrderFromQemu ();
+
+  PlatformBmPrintScRegisterHandler ();
+}
+
+/**
+  This function is called each second during the boot manager waits the
+  timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16  TimeoutRemain
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  Black;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  White;
+  UINT16                               TimeoutInitial;
+
+  TimeoutInitial = PcdGet16 (PcdPlatformBootTimeOut);
+
+  //
+  // If PcdPlatformBootTimeOut is set to zero, then we consider  // 
+ that no progress update should be enacted.
+  //
+  if (TimeoutInitial == 0) {
+    return;
+  }
+
+  Black.Raw = 0x00000000;
+  White.Raw = 0x00FFFFFF;
+
+  BootLogoUpdateProgress (
+    White.Pixel,
+    Black.Pixel,
+    L"Start boot option",
+    White.Pixel,
+    (TimeoutInitial - TimeoutRemain) * 100 / TimeoutInitial,
+    0
+    );
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to 
+applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Key;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootManagerMenu;
+  UINTN                         Index;
+
+  //
+  // BootManagerMenu doesn't contain the correct information when 
+ return status  // is EFI_NOT_FOUND.
+  //
+  Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);  if 
+ (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Normally BdsDxe does not print anything to the system console, but 
+ this is  // a last resort -- the end-user will likely not see any 
+ DEBUG messages  // logged in this situation.
+  //
+  // AsciiPrint() will NULL-check gST->ConOut internally. We check 
+ gST->ConIn  // here to see if it makes sense to request and wait for a keypress.
+  //
+  if (gST->ConIn != NULL) {
+    AsciiPrint (
+      "%a: No bootable option or device was found.\n"
+      "%a: Press any key to enter the Boot Manager Menu.\n",
+      gEfiCallerBaseName,
+      gEfiCallerBaseName
+      );
+    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
+    ASSERT_EFI_ERROR (Status);
+    ASSERT (Index == 0);
+
+    //
+    // Drain any queued keys.
+    //
+    while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {
+      //
+      // just throw away Key
+      //
+    }
+  }
+
+  for ( ; ;) {
+    EfiBootManagerBoot (&BootManagerMenu);
+  }
+}
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c
new file mode 100644
index 000000000000..736628174f4e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c
@@ -0,0 +1,77 @@
+/** @file
+  Try to load an EFI-stubbed RISC-V Linux kernel from QEMU's fw_cfg.
+
+  This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI  
+ stub in the subject kernel is a hard requirement here.
+
+  Copyright (C) 2014-2016, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Library/QemuLoadImageLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+#include "PlatformBm.h"
+
+//
+// The entry point of the feature.
+//
+
+/**
+  Download the kernel, the initial ramdisk, and the kernel command line 
+from
+  QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the 
+two
+  image files, and load and start the kernel from it.
+
+  The kernel will be instructed via its command line to load the initrd 
+ from  the same Simple FileSystem.
+
+  @retval EFI_NOT_FOUND         Kernel image was not found.
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+  @retval EFI_PROTOCOL_ERROR    Unterminated kernel command line.
+
+  @return                       Error codes from any of the underlying
+                                functions. On success, the function doesn't
+                                return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  KernelImageHandle;
+
+  Status = QemuLoadKernelImage (&KernelImageHandle);  if (EFI_ERROR 
+ (Status)) {
+    return Status;
+  }
+
+  //
+  // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event.
+  //
+  EfiSignalEventReadyToBoot ();
+
+  REPORT_STATUS_CODE (
+    EFI_PROGRESS_CODE,
+    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)
+    );
+
+  //
+  // Start the image.
+  //
+  Status = QemuStartKernelImage (&KernelImageHandle);  if (EFI_ERROR 
+ (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: QemuStartKernelImage(): %r\n",
+      __FUNCTION__,
+      Status
+      ));
+  }
+
+  QemuUnloadKernelImage (KernelImageHandle);
+
+  return Status;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library Sunil V L
@ 2023-02-06 16:01   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:01 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library

Add the PrePiHobListPointerLib required for RISC-V Qemu Virt machine since it follows PEIless design.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf | 23 +++++++
 OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c      | 65 ++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
new file mode 100644
index 000000000000..c539682e8d0b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPoint
+++ erLib.inf
@@ -0,0 +1,23 @@
+#/** @file
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> #  
+SPDX-License-Identifier: BSD-2-Clause-Patent # #**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PrePiHobListPointerLib
+  FILE_GUID                      = E3FAFC60-758C-471B-A333-FE704A4C11B4
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PrePiHobListPointerLib
+
+[Sources.RISCV64]
+  PrePiHobListPointer.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
new file mode 100644
index 000000000000..a58b7aae6bee
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPoint
+++ er.c
@@ -0,0 +1,65 @@
+/** @file
+*
+*  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+/**
+  Returns the pointer to the HOB list.
+
+  This function returns the pointer to first HOB in the list.
+
+  @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+PrePeiGetHobList (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return NULL;
+  }
+
+  return (VOID *)FirmwareContext->PrePiHobList; }
+
+/**
+  Updates the pointer to the HOB list.
+
+  @param  HobList       Hob list pointer to store
+
+**/
+EFI_STATUS
+EFIAPI
+PrePeiSetHobList (
+  IN  VOID  *HobList
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_NOT_READY;
+  }
+
+  FirmwareContext->PrePiHobList = HobList;
+  return EFI_SUCCESS;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library Sunil V L
@ 2023-02-06 16:01   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:01 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library

RISC-V Qemu virt uses SBI calls to implement the reset.
Add the base class library.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf |  38 ++++++
 OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c       | 128 ++++++++++++++++++++
 2 files changed, 166 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
new file mode 100644
index 000000000000..c3fa6bd99b52
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
@@ -0,0 +1,38 @@
+## @file
+#  Base library instance for ResetSystem library class for RISC-V # #  
+Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR> 
+# #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseResetSystemLib
+  FILE_GUID                      = AB45A200-769D-4C10-B0D6-5E1FF5EEBF31
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+
+#
+# The following information is for reference only and not required by 
+the build # tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  ResetSystemLib.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  TimerLib
+  RiscVSbiLib
diff --git a/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 000000000000..14f7653aa8de
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,128 @@
+/** @file
+  Reset System Library functions for RISC-V
+
+  Copyright (c) 2021, Hewlett Packard Development LP. All rights 
+ reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+
+/**
+  This function causes a system-wide reset (cold reset), in which
+  all circuitry within the system returns to its initial state. This 
+type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  If this function returns, it means that the system does not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  // Warm Reset via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_COLD_REBOOT, 
+SBI_SRST_RESET_REASON_NONE); }
+
+/**
+  This function causes a system-wide initialization (warm reset), in 
+which all processors
+  are set to their initial state. Pending cycles are not corrupted.
+
+  If this function returns, it means that the system does not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  // Warm Reset via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_WARM_REBOOT, 
+SBI_SRST_RESET_REASON_NONE); }
+
+/**
+  This function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  If this function returns, it means that the system does not support shutdown reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  // Shut down via SBI ecall
+  SbiSystemReset (SBI_SRST_RESET_TYPE_SHUTDOWN, 
+SBI_SRST_RESET_REASON_NONE); }
+
+/**
+  This function causes a systemwide reset. The exact type of the reset 
+is
+  defined by the EFI_GUID that follows the Null-terminated Unicode 
+string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in 
+ResetData
+  the platform must pick a supported reset type to perform. The 
+platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN  DataSize,
+  IN VOID   *ResetData
+  )
+{
+  //
+  // Can map to OpenSBI vendor or platform specific reset type.
+  //
+  return;
+}
+
+/**
+  The ResetSystem function resets the entire platform.
+
+  @param[in] ResetType      The type of reset to perform.
+  @param[in] ResetStatus    The status code for the reset.
+  @param[in] DataSize       The size, in bytes, of ResetData.
+  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+                            the data buffer starts with a Null-terminated string, optionally
+                            followed by additional binary data. The string is a description
+                            that the caller may use to further indicate the reason for the
+                            system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+  IN EFI_RESET_TYPE  ResetType,
+  IN EFI_STATUS      ResetStatus,
+  IN UINTN           DataSize,
+  IN VOID            *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+    case EfiResetWarm:
+      ResetWarm ();
+      break;
+
+    case EfiResetCold:
+      ResetCold ();
+      break;
+
+    case EfiResetShutdown:
+      ResetShutdown ();
+      return;
+
+    case EfiResetPlatformSpecific:
+      ResetPlatformSpecific (DataSize, ResetData);
+      return;
+
+    default:
+      return;
+  }
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library Sunil V L
@ 2023-02-06 16:02   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:02 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library

Qemu NOR flash driver needs this library. Add this library for RISC-V leveraged from SbsaQemu.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf | 30 +++++++++++++++
 OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c   | 40 ++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
new file mode 100644
index 000000000000..4e87bd437380
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStat
+++ icLib.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+#  Component description file for VirtNorFlashStaticLib module # #  
+Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> # #  
+SPDX-License-Identifier: BSD-2-Clause-Patent # #**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = VirtNorFlashStaticLib
+  FILE_GUID                      = 064742F1-E531-4D7D-A154-22315889CC23
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = VirtNorFlashPlatformLib
+
+[Sources.common]
+  VirtNorFlashStaticLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
diff --git a/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.c
new file mode 100644
index 000000000000..fdc2ccb6294e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStat
+++ icLib.c
@@ -0,0 +1,40 @@
+/** @file
+
+ Copyright (c) 2019, Linaro Ltd. All rights reserved
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <Base.h>
+#include <PiDxe.h>
+#include <Library/VirtNorFlashPlatformLib.h>
+
+#define QEMU_NOR_BLOCK_SIZE  SIZE_256KB
+
+EFI_STATUS
+VirtNorFlashPlatformInitialization (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+VIRT_NOR_FLASH_DESCRIPTION  mNorFlashDevice = {
+  FixedPcdGet32 (PcdOvmfFdBaseAddress),
+  FixedPcdGet64 (PcdFlashNvStorageVariableBase),
+  FixedPcdGet32 (PcdOvmfFirmwareFdSize),
+  QEMU_NOR_BLOCK_SIZE
+};
+
+EFI_STATUS
+VirtNorFlashPlatformGetDevices (
+  OUT VIRT_NOR_FLASH_DESCRIPTION  **NorFlashDescriptions,
+  OUT UINT32                      *Count
+  )
+{
+  *NorFlashDescriptions = &mNorFlashDevice;
+  *Count                = 1;
+  return EFI_SUCCESS;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Sunil V L
  2023-01-30 10:12   ` [edk2-devel] " dhaval
@ 2023-02-06 16:02   ` Andrei Warkentin
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:02 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module

Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL to add the translation for IO access. This is copied from ArmPciCpuIo2Dxe driver.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf |  48 ++
 OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c   | 557 ++++++++++++++++++++
 2 files changed, 605 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
new file mode 100644
index 000000000000..4f78cfa4067b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
@@ -0,0 +1,48 @@
+## @file
+#  Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights 
+reserved.<BR> # Copyright (c) 2016, Linaro Ltd. All rights 
+reserved.<BR> # Copyright (c) 2022, Ventana Micro Systems Inc. All 
+rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # 
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciCpuIo2Dxe
+  FILE_GUID                      = 9BD3C765-2579-4CF0-9349-D77205565030
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PciCpuIo2Initialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  PciCpuIo2Dxe.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiBootServicesTableLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid                         ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c
new file mode 100644
index 000000000000..f3bf07e63141
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c
@@ -0,0 +1,557 @@
+/** @file
+  Produces the CPU I/O 2 Protocol.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 
+Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR> Copyright (c) 
+2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Protocol/CpuIo2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define MAX_IO_PORT_ADDRESS  0xFFFF
+
+//
+// Handle for the CPU I/O 2 Protocol
+//
+STATIC EFI_HANDLE  mHandle = NULL;
+
+//
+// Lookup table for increment values based on transfer widths // STATIC 
+CONST UINT8  mInStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  0, // EfiCpuIoWidthFifoUint8
+  0, // EfiCpuIoWidthFifoUint16
+  0, // EfiCpuIoWidthFifoUint32
+  0, // EfiCpuIoWidthFifoUint64
+  1, // EfiCpuIoWidthFillUint8
+  2, // EfiCpuIoWidthFillUint16
+  4, // EfiCpuIoWidthFillUint32
+  8  // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths // STATIC 
+CONST UINT8  mOutStride[] = {
+  1, // EfiCpuIoWidthUint8
+  2, // EfiCpuIoWidthUint16
+  4, // EfiCpuIoWidthUint32
+  8, // EfiCpuIoWidthUint64
+  1, // EfiCpuIoWidthFifoUint8
+  2, // EfiCpuIoWidthFifoUint16
+  4, // EfiCpuIoWidthFifoUint32
+  8, // EfiCpuIoWidthFifoUint64
+  0, // EfiCpuIoWidthFillUint8
+  0, // EfiCpuIoWidthFillUint16
+  0, // EfiCpuIoWidthFillUint32
+  0  // EfiCpuIoWidthFillUint64
+};
+
+/**
+  Check parameters to a CPU I/O 2 Protocol service request.
+
+  The I/O operations are carried out exactly as requested. The caller 
+ is responsible  for satisfying any alignment and I/O width 
+ restrictions that a PI System on a  platform might require. For 
+ example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other 
+ hand, will  be handled by the driver.
+
+  @param[in] MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+  @param[in] Address        The base address of the I/O operation.
+  @param[in] Count          The number of I/O operations to perform. The number of
+                            bytes moved is Width size * Count, starting at Address.
+  @param[in] Buffer         For read operations, the destination buffer to store the results.
+                            For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+CpuIoCheckParameter (
+  IN BOOLEAN                    MmioOperation,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  UINT64  MaxCount;
+  UINT64  Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range  //  if ((UINT32)Width 
+ >= EfiCpuIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the 
+ access,  // so treat Count as 1  //  if ((Width >= 
+ EfiCpuIoWidthFifoUint8) && (Width <= EfiCpuIoWidthFifoUint64)) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port 
+ operations  //  Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);  if 
+ (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Address is aligned  //  if ((Address & 
+ (UINT64)(mInStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check to see if any address associated with this transfer exceeds 
+ the maximum  // allowed address.  The maximum address implied by the 
+ parameters passed in is  // Address + Size * Count.  If the following 
+ condition is met, then the transfer  // is not supported.
+  //
+  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+  //
+  // Since MAX_ADDRESS can be the maximum integer value supported by 
+ the CPU and Count  // can also be the maximum integer value supported 
+ by the CPU, this range  // check must be adjusted to avoid all overflow conditions.
+  //
+  // The following form of the range check is equivalent but assumes 
+ that  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+  //
+  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);  if 
+ (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check to see if Buffer is aligned
+  //
+  if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width])  - 1))) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller 
+ is responsible  for satisfying any alignment and I/O width 
+ restrictions that a PI System on a  platform might require. For 
+ example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other 
+ hand, will  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 
+ EfiCpuIoWidthUint32,  or EfiCpuIoWidthUint64, then both Address and 
+ Buffer are incremented for  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,  
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,  
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);  
+ if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);  for 
+ (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested. The caller 
+ is responsible  for satisfying any alignment and I/O width 
+ restrictions that a PI System on a  platform might require. For 
+ example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other 
+ hand, will  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 
+ EfiCpuIoWidthUint32,  or EfiCpuIoWidthUint64, then both Address and 
+ Buffer are incremented for  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,  
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,  
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);  
+ if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);  for 
+ (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller 
+ is responsible  for satisfying any alignment and I/O width 
+ restrictions that a PI System on a  platform might require. For 
+ example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other 
+ hand, will  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 
+ EfiCpuIoWidthUint32,  or EfiCpuIoWidthUint64, then both Address and 
+ Buffer are incremented for  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,  
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,  
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[out] Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+  IN  EFI_CPU_IO2_PROTOCOL       *This,
+  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                     Address,
+  IN  UINTN                      Count,
+  OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);  
+ if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Address += PcdGet64 (PcdPciIoTranslation);
+
+  //
+  // Select loop based on the width of the transfer  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write I/O registers.
+
+  The I/O operations are carried out exactly as requested. The caller 
+ is responsible  for satisfying any alignment and I/O width 
+ restrictions that a PI System on a  platform might require. For 
+ example on some platforms, width requests of
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other 
+ hand, will  be handled by the driver.
+
+  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 
+ EfiCpuIoWidthUint32,  or EfiCpuIoWidthUint64, then both Address and 
+ Buffer are incremented for  each of the Count operations that is performed.
+
+  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,  
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times on the same Address.
+
+  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,  
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address 
+ is  incremented for each of the Count operations that is performed. 
+ The read or  write operation is performed Count times from the first element of Buffer.
+
+  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O or Memory operation.
+  @param[in]  Address  The base address of the I/O operation.
+  @param[in]  Count    The number of I/O operations to perform. The number of
+                       bytes moved is Width size * Count, starting at Address.
+  @param[in]  Buffer   For read operations, the destination buffer to store the results.
+                       For write operations, the source buffer from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PI system.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+  IN EFI_CPU_IO2_PROTOCOL       *This,
+  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                     Address,
+  IN UINTN                      Count,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      InStride;
+  UINT8                      OutStride;
+  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
+  UINT8                      *Uint8Buffer;
+
+  //
+  // Make sure the parameters are valid  //  Status = 
+ CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);  if 
+ (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Address += PcdGet64 (PcdPciIoTranslation);
+
+  //
+  // Select loop based on the width of the transfer  //
+  InStride       = mInStride[Width];
+  OutStride      = mOutStride[Width];
+  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (OperationWidth == EfiCpuIoWidthUint8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (OperationWidth == EfiCpuIoWidthUint16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (OperationWidth == EfiCpuIoWidthUint32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// CPU I/O 2 Protocol instance
+//
+STATIC EFI_CPU_IO2_PROTOCOL  mCpuIo2 = {
+  {
+    CpuMemoryServiceRead,
+    CpuMemoryServiceWrite
+  },
+  {
+    CpuIoServiceRead,
+    CpuIoServiceWrite
+  }
+};
+
+/**
+  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCpuIo2Initialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);  
+ Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mHandle,
+                  &gEfiCpuIo2ProtocolGuid,
+                  &mCpuIo2,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module Sunil V L
  2023-01-30  5:17   ` [edk2-devel] " dhaval
@ 2023-02-06 16:03   ` Andrei Warkentin
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:03 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module

Add the SEC module for RISC-V Qemu virt machine support.
It uses the PEI less design.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/Sec/SecMain.inf |  66 +++++
 OvmfPkg/RiscVVirt/Sec/SecMain.h   | 102 ++++++++
 OvmfPkg/RiscVVirt/Sec/Cpu.c       |  33 +++
 OvmfPkg/RiscVVirt/Sec/Memory.c    | 263 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/Sec/Platform.c  |  84 +++++++
 OvmfPkg/RiscVVirt/Sec/SecMain.c   | 104 ++++++++
 OvmfPkg/RiscVVirt/Sec/SecEntry.S  |  21 ++
 7 files changed, 673 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.inf b/OvmfPkg/RiscVVirt/Sec/SecMain.inf
new file mode 100644
index 000000000000..aed35d3af596
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.inf
@@ -0,0 +1,66 @@
+## @file
+#  SEC Driver for RISC-V
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
+reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SecMainRiscV64
+  FILE_GUID                      = 16740C0A-AA84-4F62-A06D-AE328057AE07
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  SecEntry.S
+  SecMain.c
+  SecMain.h
+  Cpu.c
+  Memory.c
+  Platform.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  PcdLib
+  IoLib
+  PeCoffLib
+  LzmaDecompressLib
+  RiscVSbiLib
+  PrePiLib
+  FdtLib
+  MemoryAllocationLib
+  HobLib
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
+  gEfiTemporaryRamDonePpiGuid                   ## PRODUCES
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+
+[Guids]
+  gFdtHobGuid
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.h b/OvmfPkg/RiscVVirt/Sec/SecMain.h new file mode 100644 index 000000000000..83a8058efe40
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.h
@@ -0,0 +1,102 @@
+/** @file
+  Master header file for SecCore.
+
+  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
+ reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SEC_MAIN_H_
+#define SEC_MAIN_H_
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffExtraActionLib.h> #include 
+<Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PlatformInitLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+  @param SizeOfRam           Size of the temporary memory available for use.
+  @param TempRamBase         Base address of temporary ram
+  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartup (
+  IN  UINTN  BootHartId,
+  IN  VOID   *DeviceTreeAddress
+  );
+
+/**
+  Auto-generated function that calls the library constructors for all 
+of the module's
+  dependent libraries.  This function must be called by the SEC Core 
+once a stack has
+  been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+  VOID
+  );
+
+/**
+  Perform Platform PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPeimInitialization (
+  VOID
+  );
+
+/**
+  Perform Memory PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryPeimInitialization (
+  VOID
+  );
+
+/**
+  Perform CPU PEIM initialization.
+
+  @return EFI_SUCCESS     The platform initialized successfully.
+  @retval  Others        - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+CpuPeimInitialization (
+  VOID
+  );
+
+#endif
diff --git a/OvmfPkg/RiscVVirt/Sec/Cpu.c b/OvmfPkg/RiscVVirt/Sec/Cpu.c new file mode 100644 index 000000000000..2c16df697e37
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Cpu.c
@@ -0,0 +1,33 @@
+/** @file
+The library call to pass the device tree to DXE via HOB.
+
+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 <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+/**
+  Cpu Peim initialization.
+
+**/
+EFI_STATUS
+CpuPeimInitialization (
+  VOID
+  )
+{
+  //
+  // for MMU type >= sv39
+  //
+  BuildCpuHob (56, 32);
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Sec/Memory.c new file mode 100644 index 000000000000..70935b07b56b
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Memory.c
@@ -0,0 +1,263 @@
+/** @file
+  Memory Detection for Virtual Machines.
+
+  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All 
+ rights reserved.<BR>  Copyright (c) 2006 - 2014, Intel Corporation. 
+ All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses // #include 
+<PiPei.h>
+
+//
+// The Library classes this module consumes // #include 
+<Library/BaseMemoryLib.h> #include <Library/DebugLib.h> #include 
+<Library/HobLib.h> #include <Library/IoLib.h> #include 
+<Library/PcdLib.h> #include <Library/PeimEntryPoint.h> #include 
+<Library/ResourcePublicationLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Register/RiscV64/RiscVEncoding.h>
+#include <Library/PrePiLib.h>
+#include <libfdt.h>
+#include <Guid/FdtHob.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+/**
+  Build reserved memory range resource HOB.
+
+  @param  MemoryBase     Reserved memory range base address.
+  @param  MemorySize     Reserved memory range size.
+
+**/
+STATIC
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+/**
+  Create memory range resource HOB using the memory base
+  address and size.
+
+  @param  MemoryBase     Memory range base address.
+  @param  MemorySize     Memory range size.
+
+**/
+STATIC
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+/**
+  Create memory range resource HOB using memory base
+  address and top address of the memory range.
+
+  @param  MemoryBase     Memory range base address.
+  @param  MemoryLimit    Memory range size.
+
+**/
+STATIC
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS  MemoryBase,
+  EFI_PHYSICAL_ADDRESS  MemoryLimit
+  )
+{
+  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - 
+MemoryBase)); }
+
+/**
+  Configure MMU
+**/
+STATIC
+VOID
+InitMmu (
+  )
+{
+  //
+  // Set supervisor translation mode to Bare mode
+  //
+  RiscVSetSupervisorAddressTranslationRegister ((UINT64)SATP_MODE_OFF 
+<< 60);
+  DEBUG ((DEBUG_INFO, "%a: Set Supervisor address mode to bare-metal 
+mode.\n", __FUNCTION__)); }
+
+/**
+  Publish system RAM and reserve memory regions.
+
+**/
+STATIC
+VOID
+InitializeRamRegions (
+  EFI_PHYSICAL_ADDRESS  SystemMemoryBase,
+  UINT64                SystemMemorySize,
+  EFI_PHYSICAL_ADDRESS  MmodeResvBase,
+  UINT64                MmodeResvSize
+  )
+{
+  /*
+   * M-mode FW can be loaded anywhere in memory but should not overlap
+   * with the EDK2. This can happen if some other boot code loads the
+   * M-mode firmware.
+   *
+   * The M-mode firmware memory should be marked as reserved memory
+   * so that OS doesn't use it.
+   */
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: M-mode FW Memory Start:0x%lx End:0x%lx\n",
+    __FUNCTION__,
+    MmodeResvBase,
+    MmodeResvBase + MmodeResvSize
+    ));
+  AddReservedMemoryBaseSizeHob (MmodeResvBase, MmodeResvSize);
+
+  if (MmodeResvBase > SystemMemoryBase) {
+    AddMemoryRangeHob (SystemMemoryBase, MmodeResvBase);  }
+
+  AddMemoryRangeHob (
+    MmodeResvBase + MmodeResvSize,
+    SystemMemoryBase + SystemMemorySize
+    );
+}
+
+/**
+  Initialize memory hob based on the DTB information.
+
+  @return EFI_SUCCESS     The memory hob added successfully.
+
+**/
+EFI_STATUS
+MemoryPeimInitialization (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+  CONST UINT64                *RegProp;
+  CONST CHAR8                 *Type;
+  UINT64                      CurBase, CurSize;
+  INT32                       Node, Prev;
+  INT32                       Len;
+  VOID                        *FdtPointer;
+  EFI_PHYSICAL_ADDRESS        MmodeResvBase;
+  UINT64                      MmodeResvSize;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
+  if (FdtPointer == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  /* try to locate the reserved memory opensbi node */  Node = 
+ fdt_path_offset (FdtPointer, "/reserved-memory/mmode_resv0");  if 
+ (Node >= 0) {
+    RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);
+    if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
+      MmodeResvBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+      MmodeResvSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+    }
+  }
+
+  // Look for the lowest memory node
+  for (Prev = 0; ; Prev = Node) {
+    Node = fdt_next_node (FdtPointer, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    // Check for memory node
+    Type = fdt_getprop (FdtPointer, Node, "device_type", &Len);
+    if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
+      // Get the 'reg' property of this node. For now, we will assume
+      // two 8 byte quantities for base and size, respectively.
+      RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);
+      if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
+        CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+        CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+
+        DEBUG ((
+          DEBUG_INFO,
+          "%a: System RAM @ 0x%lx - 0x%lx\n",
+          __FUNCTION__,
+          CurBase,
+          CurBase + CurSize - 1
+          ));
+
+        if ((MmodeResvBase >= CurBase) && ((MmodeResvBase + MmodeResvSize) <= (CurBase + CurSize))) {
+          InitializeRamRegions (
+            CurBase,
+            CurSize,
+            MmodeResvBase,
+            MmodeResvSize
+            );
+        } else {
+          AddMemoryBaseSizeHob (CurBase, CurSize);
+        }
+      } else {
+        DEBUG ((
+          DEBUG_ERROR,
+          "%a: Failed to parse FDT memory node\n",
+          __FUNCTION__
+          ));
+      }
+    }
+  }
+
+  InitMmu ();
+
+  BuildMemoryTypeInformationHob ();
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/Platform.c b/OvmfPkg/RiscVVirt/Sec/Platform.c
new file mode 100644
index 000000000000..e8fd126cf800
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/Platform.c
@@ -0,0 +1,84 @@
+/** @file
+The library call to pass the device tree to DXE via HOB.
+
+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 <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h> #include 
+<Library/BaseRiscVSbiLib.h> #include <Library/PcdLib.h> #include 
+<Include/Library/PrePiLib.h> #include <libfdt.h> #include 
+<Guid/FdtHob.h>
+
+/**
+  @retval EFI_SUCCESS            The address of FDT is passed in HOB.
+          EFI_UNSUPPORTED        Can't locate FDT.
+**/
+EFI_STATUS
+EFIAPI
+PlatformPeimInitialization (
+  VOID
+  )
+{
+  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
+  VOID                        *FdtPointer;
+  VOID                        *Base;
+  VOID                        *NewBase;
+  UINTN                       FdtSize;
+  UINTN                       FdtPages;
+  UINT64                      *FdtHobData;
+
+  FirmwareContext = NULL;
+  GetFirmwareContextPointer (&FirmwareContext);
+
+  if (FirmwareContext == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
+  if (FdtPointer == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a: Build FDT HOB - FDT at address: 0x%x \n", 
+ __FUNCTION__, FdtPointer));  Base = FdtPointer;  if (fdt_check_header 
+ (Base) != 0) {
+    DEBUG ((DEBUG_ERROR, "%a: Corrupted DTB\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  FdtSize  = fdt_totalsize (Base);
+  FdtPages = EFI_SIZE_TO_PAGES (FdtSize);  NewBase  = AllocatePages 
+ (FdtPages);  if (NewBase == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Could not allocate memory for DTB\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
+
+  FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);  if 
+ (FdtHobData == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Could not build FDT Hob\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  *FdtHobData = (UINTN)NewBase;
+
+  BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 
+ (PcdOvmfDxeMemFvSize));
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.c b/OvmfPkg/RiscVVirt/Sec/SecMain.c new file mode 100644 index 000000000000..054e49ef0c1e
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecMain.c
@@ -0,0 +1,104 @@
+/** @file
+  RISC-V SEC phase module for Qemu Virt.
+
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights 
+ reserved.<BR>  Copyright (c) 2022, Ventana Micro Systems Inc. All 
+ rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecMain.h"
+
+STATIC
+EFI_STATUS
+EFIAPI
+SecInitializePlatform (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  MemoryPeimInitialization ();
+
+  CpuPeimInitialization ();
+
+  // Set the Boot Mode
+  SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+
+  Status = PlatformPeimInitialization ();  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Entry point to the C language phase of SEC. After the SEC assembly  
+ code has initialized some temporary memory and set up the stack,  the 
+ control is transferred to this function.
+
+
+  @param[in]  BootHartId         Hardware thread ID of boot hart.
+  @param[in]  DeviceTreeAddress  Pointer to Device Tree (DTB) **/ VOID 
+NORETURN EFIAPI SecStartup (
+  IN  UINTN  BootHartId,
+  IN  VOID   *DeviceTreeAddress
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *HobList;
+  EFI_RISCV_FIRMWARE_CONTEXT  FirmwareContext;
+  EFI_STATUS                  Status;
+  UINT64                      UefiMemoryBase;
+  UINT64                      StackBase;
+
+  //
+  // Report Status Code to indicate entering SEC core  //  DEBUG ((
+    DEBUG_INFO,
+    "%a() BootHartId: 0x%x, DeviceTreeAddress=0x%x\n",
+    __FUNCTION__,
+    BootHartId,
+    DeviceTreeAddress
+    ));
+
+  FirmwareContext.BootHartId          = BootHartId;
+  FirmwareContext.FlattenedDeviceTree = (UINT64)DeviceTreeAddress;  
+ SetFirmwareContextPointer (&FirmwareContext);
+
+  StackBase      = (UINT64)FixedPcdGet32 (PcdOvmfSecPeiTempRamBase);
+  UefiMemoryBase = StackBase +  FixedPcdGet32 
+ (PcdOvmfSecPeiTempRamSize) - SIZE_32MB;
+
+  // Declare the PI/UEFI memory region
+  HobList = HobConstructor (
+              (VOID *)UefiMemoryBase,
+              SIZE_32MB,
+              (VOID *)UefiMemoryBase,
+              (VOID *)StackBase // The top of the UEFI Memory is reserved for the stacks
+              );
+  PrePeiSetHobList (HobList);
+
+  SecInitializePlatform ();
+
+  //
+  // Process all libraries constructor function linked to SecMain.
+  //
+  ProcessLibraryConstructorList ();
+
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+  Status = DecompressFirstFv ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Load the DXE Core and transfer control to it
+  Status = LoadDxeCoreFromFv (NULL, 0);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Should not come here.
+  //
+  UNREACHABLE ();
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecEntry.S b/OvmfPkg/RiscVVirt/Sec/SecEntry.S
new file mode 100644
index 000000000000..e919a3cb0e80
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/Sec/SecEntry.S
@@ -0,0 +1,21 @@
+/*
+  Copyright (c) 2022 Ventana Micro Systems Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ */
+
+#include "SecMain.h"
+
+.text
+.align 3
+
+ASM_FUNC (_ModuleEntryPoint)
+  /* Use Temp memory as the stack for calling to C code */
+  li    a4, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)
+  li    a5, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)
+
+  /* Use Temp memory as the stack for calling to C code */
+  add   sp, a4, a5
+
+  call SecStartup
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform Sunil V L
@ 2023-02-06 16:03   ` Andrei Warkentin
  0 siblings, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:03 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Ard Biesheuvel, Yao, Jiewen, Justen, Jordan L, Gerd Hoffmann,
	Abner Chang

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add infrastructure files to build edk2 for RISC-V qemu virt machine.

- It follows PEI less design.
- EDK2 for qemu virt is booted in S-mode as a payload for M-mode FW
- Leveraged from ArmVirtQemu

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
---
 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 336 +++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 509 ++++++++++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf | 306 ++++++++++++
 OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc |  41 ++
 OvmfPkg/RiscVVirt/VarStore.fdf.inc  |  79 +++
 5 files changed, 1271 insertions(+)

diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
new file mode 100644
index 000000000000..526da0f7e6e9
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
@@ -0,0 +1,336 @@
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+#  Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. All rights reserved.
+#  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+#  Copyright (c) Microsoft Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+[Defines]
+  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000047
+
+[LibraryClasses.common]
+!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
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+
+  #
+  # Ramdisk Requirements
+  #
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
+  # Allow dynamic PCDs
+  #
+
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  # Networking Requirements
+!include NetworkPkg/NetworkLibs.dsc.inc
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
+!endif
+
+
+  # Add support for GCC stack protector
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+  # RISC-V Architectural Libraries
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+  RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
+  PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  ResetSystemLib|OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
+
+  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
+
+  # Flattened Device Tree (FDT) access library
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+  # PCI Libraries
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
+  PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
+  PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
+  DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+
+  # USB Libraries
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  #
+  # CryptoPkg libraries needed by multiple firmware features
+  #
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!else
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+!endif
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
+  #
+  # Secure Boot dependencies
+  #
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
+
+  # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
+  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+!else
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+  VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+  PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+[PcdsFeatureFlag]
+  #
+  # Activate AcpiSdtProtocol
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(DEBUG_ON_SERIAL_PORT) != TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  #  DEBUG_INFO      0x00000040  // Informational debug messages
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNP Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // LoadFile
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                              // significantly impact boot performance
+  #  DEBUG_ERROR     0x80000000  // Error
+!if $(DEBUG_ON_SERIAL_PORT) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
+!endif
+
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragments for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|600
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1500
+!else
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|300
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|150
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1000
+!endif
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|6000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  #
+  # Enable strict image permissions for all images. (This applies
+  # only to images that were built with >= 4 KB section alignment.)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
+
+  #
+  # Enable NX memory protection for all non-code regions, including OEM and OS
+  # reserved ones, with the exception of LoaderData regions, of which OS loaders
+  # (i.e., GRUB) may assume that its contents are executable.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
+
+[Components.common]
+  #
+  # Ramdisk support
+  #
+  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  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
+!if $(ACPIVIEW_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+!endif
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+!endif
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+  #
+  # ACPI Support
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
+    <LibraryClasses>
+      NULL|EmbeddedPkg/Library/PlatformHasAcpiLib/PlatformHasAcpiLib.inf
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
new file mode 100644
index 000000000000..17fd64a1a8d4
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -0,0 +1,509 @@
+## @file
+#  RISC-V EFI on RiscVVirtQem platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. 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                  = RiscVVirtQemu
+  PLATFORM_GUID                  = 39DADB39-1B21-4867-838E-830B6149B9E0
+  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               = OvmfPkg/RiscVVirt/RiscVVirtQemu.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 TTY_TERMINAL            = FALSE
+  DEFINE SECURE_BOOT_ENABLE      = FALSE
+  DEFINE TPM2_ENABLE             = FALSE
+  DEFINE TPM2_CONFIG_ENABLE      = FALSE
+  DEFINE DEBUG_ON_SERIAL_PORT    = TRUE
+
+  #
+  # Network definition
+  #
+  DEFINE NETWORK_IP6_ENABLE             = FALSE
+  DEFINE NETWORK_HTTP_BOOT_ENABLE       = FALSE
+  DEFINE NETWORK_SNP_ENABLE             = FALSE
+  DEFINE NETWORK_TLS_ENABLE             = FALSE
+  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
+  DEFINE NETWORK_ISCSI_ENABLE           = FALSE
+
+!if $(NETWORK_SNP_ENABLE) == TRUE
+  !error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
+!endif
+
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  GCC:*_*_RISCV64_GENFW_FLAGS    = --keepexceptiontable
+!endif
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:  *_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+  MSFT: *_*_*_DLINK_FLAGS = /ALIGN:4096
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+!include NetworkPkg/NetworkDefines.dsc.inc
+
+!include OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses.common]
+  # Virtio Support
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
+  VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
+  QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
+  QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
+
+  TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
+  VirtNorFlashPlatformLib|OvmfPkg/RiscVVirt/Library/VirtNorFlashPlatformLib/VirtNorFlashStaticLib.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+  QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
+  PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
+  PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+
+!if $(TPM2_ENABLE) == TRUE
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf
+!endif
+
+[LibraryClasses.common.DXE_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
+
+!if $(TPM2_ENABLE) == TRUE
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
+
+#!include NetworkPkg/NetworkBuildOptions.dsc.inc
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag.common]
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|TRUE
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  #
+  # The cumulative and individual VOLATILE variable size limits should be set
+  # high enough for accommodating several and/or large CA certificates.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+!endif
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"2.7"
+
+  # Serial Port
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x10000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|9600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|3686400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1
+
+  #
+  # Network Pcds
+  #
+!include NetworkPkg/NetworkPcds.dsc.inc
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  #
+  # The maximum physical I/O addressability of the processor, set with
+  # BuildCpuHob().
+  #
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
+
+  #
+  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
+
+!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
+
+  gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x02
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
+
+[PcdsDynamicDefault.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
+  ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI
+  #  enumeration to complete before installing ACPI tables.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
+
+  # set PcdPciExpressBaseAddress to MAX_UINT64, which signifies that this
+  # PCD and PcdPciDisableBusEnumeration above have not been assigned yet
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xFFFFFFFFFFFFFFFF
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation|0x0
+
+  #
+  # Set video resolution for boot options and for text setup.
+  # PlatformDxe can set the former at runtime.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1280
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0
+
+  #
+  # SMBIOS entry point version
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0300
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+
+  #
+  # IPv4 and IPv6 PXE Boot support.
+  #
+  gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
+  gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+
+  #
+  # TPM2 support
+  #
+!if $(TPM2_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
+!else
+[PcdsPatchableInModule]
+  # make this PCD patchable instead of dynamic when TPM support is not enabled
+  # this permits setting the PCD in unreachable code without pulling in dynamic PCD support
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
+!endif
+
+[PcdsDynamicHii]
+  gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
+
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+
+[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
+!if $(TPM2_ENABLE) == TRUE
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+!else
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!endif
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+
+  #
+  # SEC Phase modules
+  #
+  OvmfPkg/RiscVVirt/Sec/SecMain.inf {
+    <LibraryClasses>
+      ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+      LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+      HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+      PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+      MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
+   <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  #
+  # Architectural Protocols
+  #
+  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  }
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!if $(TPM2_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+!else
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # Status Code Routing
+  #
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+  #
+  # Platform Driver
+  #
+  OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.inf
+  EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  }
+  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
+  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  }
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Logo/LogoDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
+  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierLibNull.inf
+  }
+
+  #
+  # Networking stack
+  #
+!include NetworkPkg/NetworkComponents.dsc.inc
+
+  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
+  }
+
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
+  }
+!endif
+
+  #
+  # SCSI Bus and Disk Driver
+  #
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  #
+  # NVME Driver
+  #
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+  }
+  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+  #
+  # PCI support
+  #
+  OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
+  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+  OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+  #
+  # Video support
+  #
+  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+  OvmfPkg/PlatformDxe/Platform.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
+
+  #
+  # TPM2 support
+  #
+!if $(TPM2_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
+    <LibraryClasses>
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+  }
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+  #
+  # ACPI Support
+  #
+  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
new file mode 100644
index 000000000000..3c6e1819d9e9
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
@@ -0,0 +1,306 @@
+# @file
+#  Flash definition file on RiscVVirt RISC-V platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Platform definitions
+#
+
+!include RiscVVirt.fdf.inc
+
+################################################################################
+[FD.RISCV_VIRT]
+BaseAddress   = $(FW_BASE_ADDRESS)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size          = $(FW_SIZE)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(FW_BLOCKS)
+
+0x00000000|$(CODE_SIZE)
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+FV = FVMAIN_COMPACT
+
+!include VarStore.fdf.inc
+################################################################################
+
+[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
+
+#
+# DXE Phase modules
+#
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.inf
+INF  EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf
+INF  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
+
+#
+# PI DXE Drivers producing Architectural Protocols (EFI Services)
+#
+INF  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.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/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+INF  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+#
+# Multiple Console IO support
+#
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+# RISC-V Core Drivers
+INF  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
+INF  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+#
+# FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs
+#
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+INF  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+
+#
+# Status Code Routing
+#
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+#
+# Platform Driver
+#
+INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+INF  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+INF  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+INF  ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
+INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
+
+#
+# Bds
+#
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Application/UiApp/UiApp.inf
+INF  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+
+#
+# Networking stack
+#
+!include NetworkPkg/Network.fdf.inc
+
+#
+# SCSI Bus and Disk Driver
+#
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+#
+# NVME Driver
+#
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+#
+# SMBIOS Support
+#
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+#
+# ACPI Support
+#
+INF  OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+#
+# PCI support
+#
+INF  OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+INF  OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+#
+# Video support
+#
+INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+INF  OvmfPkg/PlatformDxe/Platform.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
+
+#
+# TianoCore logo (splash screen)
+#
+INF  MdeModulePkg/Logo/LogoDxe.inf
+
+#
+# Ramdisk support
+#
+INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+
+#INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.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
+
+INF OvmfPkg/RiscVVirt/Sec/SecMain.inf
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+     SECTION FV_IMAGE = DXEFV
+   }
+ }
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32     PE32   Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32     PE32   Align=4K         $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32   Align = 4K    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32  Align=4K  $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32   Align=4K   |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32     PE32   Align=4K   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32  Align=4K  |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc
new file mode 100644
index 000000000000..b0a1c3293f33
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc
@@ -0,0 +1,41 @@
+## @file
+#  Definitions of Flash definition file on RiscVVirt RISC-V platform
+#
+#  Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+DEFINE BLOCK_SIZE                  = 0x1000
+
+DEFINE PFLASH1_BASE                = 0x22000000
+
+DEFINE FW_BASE_ADDRESS             = $(PFLASH1_BASE)
+DEFINE FW_SIZE                     = 0x00800000
+DEFINE FW_BLOCKS                   = 0x800
+
+DEFINE CODE_BASE_ADDRESS           = $(FW_BASE_ADDRESS)
+DEFINE CODE_SIZE                   = 0x00740000
+DEFINE CODE_BLOCKS                 = 0x740
+
+DEFINE VARS_SIZE                    = 0x000C0000
+DEFINE VARS_BLOCK_SIZE              = 0x40000
+DEFINE VARS_BLOCKS                  = 0x3
+
+#
+# EFI Variable memory region.
+# The total size of EFI Variable FD must include
+# all of sub regions of EFI Variable
+#
+DEFINE VARS_OFFSET                   = $(CODE_SIZE)
+DEFINE VARS_LIVE_SIZE                = 0x00040000
+DEFINE VARS_FTW_WORKING_OFFSET       = $(VARS_OFFSET) + $(VARS_LIVE_SIZE)
+DEFINE VARS_FTW_WORKING_SIZE         = 0x00040000
+DEFINE VARS_FTW_SPARE_OFFSET         = $(VARS_FTW_WORKING_OFFSET) + $(VARS_FTW_WORKING_SIZE)
+DEFINE VARS_FTW_SPARE_SIZE           = 0x00040000
+
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency = 10000000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase = 0x83FF0000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize = 0x00010000
diff --git a/OvmfPkg/RiscVVirt/VarStore.fdf.inc b/OvmfPkg/RiscVVirt/VarStore.fdf.inc
new file mode 100644
index 000000000000..30b170d77997
--- /dev/null
+++ b/OvmfPkg/RiscVVirt/VarStore.fdf.inc
@@ -0,0 +1,79 @@
+## @file
+#  FDF include file with Layout Regions that define an empty variable store.
+#
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+#  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_LIVE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|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: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3FFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xFF, 0x03, 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)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|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)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#
+#NV_FTW_SPARE
-- 
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt Sunil V L
@ 2023-02-06 16:04   ` Andrei Warkentin
  2023-02-09  1:51   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Andrei Warkentin @ 2023-02-06 16:04 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Andrew Fish, Leif Lindholm, Kinney, Michael D

Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@apple.com>; Leif Lindholm <quic_llindhol@quicinc.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

RiscVVirt is created to support EDK2 for RISC-V qemu virt machine platform. Add maintainer entries.

Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 Maintainers.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt index 68f603b48398..fdb27c39b152 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -539,6 +539,10 @@ F: OvmfPkg/XenResetVector/
 R: Anthony Perard <anthony.perard@citrix.com> [tperard]
 R: Julien Grall <julien@xen.org> [jgrall]
 
+OvmfPkg: RISC-V Qemu Virt Platform
+F: OvmfPkg/RiscVVirt
+R: Sunil V L <sunilvl@ventanamicro.com> [vlsunil]
+
 PcAtChipsetPkg
 F: PcAtChipsetPkg/
 W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
--
2.38.0







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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
  2023-02-06 15:58   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-08  5:05     ` Sunil V L
  2023-02-09  5:43       ` Ni, Ray
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-02-08  5:05 UTC (permalink / raw)
  To: Warkentin, Andrei
  Cc: devel@edk2.groups.io, Dong, Eric, Ni, Ray, Kumar, Rahul R,
	Daniel Schaefer, Gerd Hoffmann, Abner Chang

Thanks!, Andrei.

Hi Ray,

These changes are done as per your recommendation in
https://edk2.groups.io/g/devel/message/97106

Could you please help reviewing UefiCpuPkg patches? RISC-V community is
waiting for this support for a long time now. If we get these merged
in early days after the current stable release, I think it allows us to
have sufficient time before next stable release.

Thanks!
Sunil

On Mon, Feb 06, 2023 at 03:58:13PM +0000, Warkentin, Andrei wrote:
> Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
> 
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Saturday, January 28, 2023 1:18 PM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This is copied from
> edk2-platforms/Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dsc           |   1 +
>  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf |  68 ++++  UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h  | 199 +++++++++++  UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c  | 365 ++++++++++++++++++++
>  4 files changed, 633 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 251a8213f022..8f2be6cd1b05 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -198,6 +198,7 @@ [Components.X64]
>  [Components.RISCV64]
>    UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
>    UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
> +  UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
>  
>  [BuildOptions]
>    *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
> new file mode 100644
> index 000000000000..5e590d03754f
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
> @@ -0,0 +1,68 @@
> +## @file
> +#  RISC-V CPU DXE module.
> +#
> +#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights 
> +reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = CpuDxeRiscV64
> +  MODULE_UNI_FILE                = CpuDxe.uni
> +  FILE_GUID                      = BDEA19E2-778F-473C-BF82-5E38D6A27765
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeCpu
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  CpuLib
> +  DebugLib
> +  DxeServicesTableLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  CpuExceptionHandlerLib
> +  HobLib
> +  ReportStatusCodeLib
> +  TimerLib
> +  PeCoffGetEntryPointLib
> +  RiscVSbiLib
> +
> +[Sources]
> +  RiscV64/CpuDxe.c
> +  RiscV64/CpuDxe.h
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid                       ## PRODUCES
> +  gRiscVEfiBootProtocolGuid                     ## PRODUCES
> +
> +[Guids]
> +  gIdleLoopEventGuid                            ## CONSUMES           ## Event
> +
> +[Ppis]
> +  gEfiSecPlatformInformation2PpiGuid            ## UNDEFINED # HOB
> +  gEfiSecPlatformInformationPpiGuid             ## UNDEFINED # HOB
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## CONSUMES
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## CONSUMES
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency             ## CONSUMES
> +
> +[Depex]
> +  TRUE
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  CpuDxeExtra.uni
> diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
> new file mode 100644
> index 000000000000..49f4e119665a
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.h
> @@ -0,0 +1,199 @@
> +/** @file
> +  RISC-V CPU DXE module header file.
> +
> +  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
> + All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CPU_DXE_H_
> +#define CPU_DXE_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/RiscVBootProtocol.h> #include 
> +<Library/BaseRiscVSbiLib.h> #include <Library/BaseLib.h> #include 
> +<Library/CpuExceptionHandlerLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +
> +/**
> +  Flush CPU data cache. If the instruction cache is fully coherent
> +  with all DMA operations then function can just return EFI_SUCCESS.
> +
> +  @param  This              Protocol instance structure
> +  @param  Start             Physical address to start flushing from.
> +  @param  Length            Number of bytes to flush. Round up to chipset
> +                            granularity.
> +  @param  FlushType         Specifies the type of flush operation to perform.
> +
> +  @retval EFI_SUCCESS       If cache was flushed
> +  @retval EFI_UNSUPPORTED   If flush type is not supported.
> +  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuFlushCpuDataCache (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_PHYSICAL_ADDRESS   Start,
> +  IN UINT64                 Length,
> +  IN EFI_CPU_FLUSH_TYPE     FlushType
> +  );
> +
> +/**
> +  Enables CPU interrupts.
> +
> +  @param  This              Protocol instance structure
> +
> +  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
> +  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuEnableInterrupt (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This
> +  );
> +
> +/**
> +  Disables CPU interrupts.
> +
> +  @param  This              Protocol instance structure
> +
> +  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
> +  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuDisableInterrupt (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This
> +  );
> +
> +/**
> +  Return the state of interrupts.
> +
> +  @param  This                   Protocol instance structure
> +  @param  State                  Pointer to the CPU's current interrupt state
> +
> +  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
> +  @retval EFI_INVALID_PARAMETER  State is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuGetInterruptState (
> +  IN  EFI_CPU_ARCH_PROTOCOL  *This,
> +  OUT BOOLEAN                *State
> +  );
> +
> +/**
> +  Generates an INIT to the CPU.
> +
> +  @param  This              Protocol instance structure
> +  @param  InitType          Type of CPU INIT to perform
> +
> +  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
> +                            seen.
> +  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
> +  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuInit (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_CPU_INIT_TYPE      InitType
> +  );
> +
> +/**
> +  Registers a function to be called from the CPU interrupt handler.
> +
> +  @param  This                   Protocol instance structure
> +  @param  InterruptType          Defines which interrupt to hook. IA-32
> +                                 valid range is 0x00 through 0xFF
> +  @param  InterruptHandler       A pointer to a function of type
> +                                 EFI_CPU_INTERRUPT_HANDLER that is called
> +                                 when a processor interrupt occurs.  A null
> +                                 pointer is an error condition.
> +
> +  @retval EFI_SUCCESS            If handler installed or uninstalled.
> +  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
> +                                 for InterruptType was previously installed.
> +  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
> +                                 InterruptType was not previously installed.
> +  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
> +                                 is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuRegisterInterruptHandler (
> +  IN EFI_CPU_ARCH_PROTOCOL      *This,
> +  IN EFI_EXCEPTION_TYPE         InterruptType,
> +  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
> +  );
> +
> +/**
> +  Returns a timer value from one of the CPU's internal timers. There is 
> +no
> +  inherent time interval between ticks but is a function of the CPU frequency.
> +
> +  @param  This                - Protocol instance structure.
> +  @param  TimerIndex          - Specifies which CPU timer is requested.
> +  @param  TimerValue          - Pointer to the returned timer value.
> +  @param  TimerPeriod         - A pointer to the amount of time that passes
> +                                in femtoseconds (10-15) for each increment
> +                                of TimerValue. If TimerValue does not
> +                                increment at a predictable rate, then 0 is
> +                                returned.  The amount of time that has
> +                                passed between two calls to GetTimerValue()
> +                                can be calculated with the formula
> +                                (TimerValue2 - TimerValue1) * TimerPeriod.
> +                                This parameter is optional and may be NULL.
> +
> +  @retval EFI_SUCCESS           - If the CPU timer count was returned.
> +  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
> +  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
> +  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuGetTimerValue (
> +  IN  EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN  UINT32                 TimerIndex,
> +  OUT UINT64                 *TimerValue,
> +  OUT UINT64                 *TimerPeriod OPTIONAL
> +  );
> +
> +/**
> +  Set memory cacheability attributes for given range of memeory.
> +
> +  @param  This                   Protocol instance structure
> +  @param  BaseAddress            Specifies the start address of the
> +                                 memory range
> +  @param  Length                 Specifies the length of the memory range
> +  @param  Attributes             The memory cacheability for the memory range
> +
> +  @retval EFI_SUCCESS            If the cacheability of that memory range is
> +                                 set successfully
> +  @retval EFI_UNSUPPORTED        If the desired operation cannot be done
> +  @retval EFI_INVALID_PARAMETER  The input parameter is not correct,
> +                                 such as Length = 0
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuSetMemoryAttributes (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
> +  IN UINT64                 Length,
> +  IN UINT64                 Attributes
> +  );
> +
> +#endif
> diff --git a/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
> new file mode 100644
> index 000000000000..7551e0653603
> --- /dev/null
> +++ b/UefiCpuPkg/CpuDxe/RiscV64/CpuDxe.c
> @@ -0,0 +1,365 @@
> +/** @file
> +  RISC-V CPU DXE driver.
> +
> +  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
> + All rights reserved.<BR>  Copyright (c) 2022, Ventana Micro Systems 
> + Inc. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuDxe.h"
> +
> +//
> +// Global Variables
> +//
> +STATIC BOOLEAN           mInterruptState = FALSE;
> +STATIC EFI_HANDLE        mCpuHandle      = NULL;
> +STATIC UINTN             mBootHartId;
> +RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol;
> +
> +/**
> +  Get the boot hartid
> +
> +  @param  This                   Protocol instance structure
> +  @param  BootHartId             Pointer to the Boot Hart ID variable
> +
> +  @retval EFI_SUCCESS            If BootHartId is returned
> +  @retval EFI_INVALID_PARAMETER  Either "BootHartId" is NULL or "This" is not
> +                                 a valid RISCV_EFI_BOOT_PROTOCOL instance.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RiscvGetBootHartId (
> +  IN RISCV_EFI_BOOT_PROTOCOL  *This,
> +  OUT UINTN                   *BootHartId
> +  )
> +{
> +  if ((This != &gRiscvBootProtocol) || (BootHartId == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *BootHartId = mBootHartId;
> +  return EFI_SUCCESS;
> +}
> +
> +RISCV_EFI_BOOT_PROTOCOL  gRiscvBootProtocol = {
> +  RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION,
> +  RiscvGetBootHartId
> +};
> +
> +EFI_CPU_ARCH_PROTOCOL  gCpu = {
> +  CpuFlushCpuDataCache,
> +  CpuEnableInterrupt,
> +  CpuDisableInterrupt,
> +  CpuGetInterruptState,
> +  CpuInit,
> +  CpuRegisterInterruptHandler,
> +  CpuGetTimerValue,
> +  CpuSetMemoryAttributes,
> +  1,                          // NumberOfTimers
> +  4                           // DmaBufferAlignment
> +};
> +
> +//
> +// CPU Arch Protocol Functions
> +//
> +
> +/**
> +  Flush CPU data cache. If the instruction cache is fully coherent
> +  with all DMA operations then function can just return EFI_SUCCESS.
> +
> +  @param  This              Protocol instance structure
> +  @param  Start             Physical address to start flushing from.
> +  @param  Length            Number of bytes to flush. Round up to chipset
> +                            granularity.
> +  @param  FlushType         Specifies the type of flush operation to perform.
> +
> +  @retval EFI_SUCCESS       If cache was flushed
> +  @retval EFI_UNSUPPORTED   If flush type is not supported.
> +  @retval EFI_DEVICE_ERROR  If requested range could not be flushed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuFlushCpuDataCache (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_PHYSICAL_ADDRESS   Start,
> +  IN UINT64                 Length,
> +  IN EFI_CPU_FLUSH_TYPE     FlushType
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Enables CPU interrupts.
> +
> +  @param  This              Protocol instance structure
> +
> +  @retval EFI_SUCCESS       If interrupts were enabled in the CPU
> +  @retval EFI_DEVICE_ERROR  If interrupts could not be enabled on the CPU.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuEnableInterrupt (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This
> +  )
> +{
> +  EnableInterrupts ();
> +  mInterruptState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Disables CPU interrupts.
> +
> +  @param  This              Protocol instance structure
> +
> +  @retval EFI_SUCCESS       If interrupts were disabled in the CPU.
> +  @retval EFI_DEVICE_ERROR  If interrupts could not be disabled on the CPU.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuDisableInterrupt (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This
> +  )
> +{
> +  DisableInterrupts ();
> +  mInterruptState = FALSE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Return the state of interrupts.
> +
> +  @param  This                   Protocol instance structure
> +  @param  State                  Pointer to the CPU's current interrupt state
> +
> +  @retval EFI_SUCCESS            If interrupts were disabled in the CPU.
> +  @retval EFI_INVALID_PARAMETER  State is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuGetInterruptState (
> +  IN  EFI_CPU_ARCH_PROTOCOL  *This,
> +  OUT BOOLEAN                *State
> +  )
> +{
> +  if (State == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *State = mInterruptState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Generates an INIT to the CPU.
> +
> +  @param  This              Protocol instance structure
> +  @param  InitType          Type of CPU INIT to perform
> +
> +  @retval EFI_SUCCESS       If CPU INIT occurred. This value should never be
> +                            seen.
> +  @retval EFI_DEVICE_ERROR  If CPU INIT failed.
> +  @retval EFI_UNSUPPORTED   Requested type of CPU INIT not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuInit (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_CPU_INIT_TYPE      InitType
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Registers a function to be called from the CPU interrupt handler.
> +
> +  @param  This                   Protocol instance structure
> +  @param  InterruptType          Defines which interrupt to hook. IA-32
> +                                 valid range is 0x00 through 0xFF
> +  @param  InterruptHandler       A pointer to a function of type
> +                                 EFI_CPU_INTERRUPT_HANDLER that is called
> +                                 when a processor interrupt occurs.  A null
> +                                 pointer is an error condition.
> +
> +  @retval EFI_SUCCESS            If handler installed or uninstalled.
> +  @retval EFI_ALREADY_STARTED    InterruptHandler is not NULL, and a handler
> +                                 for InterruptType was previously installed.
> +  @retval EFI_INVALID_PARAMETER  InterruptHandler is NULL, and a handler for
> +                                 InterruptType was not previously installed.
> +  @retval EFI_UNSUPPORTED        The interrupt specified by InterruptType
> +                                 is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuRegisterInterruptHandler (
> +  IN EFI_CPU_ARCH_PROTOCOL      *This,
> +  IN EFI_EXCEPTION_TYPE         InterruptType,
> +  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
> +  )
> +{
> +  return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); 
> +}
> +
> +/**
> +  Returns a timer value from one of the CPU's internal timers. There is 
> +no
> +  inherent time interval between ticks but is a function of the CPU frequency.
> +
> +  @param  This                - Protocol instance structure.
> +  @param  TimerIndex          - Specifies which CPU timer is requested.
> +  @param  TimerValue          - Pointer to the returned timer value.
> +  @param  TimerPeriod         - A pointer to the amount of time that passes
> +                                in femtoseconds (10-15) for each increment
> +                                of TimerValue. If TimerValue does not
> +                                increment at a predictable rate, then 0 is
> +                                returned.  The amount of time that has
> +                                passed between two calls to GetTimerValue()
> +                                can be calculated with the formula
> +                                (TimerValue2 - TimerValue1) * TimerPeriod.
> +                                This parameter is optional and may be NULL.
> +
> +  @retval EFI_SUCCESS           - If the CPU timer count was returned.
> +  @retval EFI_UNSUPPORTED       - If the CPU does not have any readable timers.
> +  @retval EFI_DEVICE_ERROR      - If an error occurred while reading the timer.
> +  @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuGetTimerValue (
> +  IN  EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN  UINT32                 TimerIndex,
> +  OUT UINT64                 *TimerValue,
> +  OUT UINT64                 *TimerPeriod OPTIONAL
> +  )
> +{
> +  if (TimerValue == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (TimerIndex != 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *TimerValue = (UINT64)RiscVReadTimer ();  if (TimerPeriod != NULL) {
> +    *TimerPeriod = DivU64x32 (
> +                     1000000000000000u,
> +                     PcdGet64 (PcdCpuCoreCrystalClockFrequency)
> +                     );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
> +
> +  This function modifies the attributes for the memory region specified 
> + by BaseAddress and  Length from their current attributes to the attributes specified by Attributes.
> +
> +  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
> +  @param  BaseAddress      The physical address that is the start address of a memory region.
> +  @param  Length           The size in bytes of the memory region.
> +  @param  Attributes       The bit mask of attributes to set for the memory region.
> +
> +  @retval EFI_SUCCESS           The attributes were set for the memory region.
> +  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by
> +                                BaseAddress and Length cannot be modified.
> +  @retval EFI_INVALID_PARAMETER Length is zero.
> +                                Attributes specified an illegal combination of attributes that
> +                                cannot be set together.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
> +                                the memory resource range.
> +  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory
> +                                resource range specified by BaseAddress and Length.
> +                                The bit mask of attributes is not support for the memory resource
> +                                range specified by BaseAddress and Length.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuSetMemoryAttributes (
> +  IN EFI_CPU_ARCH_PROTOCOL  *This,
> +  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
> +  IN UINT64                 Length,
> +  IN UINT64                 Attributes
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "%a: Set memory attributes not supported yet\n", 
> +__FUNCTION__));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initialize the state information for the CPU Architectural Protocol.
> +
> +  @param ImageHandle     Image handle this driver.
> +  @param SystemTable     Pointer to the System Table.
> +
> +  @retval EFI_SUCCESS           Thread can be successfully created
> +  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
> +  @retval EFI_DEVICE_ERROR      Cannot create the thread
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeCpu (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext;
> +
> +  GetFirmwareContextPointer (&FirmwareContext);  ASSERT 
> + (FirmwareContext != NULL);  if (FirmwareContext == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n", 
> + __FUNCTION__, FirmwareContext));
> +
> +  mBootHartId = FirmwareContext->BootHartId;  DEBUG ((DEBUG_INFO, " %a: 
> + mBootHartId = 0x%x.\n", __FUNCTION__, mBootHartId));
> +
> +  InitializeCpuExceptionHandlers (NULL);
> +
> +  //
> +  // Make sure interrupts are disabled
> +  //
> +  DisableInterrupts ();
> +
> +  //
> +  // Install Boot protocol
> +  //
> +  Status = gBS->InstallProtocolInterface (
> +                  &ImageHandle,
> +                  &gRiscVEfiBootProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &gRiscvBootProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install CPU Architectural Protocol
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mCpuHandle,
> +                  &gEfiCpuArchProtocolGuid,
> +                  &gCpu,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> --
> 2.38.0
> 
> 
> 
> 
> 
> 

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
@ 2023-02-08 18:02   ` Michael D Kinney
  2023-02-08 18:12     ` Sunil V L
  2023-02-09  5:21   ` Ni, Ray
  2023-02-09 10:17   ` Michael Brown
  2 siblings, 1 reply; 80+ messages in thread
From: Michael D Kinney @ 2023-02-08 18:02 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Daniel Schaefer,
	Gerd Hoffmann, Abner Chang, Kinney, Michael D

Hi Sunil,

One comment on the name of this module.  CpuTimerDxe is a very generic name, but the
Implementation is for RISCV only and depends on SBL services.  Correct?

If I look at other TimerDxe modules, they have in their name some indication of 
the timer hardware/software dependencies in their name,

* LocalApicTimerDxe.inf
* HpetTimerDxe.inf

How about RiscVTimerDxe or RiscVSbiTimerLib?

Mike


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer
> <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This DXE module initializes the timer interrupt handler
> and installs the Arch Timer protocol.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dsc                |   3 +
>  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf   |  51 ++++
>  UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h   | 177 ++++++++++++
>  UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c   | 294 ++++++++++++++++++++
>  UefiCpuPkg/CpuTimerDxe/CpuTimer.uni      |  14 +
>  UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni |  12 +
>  6 files changed, 551 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index f9a46089d2c7..96f6770281fe 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -195,5 +195,8 @@ [Components.IA32, Components.X64]
>  [Components.X64]
>    UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
> 
> +[Components.RISCV64]
> +  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> +
>  [BuildOptions]
>    *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> new file mode 100644
> index 000000000000..d7706328b591
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# Timer Arch protocol module
> +#
> +# 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                      = CpuTimerDxe
> +  MODULE_UNI_FILE                = CpuTimer.uni
> +  FILE_GUID                      = 055DDAC6-9142-4013-BF20-FC2E5BC325C9
> +  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
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  CpuLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[LibraryClasses.RISCV64]
> +  RiscVSbiLib
> +
> +[Sources.RISCV64]
> +  RiscV64/Timer.h
> +  RiscV64/Timer.c
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid       ## CONSUMES
> +  gEfiTimerArchProtocolGuid     ## PRODUCES
> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  CpuTimerExtra.uni
> diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
> new file mode 100644
> index 000000000000..586eb0cfadb4
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
> @@ -0,0 +1,177 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol definitions
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef TIMER_H_
> +#define TIMER_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/Timer.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +
> +//
> +// RISC-V use 100us timer.
> +// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units
> +//
> +#define DEFAULT_TIMER_TICK_DURATION  100000
> +
> +extern VOID
> +RiscvSetTimerPeriod (
> +  UINT32  TimerPeriod
> +  );
> +
> +//
> +// Function Prototypes
> +//
> +
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  OUT UINT64                  *TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
> +  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt is
> +  enabled when this service is called, then the registered handler will be invoked. The
> +  registered handler should not be able to distinguish a hardware-generated timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +;
> +
> +#endif
> diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
> new file mode 100644
> index 000000000000..db153f715e60
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
> @@ -0,0 +1,294 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseRiscVSbiLib.h>
> +#include "Timer.h"
> +
> +//
> +// 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;
> +
> +/**
> +  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;
> +
> +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  if (mTimerNotifyFunction != NULL) {
> +    mTimerNotifyFunction (mTimerPeriod);
> +  }
> +
> +  RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +  RiscVClearPendingTimerInterrupt ();
> +  if (mTimerPeriod == 0) {
> +    gBS->RestoreTPL (OriginalTPL);
> +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +    return;
> +  }
> +
> +  RiscvTimer               = RiscVReadTimer ();
> +  SbiSetTimer (RiscvTimer += mTimerPeriod);
> +  gBS->RestoreTPL (OriginalTPL);
> +  RiscVEnableTimerInterrupt (); // enable SMode timer int
> +}
> +
> +/**
> +
> +  This function registers the handler NotifyFunction so it is called every time
> +  the timer interrupt fires.  It also passes the amount of time since the last
> +  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
> +  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
> +  returned.  If the CPU does not support registering a timer interrupt handler,
> +  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
> +  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
> +  If an attempt is made to unregister a handler when a handler is not registered,
> +  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
> +  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
> +  is returned.
> +
> +  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction   The function to call when a timer interrupt fires.  This
> +                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
> +                          register a handler for the timer interrupt, so it can know
> +                          how much time has passed.  This information is used to
> +                          signal timer based events.  NULL will unregister the handler.
> +
> +  @retval        EFI_SUCCESS            The timer handler was registered.
> +  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
> +  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
> +                                        registered.
> +  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
> +                                        previously registered.
> +  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", NotifyFunction));
> +  mTimerNotifyFunction = NotifyFunction;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +{
> +  UINT64  RiscvTimer;
> +
> +  DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));
> +
> +  if (TimerPeriod == 0) {
> +    mTimerPeriod = 0;
> +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +    return EFI_SUCCESS;
> +  }
> +
> +  mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us
> +  RiscvTimer   = RiscVReadTimer ();
> +  SbiSetTimer (RiscvTimer + mTimerPeriod);
> +
> +  mCpu->EnableInterrupt (mCpu);
> +  RiscVEnableTimerInterrupt (); // enable SMode 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;
> +}
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
> new file mode 100644
> index 000000000000..76de1f3f352a
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +//
> +// 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 "Timer driver that provides Timer Arch protocol"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "Timer driver that provides Timer Arch protocol."
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni
> new file mode 100644
> index 000000000000..ceb93a7ce82f
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.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
> +"Timer DXE Driver"
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-02-08 18:02   ` [edk2-devel] " Michael D Kinney
@ 2023-02-08 18:12     ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-08 18:12 UTC (permalink / raw)
  To: Kinney, Michael D
  Cc: devel@edk2.groups.io, Dong, Eric, Ni, Ray, Kumar, Rahul R,
	Daniel Schaefer, Gerd Hoffmann, Abner Chang

On Wed, Feb 08, 2023 at 06:02:44PM +0000, Kinney, Michael D wrote:
> Hi Sunil,
> 
> One comment on the name of this module.  CpuTimerDxe is a very generic name, but the
> Implementation is for RISCV only and depends on SBL services.  Correct?
> 
> If I look at other TimerDxe modules, they have in their name some indication of 
> the timer hardware/software dependencies in their name,
> 
> * LocalApicTimerDxe.inf
> * HpetTimerDxe.inf
> 
> How about RiscVTimerDxe or RiscVSbiTimerLib?
> 
> Mike
> 
Thanks!, Mike. Your suggestion makes sense. Since most of the drivers in
UefiCpuPkg were named as Cpu*, I named it like this. Let me change it to
RiscVTimerDxe.

Thanks!
Sunil

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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions Sunil V L
  2023-02-06 15:46   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:43   ` Michael D Kinney
  2023-02-09  7:21     ` Sunil V L
  1 sibling, 1 reply; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:43 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Gao, Liming, Liu, Zhiguang, Daniel Schaefer, Abner Chang,
	Kinney, Michael D

Hi Sunil,

Just a formatting comment below.

Mike

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>;
> Daniel Schaefer <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> Few of the basic helper functions required for any
> RISC-V CPU were added in edk2-platforms. To support
> qemu virt, they need to be added in BaseLib.
> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  MdePkg/Library/BaseLib/BaseLib.inf              |  3 ++
>  MdePkg/Include/Library/BaseLib.h                | 50 ++++++++++++++++++
>  MdePkg/Library/BaseLib/RiscV64/CpuScratch.S     | 31 ++++++++++++
>  MdePkg/Library/BaseLib/RiscV64/ReadTimer.S      | 23 +++++++++
>  MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 53 ++++++++++++++++++--
>  MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S       | 23 +++++++++
>  6 files changed, 179 insertions(+), 4 deletions(-)
> 
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
> index 9ed46a584a14..3a48492b1a01 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -401,6 +401,9 @@ [Sources.RISCV64]
>    RiscV64/RiscVCpuPause.S           | GCC
>    RiscV64/RiscVInterrupt.S          | GCC
>    RiscV64/FlushCache.S              | GCC
> +  RiscV64/CpuScratch.S              | GCC
> +  RiscV64/ReadTimer.S               | GCC
> +  RiscV64/RiscVMmu.S                | GCC
> 
>  [Sources.LOONGARCH64]
>    Math64.c
> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> index f3f59f21c2ea..b4f4e45a1486 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -151,6 +151,56 @@ typedef struct {
> 
>  #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT  8
> 
> +VOID
> +  RiscVSetSupervisorScratch (
> +                             UINT64
> +                             );
> +
> +UINT64
> +RiscVGetSupervisorScratch (
> +  VOID
> +  );
> +
> +VOID
> +  RiscVSetSupervisorStvec (
> +                           UINT64
> +                           );
> +
> +UINT64
> +RiscVGetSupervisorStvec (
> +  VOID
> +  );
> +
> +UINT64
> +RiscVGetSupervisorTrapCause (
> +  VOID
> +  );
> +
> +VOID
> +  RiscVSetSupervisorAddressTranslationRegister (
> +                                                UINT64
> +                                                );

Formatting does not look right.

Have you run EDK II uncrustify on this patch series.

> +
> +UINT64
> +RiscVReadTimer (
> +  VOID
> +  );
> +
> +VOID
> +RiscVEnableTimerInterrupt (
> +  VOID
> +  );
> +
> +VOID
> +RiscVDisableTimerInterrupt (
> +  VOID
> +  );
> +
> +VOID
> +RiscVClearPendingTimerInterrupt (
> +  VOID
> +  );
> +
>  #endif // defined (MDE_CPU_RISCV64)
> 
>  #if defined (MDE_CPU_LOONGARCH64)
> diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
> new file mode 100644
> index 000000000000..5492a500eb5e
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/CpuScratch.S
> @@ -0,0 +1,31 @@
> +//------------------------------------------------------------------------------
> +//
> +// CPU scratch register related functions for RISC-V
> +//
> +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//------------------------------------------------------------------------------
> +
> +#include <Register/RiscV64/RiscVImpl.h>
> +
> +.data
> +.align 3
> +.section .text
> +
> +//
> +// Set Supervisor mode scratch.
> +// @param a0 : Value set to Supervisor mode scratch
> +//
> +ASM_FUNC (RiscVSetSupervisorScratch)
> +    csrw CSR_SSCRATCH, a0
> +    ret
> +
> +//
> +// Get Supervisor mode scratch.
> +// @retval a0 : Value in Supervisor mode scratch
> +//
> +ASM_FUNC (RiscVGetSupervisorScratch)
> +    csrr a0, CSR_SSCRATCH
> +    ret
> diff --git a/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
> new file mode 100644
> index 000000000000..39a06efa51ef
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/ReadTimer.S
> @@ -0,0 +1,23 @@
> +//------------------------------------------------------------------------------
> +//
> +// Read CPU timer
> +//
> +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//------------------------------------------------------------------------------
> +
> +#include <Register/RiscV64/RiscVImpl.h>
> +
> +.data
> +.align 3
> +.section .text
> +
> +//
> +// Read TIME CSR.
> +// @retval a0 : 64-bit timer.
> +//
> +ASM_FUNC (RiscVReadTimer)
> +    csrr a0, CSR_TIME
> +    ret
> diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
> index 87b3468fc7fd..6a1b90a7e45c 100644
> --- a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
> +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
> @@ -8,13 +8,13 @@
>  //
>  //------------------------------------------------------------------------------
> 
> +#include <Register/RiscV64/RiscVImpl.h>
> +
>  ASM_GLOBAL ASM_PFX(RiscVDisableSupervisorModeInterrupts)
>  ASM_GLOBAL ASM_PFX(RiscVEnableSupervisorModeInterrupt)
>  ASM_GLOBAL ASM_PFX(RiscVGetSupervisorModeInterrupts)
> 
> -#define  SSTATUS_SIE                 0x00000002
> -#define  CSR_SSTATUS                 0x100
> -  #define  SSTATUS_SPP_BIT_POSITION  8
> +#define  SSTATUS_SPP_BIT_POSITION  8
> 
>  //
>  // This routine disables supervisor mode interrupt
> @@ -53,11 +53,56 @@ InTrap:
>    ret
> 
>  //
> +// Set Supervisor mode trap vector.
> +// @param a0 : Value set to Supervisor mode trap vector
> +//
> +ASM_FUNC (RiscVSetSupervisorStvec)
> +    csrrw a1, CSR_STVEC, a0
> +    ret
> +
> +//
> +// Get Supervisor mode trap vector.
> +// @retval a0 : Value in Supervisor mode trap vector
> +//
> +ASM_FUNC (RiscVGetSupervisorStvec)
> +    csrr a0, CSR_STVEC
> +    ret
> +
> +//
> +// Get Supervisor trap cause CSR.
> +//
> +ASM_FUNC (RiscVGetSupervisorTrapCause)
> +    csrrs a0, CSR_SCAUSE, 0
> +    ret
> +//
>  // This routine returns supervisor mode interrupt
>  // status.
>  //
> -ASM_PFX(RiscVGetSupervisorModeInterrupts):
> +ASM_FUNC (RiscVGetSupervisorModeInterrupts)
>    csrr a0, CSR_SSTATUS
>    andi a0, a0, SSTATUS_SIE
>    ret
> 
> +//
> +// This routine disables supervisor mode timer interrupt
> +//
> +ASM_FUNC (RiscVDisableTimerInterrupt)
> +    li   a0, SIP_STIP
> +    csrc CSR_SIE, a0
> +    ret
> +
> +//
> +// This routine enables supervisor mode timer interrupt
> +//
> +ASM_FUNC (RiscVEnableTimerInterrupt)
> +    li    a0, SIP_STIP
> +    csrs CSR_SIE, a0
> +    ret
> +
> +//
> +// This routine clears pending supervisor mode timer interrupt
> +//
> +ASM_FUNC (RiscVClearPendingTimerInterrupt)
> +    li   a0, SIP_STIP
> +    csrc CSR_SIP, a0
> +    ret
> diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
> new file mode 100644
> index 000000000000..ac8f92f38aed
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S
> @@ -0,0 +1,23 @@
> +//------------------------------------------------------------------------------
> +//
> +// CPU scratch register related functions for RISC-V
> +//
> +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//------------------------------------------------------------------------------
> +
> +#include <Register/RiscV64/RiscVImpl.h>
> +
> +.data
> +.align 3
> +.section .text
> +
> +//
> +// Set Supervisor Address Translation and
> +// Protection Register.
> +//
> +ASM_FUNC (RiscVSetSupervisorAddressTranslationRegister)
> +    csrw  CSR_SATP, a0
> +    ret
> --
> 2.38.0


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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
  2023-02-06 15:44   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:44   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:44 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Daniel Schaefer, Gao, Liming, Liu, Zhiguang, Abner Chang,
	Kinney, Michael D

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>


> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Daniel Schaefer <git@danielschaefer.me>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>;
> Liu, Zhiguang <zhiguang.liu@intel.com>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> Add register definitions and access routines for RISC-V. These
> headers are leveraged from opensbi repo.
> 
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 119 ++++++++++++++++++++
>  MdePkg/Include/Register/RiscV64/RiscVImpl.h     |  25 ++++
>  2 files changed, 144 insertions(+)
> 
> diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
> new file mode 100644
> index 000000000000..5c2989b797bf
> --- /dev/null
> +++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
> @@ -0,0 +1,119 @@
> +/** @file
> +  RISC-V CSR encodings
> +
> +  Copyright (c) 2019, Western Digital Corporation or its affiliates. All rights reserved.<BR>
> +  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RISCV_ENCODING_H_
> +#define RISCV_ENCODING_H_
> +
> +#define MSTATUS_SIE         0x00000002UL
> +#define MSTATUS_MIE         0x00000008UL
> +#define MSTATUS_SPIE_SHIFT  5
> +#define MSTATUS_SPIE        (1UL << MSTATUS_SPIE_SHIFT)
> +#define MSTATUS_UBE         0x00000040UL
> +#define MSTATUS_MPIE        0x00000080UL
> +#define MSTATUS_SPP_SHIFT   8
> +#define MSTATUS_SPP         (1UL << MSTATUS_SPP_SHIFT)
> +#define MSTATUS_MPP_SHIFT   11
> +#define MSTATUS_MPP         (3UL << MSTATUS_MPP_SHIFT)
> +
> +#define SSTATUS_SIE         MSTATUS_SIE
> +#define SSTATUS_SPIE_SHIFT  MSTATUS_SPIE_SHIFT
> +#define SSTATUS_SPIE        MSTATUS_SPIE
> +#define SSTATUS_SPP_SHIFT   MSTATUS_SPP_SHIFT
> +#define SSTATUS_SPP         MSTATUS_SPP
> +
> +#define IRQ_S_SOFT    1
> +#define IRQ_VS_SOFT   2
> +#define IRQ_M_SOFT    3
> +#define IRQ_S_TIMER   5
> +#define IRQ_VS_TIMER  6
> +#define IRQ_M_TIMER   7
> +#define IRQ_S_EXT     9
> +#define IRQ_VS_EXT    10
> +#define IRQ_M_EXT     11
> +#define IRQ_S_GEXT    12
> +#define IRQ_PMU_OVF   13
> +
> +#define MIP_SSIP    (1UL << IRQ_S_SOFT)
> +#define MIP_VSSIP   (1UL << IRQ_VS_SOFT)
> +#define MIP_MSIP    (1UL << IRQ_M_SOFT)
> +#define MIP_STIP    (1UL << IRQ_S_TIMER)
> +#define MIP_VSTIP   (1UL << IRQ_VS_TIMER)
> +#define MIP_MTIP    (1UL << IRQ_M_TIMER)
> +#define MIP_SEIP    (1UL << IRQ_S_EXT)
> +#define MIP_VSEIP   (1UL << IRQ_VS_EXT)
> +#define MIP_MEIP    (1UL << IRQ_M_EXT)
> +#define MIP_SGEIP   (1UL << IRQ_S_GEXT)
> +#define MIP_LCOFIP  (1UL << IRQ_PMU_OVF)
> +
> +#define SIP_SSIP  MIP_SSIP
> +#define SIP_STIP  MIP_STIP
> +
> +#define PRV_U  0UL
> +#define PRV_S  1UL
> +#define PRV_M  3UL
> +
> +#define SATP64_MODE  0xF000000000000000ULL
> +#define SATP64_ASID  0x0FFFF00000000000ULL
> +#define SATP64_PPN   0x00000FFFFFFFFFFFULL
> +
> +#define SATP_MODE_OFF   0UL
> +#define SATP_MODE_SV32  1UL
> +#define SATP_MODE_SV39  8UL
> +#define SATP_MODE_SV48  9UL
> +#define SATP_MODE_SV57  10UL
> +#define SATP_MODE_SV64  11UL
> +
> +#define SATP_MODE  SATP64_MODE
> +
> +/* User Counters/Timers */
> +#define CSR_CYCLE  0xc00
> +#define CSR_TIME   0xc01
> +
> +/* Supervisor Trap Setup */
> +#define CSR_SSTATUS  0x100
> +#define CSR_SEDELEG  0x102
> +#define CSR_SIDELEG  0x103
> +#define CSR_SIE      0x104
> +#define CSR_STVEC    0x105
> +
> +/* Supervisor Configuration */
> +#define CSR_SENVCFG  0x10a
> +
> +/* Supervisor Trap Handling */
> +#define CSR_SSCRATCH  0x140
> +#define CSR_SEPC      0x141
> +#define CSR_SCAUSE    0x142
> +#define CSR_STVAL     0x143
> +#define CSR_SIP       0x144
> +
> +/* Supervisor Protection and Translation */
> +#define CSR_SATP  0x180
> +
> +/* Trap/Exception Causes */
> +#define CAUSE_MISALIGNED_FETCH          0x0
> +#define CAUSE_FETCH_ACCESS              0x1
> +#define CAUSE_ILLEGAL_INSTRUCTION       0x2
> +#define CAUSE_BREAKPOINT                0x3
> +#define CAUSE_MISALIGNED_LOAD           0x4
> +#define CAUSE_LOAD_ACCESS               0x5
> +#define CAUSE_MISALIGNED_STORE          0x6
> +#define CAUSE_STORE_ACCESS              0x7
> +#define CAUSE_USER_ECALL                0x8
> +#define CAUSE_SUPERVISOR_ECALL          0x9
> +#define CAUSE_VIRTUAL_SUPERVISOR_ECALL  0xa
> +#define CAUSE_MACHINE_ECALL             0xb
> +#define CAUSE_FETCH_PAGE_FAULT          0xc
> +#define CAUSE_LOAD_PAGE_FAULT           0xd
> +#define CAUSE_STORE_PAGE_FAULT          0xf
> +#define CAUSE_FETCH_GUEST_PAGE_FAULT    0x14
> +#define CAUSE_LOAD_GUEST_PAGE_FAULT     0x15
> +#define CAUSE_VIRTUAL_INST_FAULT        0x16
> +#define CAUSE_STORE_GUEST_PAGE_FAULT    0x17
> +
> +#endif
> diff --git a/MdePkg/Include/Register/RiscV64/RiscVImpl.h b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
> new file mode 100644
> index 000000000000..ee5c2ba60377
> --- /dev/null
> +++ b/MdePkg/Include/Register/RiscV64/RiscVImpl.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  RISC-V package definitions.
> +
> +  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RISCV_IMPL_H_
> +#define RISCV_IMPL_H_
> +
> +#include <Register/RiscV64/RiscVEncoding.h>
> +
> +#define _ASM_FUNC(Name, Section)    \
> +  .global   Name                  ; \
> +  .section  #Section, "ax"        ; \
> +  .type     Name, %function       ; \
> +  .p2align  2                     ; \
> +  Name:
> +
> +#define ASM_FUNC(Name)  _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
> +#define RISCV_TIMER_COMPARE_BITS  32
> +
> +#endif
> --
> 2.38.0


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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
  2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:45   ` Michael D Kinney
  2023-02-09  7:18     ` [edk2-devel] " Sunil V L
  1 sibling, 1 reply; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:45 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Gao, Liming, Liu, Zhiguang, Abner Chang, Kinney, Michael D

One comment below.

Mike

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>;
> Abner Chang <abner.chang@amd.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This library is required to make SBI ecalls from the S-mode EDK2.
> This is mostly copied from
> edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib
> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  MdePkg/MdePkg.dec                                  |   4 +
>  MdePkg/MdePkg.dsc                                  |   3 +
>  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
>  MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
>  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
>  5 files changed, 386 insertions(+)
> 
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 3d08f20d15b0..ca2e4dcf815c 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
>    ##  @libraryclass  Provides function to support TDX processing.
>    TdxLib|Include/Library/TdxLib.h
> 
> +[LibraryClasses.RISCV64]
> +  ##  @libraryclass  Provides function to make ecalls to SBI
> +  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
> +
>  [Guids]
>    #
>    # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
> diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
> index 32a852dc466e..0ac7618b4623 100644
> --- a/MdePkg/MdePkg.dsc
> +++ b/MdePkg/MdePkg.dsc
> @@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
>    MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>    MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> 
> +[Components.RISCV64]
> +  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> +
>  [BuildOptions]
> diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> new file mode 100644
> index 000000000000..d03132bf01c1
> --- /dev/null
> +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> @@ -0,0 +1,25 @@
> +## @file
> +# RISC-V Library to call SBI ecalls
> +#
> +#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION         = 0x0001001b
> +  BASE_NAME           = BaseRiscVSbiLib
> +  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
> +  MODULE_TYPE         = BASE
> +  VERSION_STRING      = 1.0
> +  LIBRARY_CLASS       = RiscVSbiLib
> +
> +[Sources]
> +  BaseRiscVSbiLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> new file mode 100644
> index 000000000000..3a3cbfb879f1
> --- /dev/null
> +++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> @@ -0,0 +1,127 @@
> +/** @file
> +  Library to call the RISC-V SBI ecalls
> +
> +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Hart - Hardware Thread, similar to a CPU core
> +
> +  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
> +
> +**/
> +
> +#ifndef RISCV_SBI_LIB_H_
> +#define RISCV_SBI_LIB_H_
> +
> +#include <Uefi.h>
> +
> +/* SBI Extension IDs */
> +#define SBI_EXT_TIME  0x54494D45
> +#define SBI_EXT_SRST  0x53525354
> +
> +/* SBI function IDs for TIME extension*/
> +#define SBI_EXT_TIME_SET_TIMER  0x0
> +
> +/* SBI function IDs for SRST extension */
> +#define SBI_EXT_SRST_RESET  0x0
> +
> +#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
> +#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1
> +#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
> +
> +#define SBI_SRST_RESET_REASON_NONE     0x0
> +#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
> +
> +/* SBI return error codes */
> +#define SBI_SUCCESS                0
> +#define SBI_ERR_FAILED             -1
> +#define SBI_ERR_NOT_SUPPORTED      -2
> +#define SBI_ERR_INVALID_PARAM      -3
> +#define SBI_ERR_DENIED             -4
> +#define SBI_ERR_INVALID_ADDRESS    -5
> +#define SBI_ERR_ALREADY_AVAILABLE  -6
> +#define SBI_ERR_ALREADY_STARTED    -7
> +#define SBI_ERR_ALREADY_STOPPED    -8
> +
> +#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
> +
> +typedef struct {
> +  UINT64    BootHartId;
> +  VOID      *PeiServiceTable;    // PEI Service table
> +  VOID      *PrePiHobList;       // Pre PI Hob List
> +  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
> +} EFI_RISCV_FIRMWARE_CONTEXT;
> +
> +//
> +// EDK2 OpenSBI firmware extension return status.
> +//
> +typedef struct {
> +  UINTN    Error; ///< SBI status code
> +  UINTN    Value; ///< Value returned
> +} SBI_RET;
> +
> +VOID
> +EFIAPI
> +SbiSetTimer (
> +  IN  UINT64  Time
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SbiSystemReset (
> +  IN  UINTN  ResetType,
> +  IN  UINTN  ResetReason
> +  );
> +
> +/**
> +  Get firmware context of the calling hart.
> +
> +  @param[out] FirmwareContext      The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContext (
> +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> +  );
> +
> +/**
> +  Set firmware context of the calling hart.
> +
> +  @param[in] FirmwareContext       The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContext (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> +  );
> +
> +/**
> +  Get pointer to OpenSBI Firmware Context
> +
> +  Get the pointer of firmware context.
> +
> +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> +                                 Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContextPointer (
> +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> +  );
> +
> +/**
> +  Set pointer to OpenSBI Firmware Context
> +
> +  Set the pointer of firmware context.
> +
> +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContextPointer (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> +  );
> +
> +#endif
> diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> new file mode 100644
> index 000000000000..15222a528753
> --- /dev/null
> +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> @@ -0,0 +1,227 @@
> +/** @file
> +  Instance of the SBI ecall library.
> +
> +  It allows calling an SBI function via an ecall from S-Mode.
> +
> +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseRiscVSbiLib.h>
> +
> +//
> +// Maximum arguments for SBI ecall
> +#define SBI_CALL_MAX_ARGS  6
> +
> +/**
> +  Call SBI call using ecall instruction.
> +
> +  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
> +
> +  @param[in] ExtId    SBI extension ID.
> +  @param[in] FuncId   SBI function ID.
> +  @param[in] NumArgs  Number of arguments to pass to the ecall.
> +  @param[in] ...      Argument list for the ecall.
> +
> +  @retval  Returns SBI_RET structure with value and error code.
> +
> +**/
> +STATIC
> +SBI_RET
> +EFIAPI
> +SbiCall (
> +  IN  UINTN  ExtId,
> +  IN  UINTN  FuncId,
> +  IN  UINTN  NumArgs,
> +  ...
> +  )
> +{
> +  UINTN    I;
> +  SBI_RET  Ret;
> +  UINTN    Args[SBI_CALL_MAX_ARGS];
> +  VA_LIST  ArgList;
> +
> +  VA_START (ArgList, NumArgs);
> +
> +  if (NumArgs > SBI_CALL_MAX_ARGS) {
> +    Ret.Error = SBI_ERR_INVALID_PARAM;
> +    Ret.Value = -1;
> +    return Ret;
> +  }
> +
> +  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
> +    if (I < NumArgs) {
> +      Args[I] = VA_ARG (ArgList, UINTN);
> +    } else {
> +      // Default to 0 for all arguments that are not given
> +      Args[I] = 0;
> +    }
> +  }
> +
> +  VA_END (ArgList);
> +
> +  register UINTN  a0 asm ("a0") = Args[0];
> +  register UINTN  a1 asm ("a1") = Args[1];
> +  register UINTN  a2 asm ("a2") = Args[2];
> +  register UINTN  a3 asm ("a3") = Args[3];
> +  register UINTN  a4 asm ("a4") = Args[4];
> +  register UINTN  a5 asm ("a5") = Args[5];
> +  register UINTN  a6 asm ("a6") = (UINTN)(FuncId);
> +  register UINTN  a7 asm ("a7") = (UINTN)(ExtId);
> +
> +  asm volatile ("ecall" \
> +       : "+r" (a0), "+r" (a1) \
> +       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
> +       : "memory"); \
> +  Ret.Error = a0;
> +  Ret.Value = a1;

Why is inline assembly used here?  I see use of .S files in BaseLib
Can this be converted to .S file?

> +  return Ret;
> +}
> +
> +/**
> +  Translate SBI error code to EFI status.
> +
> +  @param[in] SbiError   SBI error code
> +  @retval EFI_STATUS
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +TranslateError (
> +  IN  UINTN  SbiError
> +  )
> +{
> +  switch (SbiError) {
> +    case SBI_SUCCESS:
> +      return EFI_SUCCESS;
> +    case SBI_ERR_FAILED:
> +      return EFI_DEVICE_ERROR;
> +      break;
> +    case SBI_ERR_NOT_SUPPORTED:
> +      return EFI_UNSUPPORTED;
> +      break;
> +    case SBI_ERR_INVALID_PARAM:
> +      return EFI_INVALID_PARAMETER;
> +      break;
> +    case SBI_ERR_DENIED:
> +      return EFI_ACCESS_DENIED;
> +      break;
> +    case SBI_ERR_INVALID_ADDRESS:
> +      return EFI_LOAD_ERROR;
> +      break;
> +    case SBI_ERR_ALREADY_AVAILABLE:
> +      return EFI_ALREADY_STARTED;
> +      break;
> +    default:
> +      //
> +      // Reaches here only if SBI has defined a new error type
> +      //
> +      ASSERT (FALSE);
> +      return EFI_UNSUPPORTED;
> +      break;
> +  }
> +}
> +
> +/**
> +  Clear pending timer interrupt bit and set timer for next event after Time.
> +
> +  To clear the timer without scheduling a timer event, set Time to a
> +  practically infinite value or mask the timer interrupt by clearing sie.STIE.
> +
> +  @param[in]  Time                 The time offset to the next scheduled timer interrupt.
> +**/
> +VOID
> +EFIAPI
> +SbiSetTimer (
> +  IN  UINT64  Time
> +  )
> +{
> +  SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SbiSystemReset (
> +  IN  UINTN  ResetType,
> +  IN  UINTN  ResetReason
> +  )
> +{
> +  SBI_RET  Ret;
> +
> +  Ret = SbiCall (
> +          SBI_EXT_SRST,
> +          SBI_EXT_SRST_RESET,
> +          2,
> +          ResetType,
> +          ResetReason
> +          );
> +
> +  return TranslateError (Ret.Error);
> +}
> +
> +/**
> +  Get firmware context of the calling hart.
> +
> +  @param[out] FirmwareContext      The firmware context pointer.
> +  @retval EFI_SUCCESS              The operation succeeds.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContext (
> +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> +  )
> +{
> +  *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();
> +}
> +
> +/**
> +  Set firmware context of the calling hart.
> +
> +  @param[in] FirmwareContext       The firmware context pointer.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContext (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> +  )
> +{
> +  RiscVSetSupervisorScratch ((UINT64)FirmwareContext);
> +}
> +
> +/**
> +  Get pointer to OpenSBI Firmware Context
> +
> +  Get the pointer of firmware context through OpenSBI FW Extension SBI.
> +
> +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> +                                 Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +GetFirmwareContextPointer (
> +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> +  )
> +{
> +  GetFirmwareContext (FirmwareContextPtr);
> +}
> +
> +/**
> +  Set the pointer to OpenSBI Firmware Context
> +
> +  Set the pointer of firmware context through OpenSBI FW Extension SBI.
> +
> +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> +**/
> +VOID
> +EFIAPI
> +SetFirmwareContextPointer (
> +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> +  )
> +{
> +  SetFirmwareContext (FirmwareContextPtr);
> +}
> --
> 2.38.0


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
  2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:50   ` Michael D Kinney
  2023-02-09  5:38   ` Ni, Ray
  2 siblings, 0 replies; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:50 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Ni, Ray, Kumar, Rahul R, Gerd Hoffmann, Abner Chang,
	Kinney, Michael D

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Gerd Hoffmann
> <kraxel@redhat.com>; Abner Chang <abner.chang@amd.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> RISC-V register names do not follow the EDK2 formatting.
> So, add it to ignore list for now.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.ci.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml
> index a377366798b0..953361ba0479 100644
> --- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
> +++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
> @@ -27,6 +27,7 @@
>          ],
>          ## Both file path and directory path are accepted.
>          "IgnoreFiles": [
> +          "Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h"
>          ]
>      },
>      "CompilerPlugin": {
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V Sunil V L
  2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:51   ` Michael D Kinney
  1 sibling, 0 replies; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:51 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Leif Lindholm, Ard Biesheuvel, Abner Chang, Daniel Schaefer,
	Kinney, Michael D

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>; Abner Chang <abner.chang@amd.com>; Daniel
> Schaefer <git@danielschaefer.me>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V
> 
> This PCD is required to be enabled so that PrePiLib
> can be used in RISC-V.
> 
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> ---
>  EmbeddedPkg/EmbeddedPkg.dec | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
> index 341ef5e6a679..2965f01444e9 100644
> --- a/EmbeddedPkg/EmbeddedPkg.dec
> +++ b/EmbeddedPkg/EmbeddedPkg.dec
> @@ -165,6 +165,9 @@ [PcdsFixedAtBuild.IA32]
>  [PcdsFixedAtBuild.X64]
>    gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
> 
> +[PcdsFixedAtBuild.RISCV64]
> +  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
> +
>  [PcdsFixedAtBuild.common, PcdsDynamic.common]
>    #
>    # Value to add to a host address to obtain a device address, using
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt Sunil V L
  2023-02-06 16:04   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  1:51   ` Michael D Kinney
  2023-02-09  3:32     ` [edk2-devel] " Yao, Jiewen
  1 sibling, 1 reply; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09  1:51 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Andrew Fish, Leif Lindholm, Kinney, Michael D

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Saturday, January 28, 2023 11:18 AM
> To: devel@edk2.groups.io
> Cc: Andrew Fish <afish@apple.com>; Leif Lindholm <quic_llindhol@quicinc.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> RiscVVirt is created to support EDK2 for RISC-V qemu
> virt machine platform. Add maintainer entries.
> 
> Cc: Andrew Fish <afish@apple.com>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> ---
>  Maintainers.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt
> index 68f603b48398..fdb27c39b152 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -539,6 +539,10 @@ F: OvmfPkg/XenResetVector/
>  R: Anthony Perard <anthony.perard@citrix.com> [tperard]
>  R: Julien Grall <julien@xen.org> [jgrall]
> 
> +OvmfPkg: RISC-V Qemu Virt Platform
> +F: OvmfPkg/RiscVVirt
> +R: Sunil V L <sunilvl@ventanamicro.com> [vlsunil]
> +
>  PcAtChipsetPkg
>  F: PcAtChipsetPkg/
>  W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
> --
> 2.38.0


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09  1:51   ` Michael D Kinney
@ 2023-02-09  3:32     ` Yao, Jiewen
  2023-02-09  4:34       ` Sunil V L
  0 siblings, 1 reply; 80+ messages in thread
From: Yao, Jiewen @ 2023-02-09  3:32 UTC (permalink / raw)
  To: devel@edk2.groups.io, Kinney, Michael D, Sunil V L,
	abner.chang@amd.com
  Cc: Andrew Fish, Leif Lindholm

Hello
I have not tracked all discussion. Sorry for that.
May I know if we have discussed the option to create RiscVVirtPkg ? similar to https://github.com/tianocore/edk2/tree/master/ArmVirtPkg . To me, that is more natural place.


For the new content on RiscVVirt, I recommend to add one more reviewer/maintainer.
I notice the patches are Acked-by: Abner Chang. Can we get his help on that?

Thank you
Yao, Jiewen


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael D
> Kinney
> Sent: Thursday, February 9, 2023 9:52 AM
> To: Sunil V L <sunilvl@ventanamicro.com>; devel@edk2.groups.io
> Cc: Andrew Fish <afish@apple.com>; Leif Lindholm
> <quic_llindhol@quicinc.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> 
> > -----Original Message-----
> > From: Sunil V L <sunilvl@ventanamicro.com>
> > Sent: Saturday, January 28, 2023 11:18 AM
> > To: devel@edk2.groups.io
> > Cc: Andrew Fish <afish@apple.com>; Leif Lindholm
> <quic_llindhol@quicinc.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> > Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt:
> Add entry for OvmfPkg/RiscVVirt
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> >
> > RiscVVirt is created to support EDK2 for RISC-V qemu
> > virt machine platform. Add maintainer entries.
> >
> > Cc: Andrew Fish <afish@apple.com>
> > Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> > ---
> >  Maintainers.txt | 4 ++++
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/Maintainers.txt b/Maintainers.txt
> > index 68f603b48398..fdb27c39b152 100644
> > --- a/Maintainers.txt
> > +++ b/Maintainers.txt
> > @@ -539,6 +539,10 @@ F: OvmfPkg/XenResetVector/
> >  R: Anthony Perard <anthony.perard@citrix.com> [tperard]
> >  R: Julien Grall <julien@xen.org> [jgrall]
> >
> > +OvmfPkg: RISC-V Qemu Virt Platform
> > +F: OvmfPkg/RiscVVirt
> > +R: Sunil V L <sunilvl@ventanamicro.com> [vlsunil]
> > +
> >  PcAtChipsetPkg
> >  F: PcAtChipsetPkg/
> >  W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
> > --
> > 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09  3:32     ` [edk2-devel] " Yao, Jiewen
@ 2023-02-09  4:34       ` Sunil V L
  2023-02-09  5:07         ` Yao, Jiewen
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-02-09  4:34 UTC (permalink / raw)
  To: devel, jiewen.yao
  Cc: Kinney, Michael D, abner.chang@amd.com, Andrew Fish,
	Leif Lindholm

Hi Jiewen,

On Thu, Feb 09, 2023 at 03:32:20AM +0000, Yao, Jiewen wrote:
> Hello
> I have not tracked all discussion. Sorry for that.
> May I know if we have discussed the option to create RiscVVirtPkg ? similar to https://github.com/tianocore/edk2/tree/master/ArmVirtPkg . To me, that is more natural place.
> 

Thanks for the feedback. Yes, this was discussed and recommendation was
to add in OvmfPkg instead of creating RiscVVirtPkg..
https://edk2.groups.io/g/devel/message/85932

> 
> For the new content on RiscVVirt, I recommend to add one more reviewer/maintainer.
> I notice the patches are Acked-by: Abner Chang. Can we get his help on that?
> 

Agree, that was in my plan to find out some one. Abner had given up
RISC-V mandatory roles. He was helping me here since he was the original
to start this. So, I didn't add him but I will be happy if Abner agrees.

Will find out and add one more reviewer when I revise the series.

Thanks!
Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09  4:34       ` Sunil V L
@ 2023-02-09  5:07         ` Yao, Jiewen
  2023-02-09  5:15           ` Chang, Abner
  2023-02-09 14:05           ` Yao, Jiewen
  0 siblings, 2 replies; 80+ messages in thread
From: Yao, Jiewen @ 2023-02-09  5:07 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Kinney, Michael D, abner.chang@amd.com, Andrew Fish,
	Leif Lindholm

Thanks.

I agree to add Sunil V L <sunilvl@ventanamicro.com> to be a reviewer.
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Thursday, February 9, 2023 12:34 PM
> To: devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@intel.com>
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; abner.chang@amd.com;
> Andrew Fish <afish@apple.com>; Leif Lindholm <quic_llindhol@quicinc.com>
> Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> Hi Jiewen,
> 
> On Thu, Feb 09, 2023 at 03:32:20AM +0000, Yao, Jiewen wrote:
> > Hello
> > I have not tracked all discussion. Sorry for that.
> > May I know if we have discussed the option to create RiscVVirtPkg ? similar to
> https://github.com/tianocore/edk2/tree/master/ArmVirtPkg . To me, that is
> more natural place.
> >
> 
> Thanks for the feedback. Yes, this was discussed and recommendation was
> to add in OvmfPkg instead of creating RiscVVirtPkg..
> https://edk2.groups.io/g/devel/message/85932
> 
> >
> > For the new content on RiscVVirt, I recommend to add one more
> reviewer/maintainer.
> > I notice the patches are Acked-by: Abner Chang. Can we get his help on that?
> >
> 
> Agree, that was in my plan to find out some one. Abner had given up
> RISC-V mandatory roles. He was helping me here since he was the original
> to start this. So, I didn't add him but I will be happy if Abner agrees.
> 
> Will find out and add one more reviewer when I revise the series.
> 
> Thanks!
> Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09  5:07         ` Yao, Jiewen
@ 2023-02-09  5:15           ` Chang, Abner
  2023-02-09 14:05           ` Yao, Jiewen
  1 sibling, 0 replies; 80+ messages in thread
From: Chang, Abner @ 2023-02-09  5:15 UTC (permalink / raw)
  To: Yao, Jiewen, Sunil V L, devel@edk2.groups.io
  Cc: Kinney, Michael D, Andrew Fish, Leif Lindholm

[AMD Official Use Only - General]

Hi Jiewen and Sunil,
Sorry, I am not allowed to keep working on RISC-V stuff, at least at the moment. Maybe later in the future. 😊 
Abner
> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Thursday, February 9, 2023 1:07 PM
> To: Sunil V L <sunilvl@ventanamicro.com>; devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Chang, Abner
> <Abner.Chang@amd.com>; Andrew Fish <afish@apple.com>; Leif Lindholm
> <quic_llindhol@quicinc.com>
> Subject: RE: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> Thanks.
> 
> I agree to add Sunil V L <sunilvl@ventanamicro.com> to be a reviewer.
> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
> 
> > -----Original Message-----
> > From: Sunil V L <sunilvl@ventanamicro.com>
> > Sent: Thursday, February 9, 2023 12:34 PM
> > To: devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@intel.com>
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> > abner.chang@amd.com; Andrew Fish <afish@apple.com>; Leif Lindholm
> > <quic_llindhol@quicinc.com>
> > Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7
> > 20/20]
> > Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> >
> > Hi Jiewen,
> >
> > On Thu, Feb 09, 2023 at 03:32:20AM +0000, Yao, Jiewen wrote:
> > > Hello
> > > I have not tracked all discussion. Sorry for that.
> > > May I know if we have discussed the option to create RiscVVirtPkg ?
> > > similar to
> > https://github.com/tianocore/edk2/tree/master/ArmVirtPkg . To me, that
> > is more natural place.
> > >
> >
> > Thanks for the feedback. Yes, this was discussed and recommendation
> > was to add in OvmfPkg instead of creating RiscVVirtPkg..
> > https://edk2.groups.io/g/devel/message/85932
> >
> > >
> > > For the new content on RiscVVirt, I recommend to add one more
> > reviewer/maintainer.
> > > I notice the patches are Acked-by: Abner Chang. Can we get his help on that?
> > >
> >
> > Agree, that was in my plan to find out some one. Abner had given up
> > RISC-V mandatory roles. He was helping me here since he was the
> > original to start this. So, I didn't add him but I will be happy if Abner agrees.
> >
> > Will find out and add one more reviewer when I revise the series.
> >
> > Thanks!
> > Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions Sunil V L
  2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
@ 2023-02-09  5:16   ` Ni, Ray
  1 sibling, 0 replies; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:16 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Kumar, Rahul R, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang, Heinrich Schuchardt

Acked-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Sunday, January 29, 2023 3:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar,
> Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer
> <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner
> Chang <abner.chang@amd.com>; Heinrich Schuchardt
> <heinrich.schuchardt@canonical.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 04/20]
> UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> RISC-V UEFI based platforms need to support RISCV_EFI_BOOT_PROTOCOL.
> Add this protocol GUID definition and the header file required.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dec                       |  7 ++++
>  UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h | 34
> ++++++++++++++++++++
>  2 files changed, 41 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index cff239d5283e..903ad52da91b 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -86,6 +86,13 @@ [Protocols]
>    ## Include/Protocol/SmMonitorInit.h
>    gEfiSmMonitorInitProtocolGuid  = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4,
> 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }}
> 
> +[Protocols.RISCV64]
> +  #
> +  # Protocols defined for RISC-V systems
> +  #
> +  ## Include/Protocol/RiscVBootProtocol.h
> +  gRiscVEfiBootProtocolGuid  = { 0xccd15fec, 0x6f73, 0x4eec, { 0x83, 0x95,
> 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf }}
> +
>  #
>  # [Error.gUefiCpuPkgTokenSpaceGuid]
>  #   0x80000001 | Invalid value provided.
> diff --git a/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
> b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
> new file mode 100644
> index 000000000000..ed223b852d34
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Protocol/RiscVBootProtocol.h
> @@ -0,0 +1,34 @@
> +/** @file
> +  RISC-V Boot Protocol mandatory for RISC-V UEFI platforms.
> +
> +  @par Revision Reference:
> +  The protocol specification can be found at
> +  https://github.com/riscv-non-isa/riscv-uefi
> +
> +  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RISCV_BOOT_PROTOCOL_H_
> +#define RISCV_BOOT_PROTOCOL_H_
> +
> +typedef struct _RISCV_EFI_BOOT_PROTOCOL RISCV_EFI_BOOT_PROTOCOL;
> +
> +#define RISCV_EFI_BOOT_PROTOCOL_REVISION  0x00010000
> +#define RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION \
> +        RISCV_EFI_BOOT_PROTOCOL_REVISION
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_GET_BOOT_HARTID)(
> +  IN RISCV_EFI_BOOT_PROTOCOL   *This,
> +  OUT UINTN                    *BootHartId
> +  );
> +
> +typedef struct _RISCV_EFI_BOOT_PROTOCOL {
> +  UINT64                 Revision;
> +  EFI_GET_BOOT_HARTID    GetBootHartId;
> +} RISCV_EFI_BOOT_PROTOCOL;
> +
> +#endif
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
  2023-02-08 18:02   ` [edk2-devel] " Michael D Kinney
@ 2023-02-09  5:21   ` Ni, Ray
  2023-02-09 10:17   ` Michael Brown
  2 siblings, 0 replies; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Kumar, Rahul R, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang

I am curious if this module will support other arch as well? If it's RiscV specific, there is no need for creating the RiscV64 folder.

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Sunday, January 29, 2023 3:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar,
> Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer
> <git@danielschaefer.me>; Gerd Hoffmann <kraxel@redhat.com>; Abner
> Chang <abner.chang@amd.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20]
> UefiCpuPkg: Add CpuTimerDxe module
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This DXE module initializes the timer interrupt handler
> and installs the Arch Timer protocol.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dsc                |   3 +
>  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf   |  51 ++++
>  UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h   | 177 ++++++++++++
>  UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c   | 294 ++++++++++++++++++++
>  UefiCpuPkg/CpuTimerDxe/CpuTimer.uni      |  14 +
>  UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni |  12 +
>  6 files changed, 551 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index f9a46089d2c7..96f6770281fe 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -195,5 +195,8 @@ [Components.IA32, Components.X64]
>  [Components.X64]
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHan
> dlerLibUnitTest.inf
> 
> +[Components.RISCV64]
> +  UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> +
>  [BuildOptions]
>    *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> new file mode 100644
> index 000000000000..d7706328b591
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# Timer Arch protocol module
> +#
> +# 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                      = CpuTimerDxe
> +  MODULE_UNI_FILE                = CpuTimer.uni
> +  FILE_GUID                      = 055DDAC6-9142-4013-BF20-FC2E5BC325C9
> +  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
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  CpuLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[LibraryClasses.RISCV64]
> +  RiscVSbiLib
> +
> +[Sources.RISCV64]
> +  RiscV64/Timer.h
> +  RiscV64/Timer.c
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid       ## CONSUMES
> +  gEfiTimerArchProtocolGuid     ## PRODUCES
> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  CpuTimerExtra.uni
> diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
> b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
> new file mode 100644
> index 000000000000..586eb0cfadb4
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.h
> @@ -0,0 +1,177 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol definitions
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef TIMER_H_
> +#define TIMER_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/Timer.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +
> +//
> +// RISC-V use 100us timer.
> +// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units
> +//
> +#define DEFAULT_TIMER_TICK_DURATION  100000
> +
> +extern VOID
> +RiscvSetTimerPeriod (
> +  UINT32  TimerPeriod
> +  );
> +
> +//
> +// Function Prototypes
> +//
> +
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to
> initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to
> initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.
> If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is
> returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer
> interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the
> timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction  The rate to program the timer interrupt in 100 nS
> units.  If
> +                         the timer hardware is not programmable, then
> EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is
> supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of
> the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed
> due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.
> If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is
> returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer
> interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the
> timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS
> units.  If
> +                         the timer hardware is not programmable, then
> EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is
> supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of
> the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed
> due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If
> TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0
> is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns
> units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  OUT UINT64                  *TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not
> support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise,
> EFI_SUCCESS is returned.
> +  If a handler has been registered through the
> EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt
> is
> +  enabled when this service is called, then the registered handler will be
> invoked. The
> +  registered handler should not be able to distinguish a hardware-generated
> timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTEDT  The platform does not support the
> generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +;
> +
> +#endif
> diff --git a/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
> b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
> new file mode 100644
> index 000000000000..db153f715e60
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/RiscV64/Timer.c
> @@ -0,0 +1,294 @@
> +/** @file
> +  RISC-V Timer Architectural Protocol
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseRiscVSbiLib.h>
> +#include "Timer.h"
> +
> +//
> +// 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;
> +
> +/**
> +  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;
> +
> +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  if (mTimerNotifyFunction != NULL) {
> +    mTimerNotifyFunction (mTimerPeriod);
> +  }
> +
> +  RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +  RiscVClearPendingTimerInterrupt ();
> +  if (mTimerPeriod == 0) {
> +    gBS->RestoreTPL (OriginalTPL);
> +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +    return;
> +  }
> +
> +  RiscvTimer               = RiscVReadTimer ();
> +  SbiSetTimer (RiscvTimer += mTimerPeriod);
> +  gBS->RestoreTPL (OriginalTPL);
> +  RiscVEnableTimerInterrupt (); // enable SMode timer int
> +}
> +
> +/**
> +
> +  This function registers the handler NotifyFunction so it is called every time
> +  the timer interrupt fires.  It also passes the amount of time since the last
> +  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
> +  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
> +  returned.  If the CPU does not support registering a timer interrupt
> handler,
> +  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a
> handler
> +  when a handler is already registered, then EFI_ALREADY_STARTED is
> returned.
> +  If an attempt is made to unregister a handler when a handler is not
> registered,
> +  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting
> to
> +  register the NotifyFunction with the timer interrupt, then
> EFI_DEVICE_ERROR
> +  is returned.
> +
> +  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction   The function to call when a timer interrupt fires.
> This
> +                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
> +                          register a handler for the timer interrupt, so it can know
> +                          how much time has passed.  This information is used to
> +                          signal timer based events.  NULL will unregister the handler.
> +
> +  @retval        EFI_SUCCESS            The timer handler was registered.
> +  @retval        EFI_UNSUPPORTED        The platform does not support timer
> interrupts.
> +  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a
> handler is already
> +                                        registered.
> +  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a
> handler was not
> +                                        previously registered.
> +  @retval        EFI_DEVICE_ERROR       The timer handler could not be
> registered.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n",
> NotifyFunction));
> +  mTimerNotifyFunction = NotifyFunction;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.
> If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is
> returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer
> interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the
> timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS
> units.  If
> +                         the timer hardware is not programmable, then
> EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is
> supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of
> the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed
> due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +{
> +  UINT64  RiscvTimer;
> +
> +  DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n",
> TimerPeriod));
> +
> +  if (TimerPeriod == 0) {
> +    mTimerPeriod = 0;
> +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +    return EFI_SUCCESS;
> +  }
> +
> +  mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us
> +  RiscvTimer   = RiscVReadTimer ();
> +  SbiSetTimer (RiscvTimer + mTimerPeriod);
> +
> +  mCpu->EnableInterrupt (mCpu);
> +  RiscVEnableTimerInterrupt (); // enable SMode 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;
> +}
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
> b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
> new file mode 100644
> index 000000000000..76de1f3f352a
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimer.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +//
> +// 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 "Timer driver that
> provides Timer Arch protocol"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "Timer driver
> that provides Timer Arch protocol."
> diff --git a/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni
> b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.uni
> new file mode 100644
> index 000000000000..ceb93a7ce82f
> --- /dev/null
> +++ b/UefiCpuPkg/CpuTimerDxe/CpuTimerExtra.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
> +"Timer DXE Driver"
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance Sunil V L
@ 2023-02-09  5:24   ` Ni, Ray
  0 siblings, 0 replies; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:24 UTC (permalink / raw)
  To: devel@edk2.groups.io, sunilvl@ventanamicro.com
  Cc: Dong, Eric, Kumar, Rahul R, Daniel Schaefer, Abner Chang,
	Gerd Hoffmann

I don't prefer to mix the RiscV64 CpuExceptionHandlerLib instance code with x86 one in
the same directory because they share nothing.
Can you use name such as "RiscVCpuExceptionHandlerLib" as the directory name?

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
> Sent: Sunday, January 29, 2023 3:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar,
> Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer
> <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>; Gerd
> Hoffmann <kraxel@redhat.com>
> Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 06/20]
> UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> Add Cpu Exception Handler library for RISC-V. This is copied
> from edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVExceptionLib
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dsc                                                       |   1 +
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHan
> dlerLib.inf |  42 +++++++
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerL
> ib.h      | 116 +++++++++++++++++
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerL
> ib.c      | 133 ++++++++++++++++++++
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHandle
> r.S       | 105 ++++++++++++++++
>  5 files changed, 397 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index 96f6770281fe..251a8213f022 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -197,6 +197,7 @@ [Components.X64]
> 
>  [Components.RISCV64]
>    UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> +
> UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHan
> dlerLib.inf
> 
>  [BuildOptions]
>    *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHa
> ndlerLib.inf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHa
> ndlerLib.inf
> new file mode 100644
> index 000000000000..82ca22c4bfec
> --- /dev/null
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHa
> ndlerLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# RISC-V CPU Exception Handler Library
> +#
> +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = BaseRiscV64CpuExceptionHandlerLib
> +  MODULE_UNI_FILE                = BaseRiscV64CpuExceptionHandlerLib.uni
> +  FILE_GUID                      = 6AB0D5FD-E615-45A3-9374-E284FB061FC9
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = CpuExceptionHandlerLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV64
> +#
> +
> +[Sources]
> +  RiscV64/SupervisorTrapHandler.S
> +  RiscV64/CpuExceptionHandlerLib.c
> +  RiscV64/CpuExceptionHandlerLib.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  SerialPortLib
> +  PrintLib
> +  SynchronizationLib
> +  PeCoffGetEntryPointLib
> +  MemoryAllocationLib
> +  DebugLib
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.h
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.h
> new file mode 100644
> index 000000000000..30f47e87552b
> --- /dev/null
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.h
> @@ -0,0 +1,116 @@
> +/** @file
> +
> +  RISC-V Exception Handler library definition file.
> +
> +  Copyright (c) 2019-2022, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RISCV_CPU_EXECPTION_HANDLER_LIB_H_
> +#define RISCV_CPU_EXECPTION_HANDLER_LIB_H_
> +
> +#include <Register/RiscV64/RiscVImpl.h>
> +
> +/**
> +  Trap Handler for S-mode
> +
> +**/
> +VOID
> +SupervisorModeTrap (
> +  VOID
> +  );
> +
> +//
> +// Index of SMode trap register
> +//
> +#define SMODE_TRAP_REGS_zero     0
> +#define SMODE_TRAP_REGS_ra       1
> +#define SMODE_TRAP_REGS_sp       2
> +#define SMODE_TRAP_REGS_gp       3
> +#define SMODE_TRAP_REGS_tp       4
> +#define SMODE_TRAP_REGS_t0       5
> +#define SMODE_TRAP_REGS_t1       6
> +#define SMODE_TRAP_REGS_t2       7
> +#define SMODE_TRAP_REGS_s0       8
> +#define SMODE_TRAP_REGS_s1       9
> +#define SMODE_TRAP_REGS_a0       10
> +#define SMODE_TRAP_REGS_a1       11
> +#define SMODE_TRAP_REGS_a2       12
> +#define SMODE_TRAP_REGS_a3       13
> +#define SMODE_TRAP_REGS_a4       14
> +#define SMODE_TRAP_REGS_a5       15
> +#define SMODE_TRAP_REGS_a6       16
> +#define SMODE_TRAP_REGS_a7       17
> +#define SMODE_TRAP_REGS_s2       18
> +#define SMODE_TRAP_REGS_s3       19
> +#define SMODE_TRAP_REGS_s4       20
> +#define SMODE_TRAP_REGS_s5       21
> +#define SMODE_TRAP_REGS_s6       22
> +#define SMODE_TRAP_REGS_s7       23
> +#define SMODE_TRAP_REGS_s8       24
> +#define SMODE_TRAP_REGS_s9       25
> +#define SMODE_TRAP_REGS_s10      26
> +#define SMODE_TRAP_REGS_s11      27
> +#define SMODE_TRAP_REGS_t3       28
> +#define SMODE_TRAP_REGS_t4       29
> +#define SMODE_TRAP_REGS_t5       30
> +#define SMODE_TRAP_REGS_t6       31
> +#define SMODE_TRAP_REGS_sepc     32
> +#define SMODE_TRAP_REGS_sstatus  33
> +#define SMODE_TRAP_REGS_sie      34
> +#define SMODE_TRAP_REGS_last     35
> +
> +#define SMODE_TRAP_REGS_OFFSET(x)  ((SMODE_TRAP_REGS_##x) *
> __SIZEOF_POINTER__)
> +#define SMODE_TRAP_REGS_SIZE  SMODE_TRAP_REGS_OFFSET(last)
> +
> +#pragma pack(1)
> +typedef struct {
> +  //
> +  // Below are follow the format of EFI_SYSTEM_CONTEXT
> +  //
> +  UINT64    zero;
> +  UINT64    ra;
> +  UINT64    sp;
> +  UINT64    gp;
> +  UINT64    tp;
> +  UINT64    t0;
> +  UINT64    t1;
> +  UINT64    t2;
> +  UINT64    s0;
> +  UINT64    s1;
> +  UINT64    a0;
> +  UINT64    a1;
> +  UINT64    a2;
> +  UINT64    a3;
> +  UINT64    a4;
> +  UINT64    a5;
> +  UINT64    a6;
> +  UINT64    a7;
> +  UINT64    s2;
> +  UINT64    s3;
> +  UINT64    s4;
> +  UINT64    s5;
> +  UINT64    s6;
> +  UINT64    s7;
> +  UINT64    s8;
> +  UINT64    s9;
> +  UINT64    s10;
> +  UINT64    s11;
> +  UINT64    t3;
> +  UINT64    t4;
> +  UINT64    t5;
> +  UINT64    t6;
> +  //
> +  // Below are the additional information to
> +  // EFI_SYSTEM_CONTEXT, private to supervisor mode trap
> +  // and not public to EFI environment.
> +  //
> +  UINT64    sepc;
> +  UINT64    sstatus;
> +  UINT64    sie;
> +} SMODE_TRAP_REGISTERS;
> +#pragma pack()
> +
> +#endif
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.c
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.c
> new file mode 100644
> index 000000000000..f1ee7d236aec
> --- /dev/null
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandl
> erLib.c
> @@ -0,0 +1,133 @@
> +/** @file
> +  RISC-V Exception Handler library implementation.
> +
> +  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/CpuExceptionHandlerLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Register/RiscV64/RiscVEncoding.h>
> +
> +#include "CpuExceptionHandlerLib.h"
> +
> +STATIC EFI_CPU_INTERRUPT_HANDLER  mInterruptHandlers[2];
> +
> +/**
> +  Initializes all CPU exceptions entries and provides the default exception
> handlers.
> +
> +  Caller should try to get an array of interrupt and/or exception vectors that
> are in use and need to
> +  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
> +  If caller cannot get reserved vector list or it does not exists, set VectorInfo
> to NULL.
> +  If VectorInfo is not NULL, the exception vectors will be initialized per
> vector attribute accordingly.
> +
> +  @param[in]  VectorInfo    Pointer to reserved vector list.
> +
> +  @retval EFI_SUCCESS           CPU Exception Entries have been successfully
> initialized
> +                                with default exception handlers.
> +  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content
> if VectorInfo is not NULL.
> +  @retval EFI_UNSUPPORTED       This function is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeCpuExceptionHandlers (
> +  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL
> +  )
> +{
> +  RiscVSetSupervisorStvec ((UINT64)SupervisorModeTrap);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Registers a function to be called from the processor interrupt handler.
> +
> +  This function registers and enables the handler specified by
> InterruptHandler for a processor
> +  interrupt or exception type specified by InterruptType. If InterruptHandler
> is NULL, then the
> +  handler for the processor interrupt or exception type specified by
> InterruptType is uninstalled.
> +  The installed handler is called once for each processor interrupt or
> exception.
> +  NOTE: This function should be invoked after
> InitializeCpuExceptionHandlers() or
> +  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED
> returned.
> +
> +  @param[in]  InterruptType     Defines which interrupt or exception to hook.
> +  @param[in]  InterruptHandler  A pointer to a function of type
> EFI_CPU_INTERRUPT_HANDLER that is called
> +                                when a processor interrupt occurs. If this parameter is NULL,
> then the handler
> +                                will be uninstalled.
> +
> +  @retval EFI_SUCCESS           The handler for the processor interrupt was
> successfully installed or uninstalled.
> +  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a
> handler for InterruptType was
> +                                previously installed.
> +  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler
> for InterruptType was not
> +                                previously installed.
> +  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is
> not supported,
> +                                or this function is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RegisterCpuInterruptHandler (
> +  IN EFI_EXCEPTION_TYPE         InterruptType,
> +  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "%a: Type:%x Handler: %x\n", __FUNCTION__,
> InterruptType, InterruptHandler));
> +  mInterruptHandlers[InterruptType] = InterruptHandler;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Setup separate stacks for certain exception handlers.
> +  If the input Buffer and BufferSize are both NULL, use global variable if
> possible.
> +
> +  @param[in]       Buffer        Point to buffer used to separate exception stack.
> +  @param[in, out]  BufferSize    On input, it indicates the byte size of Buffer.
> +                                 If the size is not enough, the return status will
> +                                 be EFI_BUFFER_TOO_SMALL, and output BufferSize
> +                                 will be the size it needs.
> +
> +  @retval EFI_SUCCESS             The stacks are assigned successfully.
> +  @retval EFI_UNSUPPORTED         This function is not supported.
> +  @retval EFI_BUFFER_TOO_SMALL    This BufferSize is too small.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeSeparateExceptionStacks (
> +  IN     VOID   *Buffer,
> +  IN OUT UINTN  *BufferSize
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Supervisor mode trap handler.
> +
> +  @param[in]  SmodeTrapReg     Registers before trap occurred.
> +
> +**/
> +VOID
> +RiscVSupervisorModeTrapHandler (
> +  SMODE_TRAP_REGISTERS  *SmodeTrapReg
> +  )
> +{
> +  UINTN               SCause;
> +  EFI_SYSTEM_CONTEXT  RiscVSystemContext;
> +
> +  RiscVSystemContext.SystemContextRiscV64 =
> (EFI_SYSTEM_CONTEXT_RISCV64 *)SmodeTrapReg;
> +  //
> +  // Check scasue register.
> +  //
> +  SCause = (UINTN)RiscVGetSupervisorTrapCause ();
> +  if ((SCause & (1UL << (sizeof (UINTN) * 8- 1))) != 0) {
> +    //
> +    // This is interrupt event.
> +    //
> +    SCause &= ~(1UL << (sizeof (UINTN) * 8- 1));
> +    if ((SCause == IRQ_S_TIMER) &&
> (mInterruptHandlers[EXCEPT_RISCV_TIMER_INT] != NULL)) {
> +
> mInterruptHandlers[EXCEPT_RISCV_TIMER_INT](EXCEPT_RISCV_TIMER_INT,
> RiscVSystemContext);
> +    }
> +  }
> +}
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHand
> ler.S
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHand
> ler.S
> new file mode 100644
> index 000000000000..649c4c5becf4
> --- /dev/null
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV64/SupervisorTrapHand
> ler.S
> @@ -0,0 +1,105 @@
> +/** @file
> +  RISC-V Processor supervisor mode trap handler
> +
> +  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include "CpuExceptionHandlerLib.h"
> +
> +  .align 3
> +  .section .entry, "ax", %progbits
> +  .globl SupervisorModeTrap
> +SupervisorModeTrap:
> +  addi sp, sp, -SMODE_TRAP_REGS_SIZE
> +
> +  /* Save all general regisers except SP */
> +  sd    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
> +
> +  csrr  t0, CSR_SSTATUS
> +  and   t0, t0, (SSTATUS_SIE | SSTATUS_SPIE)
> +  sd    t0, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
> +  csrr  t0, CSR_SEPC
> +  sd    t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
> +  csrr  t0, CSR_SIE
> +  sd    t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)
> +  ld    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
> +
> +  sd    ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
> +  sd    gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
> +  sd    tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
> +  sd    t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
> +  sd    t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
> +  sd    s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
> +  sd    s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
> +  sd    a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
> +  sd    a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
> +  sd    a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
> +  sd    a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
> +  sd    a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
> +  sd    a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
> +  sd    a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
> +  sd    a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
> +  sd    s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
> +  sd    s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
> +  sd    s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
> +  sd    s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
> +  sd    s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
> +  sd    s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
> +  sd    s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
> +  sd    s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
> +  sd    s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
> +  sd    s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
> +  sd    t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
> +  sd    t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
> +  sd    t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
> +  sd    t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
> +
> +  /* Call to Supervisor mode trap handler in CpuExceptionHandlerLib.c */
> +  call  RiscVSupervisorModeTrapHandler
> +
> +  /* Restore all general regisers except SP */
> +  ld    ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
> +  ld    gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
> +  ld    tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
> +  ld    t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
> +  ld    s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
> +  ld    s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
> +  ld    a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
> +  ld    a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
> +  ld    a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
> +  ld    a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
> +  ld    a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
> +  ld    a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
> +  ld    a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
> +  ld    a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
> +  ld    s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
> +  ld    s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
> +  ld    s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
> +  ld    s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
> +  ld    s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
> +  ld    s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
> +  ld    s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
> +  ld    s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
> +  ld    s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
> +  ld    s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
> +  ld    t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
> +  ld    t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
> +  ld    t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
> +  ld    t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
> +
> +  ld    t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
> +  csrw  CSR_SEPC, t0
> +  ld    t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)
> +  csrw  CSR_SIE, t0
> +  csrr  t0, CSR_SSTATUS
> +  ld    t1, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
> +  or    t0, t0, t1
> +  csrw  CSR_SSTATUS, t0
> +  ld    t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
> +  ld    t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
> +  addi  sp, sp, SMODE_TRAP_REGS_SIZE
> +  sret
> --
> 2.38.0
> 
> 
> 
> 
> 


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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: Add RISC-V instance
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
  2023-01-30 11:07   ` [edk2-devel] " dhaval
  2023-02-06 16:00   ` Andrei Warkentin
@ 2023-02-09  5:37   ` Ni, Ray
  2 siblings, 0 replies; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:37 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Dong, Eric, Kumar, Rahul R, Daniel Schaefer, Abner Chang,
	Gerd Hoffmann

Can you rename CpuTimerLib to RiscVTimerLib or something else that's more specific?
RiscV64 sub-directory might not be necessary.

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Sunday, January 29, 2023 3:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar,
> Rahul R <rahul.r.kumar@intel.com>; Daniel Schaefer
> <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>; Gerd
> Hoffmann <kraxel@redhat.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 08/20]
> UefiCpuPkg/CpuTimerLib: Add RISC-V instance
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> This is mostly copied from
> edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dsc                                 |   1 +
>  UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf |  32 ++++
>  UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c      | 199
> ++++++++++++++++++++
>  3 files changed, 232 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index 8f2be6cd1b05..2df02bf75a35 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -199,6 +199,7 @@ [Components.RISCV64]
>    UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
> 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHan
> dlerLib.inf
>    UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
> +  UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
> 
>  [BuildOptions]
>    *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
> b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
> new file mode 100644
> index 000000000000..c920e8e098b5
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# RISC-V Base CPU Timer Library Instance
> +#
> +#  Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> +#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = BaseRisV64CpuTimerLib
> +  FILE_GUID                      = B635A600-EA24-4199-88E8-5761EEA96A51
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = TimerLib
> +
> +[Sources]
> +  RiscV64/CpuTimerLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  DebugLib
> +
> +[Pcd]
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ##
> CONSUMES
> diff --git a/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
> b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
> new file mode 100644
> index 000000000000..9c8efc0f3530
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
> @@ -0,0 +1,199 @@
> +/** @file
> +  RISC-V instance of Timer Library.
> +
> +  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Register/RiscV64/RiscVImpl.h>
> +
> +/**
> +  Stalls the CPU for at least the given number of ticks.
> +
> +  Stalls the CPU for at least the given number of ticks. It's invoked by
> +  MicroSecondDelay() and NanoSecondDelay().
> +
> +  @param  Delay     A period of time to delay in ticks.
> +
> +**/
> +VOID
> +InternalRiscVTimerDelay (
> +  IN UINT32  Delay
> +  )
> +{
> +  UINT32  Ticks;
> +  UINT32  Times;
> +
> +  Times  = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);
> +  Delay &= ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);
> +  do {
> +    //
> +    // The target timer count is calculated here
> +    //
> +    Ticks = RiscVReadTimer () + Delay;
> +    Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);
> +    while (((Ticks - RiscVReadTimer ()) & (1 << (RISCV_TIMER_COMPARE_BITS
> - 1))) == 0) {
> +      CpuPause ();
> +    }
> +  } while (Times-- > 0);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return MicroSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +MicroSecondDelay (
> +  IN UINTN  MicroSeconds
> +  )
> +{
> +  InternalRiscVTimerDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                MicroSeconds,
> +                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
> +                ),
> +              1000000u
> +              )
> +    );
> +  return MicroSeconds;
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of nanoseconds.
> +
> +  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
> +
> +  @param  NanoSeconds The minimum number of nanoseconds to delay.
> +
> +  @return NanoSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +NanoSecondDelay (
> +  IN UINTN  NanoSeconds
> +  )
> +{
> +  InternalRiscVTimerDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                NanoSeconds,
> +                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
> +                ),
> +              1000000000u
> +              )
> +    );
> +  return NanoSeconds;
> +}
> +
> +/**
> +  Retrieves the current value of a 64-bit free running performance counter.
> +
> +  Retrieves the current value of a 64-bit free running performance counter.
> The
> +  counter can either count up by 1 or count down by 1. If the physical
> +  performance counter counts by a larger increment, then the counter
> values
> +  must be translated. The properties of the counter can be retrieved from
> +  GetPerformanceCounterProperties().
> +
> +  @return The current value of the free running performance counter.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounter (
> +  VOID
> +  )
> +{
> +  return (UINT64)RiscVReadTimer ();
> +}
> +
> +/**return
> +  Retrieves the 64-bit frequency in Hz and the range of performance counter
> +  values.
> +
> +  If StartValue is not NULL, then the value that the performance counter
> starts
> +  with immediately after is it rolls over is returned in StartValue. If
> +  EndValue is not NULL, then the value that the performance counter end
> with
> +  immediately before it rolls over is returned in EndValue. The 64-bit
> +  frequency of the performance counter in Hz is always returned. If
> StartValue
> +  is less than EndValue, then the performance counter counts up. If
> StartValue
> +  is greater than EndValue, then the performance counter counts down. For
> +  example, a 64-bit free running counter that counts up would have a
> StartValue
> +  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running
> counter
> +  that counts down would have a StartValue of 0xFFFFFF and an EndValue of
> 0.
> +
> +  @param  StartValue  The value the performance counter starts with when
> it
> +                      rolls over.
> +  @param  EndValue    The value that the performance counter ends with
> before
> +                      it rolls over.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounterProperties (
> +  OUT      UINT64 *StartValue, OPTIONAL
> +  OUT      UINT64                    *EndValue     OPTIONAL
> +  )
> +{
> +  if (StartValue != NULL) {
> +    *StartValue = 0;
> +  }
> +
> +  if (EndValue != NULL) {
> +    *EndValue = 32 - 1;
> +  }
> +
> +  return PcdGet64 (PcdCpuCoreCrystalClockFrequency);
> +}
> +
> +/**
> +  Converts elapsed ticks of performance counter to time in nanoseconds.
> +
> +  This function converts the elapsed ticks of running performance counter to
> +  time value in unit of nanoseconds.
> +
> +  @param  Ticks     The number of elapsed ticks of running performance
> counter.
> +
> +  @return The elapsed time in nanoseconds.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetTimeInNanoSecond (
> +  IN      UINT64  Ticks
> +  )
> +{
> +  UINT64  NanoSeconds;
> +  UINT32  Remainder;
> +
> +  //
> +  //          Ticks
> +  // Time = --------- x 1,000,000,000
> +  //        Frequency
> +  //
> +  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64
> (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);
> +
> +  //
> +  // Frequency < 0x100000000, so Remainder < 0x100000000, then
> (Remainder * 1,000,000,000)
> +  // will not overflow 64-bit.
> +  //
> +  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder,
> 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));
> +
> +  return NanoSeconds;
> +}
> --
> 2.38.0


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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
  2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
  2023-02-09  1:50   ` Michael D Kinney
@ 2023-02-09  5:38   ` Ni, Ray
  2 siblings, 0 replies; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:38 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Dong, Eric, Kumar, Rahul R, Gerd Hoffmann, Abner Chang

Acked-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Sunday, January 29, 2023 3:18 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar,
> Rahul R <rahul.r.kumar@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Abner Chang <abner.chang@amd.com>
> Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 09/20]
> UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> 
> RISC-V register names do not follow the EDK2 formatting.
> So, add it to ignore list for now.
> 
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Acked-by: Abner Chang <abner.chang@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.ci.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml
> b/UefiCpuPkg/UefiCpuPkg.ci.yaml
> index a377366798b0..953361ba0479 100644
> --- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
> +++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
> @@ -27,6 +27,7 @@
>          ],
>          ## Both file path and directory path are accepted.
>          "IgnoreFiles": [
> +          "Library/CpuExceptionHandlerLib/RiscV64/CpuExceptionHandlerLib.h"
>          ]
>      },
>      "CompilerPlugin": {
> --
> 2.38.0


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
  2023-02-08  5:05     ` Sunil V L
@ 2023-02-09  5:43       ` Ni, Ray
  2023-02-09  5:49         ` Sunil V L
  0 siblings, 1 reply; 80+ messages in thread
From: Ni, Ray @ 2023-02-09  5:43 UTC (permalink / raw)
  To: Sunil V L, devel

[-- Attachment #1: Type: text/plain, Size: 120 bytes --]

Since there is nothing shared between RiscV and X86, can you put the driver in a different folder such as RiscVCpuDxe?

[-- Attachment #2: Type: text/html, Size: 127 bytes --]

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: Add RISC-V instance
  2023-02-09  5:43       ` Ni, Ray
@ 2023-02-09  5:49         ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-09  5:49 UTC (permalink / raw)
  To: Ni, Ray; +Cc: devel

On Wed, Feb 08, 2023 at 09:43:39PM -0800, Ni, Ray wrote:
> Since there is nothing shared between RiscV and X86, can you put the driver in a different folder such as RiscVCpuDxe?

Thank you very much Ray. Mike had given similar feedback. I am fine with
your suggestion. Let me update the series with your suggestion for other
patches also.

Thanks,
Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  2023-02-09  1:45   ` Michael D Kinney
@ 2023-02-09  7:18     ` Sunil V L
  2023-02-09 15:47       ` Michael D Kinney
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-02-09  7:18 UTC (permalink / raw)
  To: devel, michael.d.kinney; +Cc: Gao, Liming, Liu, Zhiguang, Abner Chang

Hi Mike,

On Thu, Feb 09, 2023 at 01:45:48AM +0000, Michael D Kinney wrote:
> One comment below.
> 
> Mike
> 
> > -----Original Message-----
> > From: Sunil V L <sunilvl@ventanamicro.com>
> > Sent: Saturday, January 28, 2023 11:18 AM
> > To: devel@edk2.groups.io
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>;
> > Abner Chang <abner.chang@amd.com>
> > Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
> > 
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> > 
> > This library is required to make SBI ecalls from the S-mode EDK2.
> > This is mostly copied from
> > edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib
> > 
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> > Acked-by: Abner Chang <abner.chang@amd.com>
> > ---
> >  MdePkg/MdePkg.dec                                  |   4 +
> >  MdePkg/MdePkg.dsc                                  |   3 +
> >  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
> >  MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
> >  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
> >  5 files changed, 386 insertions(+)
> > 
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > index 3d08f20d15b0..ca2e4dcf815c 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
> >    ##  @libraryclass  Provides function to support TDX processing.
> >    TdxLib|Include/Library/TdxLib.h
> > 
> > +[LibraryClasses.RISCV64]
> > +  ##  @libraryclass  Provides function to make ecalls to SBI
> > +  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
> > +
> >  [Guids]
> >    #
> >    # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
> > diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
> > index 32a852dc466e..0ac7618b4623 100644
> > --- a/MdePkg/MdePkg.dsc
> > +++ b/MdePkg/MdePkg.dsc
> > @@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
> >    MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
> >    MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> > 
> > +[Components.RISCV64]
> > +  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > +
> >  [BuildOptions]
> > diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > new file mode 100644
> > index 000000000000..d03132bf01c1
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > @@ -0,0 +1,25 @@
> > +## @file
> > +# RISC-V Library to call SBI ecalls
> > +#
> > +#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION         = 0x0001001b
> > +  BASE_NAME           = BaseRiscVSbiLib
> > +  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
> > +  MODULE_TYPE         = BASE
> > +  VERSION_STRING      = 1.0
> > +  LIBRARY_CLASS       = RiscVSbiLib
> > +
> > +[Sources]
> > +  BaseRiscVSbiLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> > new file mode 100644
> > index 000000000000..3a3cbfb879f1
> > --- /dev/null
> > +++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> > @@ -0,0 +1,127 @@
> > +/** @file
> > +  Library to call the RISC-V SBI ecalls
> > +
> > +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +  @par Glossary:
> > +    - Hart - Hardware Thread, similar to a CPU core
> > +
> > +  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
> > +
> > +**/
> > +
> > +#ifndef RISCV_SBI_LIB_H_
> > +#define RISCV_SBI_LIB_H_
> > +
> > +#include <Uefi.h>
> > +
> > +/* SBI Extension IDs */
> > +#define SBI_EXT_TIME  0x54494D45
> > +#define SBI_EXT_SRST  0x53525354
> > +
> > +/* SBI function IDs for TIME extension*/
> > +#define SBI_EXT_TIME_SET_TIMER  0x0
> > +
> > +/* SBI function IDs for SRST extension */
> > +#define SBI_EXT_SRST_RESET  0x0
> > +
> > +#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
> > +#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1
> > +#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
> > +
> > +#define SBI_SRST_RESET_REASON_NONE     0x0
> > +#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
> > +
> > +/* SBI return error codes */
> > +#define SBI_SUCCESS                0
> > +#define SBI_ERR_FAILED             -1
> > +#define SBI_ERR_NOT_SUPPORTED      -2
> > +#define SBI_ERR_INVALID_PARAM      -3
> > +#define SBI_ERR_DENIED             -4
> > +#define SBI_ERR_INVALID_ADDRESS    -5
> > +#define SBI_ERR_ALREADY_AVAILABLE  -6
> > +#define SBI_ERR_ALREADY_STARTED    -7
> > +#define SBI_ERR_ALREADY_STOPPED    -8
> > +
> > +#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
> > +
> > +typedef struct {
> > +  UINT64    BootHartId;
> > +  VOID      *PeiServiceTable;    // PEI Service table
> > +  VOID      *PrePiHobList;       // Pre PI Hob List
> > +  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
> > +} EFI_RISCV_FIRMWARE_CONTEXT;
> > +
> > +//
> > +// EDK2 OpenSBI firmware extension return status.
> > +//
> > +typedef struct {
> > +  UINTN    Error; ///< SBI status code
> > +  UINTN    Value; ///< Value returned
> > +} SBI_RET;
> > +
> > +VOID
> > +EFIAPI
> > +SbiSetTimer (
> > +  IN  UINT64  Time
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SbiSystemReset (
> > +  IN  UINTN  ResetType,
> > +  IN  UINTN  ResetReason
> > +  );
> > +
> > +/**
> > +  Get firmware context of the calling hart.
> > +
> > +  @param[out] FirmwareContext      The firmware context pointer.
> > +**/
> > +VOID
> > +EFIAPI
> > +GetFirmwareContext (
> > +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> > +  );
> > +
> > +/**
> > +  Set firmware context of the calling hart.
> > +
> > +  @param[in] FirmwareContext       The firmware context pointer.
> > +**/
> > +VOID
> > +EFIAPI
> > +SetFirmwareContext (
> > +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> > +  );
> > +
> > +/**
> > +  Get pointer to OpenSBI Firmware Context
> > +
> > +  Get the pointer of firmware context.
> > +
> > +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> > +                                 Firmware Context.
> > +**/
> > +VOID
> > +EFIAPI
> > +GetFirmwareContextPointer (
> > +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> > +  );
> > +
> > +/**
> > +  Set pointer to OpenSBI Firmware Context
> > +
> > +  Set the pointer of firmware context.
> > +
> > +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> > +**/
> > +VOID
> > +EFIAPI
> > +SetFirmwareContextPointer (
> > +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> > +  );
> > +
> > +#endif
> > diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> > new file mode 100644
> > index 000000000000..15222a528753
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> > @@ -0,0 +1,227 @@
> > +/** @file
> > +  Instance of the SBI ecall library.
> > +
> > +  It allows calling an SBI function via an ecall from S-Mode.
> > +
> > +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseRiscVSbiLib.h>
> > +
> > +//
> > +// Maximum arguments for SBI ecall
> > +#define SBI_CALL_MAX_ARGS  6
> > +
> > +/**
> > +  Call SBI call using ecall instruction.
> > +
> > +  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
> > +
> > +  @param[in] ExtId    SBI extension ID.
> > +  @param[in] FuncId   SBI function ID.
> > +  @param[in] NumArgs  Number of arguments to pass to the ecall.
> > +  @param[in] ...      Argument list for the ecall.
> > +
> > +  @retval  Returns SBI_RET structure with value and error code.
> > +
> > +**/
> > +STATIC
> > +SBI_RET
> > +EFIAPI
> > +SbiCall (
> > +  IN  UINTN  ExtId,
> > +  IN  UINTN  FuncId,
> > +  IN  UINTN  NumArgs,
> > +  ...
> > +  )
> > +{
> > +  UINTN    I;
> > +  SBI_RET  Ret;
> > +  UINTN    Args[SBI_CALL_MAX_ARGS];
> > +  VA_LIST  ArgList;
> > +
> > +  VA_START (ArgList, NumArgs);
> > +
> > +  if (NumArgs > SBI_CALL_MAX_ARGS) {
> > +    Ret.Error = SBI_ERR_INVALID_PARAM;
> > +    Ret.Value = -1;
> > +    return Ret;
> > +  }
> > +
> > +  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
> > +    if (I < NumArgs) {
> > +      Args[I] = VA_ARG (ArgList, UINTN);
> > +    } else {
> > +      // Default to 0 for all arguments that are not given
> > +      Args[I] = 0;
> > +    }
> > +  }
> > +
> > +  VA_END (ArgList);
> > +
> > +  register UINTN  a0 asm ("a0") = Args[0];
> > +  register UINTN  a1 asm ("a1") = Args[1];
> > +  register UINTN  a2 asm ("a2") = Args[2];
> > +  register UINTN  a3 asm ("a3") = Args[3];
> > +  register UINTN  a4 asm ("a4") = Args[4];
> > +  register UINTN  a5 asm ("a5") = Args[5];
> > +  register UINTN  a6 asm ("a6") = (UINTN)(FuncId);
> > +  register UINTN  a7 asm ("a7") = (UINTN)(ExtId);
> > +
> > +  asm volatile ("ecall" \
> > +       : "+r" (a0), "+r" (a1) \
> > +       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
> > +       : "memory"); \
> > +  Ret.Error = a0;
> > +  Ret.Value = a1;
> 
> Why is inline assembly used here?  I see use of .S files in BaseLib
> Can this be converted to .S file?
> 
It was ported as is from edk2-platforms. I can convert into .S file and
I prefer to add it in this library itself than BaseLib.

Thanks!,
Sunil

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

* Re: [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
  2023-02-09  1:43   ` Michael D Kinney
@ 2023-02-09  7:21     ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-09  7:21 UTC (permalink / raw)
  To: Kinney, Michael D
  Cc: devel@edk2.groups.io, Gao, Liming, Liu, Zhiguang, Daniel Schaefer,
	Abner Chang

Hi Mike,

On Thu, Feb 09, 2023 at 01:43:57AM +0000, Kinney, Michael D wrote:
> Hi Sunil,
> 
> Just a formatting comment below.
> 
> Mike
> 
> > -----Original Message-----
> > From: Sunil V L <sunilvl@ventanamicro.com>
> > Sent: Saturday, January 28, 2023 11:18 AM
> > To: devel@edk2.groups.io
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>;
> > Daniel Schaefer <git@danielschaefer.me>; Abner Chang <abner.chang@amd.com>
> > Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions
> > 
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> > 
> > Few of the basic helper functions required for any
> > RISC-V CPU were added in edk2-platforms. To support
> > qemu virt, they need to be added in BaseLib.
> > 
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> > Cc: Daniel Schaefer <git@danielschaefer.me>
> > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> > Acked-by: Abner Chang <abner.chang@amd.com>
> > ---
> >  MdePkg/Library/BaseLib/BaseLib.inf              |  3 ++
> >  MdePkg/Include/Library/BaseLib.h                | 50 ++++++++++++++++++
> >  MdePkg/Library/BaseLib/RiscV64/CpuScratch.S     | 31 ++++++++++++
> >  MdePkg/Library/BaseLib/RiscV64/ReadTimer.S      | 23 +++++++++
> >  MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 53 ++++++++++++++++++--
> >  MdePkg/Library/BaseLib/RiscV64/RiscVMmu.S       | 23 +++++++++
> >  6 files changed, 179 insertions(+), 4 deletions(-)
> > 
> > diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
> > index 9ed46a584a14..3a48492b1a01 100644
> > --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > @@ -401,6 +401,9 @@ [Sources.RISCV64]
> >    RiscV64/RiscVCpuPause.S           | GCC
> >    RiscV64/RiscVInterrupt.S          | GCC
> >    RiscV64/FlushCache.S              | GCC
> > +  RiscV64/CpuScratch.S              | GCC
> > +  RiscV64/ReadTimer.S               | GCC
> > +  RiscV64/RiscVMmu.S                | GCC
> > 
> >  [Sources.LOONGARCH64]
> >    Math64.c
> > diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> > index f3f59f21c2ea..b4f4e45a1486 100644
> > --- a/MdePkg/Include/Library/BaseLib.h
> > +++ b/MdePkg/Include/Library/BaseLib.h
> > @@ -151,6 +151,56 @@ typedef struct {
> > 
> >  #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT  8
> > 
> > +VOID
> > +  RiscVSetSupervisorScratch (
> > +                             UINT64
> > +                             );
> > +
> > +UINT64
> > +RiscVGetSupervisorScratch (
> > +  VOID
> > +  );
> > +
> > +VOID
> > +  RiscVSetSupervisorStvec (
> > +                           UINT64
> > +                           );
> > +
> > +UINT64
> > +RiscVGetSupervisorStvec (
> > +  VOID
> > +  );
> > +
> > +UINT64
> > +RiscVGetSupervisorTrapCause (
> > +  VOID
> > +  );
> > +
> > +VOID
> > +  RiscVSetSupervisorAddressTranslationRegister (
> > +                                                UINT64
> > +                                                );
> 
> Formatting does not look right.
> 
> Have you run EDK II uncrustify on this patch series.
> 
Interesting. I ran both offline CI and CI through PR for these changes.
Anyway, thanks for catching this. Let me fix it in the next revision.

Thanks!
Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
  2023-02-08 18:02   ` [edk2-devel] " Michael D Kinney
  2023-02-09  5:21   ` Ni, Ray
@ 2023-02-09 10:17   ` Michael Brown
  2023-02-09 10:28     ` Sunil V L
  2 siblings, 1 reply; 80+ messages in thread
From: Michael Brown @ 2023-02-09 10:17 UTC (permalink / raw)
  To: devel, sunilvl
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang

> +/**
> +  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;
> +
> +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  if (mTimerNotifyFunction != NULL) {
> +    mTimerNotifyFunction (mTimerPeriod);
> +  }
> +
> +  RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +  RiscVClearPendingTimerInterrupt ();
> +  if (mTimerPeriod == 0) {
> +    gBS->RestoreTPL (OriginalTPL);
> +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> +    return;
> +  }
> +
> +  RiscvTimer               = RiscVReadTimer ();
> +  SbiSetTimer (RiscvTimer += mTimerPeriod);
> +  gBS->RestoreTPL (OriginalTPL);
> +  RiscVEnableTimerInterrupt (); // enable SMode timer int
> +}

This design looks as though it does not support nested timer interrupts. 
  The call to RestoreTPL() may invoke callbacks that may themselves 
include delay loops that wait upon further timer interrupts.  With the 
above code, those timer interrupts will never arrive since the timer 
interrupt is disabled at the point that you call RestoreTPL().

This will break device drivers such as those for USB network devices 
that rely on nested timer interrupts.


The easiest fix is to use NestedTimerInterruptLib and change the code as 
follows:

Add at the start of the function:

   STATIC NESTED_INTERRUPT_STATE NestedInterruptState;

Change:

   OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

to

   OriginalTPL = NestedInterruptRaiseTPL ();

Change:

   gBS->RestoreTPL (OriginalTPL);
   RiscVEnableTimerInterrupt (); // enable SMode timer int

to

   RiscVEnableTimerInterrupt (); // enable SMode timer int
   NestedInterruptRestoreTPL (OriginalTpl, SystemContext, 
&NestedInterruptState);

Note that the timer interrupt is then correctly re-enabled before the 
call to NestedInterruptRestoreTPL().  NestedInterruptTplLib takes care 
of the mess required behind the scenes to make this all provably safe.


You'll also need to extend Library/NestedInterruptTplLib/Iret.c to 
support MDE_CPU_RISCV64: it should be fairly obvious what's needed there.


See commit https://github.com/tianocore/edk2/commit/a086f4a63b for the 
equivalent fix being applied to OVMF.


You can find the background leading up to the creation of 
NestedInterruptTplLib at:

   https://bugzilla.tianocore.org/show_bug.cgi?id=4162
   https://github.com/tianocore/edk2/commit/9bf473da4c
   https://github.com/tianocore/edk2/commit/a24fbd6061
   https://github.com/tianocore/edk2/commit/a086f4a63b

Thanks,

Michael


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-02-09 10:17   ` Michael Brown
@ 2023-02-09 10:28     ` Sunil V L
  2023-02-09 10:30       ` Michael Brown
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-02-09 10:28 UTC (permalink / raw)
  To: Michael Brown
  Cc: devel, Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer,
	Gerd Hoffmann, Abner Chang

On Thu, Feb 09, 2023 at 10:17:56AM +0000, Michael Brown wrote:
> > +/**
> > +  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;
> > +
> > +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> > +  if (mTimerNotifyFunction != NULL) {
> > +    mTimerNotifyFunction (mTimerPeriod);
> > +  }
> > +
> > +  RiscVDisableTimerInterrupt (); // Disable SMode timer int
> > +  RiscVClearPendingTimerInterrupt ();
> > +  if (mTimerPeriod == 0) {
> > +    gBS->RestoreTPL (OriginalTPL);
> > +    RiscVDisableTimerInterrupt (); // Disable SMode timer int
> > +    return;
> > +  }
> > +
> > +  RiscvTimer               = RiscVReadTimer ();
> > +  SbiSetTimer (RiscvTimer += mTimerPeriod);
> > +  gBS->RestoreTPL (OriginalTPL);
> > +  RiscVEnableTimerInterrupt (); // enable SMode timer int
> > +}
> 
> This design looks as though it does not support nested timer interrupts.
> The call to RestoreTPL() may invoke callbacks that may themselves include
> delay loops that wait upon further timer interrupts.  With the above code,
> those timer interrupts will never arrive since the timer interrupt is
> disabled at the point that you call RestoreTPL().
> 
> This will break device drivers such as those for USB network devices that
> rely on nested timer interrupts.
> 
> 
Hi Michael!,

Thanks a lot for this feedback and background. We are aware of few issues
in this module. Currently, it is mostly porting what exists today in
edk2-platforms repo. We want to add all these additional fixes after
this basic thing is merged. That way we will have git history instead of
combining all fixes single commit. Andrei has a patch ready and waiting
for this to get merged. We can either combine this with his patch or
create one more.

Would that strategy be fine with you?

Thanks!
Sunil

> The easiest fix is to use NestedTimerInterruptLib and change the code as
> follows:
> 
> Add at the start of the function:
> 
>   STATIC NESTED_INTERRUPT_STATE NestedInterruptState;
> 
> Change:
> 
>   OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> 
> to
> 
>   OriginalTPL = NestedInterruptRaiseTPL ();
> 
> Change:
> 
>   gBS->RestoreTPL (OriginalTPL);
>   RiscVEnableTimerInterrupt (); // enable SMode timer int
> 
> to
> 
>   RiscVEnableTimerInterrupt (); // enable SMode timer int
>   NestedInterruptRestoreTPL (OriginalTpl, SystemContext,
> &NestedInterruptState);
> 
> Note that the timer interrupt is then correctly re-enabled before the call
> to NestedInterruptRestoreTPL().  NestedInterruptTplLib takes care of the
> mess required behind the scenes to make this all provably safe.
> 
> 
> You'll also need to extend Library/NestedInterruptTplLib/Iret.c to support
> MDE_CPU_RISCV64: it should be fairly obvious what's needed there.
> 
> 
> See commit https://github.com/tianocore/edk2/commit/a086f4a63b for the
> equivalent fix being applied to OVMF.
> 
> 
> You can find the background leading up to the creation of
> NestedInterruptTplLib at:
> 
>   https://bugzilla.tianocore.org/show_bug.cgi?id=4162
>   https://github.com/tianocore/edk2/commit/9bf473da4c
>   https://github.com/tianocore/edk2/commit/a24fbd6061
>   https://github.com/tianocore/edk2/commit/a086f4a63b
> 
> Thanks,
> 
> Michael
> 

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-02-09 10:28     ` Sunil V L
@ 2023-02-09 10:30       ` Michael Brown
  2023-02-09 10:37         ` Sunil V L
  0 siblings, 1 reply; 80+ messages in thread
From: Michael Brown @ 2023-02-09 10:30 UTC (permalink / raw)
  To: devel, sunilvl
  Cc: Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer, Gerd Hoffmann,
	Abner Chang

On 09/02/2023 10:28, Sunil V L wrote:
>>> +  gBS->RestoreTPL (OriginalTPL);
>>> +  RiscVEnableTimerInterrupt (); // enable SMode timer int
>>> +}
>>
>> This design looks as though it does not support nested timer interrupts.
>> The call to RestoreTPL() may invoke callbacks that may themselves include
>> delay loops that wait upon further timer interrupts.  With the above code,
>> those timer interrupts will never arrive since the timer interrupt is
>> disabled at the point that you call RestoreTPL().
>>
>> This will break device drivers such as those for USB network devices that
>> rely on nested timer interrupts.
> 
> Thanks a lot for this feedback and background. We are aware of few issues
> in this module. Currently, it is mostly porting what exists today in
> edk2-platforms repo. We want to add all these additional fixes after
> this basic thing is merged. That way we will have git history instead of
> combining all fixes single commit. Andrei has a patch ready and waiting
> for this to get merged. We can either combine this with his patch or
> create one more.
> 
> Would that strategy be fine with you?

Sure, as long as someone other than me is keeping track of the need to 
fix this bug.  My work here is done.  :)

Thanks,

Michael


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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module
  2023-02-09 10:30       ` Michael Brown
@ 2023-02-09 10:37         ` Sunil V L
  0 siblings, 0 replies; 80+ messages in thread
From: Sunil V L @ 2023-02-09 10:37 UTC (permalink / raw)
  To: Michael Brown
  Cc: devel, Eric Dong, Ray Ni, Rahul Kumar, Daniel Schaefer,
	Gerd Hoffmann, Abner Chang

On Thu, Feb 09, 2023 at 10:30:58AM +0000, Michael Brown wrote:
> On 09/02/2023 10:28, Sunil V L wrote:
> > > > +  gBS->RestoreTPL (OriginalTPL);
> > > > +  RiscVEnableTimerInterrupt (); // enable SMode timer int
> > > > +}
> > > 
> > > This design looks as though it does not support nested timer interrupts.
> > > The call to RestoreTPL() may invoke callbacks that may themselves include
> > > delay loops that wait upon further timer interrupts.  With the above code,
> > > those timer interrupts will never arrive since the timer interrupt is
> > > disabled at the point that you call RestoreTPL().
> > > 
> > > This will break device drivers such as those for USB network devices that
> > > rely on nested timer interrupts.
> > 
> > Thanks a lot for this feedback and background. We are aware of few issues
> > in this module. Currently, it is mostly porting what exists today in
> > edk2-platforms repo. We want to add all these additional fixes after
> > this basic thing is merged. That way we will have git history instead of
> > combining all fixes single commit. Andrei has a patch ready and waiting
> > for this to get merged. We can either combine this with his patch or
> > create one more.
> > 
> > Would that strategy be fine with you?
> 
> Sure, as long as someone other than me is keeping track of the need to fix
> this bug.  My work here is done.  :)
> 
Sure, I will keep track of this. We will need your help to review the changes.
Hope that is fine.

Thanks!
Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09  5:07         ` Yao, Jiewen
  2023-02-09  5:15           ` Chang, Abner
@ 2023-02-09 14:05           ` Yao, Jiewen
  2023-02-09 15:19             ` Sunil V L
  1 sibling, 1 reply; 80+ messages in thread
From: Yao, Jiewen @ 2023-02-09 14:05 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Kinney, Michael D, abner.chang@amd.com, Andrew Fish,
	Leif Lindholm

Hi Sunil
I did not find any RiscV64QemuVirt related PR there. (I searched RiscV64QemuVirt)

May I know if you have tried the patch series in EDK2 CI?

Thank you
Yao, Jiewen

> -----Original Message-----
> From: Yao, Jiewen
> Sent: Thursday, February 9, 2023 1:07 PM
> To: Sunil V L <sunilvl@ventanamicro.com>; devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; abner.chang@amd.com;
> Andrew Fish <afish@apple.com>; Leif Lindholm <quic_llindhol@quicinc.com>
> Subject: RE: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> Thanks.
> 
> I agree to add Sunil V L <sunilvl@ventanamicro.com> to be a reviewer.
> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
> 
> > -----Original Message-----
> > From: Sunil V L <sunilvl@ventanamicro.com>
> > Sent: Thursday, February 9, 2023 12:34 PM
> > To: devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@intel.com>
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; abner.chang@amd.com;
> > Andrew Fish <afish@apple.com>; Leif Lindholm <quic_llindhol@quicinc.com>
> > Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> > Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> >
> > Hi Jiewen,
> >
> > On Thu, Feb 09, 2023 at 03:32:20AM +0000, Yao, Jiewen wrote:
> > > Hello
> > > I have not tracked all discussion. Sorry for that.
> > > May I know if we have discussed the option to create RiscVVirtPkg ? similar
> to
> > https://github.com/tianocore/edk2/tree/master/ArmVirtPkg . To me, that is
> > more natural place.
> > >
> >
> > Thanks for the feedback. Yes, this was discussed and recommendation was
> > to add in OvmfPkg instead of creating RiscVVirtPkg..
> > https://edk2.groups.io/g/devel/message/85932
> >
> > >
> > > For the new content on RiscVVirt, I recommend to add one more
> > reviewer/maintainer.
> > > I notice the patches are Acked-by: Abner Chang. Can we get his help on that?
> > >
> >
> > Agree, that was in my plan to find out some one. Abner had given up
> > RISC-V mandatory roles. He was helping me here since he was the original
> > to start this. So, I didn't add him but I will be happy if Abner agrees.
> >
> > Will find out and add one more reviewer when I revise the series.
> >
> > Thanks!
> > Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09 14:05           ` Yao, Jiewen
@ 2023-02-09 15:19             ` Sunil V L
  2023-02-09 15:21               ` Yao, Jiewen
  0 siblings, 1 reply; 80+ messages in thread
From: Sunil V L @ 2023-02-09 15:19 UTC (permalink / raw)
  To: Yao, Jiewen
  Cc: devel@edk2.groups.io, Kinney, Michael D, abner.chang@amd.com,
	Andrew Fish, Leif Lindholm

On Thu, Feb 09, 2023 at 02:05:34PM +0000, Yao, Jiewen wrote:
> Hi Sunil
> I did not find any RiscV64QemuVirt related PR there. (I searched RiscV64QemuVirt)
> 
> May I know if you have tried the patch series in EDK2 CI?
> 
> Thank you
> Yao, Jiewen
> 

Hi Jiewen,

Yes, https://github.com/tianocore/edk2/pull/3962 was the PR. Once it
succeeded, I closed it since it will keep sending reminder when master
branch changes while review is in progress.

I am addressing feedback from Mike and Ray. Will raise a new CI Test PR
and send the new version of the patch series once it passes.

Thanks!
Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
  2023-02-09 15:19             ` Sunil V L
@ 2023-02-09 15:21               ` Yao, Jiewen
  0 siblings, 0 replies; 80+ messages in thread
From: Yao, Jiewen @ 2023-02-09 15:21 UTC (permalink / raw)
  To: Sunil V L
  Cc: devel@edk2.groups.io, Kinney, Michael D, abner.chang@amd.com,
	Andrew Fish, Leif Lindholm

Sounds great. Thank you!

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Thursday, February 9, 2023 11:20 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>
> Cc: devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>;
> abner.chang@amd.com; Andrew Fish <afish@apple.com>; Leif Lindholm
> <quic_llindhol@quicinc.com>
> Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 20/20]
> Maintainers.txt: Add entry for OvmfPkg/RiscVVirt
> 
> On Thu, Feb 09, 2023 at 02:05:34PM +0000, Yao, Jiewen wrote:
> > Hi Sunil
> > I did not find any RiscV64QemuVirt related PR there. (I searched
> RiscV64QemuVirt)
> >
> > May I know if you have tried the patch series in EDK2 CI?
> >
> > Thank you
> > Yao, Jiewen
> >
> 
> Hi Jiewen,
> 
> Yes, https://github.com/tianocore/edk2/pull/3962 was the PR. Once it
> succeeded, I closed it since it will keep sending reminder when master
> branch changes while review is in progress.
> 
> I am addressing feedback from Mike and Ray. Will raise a new CI Test PR
> and send the new version of the patch series once it passes.
> 
> Thanks!
> Sunil

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

* Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
  2023-02-09  7:18     ` [edk2-devel] " Sunil V L
@ 2023-02-09 15:47       ` Michael D Kinney
  0 siblings, 0 replies; 80+ messages in thread
From: Michael D Kinney @ 2023-02-09 15:47 UTC (permalink / raw)
  To: Sunil V L, devel@edk2.groups.io
  Cc: Gao, Liming, Liu, Zhiguang, Abner Chang, Kinney, Michael D

I agree with keeping the .S file in this component.

I was only referring to BaseLib as other examples that used
.S instead of inline assembly.

Mike

> -----Original Message-----
> From: Sunil V L <sunilvl@ventanamicro.com>
> Sent: Wednesday, February 8, 2023 11:19 PM
> To: devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang <zhiguang.liu@intel.com>; Abner Chang <abner.chang@amd.com>
> Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
> 
> Hi Mike,
> 
> On Thu, Feb 09, 2023 at 01:45:48AM +0000, Michael D Kinney wrote:
> > One comment below.
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: Sunil V L <sunilvl@ventanamicro.com>
> > > Sent: Saturday, January 28, 2023 11:18 AM
> > > To: devel@edk2.groups.io
> > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang
> <zhiguang.liu@intel.com>;
> > > Abner Chang <abner.chang@amd.com>
> > > Subject: [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076
> > >
> > > This library is required to make SBI ecalls from the S-mode EDK2.
> > > This is mostly copied from
> > > edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib
> > >
> > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> > > Acked-by: Abner Chang <abner.chang@amd.com>
> > > ---
> > >  MdePkg/MdePkg.dec                                  |   4 +
> > >  MdePkg/MdePkg.dsc                                  |   3 +
> > >  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf |  25 +++
> > >  MdePkg/Include/Library/BaseRiscVSbiLib.h           | 127 +++++++++++
> > >  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c   | 227 ++++++++++++++++++++
> > >  5 files changed, 386 insertions(+)
> > >
> > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > > index 3d08f20d15b0..ca2e4dcf815c 100644
> > > --- a/MdePkg/MdePkg.dec
> > > +++ b/MdePkg/MdePkg.dec
> > > @@ -316,6 +316,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
> > >    ##  @libraryclass  Provides function to support TDX processing.
> > >    TdxLib|Include/Library/TdxLib.h
> > >
> > > +[LibraryClasses.RISCV64]
> > > +  ##  @libraryclass  Provides function to make ecalls to SBI
> > > +  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
> > > +
> > >  [Guids]
> > >    #
> > >    # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
> > > diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
> > > index 32a852dc466e..0ac7618b4623 100644
> > > --- a/MdePkg/MdePkg.dsc
> > > +++ b/MdePkg/MdePkg.dsc
> > > @@ -190,4 +190,7 @@ [Components.ARM, Components.AARCH64]
> > >    MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
> > >    MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> > >
> > > +[Components.RISCV64]
> > > +  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > > +
> > >  [BuildOptions]
> > > diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > > new file mode 100644
> > > index 000000000000..d03132bf01c1
> > > --- /dev/null
> > > +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
> > > @@ -0,0 +1,25 @@
> > > +## @file
> > > +# RISC-V Library to call SBI ecalls
> > > +#
> > > +#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> > > +#
> > > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +#
> > > +##
> > > +
> > > +[Defines]
> > > +  INF_VERSION         = 0x0001001b
> > > +  BASE_NAME           = BaseRiscVSbiLib
> > > +  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508
> > > +  MODULE_TYPE         = BASE
> > > +  VERSION_STRING      = 1.0
> > > +  LIBRARY_CLASS       = RiscVSbiLib
> > > +
> > > +[Sources]
> > > +  BaseRiscVSbiLib.c
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +
> > > +[LibraryClasses]
> > > +  BaseLib
> > > diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> > > new file mode 100644
> > > index 000000000000..3a3cbfb879f1
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h
> > > @@ -0,0 +1,127 @@
> > > +/** @file
> > > +  Library to call the RISC-V SBI ecalls
> > > +
> > > +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> > > +
> > > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +  @par Glossary:
> > > +    - Hart - Hardware Thread, similar to a CPU core
> > > +
> > > +  Currently, EDK2 needs to call SBI only to set the time and to do system reset.
> > > +
> > > +**/
> > > +
> > > +#ifndef RISCV_SBI_LIB_H_
> > > +#define RISCV_SBI_LIB_H_
> > > +
> > > +#include <Uefi.h>
> > > +
> > > +/* SBI Extension IDs */
> > > +#define SBI_EXT_TIME  0x54494D45
> > > +#define SBI_EXT_SRST  0x53525354
> > > +
> > > +/* SBI function IDs for TIME extension*/
> > > +#define SBI_EXT_TIME_SET_TIMER  0x0
> > > +
> > > +/* SBI function IDs for SRST extension */
> > > +#define SBI_EXT_SRST_RESET  0x0
> > > +
> > > +#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0
> > > +#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1
> > > +#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2
> > > +
> > > +#define SBI_SRST_RESET_REASON_NONE     0x0
> > > +#define SBI_SRST_RESET_REASON_SYSFAIL  0x1
> > > +
> > > +/* SBI return error codes */
> > > +#define SBI_SUCCESS                0
> > > +#define SBI_ERR_FAILED             -1
> > > +#define SBI_ERR_NOT_SUPPORTED      -2
> > > +#define SBI_ERR_INVALID_PARAM      -3
> > > +#define SBI_ERR_DENIED             -4
> > > +#define SBI_ERR_INVALID_ADDRESS    -5
> > > +#define SBI_ERR_ALREADY_AVAILABLE  -6
> > > +#define SBI_ERR_ALREADY_STARTED    -7
> > > +#define SBI_ERR_ALREADY_STOPPED    -8
> > > +
> > > +#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED
> > > +
> > > +typedef struct {
> > > +  UINT64    BootHartId;
> > > +  VOID      *PeiServiceTable;    // PEI Service table
> > > +  VOID      *PrePiHobList;       // Pre PI Hob List
> > > +  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree
> > > +} EFI_RISCV_FIRMWARE_CONTEXT;
> > > +
> > > +//
> > > +// EDK2 OpenSBI firmware extension return status.
> > > +//
> > > +typedef struct {
> > > +  UINTN    Error; ///< SBI status code
> > > +  UINTN    Value; ///< Value returned
> > > +} SBI_RET;
> > > +
> > > +VOID
> > > +EFIAPI
> > > +SbiSetTimer (
> > > +  IN  UINT64  Time
> > > +  );
> > > +
> > > +EFI_STATUS
> > > +EFIAPI
> > > +SbiSystemReset (
> > > +  IN  UINTN  ResetType,
> > > +  IN  UINTN  ResetReason
> > > +  );
> > > +
> > > +/**
> > > +  Get firmware context of the calling hart.
> > > +
> > > +  @param[out] FirmwareContext      The firmware context pointer.
> > > +**/
> > > +VOID
> > > +EFIAPI
> > > +GetFirmwareContext (
> > > +  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext
> > > +  );
> > > +
> > > +/**
> > > +  Set firmware context of the calling hart.
> > > +
> > > +  @param[in] FirmwareContext       The firmware context pointer.
> > > +**/
> > > +VOID
> > > +EFIAPI
> > > +SetFirmwareContext (
> > > +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext
> > > +  );
> > > +
> > > +/**
> > > +  Get pointer to OpenSBI Firmware Context
> > > +
> > > +  Get the pointer of firmware context.
> > > +
> > > +  @param    FirmwareContextPtr   Pointer to retrieve pointer to the
> > > +                                 Firmware Context.
> > > +**/
> > > +VOID
> > > +EFIAPI
> > > +GetFirmwareContextPointer (
> > > +  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr
> > > +  );
> > > +
> > > +/**
> > > +  Set pointer to OpenSBI Firmware Context
> > > +
> > > +  Set the pointer of firmware context.
> > > +
> > > +  @param    FirmwareContextPtr   Pointer to Firmware Context.
> > > +**/
> > > +VOID
> > > +EFIAPI
> > > +SetFirmwareContextPointer (
> > > +  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr
> > > +  );
> > > +
> > > +#endif
> > > diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> > > new file mode 100644
> > > index 000000000000..15222a528753
> > > --- /dev/null
> > > +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
> > > @@ -0,0 +1,227 @@
> > > +/** @file
> > > +  Instance of the SBI ecall library.
> > > +
> > > +  It allows calling an SBI function via an ecall from S-Mode.
> > > +
> > > +  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
> > > +
> > > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#include <Library/BaseLib.h>
> > > +#include <Library/BaseMemoryLib.h>
> > > +#include <Library/DebugLib.h>
> > > +#include <Library/BaseRiscVSbiLib.h>
> > > +
> > > +//
> > > +// Maximum arguments for SBI ecall
> > > +#define SBI_CALL_MAX_ARGS  6
> > > +
> > > +/**
> > > +  Call SBI call using ecall instruction.
> > > +
> > > +  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
> > > +
> > > +  @param[in] ExtId    SBI extension ID.
> > > +  @param[in] FuncId   SBI function ID.
> > > +  @param[in] NumArgs  Number of arguments to pass to the ecall.
> > > +  @param[in] ...      Argument list for the ecall.
> > > +
> > > +  @retval  Returns SBI_RET structure with value and error code.
> > > +
> > > +**/
> > > +STATIC
> > > +SBI_RET
> > > +EFIAPI
> > > +SbiCall (
> > > +  IN  UINTN  ExtId,
> > > +  IN  UINTN  FuncId,
> > > +  IN  UINTN  NumArgs,
> > > +  ...
> > > +  )
> > > +{
> > > +  UINTN    I;
> > > +  SBI_RET  Ret;
> > > +  UINTN    Args[SBI_CALL_MAX_ARGS];
> > > +  VA_LIST  ArgList;
> > > +
> > > +  VA_START (ArgList, NumArgs);
> > > +
> > > +  if (NumArgs > SBI_CALL_MAX_ARGS) {
> > > +    Ret.Error = SBI_ERR_INVALID_PARAM;
> > > +    Ret.Value = -1;
> > > +    return Ret;
> > > +  }
> > > +
> > > +  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
> > > +    if (I < NumArgs) {
> > > +      Args[I] = VA_ARG (ArgList, UINTN);
> > > +    } else {
> > > +      // Default to 0 for all arguments that are not given
> > > +      Args[I] = 0;
> > > +    }
> > > +  }
> > > +
> > > +  VA_END (ArgList);
> > > +
> > > +  register UINTN  a0 asm ("a0") = Args[0];
> > > +  register UINTN  a1 asm ("a1") = Args[1];
> > > +  register UINTN  a2 asm ("a2") = Args[2];
> > > +  register UINTN  a3 asm ("a3") = Args[3];
> > > +  register UINTN  a4 asm ("a4") = Args[4];
> > > +  register UINTN  a5 asm ("a5") = Args[5];
> > > +  register UINTN  a6 asm ("a6") = (UINTN)(FuncId);
> > > +  register UINTN  a7 asm ("a7") = (UINTN)(ExtId);
> > > +
> > > +  asm volatile ("ecall" \
> > > +       : "+r" (a0), "+r" (a1) \
> > > +       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \
> > > +       : "memory"); \
> > > +  Ret.Error = a0;
> > > +  Ret.Value = a1;
> >
> > Why is inline assembly used here?  I see use of .S files in BaseLib
> > Can this be converted to .S file?
> >
> It was ported as is from edk2-platforms. I can convert into .S file and
> I prefer to add it in this library itself than BaseLib.
> 
> Thanks!,
> Sunil

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

end of thread, other threads:[~2023-02-09 15:47 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-28 19:17 [edk2-staging/RiscV64QemuVirt PATCH V7 00/20] Add support for RISC-V virt machine Sunil V L
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 01/20] MdePkg/Register: Add register definition header files for RISC-V Sunil V L
2023-02-06 15:44   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:44   ` Michael D Kinney
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 02/20] MdePkg/BaseLib: RISC-V: Add few more helper functions Sunil V L
2023-02-06 15:46   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:43   ` Michael D Kinney
2023-02-09  7:21     ` Sunil V L
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:45   ` Michael D Kinney
2023-02-09  7:18     ` [edk2-devel] " Sunil V L
2023-02-09 15:47       ` Michael D Kinney
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 04/20] UefiCpuPkg: Add RISCV_EFI_BOOT_PROTOCOL related definitions Sunil V L
2023-02-06 15:47   ` [edk2-devel] " Andrei Warkentin
2023-02-09  5:16   ` Ni, Ray
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 05/20] UefiCpuPkg: Add CpuTimerDxe module Sunil V L
2023-02-08 18:02   ` [edk2-devel] " Michael D Kinney
2023-02-08 18:12     ` Sunil V L
2023-02-09  5:21   ` Ni, Ray
2023-02-09 10:17   ` Michael Brown
2023-02-09 10:28     ` Sunil V L
2023-02-09 10:30       ` Michael Brown
2023-02-09 10:37         ` Sunil V L
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 06/20] UefiCpuPkg/CpuExceptionHandlerLib: Add RISC-V instance Sunil V L
2023-02-09  5:24   ` [edk2-devel] " Ni, Ray
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 07/20] UefiCpuPkg/CpuDxe: " Sunil V L
2023-02-06 15:58   ` [edk2-devel] " Andrei Warkentin
2023-02-08  5:05     ` Sunil V L
2023-02-09  5:43       ` Ni, Ray
2023-02-09  5:49         ` Sunil V L
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] UefiCpuPkg/CpuTimerLib: " Sunil V L
2023-01-30 11:07   ` [edk2-devel] " dhaval
2023-01-30 13:08     ` Sunil V L
2023-02-06 16:00   ` Andrei Warkentin
2023-02-09  5:37   ` Ni, Ray
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 09/20] UefiCpuPkg/UefiCpuPkg.ci.yaml: Ignore RISC-V file Sunil V L
2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:50   ` Michael D Kinney
2023-02-09  5:38   ` Ni, Ray
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize for RISC-V Sunil V L
2023-02-06 16:00   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:51   ` Michael D Kinney
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:17 ` [edk2-staging/RiscV64QemuVirt PATCH V7 12/20] ArmVirtPkg: Fix up the location of PlatformHasAcpiDtDxe Sunil V L
2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Sunil V L
2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 14/20] OvmfPkg/RiscVVirt: Add PrePiHobListPointerLib library Sunil V L
2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 15/20] OvmfPkg/RiscVVirt: Add ResetSystemLib library Sunil V L
2023-02-06 16:01   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 16/20] OvmfPkg/RiscVVirt: Add VirtNorFlashPlatformLib library Sunil V L
2023-02-06 16:02   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Sunil V L
2023-01-30 10:12   ` [edk2-devel] " dhaval
2023-01-30 13:05     ` Sunil V L
2023-01-30 14:33       ` dhaval
2023-02-06 16:02   ` Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 18/20] OvmfPkg/RiscVVirt: Add SEC module Sunil V L
2023-01-30  5:17   ` [edk2-devel] " dhaval
2023-01-30  6:00     ` Sunil V L
2023-02-06 16:03   ` Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 19/20] OvmfPkg/RiscVVirt: Add build files for Qemu Virt platform Sunil V L
2023-02-06 16:03   ` [edk2-devel] " Andrei Warkentin
2023-01-28 19:18 ` [edk2-staging/RiscV64QemuVirt PATCH V7 20/20] Maintainers.txt: Add entry for OvmfPkg/RiscVVirt Sunil V L
2023-02-06 16:04   ` [edk2-devel] " Andrei Warkentin
2023-02-09  1:51   ` Michael D Kinney
2023-02-09  3:32     ` [edk2-devel] " Yao, Jiewen
2023-02-09  4:34       ` Sunil V L
2023-02-09  5:07         ` Yao, Jiewen
2023-02-09  5:15           ` Chang, Abner
2023-02-09 14:05           ` Yao, Jiewen
2023-02-09 15:19             ` Sunil V L
2023-02-09 15:21               ` Yao, Jiewen
     [not found] ` <173E8F29CD0D02D8.27165@groups.io>
2023-01-30 13:43   ` [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 11/20] ArmVirtPkg/PlatformHasAcpiDtDxe: Move to OvmfPkg Sunil V L
2023-02-03 12:29     ` Ard Biesheuvel
     [not found] ` <173E8F254E9BED62.27165@groups.io>
2023-02-02 14:35   ` [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 03/20] MdePkg: Add BaseRiscVSbiLib Library for RISC-V Sunil V L
     [not found] ` <173E8F293E682CB4.27165@groups.io>
2023-02-03  9:46   ` [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 10/20] EmbeddedPkg: Enable PcdPrePiCpuIoSize " Sunil V L

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