minda.chen 5e944aa9ef mem: uefi mem region move to 0x41000000. | 1 anno fa | |
---|---|---|
.. | ||
Documents | 2 anni fa | |
Include | 2 anni fa | |
Library | 2 anni fa | |
Universal | 1 anno fa | |
Readme.md | 1 anno fa | |
RiscVPlatformPkg.dec | 2 anni fa | |
RiscVPlatformPkg.dsc | 2 anni fa | |
RiscVPlatformPkg.uni | 2 anni fa | |
RiscVPlatformPkgExtra.uni | 3 anni fa |
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,
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 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 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.
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.
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.
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.
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.
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.
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.
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.
Indicated as #11 in the figure
edk2 PEI OpenSBI PPI (TODO) provides the unified interface for all PEI drivers to invoke SBI services.
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.
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.
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.
The edk2 build architecture which is supported and verified on edk2 code base for
RISC-V platforms is RISCV64
.
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
.
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.
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.
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
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 |
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 |
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 | - | - |
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 |
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 |
Currently support boot to EFI Shell and Linux kernel. Refer to below link for more information, https://github.com/riscv/riscv-uefi-edk2-docs
Only RISC-V RV64 is verified on edk2.