minda.chen 5e944aa9ef mem: uefi mem region move to 0x41000000. 1 year ago
..
Documents ce006f2857 RISC-V/PlatformPkg: Update document 2 years ago
Include 0c6c5df263 RISC-V/PlatformPkg: Address Core CI Uncrustify errors 2 years ago
Library 0c6c5df263 RISC-V/PlatformPkg: Address Core CI Uncrustify errors 2 years ago
Universal 5e944aa9ef mem: uefi mem region move to 0x41000000. 1 year ago
Readme.md 28f3ce4a6a Platform/RISC-V/PlatformPkg: Fix image link error 1 year ago
RiscVPlatformPkg.dec 8a3326d280 RISC-V/PlatformPkg: Address Core CI library header check errors 2 years ago
RiscVPlatformPkg.dsc b44ca4983e RISC-V/PlatformPkg: Address ECC errors 2 years ago
RiscVPlatformPkg.uni b44ca4983e RISC-V/PlatformPkg: Address ECC errors 2 years ago
RiscVPlatformPkgExtra.uni 5fa32850d7 PlatformPkg: Add RiscVPlatformPkg 3 years ago

Readme.md

Introduction

EDK2 RISC-V Platform Project

EDK2 RISC-V Design and the Boot Processes

RISC-V edk2 port is designed base on edk2 boot phases and leverage RISC-V OpenSBI (which is the implementation of RISC-V SBI) as an edk2 library. The design concept is to leverage RISC-V SBI implementation, the basic RISC-V HARTs and the platform initialization. However, it still keeps the edk2 build mechanism and the boot processes. RISC-V OpenSBI is built as an library and linked with edk2 SEC module. The design diagram and the boot flow is shown in below figure,

RISC-V EDK2 Port Design Diagrams

RISC-V EDK2 Port

SEC Phase

As the most of edk2 platforms SEC implementations, RISC-V edk2 port SEC module initiates the fundamental platform boot environment. RISC-V edk2 SEC module linked with RiscVOpensbiLib that pulls in the OpenSBI core source files into the build as a library. SEC module invokes sbi_init() to execute through the OpenSBI initialization flow. Afterwards, SEC phase hands off to PEI phase via OpenSBI with the NextAddress and NextMode are configured. The entire SEC phase with RiscVOpensbiLib is executed in the Machine-mode (M-mode) which is the highest and the mandatory privilege mode of RISC-V HART. The SBI implementation is also executed in the M-mode that provides the Supervisor Binary Interface for the entities run in the Supervisor-mode (S-mode). The default privilege mode is configured to S-mode for the next phase after SEC, that says the PEI, DXE and BDS phases are default executed in S-mode unless the corresponding PCDs are configured differently from the default settings according to the OEM platform design.

RiscVOpensbiLib Library

Indicated as #1 in the figure

RiscVOpensbiLib is a edk2 wrapper library of OpenSBI. SEC module is the only consumer of RiscVOpensbiLib across the entire edk2 boot processes. The sub-module under RiscVOpensbiLib is updated to align with OpenSBI project. As mentioned earlier, RiscVOpensbiLib provides the RISC-V SBI implementation and initialize the OpenSBI boot flow. SEC module is also linked with below libraries,

  • edk2 OpenSbiPlatformLib library that provides the generic RISC-V platform initialization code.
  • edk2 RiscVSpecialPlatformLib library which is provided by the RISC-V platform vendor for the platform-specific initialization. The underlying implementation of above two edk2 libraries are from OpenSBI project. edk2 libraries are introduced as the wrapper libraries that separates and organizes OpenSBI core and platform code based on edk2 framework and the the build mechanism for edk2 RISC-V platforms. RiscVOpensbiLib library is located under RISC-V ProcessorPkg while the platform code (e.g. OpenSbiPlatformLib) is located under RISC-V PlatformPkg.
  • edk2 RiscVSpecialPlatformLib library is provided by the platform vendor and located under edk2 RISC-V platform-specific folder.
OpenSbiPlatformLib Library

Indicated as #2 in the figure

OpenSbiPlatformLib provides the generic RISC-V platform initialization code. Platform vendor can just utilize this library if they don’t have additional requirements on the platform initialization.

Edk2OpensbiPlatformWrapperLib Library

Indicated as #3 in the figure

In order to providing the flexibility to edk2 RISC-V firmware solution, Edk2OpensbiPlatformWrapperLib is the wrapper library of OpenSbiPlatformLib to provide the interfaces for OEM. The platform_ops_addressin the generic platform structure is replaced with Edk2OpensbiplatformOps in SEC module. The platform function invoked by OpenSBI core is hooked to Edk2OpensbiPlatformWrapperLib. This gives a change to OEM for implementing platform-specific initialization before and after the generic platform code. OEM can override this library under their platform folder on demand without touching RiscVOpensbiLib library source files and other common source files.

RiscVSpecialPlatformLib Library

Indicated as #4 in the figure

The major use case of this library is to facilitate the interfaces for platform vendors to provide the special platform initialization based on the generic platform initialization library.

Next Phase Address and Privilege Mode

Indicated as #5 in the figure

Once OpenSBI finishes the boot initialization, it will jump to the next phase with the default privilege set to S-mode. In order to facilitate the flexibility for a variant of platform demands. EDK2 RISC-V provides the PCDs as the configurable privilege for the next phase. Whether to have PEI or later phases executed in the default S-mode or to keep the RISC-V edk2 boot phase privilege in M-mode is at platform design discretion. The SEC module sets the next phase address to the PEI Core entry point with a configurable privilege according to the PCD.

PEI Phase

SEC module hands off the boot process to PEI core in the privilege configured by PcdPeiCorePrivilegeMode PCD (TODO, currently the privilege is forced to S-mode). PEI and later phases are allowed to executed in M-mode if the platform doesn’t require Hypervisor-extended Supervisor mode (HS-mode) for the virtualization. RISC-V edk2 port provides its own instance PeiCoreEntryPoint library (indicated as #7 in the figure) and linked with PlatformSecPpiLib in order to support the S-mode PEI phase. PEI core requires RiscVFirmwareContextLib library to retrieve the information of RISC-V HARTs and platform (e.g. FDT) configurations that built up in SEC phase. PeiServicePointer is also maintained in the RISC-V OpenSBI FirmwareContext structure and the pointer is retrieved by PeiServiceTablePointerOpensbi library.

PlatformSecPpiLib Library

Indicated as #8 in the figure

Some platform has the PEI protocol interface (PPI) prepared in SEC phase and pass the PPI description to PEI phase for the installation. That means the PPI code resides in SEC module and executed in PEI phase. Due to the SEC (with OpenSBI) is protected by the RISC-V Physical Memory Protection (PMP) through OpenSBI firmware domain, the SEC can be only accessed and executed when RISC-V HART is operated in M-mode. The SEC PPI passed to PEI is not able to be executed by any PEI modules. Thus we have PlatformSecPpiLib library for the platforms that requires to install the PPI at the early stage of PEI core instead of installing PPI during PEI dispatcher that maybe too late for some platform use cases. PlatformSecPpiLib is currently executed in S-mode because we force to switch RISC-V boot HART to S-mode when SEC hands of boot process to PEI phase. PlatformSecPpiLib can also executed in M-mode once we have the full implementation of PcdPeiCorePrivilegeMode.

RiscVFirmwareContextLib Library

Indicated as #9 in the figure

The OpenSBI FirmwareContext is a structure member in sbi_platform, that can carry the firmware solution-defined information to edk2 boot phases after SEC. edk2 defines its own FirmwareContext as below in the current implementation.

typedef struct {
    UINT64              BootHartId;
    VOID                *PeiServiceTable;      // PEI Service table
    UINT64              FlattenedDeviceTree;   // Pointer to Flattened Device tree
    UINT64              SecPeiHandOffData;     // This is EFI_SEC_PEI_HAND_OFF passed to PEI Core.
    EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC  *HartSpecific[RISC_V_MAX_HART_SUPPORTED];
} EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT;

RiscVFirmwareContextLib library is used by PEI module for obtaining the FirmwareContext pointer.

PeiServiceTablePointerOpensbi Library

Indicated as #10 in the figure

PeiServiceTablePointerOpensbi is the library that provides Get/Set PeiServiceTablePointer. RiscVFirmwareContextLib is the underlying library for the operations on PEI service table pointer.

PEI OpenSBI PPI

Indicated as #11 in the figure

edk2 PEI OpenSBI PPI (TODO) provides the unified interface for all PEI drivers to invoke SBI services.

DXE Phase

DXE IPL PEI module hands off the boot process to DXE Core in the privilege configured by PcdDxeCorePrivilegeMode PCD (TODO, currently is not implemented yet). edk2 DXE OpenSBI protocol (TODO, indicated as #12 in the figure) provides the unified interface for all DXE drivers to invoke SBI services.

BDS Phase

The implementation of RISC-V edk2 port in BDS phase is the same as it is in DXE phase which is executed in the privilege configured by PcdDxeCorePrivilegeMode PCD (TODO, currently the privilege is forced to S-mode). The OpenSBI is also provided through edk2 DXE OpenSBI Protocol(TODO, indicated as #12 in the figure). However, BDS must transits the privilege mode to S-mode before it handing off the boot process to S-mode OS, OS boot loader or EFI application.

EDK2 OpenSBI Firmware Domain

RISC-V EDK2 FW Domain

OpenSBI implements the firmware domain mechanism to protect the root firmware (which is the OpenSBI itself) as the M-mode only access and execute region. RISC-V edk2 port configures the root firmware domain via PCDs to protect SEC firmware volume, memory and OpenSBI stuff. The firmware region (non-root firmware) that accommodates PEI and DXE phase FV regions, while EFI variable region is reported as a separate firmware region as it shows in above figure.

EDK2 Build Architecture for RISC-V

The edk2 build architecture which is supported and verified on edk2 code base for RISC-V platforms is RISCV64.

Toolchain for RISC-V

The toolchain is on RISC-V GitHub (https://github.com/riscv/riscv-gnu-toolchain) for building edk2 RISC-V binary. The corresponding edk2 Toolchain tag for building RISC-V platform is «GCC5» declared in tools_def.txt.

Packages

There are two packages to support RISC-V edk2 platforms:

  • Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
  • Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec

RiscVPlatformPkg currently provides the generic SEC driver for all RISC-V platforms, and some platform level libraries. RiscVProcessorPkg currently provides RISC-V processor related libraries, PEI modules, DXE drivers and industrial standard header files.

EDK2 RISC-V Platform Package

RISC-V platform package provides the common modules for RISC-V platforms. RISC-V platform vendors could include RiscPlatformPkg.dec to use the common drivers, libraries, definitions, PCDs and etc. for the RISC-V platforms development.

Download the Source Code

git clone https://github.com/tianocore/edk2.git
git clone https://github.com/tianocore/edk2-platforms.git

You have to follow the build steps for EDK2 (https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II) and additionally set an environment variable to point to your RISC-V toolchain binaries for building RISC-V platforms,

# e.g. If the toolchain binaries are under /riscv-gnu-toolchain-binaries/bin
export GCC5_RISCV64_PREFIX=/riscv-gnu-toolchain-binaries/bin/riscv64-unknown-elf-

Then you can build the edk2 firmware image for RISC-V platforms.

# e.g. For building SiFive Hifive Unleashed platform:
build -a RISCV64 -t GCC5 -p Platform/SiFive/U5SeriesPkg/FreedomU540HiFiveUnleashedBoard/U540.dsc

RISC-V Platform PCD settings

EDK2 Firmware Volume Settings

EDK2 Firmware volume related PCDs which is declared in platform FDF file.

PCD name Usage
PcdRiscVSecFvBase The base address of SEC Firmware Volume
PcdRiscVSecFvSize The size of SEC Firmware Volume
PcdRiscVPeiFvBase The base address of PEI Firmware Volume
PcdRiscVPeiFvSize The size of PEI Firmware Volume
PcdRiscVDxeFvBase The base address of DXE Firmware Volume
PcdRiscVDxeFvSize The size of DXE Firmware Volume

EDK2 EFI Variable Region Settings

The PCD settings regard to EFI Variable

PCD name Usage
PcdVariableFdBaseAddress The EFI variable firmware device base address
PcdVariableFdSize The EFI variable firmware device size
PcdVariableFdBlockSize The block size of EFI variable firmware device
PcdPlatformFlashNvStorageVariableBase EFI variable base address within firmware device
PcdPlatformFlashNvStorageFtwWorkingBase The base address of EFI variable fault tolerance workspace (FTW) within firmware device
PcdPlatformFlashNvStorageFtwSpareBase The base address of EFI variable spare FTW within firmware device

RISC-V Physical Memory Protection (PMP) Region Settings

Below PCDs could be set in platform FDF file.

PCD name Usage Access Permission in M-mode Access Permission in S-mode
PcdRootFirmwareDomainBaseAddress The starting address of root firmware domain protected by PMP Full access No Access
PcdRootFirmwareDomainSize The size of root firmware domain - -
PcdFirmwareDomainBaseAddress The starting address of firmware domain that can be accessed and executed in S-mode Full access Readable and Executable
PcdFirmwareDomainSize The size of firmware domain - -
PcdVariableFirmwareRegionBaseAddress The starting address of EFI variable region that can be accessed in S-mode Full access Readable and Writable
PcdVariableFirmwareRegionSize The size of EFI variable firmware region - -

RISC-V Processor HART Settings

PCD name Usage
PcdHartCount Number of RISC-V HARTs, the value is processor-implementation specific
PcdBootHartId The ID of RISC-V HART to execute main firmware code and boot system to OS
PcdBootableHartNumber The bootable HART number, which is incorporate with RISC-V OpenSBI platform hart_index2id value
PcdBootableHartIndexToId if PcdBootableHartNumber == 0, hart_index2id is built from Device Tree, otherwise this is an array of HART index to HART ID

RISC-V OpenSBI Settings

PCD name Usage
PcdScratchRamBase The base address of RISC-V OpenSBI scratch buffer for all RISC-V HARTs
PcdScratchRamSize The total size of RISC-V OpenSBI scratch buffer for all RISC-V HARTs
PcdOpenSbiStackSize The size of initial stack of each RISC-V HART for booting system use RISC-V OpenSBI
PcdTemporaryRamBase The base address of temporary memory for PEI phase
PcdTemporaryRamSize The temporary memory size for PEI phase
PcdPeiCorePrivilegeMode The target RISC-V privilege mode for edk2 PEI phase
PcdDxeCorePrivilegeMode (TODO) The target RISC-V privilege mode for edk2 DXE phase

Supported Operating Systems

Currently support boot to EFI Shell and Linux kernel. Refer to below link for more information, https://github.com/riscv/riscv-uefi-edk2-docs

Known Issues and Limitations

Only RISC-V RV64 is verified on edk2.