* [PATCH v2 0/3] New RISC-V Patches @ 2020-05-15 13:39 Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule Daniel Schaefer ` (3 more replies) 0 siblings, 4 replies; 19+ messages in thread From: Daniel Schaefer @ 2020-05-15 13:39 UTC (permalink / raw) To: devel; +Cc: Abner Chang, Gilbert Chen, Michael D Kinney, Leif Lindholm In this updated version I addressed Leif's comments and made the following changes: - Refactor sbi_call* to SbiCall* (EDKII style) - Use OpenSBI constants if possible - Include Base.h in OpensbiTypes.h - Only use __builtin_expect with Clang and GCC (not MSVC) I'm sorry, I hadn't explained the new branches properly. Previously we had all code going to EDK2 via the RISC-V-V2 branch. Now we're only making the least amount of necessary changes in edk2 and everything else in edk2-platforms. Those changes to edk2 can be grouped into different categories: - Patches for RISC-V EDK2 CI enablement - Patches for edk2 modules other than RISC-V ones, to allow building them with the RISC-V toolchain - Other RISC-V enablement like PE/COFF relocation Those have all been reviewed and merged to edk2 master. Previously we had two packages just for RISC-V on our edk2 branch: RiscVPkg and RiscVPlatformPkg They are now under Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg in edk2-platforms. You, Leif, have previously reviewed those. In addition to this old code, which was moved, we need some more patches to allow running PEI in S-Mode and building in edk2-platforms. That's what this patch series is about. In the previous version of this patchseries I forgot to attach the biggest new commit, which adds RiscVEdk2SbiLib. It wraps the ecall interface for calling SBI in a C API and lets PEI and DXE call SBI interfaces. Because we need more M-Mode capabilities in PEI and DXE than SBI gives us, we register another SBI extension, that gives us access to the mscratch register. I hope now it makes more sense. - Daniel Cc: Abner Chang <abner.chang@hpe.com> Cc: Gilbert Chen <gilbert.chen@hpe.com> Cc: Michael D Kinney <michael.k.kinney@intel.com> Cc: Leif Lindholm <leif@nuviainc.com> Abner Chang (1): ProcessorPkg/Library: Add RiscVOpensbiLib Daniel Schaefer (2): ProcessorPkg/RiscVOpensbLib: Add opensbi submodule ProcessorPkg/Library: Add RiscVEdk2SbiLib Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 60 ++ Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 72 ++ Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h | 73 ++ Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ .gitmodules | 3 + Readme.md | 36 + Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi | 1 + 9 files changed, 1693 insertions(+) create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c create mode 100644 .gitmodules create mode 160000 Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi -- 2.26.1 ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule 2020-05-15 13:39 [PATCH v2 0/3] New RISC-V Patches Daniel Schaefer @ 2020-05-15 13:39 ` Daniel Schaefer 2020-05-20 11:51 ` Leif Lindholm 2020-05-15 13:39 ` [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib Daniel Schaefer ` (2 subsequent siblings) 3 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-15 13:39 UTC (permalink / raw) To: devel; +Cc: Gilbert Chen, Abner Chang, Michael D Kinney, Leif Lindholm Add submodule opensbi under Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbLlib. The current supported opensbi version for RISC-V edk2 port is tags/v0.6. Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> Co-authored-by: Abner Chang <abner.chang@hpe.com> Cc: Abner Chang <abner.chang@hpe.com> Cc: Gilbert Chen <gilbert.chen@hpe.com> Cc: Michael D Kinney <michael.k.kinney@intel.com> Cc: Leif Lindholm <leif@nuviainc.com> --- .gitmodules | 3 ++ Readme.md | 36 ++++++++++++++++++++ Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi | 1 + 3 files changed, 40 insertions(+) diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..88aafaf15820 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi"] + path = Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi + url = https://github.com/riscv/opensbi diff --git a/Readme.md b/Readme.md index 8f9522659d7b..8f7317e6b029 100644 --- a/Readme.md +++ b/Readme.md @@ -10,6 +10,10 @@ The majority of the content in the EDK II open source project uses a [BSD-2-Clause Plus Patent License](License.txt). Additional details on EDK II open source project code contributions can be found in the edk2 repository [Readme.md](https://github.com/tianocore/edk2/blob/master/Readme.md). +The EDK II Platforms open source project contains the following components that +are covered by additional licenses: + +- [`Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi`](https://github.com/riscv/opensbi/blob/master/COPYING.BSD) # INDEX * [Overview](#overview) @@ -260,3 +264,35 @@ For more information, see the # Maintainers See [Maintainers.txt](Maintainers.txt). + +# Submodules + +Submodule in EDK II Platforms is allowed but submodule chain should be avoided +as possible as we can. Currently EDK II Platforms contains the following +submodules + +- Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi + +To get a full, buildable EDK II repository, use following steps of git command + +```bash + git clone https://github.com/tianocore/edk2-platforms.git + cd edk2-platforms + git submodule update --init + cd .. +``` + +If there's update for submodules, use following git commands to get the latest +submodules code. + +```bash + cd edk2-platforms + git pull + git submodule update +``` + +Note: When cloning submodule repos, '--recursive' option is not recommended. +EDK II Platforms itself will not use any code/feature from submodules in above +submodules. So using '--recursive' adds a dependency on being able to reach +servers we do not actually want any code from, as well as needlessly +downloading code we will not use. diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi new file mode 160000 index 000000000000..ac5e821d50be --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi @@ -0,0 +1 @@ +Subproject commit ac5e821d50be631f26274765a59bc1b444ffd862 -- 2.26.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule 2020-05-15 13:39 ` [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule Daniel Schaefer @ 2020-05-20 11:51 ` Leif Lindholm 0 siblings, 0 replies; 19+ messages in thread From: Leif Lindholm @ 2020-05-20 11:51 UTC (permalink / raw) To: Daniel Schaefer; +Cc: devel, Gilbert Chen, Abner Chang, Michael D Kinney On Fri, May 15, 2020 at 15:39:35 +0200, Daniel Schaefer wrote: > Add submodule opensbi under > Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbLlib. > The current supported opensbi version for RISC-V edk2 port is tags/v0.6. > > Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> > Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> > Co-authored-by: Abner Chang <abner.chang@hpe.com> Please drop the above two lines. >From a project standpoint they are no-ops and I don't really mind keeping them in 2-3/3 (I appreciate the sentiment), but this patch isn't interesting enough to justify it, and mainly duplicates/modifies content already in edk2/ReadMe.rst. With that: Reviewed-by: Leif Lindholm <leif@nuviainc.com> > > Cc: Abner Chang <abner.chang@hpe.com> > Cc: Gilbert Chen <gilbert.chen@hpe.com> > Cc: Michael D Kinney <michael.k.kinney@intel.com> > Cc: Leif Lindholm <leif@nuviainc.com> > --- > .gitmodules | 3 ++ > Readme.md | 36 ++++++++++++++++++++ > Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi | 1 + > 3 files changed, 40 insertions(+) > > diff --git a/.gitmodules b/.gitmodules > new file mode 100644 > index 000000000000..88aafaf15820 > --- /dev/null > +++ b/.gitmodules > @@ -0,0 +1,3 @@ > +[submodule "Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi"] > + path = Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi > + url = https://github.com/riscv/opensbi > diff --git a/Readme.md b/Readme.md > index 8f9522659d7b..8f7317e6b029 100644 > --- a/Readme.md > +++ b/Readme.md > @@ -10,6 +10,10 @@ The majority of the content in the EDK II open source project uses a > [BSD-2-Clause Plus Patent License](License.txt). Additional details on EDK II > open source project code contributions can be found in the edk2 repository > [Readme.md](https://github.com/tianocore/edk2/blob/master/Readme.md). > +The EDK II Platforms open source project contains the following components that > +are covered by additional licenses: > + > +- [`Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi`](https://github.com/riscv/opensbi/blob/master/COPYING.BSD) > > # INDEX > * [Overview](#overview) > @@ -260,3 +264,35 @@ For more information, see the > # Maintainers > > See [Maintainers.txt](Maintainers.txt). > + > +# Submodules > + > +Submodule in EDK II Platforms is allowed but submodule chain should be avoided > +as possible as we can. Currently EDK II Platforms contains the following > +submodules > + > +- Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi > + > +To get a full, buildable EDK II repository, use following steps of git command > + > +```bash > + git clone https://github.com/tianocore/edk2-platforms.git > + cd edk2-platforms > + git submodule update --init > + cd .. > +``` > + > +If there's update for submodules, use following git commands to get the latest > +submodules code. > + > +```bash > + cd edk2-platforms > + git pull > + git submodule update > +``` > + > +Note: When cloning submodule repos, '--recursive' option is not recommended. > +EDK II Platforms itself will not use any code/feature from submodules in above > +submodules. So using '--recursive' adds a dependency on being able to reach > +servers we do not actually want any code from, as well as needlessly > +downloading code we will not use. > diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi > new file mode 160000 > index 000000000000..ac5e821d50be > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi > @@ -0,0 +1 @@ > +Subproject commit ac5e821d50be631f26274765a59bc1b444ffd862 > -- > 2.26.1 > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib 2020-05-15 13:39 [PATCH v2 0/3] New RISC-V Patches Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule Daniel Schaefer @ 2020-05-15 13:39 ` Daniel Schaefer 2020-05-20 12:00 ` Leif Lindholm 2020-05-15 13:39 ` [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Daniel Schaefer 2020-05-20 11:43 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches Leif Lindholm 3 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-15 13:39 UTC (permalink / raw) To: devel Cc: Gilbert Chen, Leif Lindholm, Abner Chang, Michael D Kinney, Leif Lindholm From: Abner Chang <abner.chang@hpe.com> EDK2 RISC-V OpenSBI library which pull in external source files under RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi to the build process. Signed-off-by: Abner Chang <abner.chang@hpe.com> Co-authored-by: Daniel Schaefer <daniel.schaefer@hpe.com> Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Cc: Abner Chang <abner.chang@hpe.com> Cc: Gilbert Chen <gilbert.chen@hpe.com> Cc: Michael D Kinney <michael.k.kinney@intel.com> Cc: Leif Lindholm <leif@nuviainc.com> --- Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 60 +++++++++++++++ Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 79 ++++++++++++++++++++ Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h | 73 ++++++++++++++++++ 3 files changed, 212 insertions(+) diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf new file mode 100644 index 000000000000..59dbd67d8e03 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf @@ -0,0 +1,60 @@ +## @file +# RISC-V Opensbi Library Instance. +# +# 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 = RiscVOpensbiLib + FILE_GUID = 6EF0C812-66F6-11E9-93CE-3F5D5F0DF0A7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RiscVOpensbiLib + +[Sources] + opensbi/lib/sbi/riscv_asm.c + opensbi/lib/sbi/riscv_atomic.c + opensbi/lib/sbi/riscv_hardfp.S + opensbi/lib/sbi/riscv_locks.c + opensbi/lib/sbi/sbi_console.c + opensbi/lib/sbi/sbi_ecall.c + opensbi/lib/sbi/sbi_ecall_vendor.c + opensbi/lib/sbi/sbi_ecall_replace.c + opensbi/lib/sbi/sbi_ecall_legacy.c + opensbi/lib/sbi/sbi_ecall_base.c + opensbi/lib/sbi/sbi_emulate_csr.c + opensbi/lib/sbi/sbi_fifo.c + opensbi/lib/sbi/sbi_hart.c + opensbi/lib/sbi/sbi_hfence.S + opensbi/lib/sbi/sbi_illegal_insn.c + opensbi/lib/sbi/sbi_init.c + opensbi/lib/sbi/sbi_ipi.c + opensbi/lib/sbi/sbi_misaligned_ldst.c + opensbi/lib/sbi/sbi_scratch.c + opensbi/lib/sbi/sbi_string.c + opensbi/lib/sbi/sbi_system.c + opensbi/lib/sbi/sbi_timer.c + opensbi/lib/sbi/sbi_tlb.c + opensbi/lib/sbi/sbi_trap.c + opensbi/lib/sbi/sbi_unpriv.c + opensbi/lib/utils/sys/clint.c + opensbi/lib/utils/irqchip/plic.c + opensbi/lib/utils/serial/sifive-uart.c + opensbi/lib/utils/serial/uart8250.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec # For libfdt. + MdePkg/MdePkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + RiscVCpuLib + + + diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h new file mode 100644 index 000000000000..c5c0bd6d9b01 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h @@ -0,0 +1,79 @@ +/** @file + SBI inline function calls. + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDK2_SBI_H_ +#define EDK2_SBI_H_ + +#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi +#include <RiscVImpl.h> +#include <sbi/sbi_types.h> // Reference to header file wrapper + +#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_BASE_EXT 0x10 +#define SBI_HSM_EXT 0x48534D +#define SBI_TIME_EXT 0x54494D45 +#define SBI_IPI_EXT 0x735049 +#define SBI_RFNC_EXT 0x52464E43 + +// +// Below two definitions should be defined in OpenSBI. +// +#define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 +#define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF + +#define SBI_GET_SPEC_VERSION_FUNC 0 +#define SBI_GET_IMPL_ID_FUNC 1 +#define SBI_GET_IMPL_VERSION_FUNC 2 +#define SBI_PROBE_EXTENSION_FUNC 3 +#define SBI_GET_MVENDORID_FUNC 4 +#define SBI_GET_MARCHID_FUNC 5 +#define SBI_GET_MIMPID_FUNC 6 + +#define SBI_HART_START_FUNC 0 +#define SBI_HART_STOP_FUNC 1 +#define SBI_HART_GET_STATUS_FUNC 2 + +#define RISC_V_MAX_HART_SUPPORTED 16 + +typedef +VOID +(EFIAPI *RISCV_HART_SWITCH_MODE)( + IN UINTN FuncArg0, + IN UINTN FuncArg1, + IN UINTN NextAddr, + IN UINTN NextMode, + IN BOOLEAN NextVirt + ); + +// +// Keep the structure member in 64-bit alignment. +// +typedef struct { + UINT64 IsaExtensionSupported; // The ISA extension this core supported. + RISCV_UINT128 MachineVendorId; // Machine vendor ID + RISCV_UINT128 MachineArchId; // Machine Architecture ID + RISCV_UINT128 MachineImplId; // Machine Implementation ID + RISCV_HART_SWITCH_MODE HartSwitchMode; // OpenSBI's function to switch the mode of a hart +} EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC; +#define FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE (64 * 8) // This is the size of EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC + // structure. Referred by both C code and assembly code. + +typedef struct { + VOID *PeiServiceTable; // PEI Service table + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartSpecific[RISC_V_MAX_HART_SUPPORTED]; +} EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT; + +#endif diff --git a/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h new file mode 100644 index 000000000000..5f3278e8461f --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h @@ -0,0 +1,73 @@ +/** @file + RISC-V OpesbSBI header file reference. + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef EDK2_SBI_TYPES_H_ +#define EDK2_SBI_TYPES_H_ + +#include <Base.h> + +typedef INT8 s8; +typedef UINT8 u8; +typedef UINT8 uint8_t; + +typedef INT16 s16; +typedef UINT16 u16; +typedef INT16 int16_t; +typedef UINT16 uint16_t; + +typedef INT32 s32; +typedef UINT32 u32; +typedef INT32 int32_t; +typedef UINT32 uint32_t; + +typedef INT64 s64; +typedef UINT64 u64; +typedef INT64 int64_t; +typedef UINT64 uint64_t; + +#define PRILX "016lx" + +typedef BOOLEAN bool; +typedef unsigned long ulong; +typedef UINT64 uintptr_t; +typedef UINT64 size_t; +typedef INT64 ssize_t; +typedef UINT64 virtual_addr_t; +typedef UINT64 virtual_size_t; +typedef UINT64 physical_addr_t; +typedef UINT64 physical_size_t; + +#define __packed __attribute__((packed)) +#define __noreturn __attribute__((noreturn)) + +#if defined(__GNUC__) || defined(__clang__) + #define likely(x) __builtin_expect((x), 1) + #define unlikely(x) __builtin_expect((x), 0) +#else + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +#undef offsetof +#ifdef __compiler_offsetof +#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER) +#else +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member) * __mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) + +#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi) +#define ROUNDUP(a, b) ((((a)-1) / (b) + 1) * (b)) +#define ROUNDDOWN(a, b) ((a) / (b) * (b)) + +/* clang-format on */ + +#endif -- 2.26.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib 2020-05-15 13:39 ` [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib Daniel Schaefer @ 2020-05-20 12:00 ` Leif Lindholm 2020-05-20 14:44 ` Daniel Schaefer 0 siblings, 1 reply; 19+ messages in thread From: Leif Lindholm @ 2020-05-20 12:00 UTC (permalink / raw) To: Daniel Schaefer Cc: devel, Gilbert Chen, Leif Lindholm, Abner Chang, Michael D Kinney (Fixing Mike's email in reply) On Fri, May 15, 2020 at 15:39:36 +0200, Daniel Schaefer wrote: > From: Abner Chang <abner.chang@hpe.com> > > EDK2 RISC-V OpenSBI library which pull in external source files under > RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi to the build process. > > Signed-off-by: Abner Chang <abner.chang@hpe.com> > Co-authored-by: Daniel Schaefer <daniel.schaefer@hpe.com> These two fields have flipped contents since v1 (without being mentioned in either cover letter or below --- of this one). The v1 form was correct - only the contributor can certify the adherence of the contribution to https://developercertificate.org/. > Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> > Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> > > Cc: Abner Chang <abner.chang@hpe.com> > Cc: Gilbert Chen <gilbert.chen@hpe.com> > Cc: Michael D Kinney <michael.k.kinney@intel.com> > Cc: Leif Lindholm <leif@nuviainc.com> > --- > Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 60 +++++++++++++++ > Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 79 ++++++++++++++++++++ > Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h | 73 ++++++++++++++++++ > 3 files changed, 212 insertions(+) > > diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf > new file mode 100644 > index 000000000000..59dbd67d8e03 > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf > @@ -0,0 +1,60 @@ > +## @file > +# RISC-V Opensbi Library Instance. > +# > +# 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 = RiscVOpensbiLib > + FILE_GUID = 6EF0C812-66F6-11E9-93CE-3F5D5F0DF0A7 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = RiscVOpensbiLib > + > +[Sources] > + opensbi/lib/sbi/riscv_asm.c > + opensbi/lib/sbi/riscv_atomic.c > + opensbi/lib/sbi/riscv_hardfp.S > + opensbi/lib/sbi/riscv_locks.c > + opensbi/lib/sbi/sbi_console.c > + opensbi/lib/sbi/sbi_ecall.c > + opensbi/lib/sbi/sbi_ecall_vendor.c > + opensbi/lib/sbi/sbi_ecall_replace.c > + opensbi/lib/sbi/sbi_ecall_legacy.c > + opensbi/lib/sbi/sbi_ecall_base.c > + opensbi/lib/sbi/sbi_emulate_csr.c > + opensbi/lib/sbi/sbi_fifo.c > + opensbi/lib/sbi/sbi_hart.c > + opensbi/lib/sbi/sbi_hfence.S > + opensbi/lib/sbi/sbi_illegal_insn.c > + opensbi/lib/sbi/sbi_init.c > + opensbi/lib/sbi/sbi_ipi.c > + opensbi/lib/sbi/sbi_misaligned_ldst.c > + opensbi/lib/sbi/sbi_scratch.c > + opensbi/lib/sbi/sbi_string.c > + opensbi/lib/sbi/sbi_system.c > + opensbi/lib/sbi/sbi_timer.c > + opensbi/lib/sbi/sbi_tlb.c > + opensbi/lib/sbi/sbi_trap.c > + opensbi/lib/sbi/sbi_unpriv.c > + opensbi/lib/utils/sys/clint.c > + opensbi/lib/utils/irqchip/plic.c > + opensbi/lib/utils/serial/sifive-uart.c > + opensbi/lib/utils/serial/uart8250.c > + > +[Packages] > + EmbeddedPkg/EmbeddedPkg.dec # For libfdt. > + MdePkg/MdePkg.dec > + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec > + > +[LibraryClasses] > + BaseLib > + PcdLib > + RiscVCpuLib > + > + > + > diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > new file mode 100644 > index 000000000000..c5c0bd6d9b01 > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > @@ -0,0 +1,79 @@ > +/** @file > + SBI inline function calls. > + > + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef EDK2_SBI_H_ > +#define EDK2_SBI_H_ > + > +#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi > +#include <RiscVImpl.h> > +#include <sbi/sbi_types.h> // Reference to header file wrapper > + > +#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 Did the cover-letter changelog not suggest these had been changed from local definitions to redefining the existing ones from Opensbi? If this was "not possible" (the exception stated in cover letter), I would have expected a comment above (below ---) on why. Or a reply to my feedback on v1. > + > +#define SBI_BASE_EXT 0x10 > +#define SBI_HSM_EXT 0x48534D > +#define SBI_TIME_EXT 0x54494D45 > +#define SBI_IPI_EXT 0x735049 > +#define SBI_RFNC_EXT 0x52464E43 > + > +// > +// Below two definitions should be defined in OpenSBI. > +// > +#define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 > +#define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF > + > +#define SBI_GET_SPEC_VERSION_FUNC 0 > +#define SBI_GET_IMPL_ID_FUNC 1 > +#define SBI_GET_IMPL_VERSION_FUNC 2 > +#define SBI_PROBE_EXTENSION_FUNC 3 > +#define SBI_GET_MVENDORID_FUNC 4 > +#define SBI_GET_MARCHID_FUNC 5 > +#define SBI_GET_MIMPID_FUNC 6 > + > +#define SBI_HART_START_FUNC 0 > +#define SBI_HART_STOP_FUNC 1 > +#define SBI_HART_GET_STATUS_FUNC 2 > + > +#define RISC_V_MAX_HART_SUPPORTED 16 > + > +typedef > +VOID > +(EFIAPI *RISCV_HART_SWITCH_MODE)( > + IN UINTN FuncArg0, > + IN UINTN FuncArg1, > + IN UINTN NextAddr, > + IN UINTN NextMode, > + IN BOOLEAN NextVirt > + ); > + > +// > +// Keep the structure member in 64-bit alignment. > +// > +typedef struct { > + UINT64 IsaExtensionSupported; // The ISA extension this core supported. > + RISCV_UINT128 MachineVendorId; // Machine vendor ID > + RISCV_UINT128 MachineArchId; // Machine Architecture ID > + RISCV_UINT128 MachineImplId; // Machine Implementation ID > + RISCV_HART_SWITCH_MODE HartSwitchMode; // OpenSBI's function to switch the mode of a hart > +} EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC; > +#define FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE (64 * 8) // This is the size of EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC > + // structure. Referred by both C code and assembly code. > + > +typedef struct { > + VOID *PeiServiceTable; // PEI Service table > + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartSpecific[RISC_V_MAX_HART_SUPPORTED]; > +} EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT; > + > +#endif > diff --git a/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h > new file mode 100644 > index 000000000000..5f3278e8461f > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h > @@ -0,0 +1,73 @@ > +/** @file > + RISC-V OpesbSBI header file reference. > + > + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#ifndef EDK2_SBI_TYPES_H_ > +#define EDK2_SBI_TYPES_H_ > + > +#include <Base.h> > + > +typedef INT8 s8; > +typedef UINT8 u8; > +typedef UINT8 uint8_t; > + > +typedef INT16 s16; > +typedef UINT16 u16; > +typedef INT16 int16_t; > +typedef UINT16 uint16_t; > + > +typedef INT32 s32; > +typedef UINT32 u32; > +typedef INT32 int32_t; > +typedef UINT32 uint32_t; > + > +typedef INT64 s64; > +typedef UINT64 u64; > +typedef INT64 int64_t; > +typedef UINT64 uint64_t; > + > +#define PRILX "016lx" Feedback on PRILX not addressed, or commented on. / Leif > + > +typedef BOOLEAN bool; > +typedef unsigned long ulong; > +typedef UINT64 uintptr_t; > +typedef UINT64 size_t; > +typedef INT64 ssize_t; > +typedef UINT64 virtual_addr_t; > +typedef UINT64 virtual_size_t; > +typedef UINT64 physical_addr_t; > +typedef UINT64 physical_size_t; > + > +#define __packed __attribute__((packed)) > +#define __noreturn __attribute__((noreturn)) > + > +#if defined(__GNUC__) || defined(__clang__) > + #define likely(x) __builtin_expect((x), 1) > + #define unlikely(x) __builtin_expect((x), 0) > +#else > + #define likely(x) (x) > + #define unlikely(x) (x) > +#endif > + > +#undef offsetof > +#ifdef __compiler_offsetof > +#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER) > +#else > +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) > +#endif > + > +#define container_of(ptr, type, member) ({ \ > + const typeof(((type *)0)->member) * __mptr = (ptr); \ > + (type *)((char *)__mptr - offsetof(type, member)); }) > + > +#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi) > +#define ROUNDUP(a, b) ((((a)-1) / (b) + 1) * (b)) > +#define ROUNDDOWN(a, b) ((a) / (b) * (b)) > + > +/* clang-format on */ > + > +#endif > -- > 2.26.1 > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib 2020-05-20 12:00 ` Leif Lindholm @ 2020-05-20 14:44 ` Daniel Schaefer 0 siblings, 0 replies; 19+ messages in thread From: Daniel Schaefer @ 2020-05-20 14:44 UTC (permalink / raw) To: Leif Lindholm Cc: devel, Gilbert Chen, Leif Lindholm, Abner Chang, Michael D Kinney On 5/20/20 2:00 PM, Leif Lindholm wrote: > (Fixing Mike's email in reply) > > On Fri, May 15, 2020 at 15:39:36 +0200, Daniel Schaefer wrote: >> From: Abner Chang <abner.chang@hpe.com> >> >> EDK2 RISC-V OpenSBI library which pull in external source files under >> RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi to the build process. >> >> Signed-off-by: Abner Chang <abner.chang@hpe.com> >> Co-authored-by: Daniel Schaefer <daniel.schaefer@hpe.com> > > These two fields have flipped contents since v1 (without being > mentioned in either cover letter or below --- of this one). > > The v1 form was correct - only the contributor can certify the > adherence of the contribution to https://developercertificate.org/ . > Meaning if the commit says Signed-off-by: Abner, I can't send it to the list? >> Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> >> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> >> >> Cc: Abner Chang <abner.chang@hpe.com> >> Cc: Gilbert Chen <gilbert.chen@hpe.com> >> Cc: Michael D Kinney <michael.k.kinney@intel.com> >> Cc: Leif Lindholm <leif@nuviainc.com> >> --- >> Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 60 +++++++++++++++ >> Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 79 ++++++++++++++++++++ >> Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h | 73 ++++++++++++++++++ >> 3 files changed, 212 insertions(+) >> >> diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf >> new file mode 100644 >> index 000000000000..59dbd67d8e03 >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf >> @@ -0,0 +1,60 @@ >> +## @file >> +# RISC-V Opensbi Library Instance. >> +# >> +# 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 = RiscVOpensbiLib >> + FILE_GUID = 6EF0C812-66F6-11E9-93CE-3F5D5F0DF0A7 >> + MODULE_TYPE = BASE >> + VERSION_STRING = 1.0 >> + LIBRARY_CLASS = RiscVOpensbiLib >> + >> +[Sources] >> + opensbi/lib/sbi/riscv_asm.c >> + opensbi/lib/sbi/riscv_atomic.c >> + opensbi/lib/sbi/riscv_hardfp.S >> + opensbi/lib/sbi/riscv_locks.c >> + opensbi/lib/sbi/sbi_console.c >> + opensbi/lib/sbi/sbi_ecall.c >> + opensbi/lib/sbi/sbi_ecall_vendor.c >> + opensbi/lib/sbi/sbi_ecall_replace.c >> + opensbi/lib/sbi/sbi_ecall_legacy.c >> + opensbi/lib/sbi/sbi_ecall_base.c >> + opensbi/lib/sbi/sbi_emulate_csr.c >> + opensbi/lib/sbi/sbi_fifo.c >> + opensbi/lib/sbi/sbi_hart.c >> + opensbi/lib/sbi/sbi_hfence.S >> + opensbi/lib/sbi/sbi_illegal_insn.c >> + opensbi/lib/sbi/sbi_init.c >> + opensbi/lib/sbi/sbi_ipi.c >> + opensbi/lib/sbi/sbi_misaligned_ldst.c >> + opensbi/lib/sbi/sbi_scratch.c >> + opensbi/lib/sbi/sbi_string.c >> + opensbi/lib/sbi/sbi_system.c >> + opensbi/lib/sbi/sbi_timer.c >> + opensbi/lib/sbi/sbi_tlb.c >> + opensbi/lib/sbi/sbi_trap.c >> + opensbi/lib/sbi/sbi_unpriv.c >> + opensbi/lib/utils/sys/clint.c >> + opensbi/lib/utils/irqchip/plic.c >> + opensbi/lib/utils/serial/sifive-uart.c >> + opensbi/lib/utils/serial/uart8250.c >> + >> +[Packages] >> + EmbeddedPkg/EmbeddedPkg.dec # For libfdt. >> + MdePkg/MdePkg.dec >> + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> + PcdLib >> + RiscVCpuLib >> + I talked to Abner about this and we're going to remove this LibraryClasses section. It's not needed. >> + >> + >> diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h >> new file mode 100644 >> index 000000000000..c5c0bd6d9b01 >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h >> @@ -0,0 +1,79 @@ >> +/** @file >> + SBI inline function calls. >> + >> + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> >> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef EDK2_SBI_H_ >> +#define EDK2_SBI_H_ >> + >> +#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi >> +#include <RiscVImpl.h> >> +#include <sbi/sbi_types.h> // Reference to header file wrapper >> + >> +#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 > > Did the cover-letter changelog not suggest these had been changed from > local definitions to redefining the existing ones from Opensbi? > If this was "not possible" (the exception stated in cover letter), I > would have expected a comment above (below ---) on why. Or a reply to > my feedback on v1. Oh, I squashed it into the other commit: ProcessorPkg/Library: Add RiscVEdk2SbiLib > >> + >> +#define SBI_BASE_EXT 0x10 >> +#define SBI_HSM_EXT 0x48534D >> +#define SBI_TIME_EXT 0x54494D45 >> +#define SBI_IPI_EXT 0x735049 >> +#define SBI_RFNC_EXT 0x52464E43 >> + >> +// >> +// Below two definitions should be defined in OpenSBI. >> +// >> +#define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 >> +#define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF >> + >> +#define SBI_GET_SPEC_VERSION_FUNC 0 >> +#define SBI_GET_IMPL_ID_FUNC 1 >> +#define SBI_GET_IMPL_VERSION_FUNC 2 >> +#define SBI_PROBE_EXTENSION_FUNC 3 >> +#define SBI_GET_MVENDORID_FUNC 4 >> +#define SBI_GET_MARCHID_FUNC 5 >> +#define SBI_GET_MIMPID_FUNC 6 >> + >> +#define SBI_HART_START_FUNC 0 >> +#define SBI_HART_STOP_FUNC 1 >> +#define SBI_HART_GET_STATUS_FUNC 2 >> + >> +#define RISC_V_MAX_HART_SUPPORTED 16 >> + >> +typedef >> +VOID >> +(EFIAPI *RISCV_HART_SWITCH_MODE)( >> + IN UINTN FuncArg0, >> + IN UINTN FuncArg1, >> + IN UINTN NextAddr, >> + IN UINTN NextMode, >> + IN BOOLEAN NextVirt >> + ); >> + >> +// >> +// Keep the structure member in 64-bit alignment. >> +// >> +typedef struct { >> + UINT64 IsaExtensionSupported; // The ISA extension this core supported. >> + RISCV_UINT128 MachineVendorId; // Machine vendor ID >> + RISCV_UINT128 MachineArchId; // Machine Architecture ID >> + RISCV_UINT128 MachineImplId; // Machine Implementation ID >> + RISCV_HART_SWITCH_MODE HartSwitchMode; // OpenSBI's function to switch the mode of a hart >> +} EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC; >> +#define FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE (64 * 8) // This is the size of EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC >> + // structure. Referred by both C code and assembly code. >> + >> +typedef struct { >> + VOID *PeiServiceTable; // PEI Service table >> + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartSpecific[RISC_V_MAX_HART_SUPPORTED]; >> +} EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT; >> + >> +#endif >> diff --git a/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h >> new file mode 100644 >> index 000000000000..5f3278e8461f >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h >> @@ -0,0 +1,73 @@ >> +/** @file >> + RISC-V OpesbSBI header file reference. >> + >> + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> >> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> +#ifndef EDK2_SBI_TYPES_H_ >> +#define EDK2_SBI_TYPES_H_ >> + >> +#include <Base.h> >> + >> +typedef INT8 s8; >> +typedef UINT8 u8; >> +typedef UINT8 uint8_t; >> + >> +typedef INT16 s16; >> +typedef UINT16 u16; >> +typedef INT16 int16_t; >> +typedef UINT16 uint16_t; >> + >> +typedef INT32 s32; >> +typedef UINT32 u32; >> +typedef INT32 int32_t; >> +typedef UINT32 uint32_t; >> + >> +typedef INT64 s64; >> +typedef UINT64 u64; >> +typedef INT64 int64_t; >> +typedef UINT64 uint64_t; >> + >> +#define PRILX "016lx" > > Feedback on PRILX not addressed, or commented on.> / > Leif > In addition to the cover letter, I also responded to your previous review, see: https://edk2.groups.io/g/devel/message/59681 TLDR; we need to keep it. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib 2020-05-15 13:39 [PATCH v2 0/3] New RISC-V Patches Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib Daniel Schaefer @ 2020-05-15 13:39 ` Daniel Schaefer 2020-05-20 18:27 ` Leif Lindholm 2020-05-20 11:43 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches Leif Lindholm 3 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-15 13:39 UTC (permalink / raw) To: devel; +Cc: Abner Chang, Gilbert Chen, Michael D Kinney, Leif Lindholm Library provides interfaces to invoke SBI extensions. Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> Cc: Abner Chang <abner.chang@hpe.com> Cc: Gilbert Chen <gilbert.chen@hpe.com> Cc: Michael D Kinney <michael.k.kinney@intel.com> Cc: Leif Lindholm <leif@nuviainc.com> --- Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 43 +- Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ 4 files changed, 1466 insertions(+), 25 deletions(-) diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf new file mode 100644 index 000000000000..665dcbf40e01 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf @@ -0,0 +1,28 @@ +## @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 = RiscVEdk2SbiLib + FILE_GUID = 0DF1BBBD-F7E5-4E8A-BCF1-9D63D2DD9FDD + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RiscVEdk2SbiLib + +[Sources] + RiscVEdk2SbiLib.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + +[LibraryClasses] + BaseLib + RiscVOpensbiLib diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h index c5c0bd6d9b01..18a85e2238d2 100644 --- a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h @@ -10,42 +10,35 @@ #ifndef EDK2_SBI_H_ #define EDK2_SBI_H_ -#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi #include <RiscVImpl.h> +#include <sbi/riscv_asm.h> // Reference to header file in opensbi +#include <sbi/sbi_ecall_interface.h> +#include <sbi/sbi_error.h> #include <sbi/sbi_types.h> // Reference to header file wrapper -#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 +// Translation from OpenSBI constants to SBI names +#define SBI_SUCCESS SBI_OK +#define SBI_ERR_FAILED SBI_EFAIL +#define SBI_ERR_NOT_SUPPORTED SBI_ENOTSUPP +#define SBI_ERR_INVALID_PARAM SBI_EINVAL +#define SBI_ERR_DENIED SBI_DENIED +#define SBI_ERR_INVALID_ADDRESS SBI_INVALID_ADDR +#define SBI_ERR_ALREADY_AVAILABLE -6 -#define SBI_BASE_EXT 0x10 -#define SBI_HSM_EXT 0x48534D -#define SBI_TIME_EXT 0x54494D45 -#define SBI_IPI_EXT 0x735049 -#define SBI_RFNC_EXT 0x52464E43 +// Included in OpenSBI 0.7 +// Can be removed, once we upgrade +#define SBI_EXT_HSM 0x48534D +#define SBI_EXT_HSM_HART_START 0x0 +#define SBI_EXT_HSM_HART_STOP 0x1 +#define SBI_EXT_HSM_HART_GET_STATUS 0x2 // // Below two definitions should be defined in OpenSBI. +// Submitted to upstream, waiting for merge and release. // #define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 #define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF -#define SBI_GET_SPEC_VERSION_FUNC 0 -#define SBI_GET_IMPL_ID_FUNC 1 -#define SBI_GET_IMPL_VERSION_FUNC 2 -#define SBI_PROBE_EXTENSION_FUNC 3 -#define SBI_GET_MVENDORID_FUNC 4 -#define SBI_GET_MARCHID_FUNC 5 -#define SBI_GET_MIMPID_FUNC 6 - -#define SBI_HART_START_FUNC 0 -#define SBI_HART_STOP_FUNC 1 -#define SBI_HART_GET_STATUS_FUNC 2 - #define RISC_V_MAX_HART_SUPPORTED 16 typedef diff --git a/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h new file mode 100644 index 000000000000..cf77814e3bbc --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h @@ -0,0 +1,631 @@ +/** @file Defines the PPIs to let PEIMs call SBI + +Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef RISCV_SBI_LIB_H_ +#define RISCV_SBI_LIB_H_ + +#include <Uefi.h> +#include <IndustryStandard/RiscVOpensbi.h> +#include <sbi/sbi_scratch.h> +#include <sbi/sbi_platform.h> + +// +// EDK2 OpenSBI Firmware extension. +// +#define SBI_EDK2_FW_EXT (SBI_EXT_FIRMWARE_CODE_BASE_START | SBI_OPENSBI_IMPID) +// +// EDK2 OpenSBI Firmware extension functions. +// +#define SBI_EXT_FW_MSCRATCH_FUNC 0 +#define SBI_EXT_FW_MSCRATCH_HARTID_FUNC 1 + +// +// EDK2 OpenSBI firmware extension return status. +// +struct sbiret { + long error; ///< SBI status code + long value; ///< Value returned +}; + +#define SbiCall0(ext_id, func_id) \ + SbiCall(ext_id, func_id, 0, 0, 0, 0, 0, 0) +#define SbiCall1(ext_id, func_id, arg0) \ + SbiCall(ext_id, func_id, arg0, 0, 0, 0, 0, 0) +#define SbiCall2(ext_id, func_id, arg0, arg1) \ + SbiCall(ext_id, func_id, arg0, arg1, 0, 0, 0, 0) +#define SbiCall3(ext_id, func_id, arg0, arg1, arg2) \ + SbiCall(ext_id, func_id, arg0, arg1, arg2, 0, 0, 0) +#define SbiCall4(ext_id, func_id, arg0, arg1, arg2, arg3) \ + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, 0, 0) +#define SbiCall5(ext_id, func_id, arg0, arg1, arg2, arg3, arg4) \ + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, 0) +#define SbiCall6(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) \ + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) + +/** + EDK2 SbiCall to invoke SBI extensions. + + @param[in] ext_id Sbi extension ID. + @param[in] func_id Sbi functions ID. + @param[in] arg0 Arg0 to function. + @param[in] arg1 Arg1 to function. + @param[in] arg2 Arg2 to function. + @param[in] arg3 Arg3 to function. + @param[in] arg4 Arg4 to function. + @param[in] arg5 Arg5 to function. + + @retval Returns sbiret structure. + +**/ +inline +EFIAPI +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) +__attribute__((always_inline)); + +/** + EDK2 SbiCall to invoke SBI extensions. + + @param[in] ext_id Sbi extension ID. + @param[in] func_id Sbi functions ID. + @param[in] arg0 Arg0 to function. + @param[in] arg1 Arg1 to function. + @param[in] arg2 Arg2 to function. + @param[in] arg3 Arg3 to function. + @param[in] arg4 Arg4 to function. + @param[in] arg5 Arg5 to function. + + @retval Returns sbiret structure. + +**/ +inline +EFIAPI +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) { + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); + register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); + register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); + register uintptr_t a6 asm ("a6") = (uintptr_t)(func_id); + register uintptr_t a7 asm ("a7") = (uintptr_t)(ext_id); + asm volatile ("ecall" \ + : "+r" (a0) \ + : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \ + : "memory"); \ + struct sbiret ret = { a0, a1 }; + return ret; +} + +/** + Get the implemented SBI specification version + + The minor number of the SBI specification is encoded in the low 24 bits, + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is + reserved for future expansion. + + @param[out] SpecVersion The Version of the SBI specification. +**/ +VOID +EFIAPI +SbiGetSpecVersion ( + OUT UINTN *SpecVersion + ); + +/** + Get the SBI implementation ID + + This ID is used to idenetify a specific SBI implementation in order to work + around any quirks it might have. + + @param[out] ImplId The ID of the SBI implementation. +**/ +VOID +EFIAPI +SbiGetImplId ( + OUT UINTN *ImplId + ); + +/** + Get the SBI implementation version + + The version of this SBI implementation. + The encoding of this number is determined by the specific SBI implementation. + + @param[out] ImplVersion The version of the SBI implementation. +**/ +VOID +EFIAPI +SbiGetImplversion ( + OUT UINTN *ImplVersion + ); + +/** + Probe whether an SBI extension is available + + ProbeResult is set to 0 if the extension is not available or to an extension + specified value if it is available. + + @param[in] ExtensionId The extension ID. + @param[out] ProbeResult The return value of the probe. +**/ +VOID +EFIAPI +SbiProbeExtension ( + IN INTN ExtensionId, + OUT INTN *ProbeResult + ); + +/** + Get the CPU's vendor ID + + Reads the mvendorid CSR. + + @param[out] MvendorId The CPU's vendor ID. +**/ +VOID +EFIAPI +SbiGetMvendorId ( + OUT UINTN *MvendorId + ); + +/** + Get the CPU's architecture ID + + Reads the marchid CSR. + + @param[out] MarchId The CPU's architecture ID. +**/ +VOID +EFIAPI +SbiGetMarchId ( + OUT UINTN *MarchId + ); + +/** + Get the CPU's implementation ID + + Reads the mimpid CSR. + + @param[out] MimpId The CPU's implementation ID. +**/ +VOID +EFIAPI +SbiGetMimpId ( + OUT UINTN *Mimpid + ); + +/** + Politely ask the SBI to start a given hart. + + This call may return before the hart has actually started executing, if the + SBI implementation can guarantee that the hart is actually going to start. + + Before the hart jumps to StartAddr, the hart MUST configure PMP if present + and switch to S-mode. + + @param[in] HartId The id of the hart to start. + @param[in] StartAddr The physical address, where the hart starts + executing from. + @param[in] Priv An XLEN-bit value, which will be in register + a1 when the hart starts. + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: + - It is not a valid physical address. + - The address is prohibited by PMP to run in + supervisor mode. + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id + @retval EFI_ALREADY_STARTED The hart is already running. + @retval other The start request failed for unknown reasons. +**/ +EFI_STATUS +EFIAPI +SbiHartStart ( + IN UINTN HartId, + IN UINTN StartAddr, + IN UINTN Priv + ); + +/** + Return execution of the calling hart to SBI. + + MUST be called in S-Mode with user interrupts disabled. + This call is not expected to return, unless a failure occurs. + + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. + @retval other Failed to stop hard for an unknown reason. +**/ +EFI_STATUS +EFIAPI +SbiHartStop ( + ); + +/** + Get the current status of a hart. + + Since harts can transition between states at any time, the status retrieved + by this function may already be out of date, once it returns. + + Possible values for HartStatus are: + 0: STARTED + 1: STOPPED + 2: START_REQUEST_PENDING + 3: STOP_REQUEST_PENDING + + @param[out] HartStatus The pointer in which the hart's status is + stored. + @retval EFI_SUCCESS The operation succeeds. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +SbiHartGetStatus ( + IN UINTN HartId, + OUT UINTN *HartStatus + ); + +/// +/// Timer extension +/// + +/** + Clear pending timer interrupt bit and set timer for next event after StimeValue. + + To clear the timer without scheduling a timer event, set StimeValue to a + practically infinite value or mask the timer interrupt by clearing sie.STIE. + + @param[in] StimeValue The time offset to the next scheduled timer interrupt. +**/ +VOID +EFIAPI +SbiSetTimer ( + IN UINT64 StimeValue + ); + +/// +/// IPI extension +/// + +/** + Send IPI to all harts specified in the mask. + + The interrupts are registered as supervisor software interrupts at the + receiving hart. + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiSendIpi ( + IN UINTN *HartMask, + IN UINTN HartMaskBase + ); + +/// +/// Remote fence extension +/// + +/** + Instructs remote harts to execute a FENCE.I instruction. + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteFenceI ( + IN UINTN *HartMask, + IN UINTN HartMaskBase + ); + +/** + Instructs the remote harts to execute one or more SFENCE.VMA instructions. + + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteSfenceVma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ); + +/** + Instructs the remote harts to execute one or more SFENCE.VMA instructions. + + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given ASID. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteSfenceVmaAsid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Asid + ); + +/** + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given VMID. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHfenceGvmaVmid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Vmid + ); + +/** + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHfenceGvma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ); + +/** + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given ASID. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHfenceVvmaAsid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Asid + ); + +/** + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHfenceVvma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ); + +/// +/// Vendor Specific extension space: Extension Ids 0x09000000 through 0x09FFFFFF +/// + +/** + Call a function in a vendor defined SBI extension + + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension + Space. + + @param[in] ExtensionId The SBI vendor extension ID. + @param[in] FunctionId The function ID to call in this extension. + @param[in] NumArgs How many arguments are passed. + @param[in] ... Actual Arguments to the function. + @retval EFI_SUCCESS if the SBI function was called and it was successful + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 + @retval others if the called SBI function returns an error +**/ +EFI_STATUS +EFIAPI +SbiVendorCall ( + IN UINTN ExtensionId, + IN UINTN FunctionId, + IN UINTN NumArgs, + ... + ); + +/// +/// Firmware SBI Extension +/// +/// This SBI Extension is defined and used by EDK2 only in order to be able to +/// run PI and DXE phase in S-Mode. +/// + +/** + Get scratch space of the current hart. + + Please consider using the wrapper SbiGetFirmwareContext if you only need to + access the firmware context. + + @param[out] ScratchSpace The scratch space pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetMscratch ( + OUT struct sbi_scratch **ScratchSpace + ); + +/** + Get scratch space of the given hart id. + + @param[in] HartId The hart id. + @param[out] ScratchSpace The scratch space pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetMscratchHartid ( + IN UINTN HartId, + OUT struct sbi_scratch **ScratchSpace + ); + +/** + Get firmware context of the calling hart. + + @param[out] FirmwareContext The firmware context pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetFirmwareContext ( + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext + ); + +/** + Set firmware context of the calling hart. + + @param[in] FirmwareContext The firmware context pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiSetFirmwareContext ( + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext + ); + +#endif diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c new file mode 100644 index 000000000000..bbe006a78af8 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c @@ -0,0 +1,789 @@ +/** @file + Instance of the SBI ecall library. + + It allows calling an SBI function via an ecall from S-Mode. + + The legacy extensions are not included because they are not necessary. + They would be: + - SbiLegacySetTimer -> Use SbiSetTimer + - SbiLegacyConsolePutChar -> No replacement - Use regular UEFI functions + - SbiLegacyConsoleGetChar -> No replacement - Use regular UEFI functions + - SbiLegacyClearIpi -> Write 0 to SSIP + - SbiLegacySendIpi -> Use SbiSendIpi + - SbiLegacyRemoteFenceI -> Use SbiRemoteFenceI + - SbiLegacyRemoteSfenceVma -> Use SbiRemoteSfenceVma + - SbiLegacyRemoteSfenceVmaAsid -> Use SbiRemoteSfenceVmaAsid + - SbiLegacyShutdown -> Wait for new System Reset extension + + Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <IndustryStandard/RiscVOpensbi.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/RiscVEdk2SbiLib.h> +#include <sbi/riscv_asm.h> +#include <sbi/sbi_hart.h> +#include <sbi/sbi_types.h> +#include <sbi/sbi_platform.h> +#include <sbi/sbi_init.h> + +/** + Translate SBI error code to EFI status. + + @param[in] SbiError SBI error code + @retval EFI_STATUS +**/ + +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; + } +} + +// +// OpenSBI libraary interface function for the base extension +// + +/** + Get the implemented SBI specification version + + The minor number of the SBI specification is encoded in the low 24 bits, + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is + reserved for future expansion. + + @param[out] SpecVersion The Version of the SBI specification. +**/ +VOID +EFIAPI +SbiGetSpecVersion ( + OUT UINTN *SpecVersion + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION); + + if (!ret.error) { + *SpecVersion = (UINTN) ret.value; + } + + //return TranslateError(ret.error); +} + +/** + Get the SBI implementation ID + + This ID is used to idenetify a specific SBI implementation in order to work + around any quirks it might have. + + @param[out] ImplId The ID of the SBI implementation. +**/ +VOID +EFIAPI +SbiGetImplId ( + OUT UINTN *ImplId + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID); + *ImplId = (UINTN) ret.value; +} + +/** + Get the SBI implementation version + + The version of this SBI implementation. + The encoding of this number is determined by the specific SBI implementation. + + @param[out] ImplVersion The version of the SBI implementation. +**/ +VOID +EFIAPI +SbiGetImplVersion ( + OUT UINTN *ImplVersion + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSION); + *ImplVersion = (UINTN) ret.value; +} + +/** + Probe whether an SBI extension is available + + ProbeResult is set to 0 if the extension is not available or to an extension + specified value if it is available. + + @param[in] ExtensionId The extension ID. + @param[out] ProbeResult The return value of the probe. +**/ +VOID +EFIAPI +SbiProbeExtension ( + IN INTN ExtensionId, + OUT INTN *ProbeResult + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT); + *ProbeResult = (UINTN) ret.value; +} + +/** + Get the CPU's vendor ID + + Reads the mvendorid CSR. + + @param[out] MvendorId The CPU's vendor ID. +**/ +VOID +EFIAPI +SbiGetMvendorId ( + OUT UINTN *MvendorId + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID); + *MvendorId = (UINTN) ret.value; +} + +/** + Get the CPU's vendor ID + + Reads the mvendorid CSR. + + @param[out] MvendorId The CPU's vendor ID. +**/ +VOID +EFIAPI +SbiGetMarchId ( + OUT UINTN *MarchId + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MARCHID); + *MarchId = (UINTN) ret.value; +} + +/** + Get the CPU's architecture ID + + Reads the marchid CSR. + + @param[out] MarchId The CPU's architecture ID. +**/ +VOID +EFIAPI +SbiGetMimpId ( + OUT UINTN *MimpId + ) +{ + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MIMPID); + *MimpId = (UINTN) ret.value; +} + +// +// SBI interface function for the hart state management extension +// + +/** + Politely ask the SBI to start a given hart. + + This call may return before the hart has actually started executing, if the + SBI implementation can guarantee that the hart is actually going to start. + + Before the hart jumps to StartAddr, the hart MUST configure PMP if present + and switch to S-mode. + + @param[in] HartId The id of the hart to start. + @param[in] StartAddr The physical address, where the hart starts + executing from. + @param[in] Priv An XLEN-bit value, which will be in register + a1 when the hart starts. + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: + - It is not a valid physical address. + - The address is prohibited by PMP to run in + supervisor mode. + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id + @retval EFI_ALREADY_STARTED The hart is already running. + @retval other The start request failed for unknown reasons. +**/ +EFI_STATUS +EFIAPI +SbiHartStart ( + IN UINTN HartId, + IN UINTN StartAddr, + IN UINTN Priv + ) +{ + struct sbiret ret = SbiCall3 (SBI_EXT_HSM, + SBI_EXT_HSM_HART_START, + HartId, + StartAddr, + Priv); + return TranslateError(ret.error); +} + +/** + Return execution of the calling hart to SBI. + + MUST be called in S-Mode with user interrupts disabled. + This call is not expected to return, unless a failure occurs. + + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. + @retval other Failed to stop hard for an unknown reason. +**/ +EFI_STATUS +EFIAPI +SbiHartStop ( + ) +{ + struct sbiret Ret = SbiCall0 (SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP); + return TranslateError(Ret.error); +} + +/** + Get the current status of a hart. + + Since harts can transition between states at any time, the status retrieved + by this function may already be out of date, once it returns. + + Possible values for HartStatus are: + 0: STARTED + 1: STOPPED + 2: START_REQUEST_PENDING + 3: STOP_REQUEST_PENDING + + @param[out] HartStatus The pointer in which the hart's status is + stored. + @retval EFI_SUCCESS The operation succeeds. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +SbiHartGetStatus ( + IN UINTN HartId, + OUT UINTN *HartStatus + ) +{ + struct sbiret ret = SbiCall1 (SBI_EXT_HSM, SBI_EXT_HSM_HART_GET_STATUS, HartId); + + if (!ret.error) { + *HartStatus = (UINTN) ret.value; + } + + return TranslateError(ret.error); +} + +/** + Clear pending timer interrupt bit and set timer for next event after StimeValue. + + To clear the timer without scheduling a timer event, set StimeValue to a + practically infinite value or mask the timer interrupt by clearing sie.STIE. + + @param[in] StimeValue The time offset to the next scheduled timer interrupt. +**/ +VOID +EFIAPI +SbiSetTimer ( + IN UINT64 StimeValue + ) +{ + SbiCall1 (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, StimeValue); +} + +EFI_STATUS +EFIAPI +SbiSendIpi ( + IN UINTN *HartMask, + IN UINTN HartMaskBase + ) +{ + struct sbiret ret = SbiCall2 (SBI_EXT_IPI, + SBI_EXT_IPI_SEND_IPI, + (UINTN) HartMask, + HartMaskBase); + return TranslateError(ret.error); +} + +/** + Instructs remote harts to execute a FENCE.I instruction. + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteFenceI ( + IN UINTN *HartMask, + IN UINTN HartMaskBase + ) +{ + struct sbiret ret = SbiCall2 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_FENCE_I, + (UINTN) HartMask, + HartMaskBase); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.VMA instructions. + + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteSfenceVma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ) +{ + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.VMA instructions. + + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given ASID. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteSfenceVmaAsid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Asid + ) +{ + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size, + Asid); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given VMID. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHFenceGvmaVmid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Vmid + ) +{ + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size, + Vmid); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHFenceGvma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ) +{ + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + Covers only the given ASID. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHFenceVvmaAsid ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size, + IN UINTN Asid + ) +{ + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size, + Asid); + return TranslateError(ret.error); +} + +/** + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. + + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. + This function call is only valid for harts implementing the hypervisor extension. + + The remote fence function acts as a full tlb flush if * StartAddr and size + are both 0 * size is equal to 2^XLEN-1 + + @param[in] HartMask Scalar bit-vector containing hart ids + @param[in] HartMaskBase The starting hartid from which the bit-vector + must be computed. If set to -1, HartMask is + ignored and all harts are considered. + @param[in] StartAddr The first address of the affected range. + @param[in] Size How many addresses are affected. + @retval EFI_SUCCESS IPI was sent to all the targeted harts. + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. + @retval EFI_UNSUPPORTED SBI does not implement this function or one + of the target harts does not support the + hypervisor extension. + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid + from hart_mask is not valid i.e. either the + hartid is not enabled by the platform or is + not available to the supervisor. +**/ +EFI_STATUS +EFIAPI +SbiRemoteHFenceVvma ( + IN UINTN *HartMask, + IN UINTN HartMaskBase, + IN UINTN StartAddr, + IN UINTN Size + ) +{ + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, + (UINTN) HartMask, + HartMaskBase, + StartAddr, + Size); + return TranslateError(ret.error); +} + +// +// SBI interface function for the vendor extension +// + +/** + Call a function in a vendor defined SBI extension + + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension + Space. + + @param[in] ExtensionId The SBI vendor extension ID. + @param[in] FunctionId The function ID to call in this extension. + @param[in] NumArgs How many arguments are passed. + @param[in] ... Actual Arguments to the function. + @retval EFI_SUCCESS if the SBI function was called and it was successful + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 + @retval others if the called SBI function returns an error +**/ +EFI_STATUS +EFIAPI +SbiVendorCall ( + IN UINTN ExtensionId, + IN UINTN FunctionId, + IN UINTN NumArgs, + ... + ) +{ + struct sbiret ret; + VA_LIST Args; + VA_START(Args, NumArgs); + + ASSERT (ExtensionId >= 0x09000000 && ExtensionId <= 0x09FFFFFF); + + switch (NumArgs) { + case 0: + ret = SbiCall0 (ExtensionId, FunctionId); + break; + case 1: + ret = SbiCall1 (ExtensionId, FunctionId, VA_ARG(Args, UINTN)); + break; + case 2: + ret = SbiCall2 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); + break; + case 3: + ret = SbiCall3 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); + break; + case 4: + ret = SbiCall4 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); + break; + case 5: + ret = SbiCall5 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); + break; + case 6: + ret = SbiCall6 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); + break; + default: + // Too many args. In theory SBI can handle more arguments when they are + // passed on the stack but no SBI extension uses this, therefore it's + // not yet implemented here. + return EFI_INVALID_PARAMETER; + } + + VA_END(Args); + return TranslateError(ret.error); +} + +// +// SBI Firmware extension +// + +/** + Get scratch space of the current hart. + + Please consider using the wrapper SbiGetFirmwareContext if you only need to + access the firmware context. + + @param[out] ScratchSpace The scratch space pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetMscratch ( + OUT struct sbi_scratch **ScratchSpace + ) +{ + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); + + if (!ret.error) { + *ScratchSpace = (struct sbi_scratch *) ret.value; + } + + return EFI_SUCCESS; +} + +/** + Get scratch space of the given hart id. + + @param[in] HartId The hart id. + @param[out] ScratchSpace The scratch space pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetMscratchHartid ( + IN UINTN HartId, + OUT struct sbi_scratch **ScratchSpace + ) +{ + struct sbiret ret = SbiCall1 (SBI_EDK2_FW_EXT, + SBI_EXT_FW_MSCRATCH_HARTID_FUNC, + HartId); + + if (!ret.error) { + *ScratchSpace = (struct sbi_scratch *) ret.value; + } + + return EFI_SUCCESS; +} + +/** + Get firmware context of the calling hart. + + @param[out] FirmwareContext The firmware context pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiGetFirmwareContext ( + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext + ) +{ + struct sbi_scratch *ScratchSpace; + struct sbi_platform *SbiPlatform; + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); + + if (!ret.error) { + ScratchSpace = (struct sbi_scratch *) ret.value; + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); + *FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *) SbiPlatform->firmware_context; + } + + return EFI_SUCCESS; +} + +/** + Set firmware context of the calling hart. + + @param[in] FirmwareContext The firmware context pointer. + @retval EFI_SUCCESS The operation succeeds. +**/ +EFI_STATUS +EFIAPI +SbiSetFirmwareContext ( + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext + ) +{ + struct sbi_scratch *ScratchSpace; + struct sbi_platform *SbiPlatform; + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); + + if (!ret.error) { + ScratchSpace = (struct sbi_scratch *) ret.value; + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); + SbiPlatform->firmware_context = (long unsigned int) FirmwareContext; + } + + return EFI_SUCCESS; +} -- 2.26.1 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib 2020-05-15 13:39 ` [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Daniel Schaefer @ 2020-05-20 18:27 ` Leif Lindholm 2020-05-29 12:43 ` [edk2-devel] " Daniel Schaefer 0 siblings, 1 reply; 19+ messages in thread From: Leif Lindholm @ 2020-05-20 18:27 UTC (permalink / raw) To: Daniel Schaefer; +Cc: devel, Abner Chang, Gilbert Chen, Michael D Kinney On Fri, May 15, 2020 at 15:39:37 +0200, Daniel Schaefer wrote: > Library provides interfaces to invoke SBI extensions. > > Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> > > Cc: Abner Chang <abner.chang@hpe.com> > Cc: Gilbert Chen <gilbert.chen@hpe.com> > Cc: Michael D Kinney <michael.k.kinney@intel.com> > Cc: Leif Lindholm <leif@nuviainc.com> > --- > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + > Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 43 +- > Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ > 4 files changed, 1466 insertions(+), 25 deletions(-) > > diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf > new file mode 100644 > index 000000000000..665dcbf40e01 > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf > @@ -0,0 +1,28 @@ > +## @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 = RiscVEdk2SbiLib > + FILE_GUID = 0DF1BBBD-F7E5-4E8A-BCF1-9D63D2DD9FDD > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = RiscVEdk2SbiLib > + > +[Sources] > + RiscVEdk2SbiLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec > + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec > + > +[LibraryClasses] > + BaseLib > + RiscVOpensbiLib > diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > index c5c0bd6d9b01..18a85e2238d2 100644 > --- a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > @@ -10,42 +10,35 @@ > #ifndef EDK2_SBI_H_ > #define EDK2_SBI_H_ > > -#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi > #include <RiscVImpl.h> > +#include <sbi/riscv_asm.h> // Reference to header file in opensbi I don't see anything in *this* patch requiring this change - does this belong squashed into 2/3? > +#include <sbi/sbi_ecall_interface.h> > +#include <sbi/sbi_error.h> > #include <sbi/sbi_types.h> // Reference to header file wrapper > > -#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 > +// Translation from OpenSBI constants to SBI names > +#define SBI_SUCCESS SBI_OK > +#define SBI_ERR_FAILED SBI_EFAIL > +#define SBI_ERR_NOT_SUPPORTED SBI_ENOTSUPP > +#define SBI_ERR_INVALID_PARAM SBI_EINVAL > +#define SBI_ERR_DENIED SBI_DENIED > +#define SBI_ERR_INVALID_ADDRESS SBI_INVALID_ADDR > +#define SBI_ERR_ALREADY_AVAILABLE -6 Ah, right, see my confusion from reviewing 2/3. Please move this to 2/3, adding a comment on why SBI_ERR_ALREADY_AVAILABLE needs to be locally defined here. > > -#define SBI_BASE_EXT 0x10 > -#define SBI_HSM_EXT 0x48534D > -#define SBI_TIME_EXT 0x54494D45 > -#define SBI_IPI_EXT 0x735049 > -#define SBI_RFNC_EXT 0x52464E43 Why do we add these in 2/3 only to delete them again here? > +// Included in OpenSBI 0.7 > +// Can be removed, once we upgrade > +#define SBI_EXT_HSM 0x48534D > +#define SBI_EXT_HSM_HART_START 0x0 > +#define SBI_EXT_HSM_HART_STOP 0x1 > +#define SBI_EXT_HSM_HART_GET_STATUS 0x2 > > // > // Below two definitions should be defined in OpenSBI. > +// Submitted to upstream, waiting for merge and release. Good call out. This isn't pretty, but it is the right thing to do. > // > #define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 > #define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF > > -#define SBI_GET_SPEC_VERSION_FUNC 0 > -#define SBI_GET_IMPL_ID_FUNC 1 > -#define SBI_GET_IMPL_VERSION_FUNC 2 > -#define SBI_PROBE_EXTENSION_FUNC 3 > -#define SBI_GET_MVENDORID_FUNC 4 > -#define SBI_GET_MARCHID_FUNC 5 > -#define SBI_GET_MIMPID_FUNC 6 > - > -#define SBI_HART_START_FUNC 0 > -#define SBI_HART_STOP_FUNC 1 > -#define SBI_HART_GET_STATUS_FUNC 2 > - Why do we add these in 2/3 only to delete them again here? > #define RISC_V_MAX_HART_SUPPORTED 16 > > typedef > diff --git a/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > new file mode 100644 > index 000000000000..cf77814e3bbc > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > @@ -0,0 +1,631 @@ > +/** @file Defines the PPIs to let PEIMs call SBI > + > +Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> > + > +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef RISCV_SBI_LIB_H_ > +#define RISCV_SBI_LIB_H_ > + > +#include <Uefi.h> > +#include <IndustryStandard/RiscVOpensbi.h> > +#include <sbi/sbi_scratch.h> > +#include <sbi/sbi_platform.h> > + > +// > +// EDK2 OpenSBI Firmware extension. > +// > +#define SBI_EDK2_FW_EXT (SBI_EXT_FIRMWARE_CODE_BASE_START | SBI_OPENSBI_IMPID) > +// > +// EDK2 OpenSBI Firmware extension functions. > +// > +#define SBI_EXT_FW_MSCRATCH_FUNC 0 > +#define SBI_EXT_FW_MSCRATCH_HARTID_FUNC 1 > + > +// > +// EDK2 OpenSBI firmware extension return status. > +// > +struct sbiret { This struct appears only to be referenceed outside the opensbi submodule, so name should conform to EDK2 coding style (and preferably with a typedef). > + long error; ///< SBI status code > + long value; ///< Value returned This looks like a maintenance hazard (means different things to GCC and VS for example). Can we use UINT32? > +}; > + > +#define SbiCall0(ext_id, func_id) \ > + SbiCall(ext_id, func_id, 0, 0, 0, 0, 0, 0) > +#define SbiCall1(ext_id, func_id, arg0) \ > + SbiCall(ext_id, func_id, arg0, 0, 0, 0, 0, 0) > +#define SbiCall2(ext_id, func_id, arg0, arg1) \ > + SbiCall(ext_id, func_id, arg0, arg1, 0, 0, 0, 0) > +#define SbiCall3(ext_id, func_id, arg0, arg1, arg2) \ > + SbiCall(ext_id, func_id, arg0, arg1, arg2, 0, 0, 0) > +#define SbiCall4(ext_id, func_id, arg0, arg1, arg2, arg3) \ > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, 0, 0) > +#define SbiCall5(ext_id, func_id, arg0, arg1, arg2, arg3, arg4) \ > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, 0) > +#define SbiCall6(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) \ > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) Ugh. This looks way too much like pre-EFIAPI x86 code. Is this a pattern used across multiple codebases? If not, could we make this a simple argc/argv instead and do the unpacking inside SbiCall()? Hmm, maybe that would make the call sites even worse. If we need to keep these, coding style says all macros should use UPPERCASE_AND_UNDERSCORES. > + > +/** > + EDK2 SbiCall to invoke SBI extensions. > + > + @param[in] ext_id Sbi extension ID. > + @param[in] func_id Sbi functions ID. > + @param[in] arg0 Arg0 to function. > + @param[in] arg1 Arg1 to function. > + @param[in] arg2 Arg2 to function. > + @param[in] arg3 Arg3 to function. > + @param[in] arg4 Arg4 to function. > + @param[in] arg5 Arg5 to function. > + > + @retval Returns sbiret structure. > + > +**/ > +inline > +EFIAPI > +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, Function name starts in the first column of a new line. But please drop the entire forward-declaration. > + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) > +__attribute__((always_inline)); > + > +/** > + EDK2 SbiCall to invoke SBI extensions. > + > + @param[in] ext_id Sbi extension ID. > + @param[in] func_id Sbi functions ID. > + @param[in] arg0 Arg0 to function. > + @param[in] arg1 Arg1 to function. > + @param[in] arg2 Arg2 to function. > + @param[in] arg3 Arg3 to function. > + @param[in] arg4 Arg4 to function. > + @param[in] arg5 Arg5 to function. > + > + @retval Returns sbiret structure. > + > +**/ > +inline Technically, the coding standard bans function definitions in header files[1]. If you can give me a good reason for why this function should be here, I may consider to consider making an exception. If I do, make it just STATIC (let the compiler worry about the inlining). If it is just by habit from other projects of putting helper functions into headers, please move them to a .c file. [1] https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/53_include_files#5-3-7-include-files-shall-not-generate-code-or-define-data-variables > +EFIAPI > +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, > + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) { > + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); > + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); > + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); > + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); > + register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); > + register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); > + register uintptr_t a6 asm ("a6") = (uintptr_t)(func_id); > + register uintptr_t a7 asm ("a7") = (uintptr_t)(ext_id); I would *prefer* UINTN over uintptr_t here. > + asm volatile ("ecall" \ > + : "+r" (a0) \ Isn't a1 also an input/output operand here? > + : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \ > + : "memory"); \ > + struct sbiret ret = { a0, a1 }; > + return ret; CamelCase naming. > +} > + > +/** > + Get the implemented SBI specification version > + > + The minor number of the SBI specification is encoded in the low 24 bits, > + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is > + reserved for future expansion. > + > + @param[out] SpecVersion The Version of the SBI specification. > +**/ > +VOID > +EFIAPI > +SbiGetSpecVersion ( > + OUT UINTN *SpecVersion > + ); > + > +/** > + Get the SBI implementation ID > + > + This ID is used to idenetify a specific SBI implementation in order to work > + around any quirks it might have. > + > + @param[out] ImplId The ID of the SBI implementation. > +**/ > +VOID > +EFIAPI > +SbiGetImplId ( > + OUT UINTN *ImplId > + ); > + > +/** > + Get the SBI implementation version > + > + The version of this SBI implementation. > + The encoding of this number is determined by the specific SBI implementation. > + > + @param[out] ImplVersion The version of the SBI implementation. > +**/ > +VOID > +EFIAPI > +SbiGetImplversion ( Uppercase V for CamelCase (and matching the argument name below). > + OUT UINTN *ImplVersion > + ); > + > +/** > + Probe whether an SBI extension is available > + > + ProbeResult is set to 0 if the extension is not available or to an extension > + specified value if it is available. > + > + @param[in] ExtensionId The extension ID. > + @param[out] ProbeResult The return value of the probe. > +**/ > +VOID > +EFIAPI > +SbiProbeExtension ( > + IN INTN ExtensionId, > + OUT INTN *ProbeResult > + ); > + > +/** > + Get the CPU's vendor ID > + > + Reads the mvendorid CSR. What is an MvendorId? MachineVendorId? Even if an official register name, I would prefer function and arguments to be given proper descriptive CamelCase names. > + > + @param[out] MvendorId The CPU's vendor ID. > +**/ > +VOID > +EFIAPI > +SbiGetMvendorId ( > + OUT UINTN *MvendorId > + ); > + > +/** > + Get the CPU's architecture ID > + > + Reads the marchid CSR. > + > + @param[out] MarchId The CPU's architecture ID. This should probebly be MArchId (or MachineArchId?)? > +**/ > +VOID > +EFIAPI > +SbiGetMarchId ( > + OUT UINTN *MarchId > + ); > + > +/** > + Get the CPU's implementation ID > + > + Reads the mimpid CSR. > + > + @param[out] MimpId The CPU's implementation ID. Above "Impl" is used for "Impelentation". *Strictly* speaking, "Impl" doesn't fall in the pretty small group of abbreviations permitted without a glossary section in the source file, but it's clear enough to me I'll let it slip. The same cannot be said for "Imp". MachineImplId? > +**/ > +VOID > +EFIAPI > +SbiGetMimpId ( > + OUT UINTN *Mimpid > + ); > + > +/** > + Politely ask the SBI to start a given hart. I know hart is a pretty fundamental concept in RISC-V. Still, I would request to have it added in a glossary section in the top-of-file comment header. > + > + This call may return before the hart has actually started executing, if the > + SBI implementation can guarantee that the hart is actually going to start. > + > + Before the hart jumps to StartAddr, the hart MUST configure PMP if present > + and switch to S-mode. > + > + @param[in] HartId The id of the hart to start. > + @param[in] StartAddr The physical address, where the hart starts > + executing from. > + @param[in] Priv An XLEN-bit value, which will be in register > + a1 when the hart starts. > + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. > + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: > + - It is not a valid physical address. > + - The address is prohibited by PMP to run in > + supervisor mode. > + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id > + @retval EFI_ALREADY_STARTED The hart is already running. > + @retval other The start request failed for unknown reasons. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartStart ( (With great effort, I suppress a Mötley Crüe joke.) > + IN UINTN HartId, > + IN UINTN StartAddr, > + IN UINTN Priv > + ); > + > +/** > + Return execution of the calling hart to SBI. > + > + MUST be called in S-Mode with user interrupts disabled. > + This call is not expected to return, unless a failure occurs. > + > + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. > + @retval other Failed to stop hard for an unknown reason. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartStop ( > + ); > + > +/** > + Get the current status of a hart. > + > + Since harts can transition between states at any time, the status retrieved > + by this function may already be out of date, once it returns. > + > + Possible values for HartStatus are: > + 0: STARTED > + 1: STOPPED > + 2: START_REQUEST_PENDING > + 3: STOP_REQUEST_PENDING > + > + @param[out] HartStatus The pointer in which the hart's status is > + stored. > + @retval EFI_SUCCESS The operation succeeds. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartGetStatus ( > + IN UINTN HartId, > + OUT UINTN *HartStatus > + ); > + > +/// > +/// Timer extension > +/// > + > +/** > + Clear pending timer interrupt bit and set timer for next event after StimeValue. What does the S stand for in Stime? > + > + To clear the timer without scheduling a timer event, set StimeValue to a > + practically infinite value or mask the timer interrupt by clearing sie.STIE. > + > + @param[in] StimeValue The time offset to the next scheduled timer interrupt. > +**/ > +VOID > +EFIAPI > +SbiSetTimer ( > + IN UINT64 StimeValue > + ); > + > +/// > +/// IPI extension > +/// > + > +/** > + Send IPI to all harts specified in the mask. > + > + The interrupts are registered as supervisor software interrupts at the > + receiving hart. > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiSendIpi ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase > + ); > + > +/// > +/// Remote fence extension > +/// > + > +/** > + Instructs remote harts to execute a FENCE.I instruction. > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteFenceI ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VMA instructions. > + > + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteSfenceVma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VMA instructions. > + > + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given ASID. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteSfenceVmaAsid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Asid > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given VMID. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHfenceGvmaVmid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Vmid > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHfenceGvma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given ASID. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHfenceVvmaAsid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Asid > + ); > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHfenceVvma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ); > + > +/// > +/// Vendor Specific extension space: Extension Ids 0x09000000 through 0x09FFFFFF > +/// > + > +/** > + Call a function in a vendor defined SBI extension > + > + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension > + Space. > + > + @param[in] ExtensionId The SBI vendor extension ID. > + @param[in] FunctionId The function ID to call in this extension. > + @param[in] NumArgs How many arguments are passed. > + @param[in] ... Actual Arguments to the function. > + @retval EFI_SUCCESS if the SBI function was called and it was successful > + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 > + @retval others if the called SBI function returns an error > +**/ > +EFI_STATUS > +EFIAPI > +SbiVendorCall ( > + IN UINTN ExtensionId, > + IN UINTN FunctionId, > + IN UINTN NumArgs, > + ... > + ); > + > +/// > +/// Firmware SBI Extension > +/// > +/// This SBI Extension is defined and used by EDK2 only in order to be able to > +/// run PI and DXE phase in S-Mode. > +/// > + > +/** > + Get scratch space of the current hart. > + > + Please consider using the wrapper SbiGetFirmwareContext if you only need to > + access the firmware context. > + > + @param[out] ScratchSpace The scratch space pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetMscratch ( > + OUT struct sbi_scratch **ScratchSpace Could we add a typedef for "struct sbi_scratch" to make the code more style compliant? > + ); > + > +/** > + Get scratch space of the given hart id. > + > + @param[in] HartId The hart id. > + @param[out] ScratchSpace The scratch space pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetMscratchHartid ( > + IN UINTN HartId, > + OUT struct sbi_scratch **ScratchSpace > + ); > + > +/** > + Get firmware context of the calling hart. > + > + @param[out] FirmwareContext The firmware context pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetFirmwareContext ( > + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext > + ); > + > +/** > + Set firmware context of the calling hart. > + > + @param[in] FirmwareContext The firmware context pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiSetFirmwareContext ( > + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext > + ); > + > +#endif > diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > new file mode 100644 > index 000000000000..bbe006a78af8 > --- /dev/null > +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > @@ -0,0 +1,789 @@ > +/** @file > + Instance of the SBI ecall library. > + > + It allows calling an SBI function via an ecall from S-Mode. > + > + The legacy extensions are not included because they are not necessary. > + They would be: > + - SbiLegacySetTimer -> Use SbiSetTimer > + - SbiLegacyConsolePutChar -> No replacement - Use regular UEFI functions > + - SbiLegacyConsoleGetChar -> No replacement - Use regular UEFI functions > + - SbiLegacyClearIpi -> Write 0 to SSIP > + - SbiLegacySendIpi -> Use SbiSendIpi > + - SbiLegacyRemoteFenceI -> Use SbiRemoteFenceI > + - SbiLegacyRemoteSfenceVma -> Use SbiRemoteSfenceVma > + - SbiLegacyRemoteSfenceVmaAsid -> Use SbiRemoteSfenceVmaAsid > + - SbiLegacyShutdown -> Wait for new System Reset extension > + > + Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <IndustryStandard/RiscVOpensbi.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/RiscVEdk2SbiLib.h> > +#include <sbi/riscv_asm.h> > +#include <sbi/sbi_hart.h> > +#include <sbi/sbi_types.h> > +#include <sbi/sbi_platform.h> > +#include <sbi/sbi_init.h> > + > +/** > + Translate SBI error code to EFI status. > + > + @param[in] SbiError SBI error code > + @retval EFI_STATUS > +**/ > + > +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; > + } > +} > + > +// > +// OpenSBI libraary interface function for the base extension > +// > + > +/** > + Get the implemented SBI specification version > + > + The minor number of the SBI specification is encoded in the low 24 bits, > + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is > + reserved for future expansion. > + > + @param[out] SpecVersion The Version of the SBI specification. > +**/ > +VOID > +EFIAPI > +SbiGetSpecVersion ( > + OUT UINTN *SpecVersion > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION); > + > + if (!ret.error) { > + *SpecVersion = (UINTN) ret.value; > + } > + > + //return TranslateError(ret.error); > +} > + > +/** > + Get the SBI implementation ID > + > + This ID is used to idenetify a specific SBI implementation in order to work > + around any quirks it might have. > + > + @param[out] ImplId The ID of the SBI implementation. > +**/ > +VOID > +EFIAPI > +SbiGetImplId ( > + OUT UINTN *ImplId > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID); > + *ImplId = (UINTN) ret.value; > +} > + > +/** > + Get the SBI implementation version > + > + The version of this SBI implementation. > + The encoding of this number is determined by the specific SBI implementation. > + > + @param[out] ImplVersion The version of the SBI implementation. > +**/ > +VOID > +EFIAPI > +SbiGetImplVersion ( > + OUT UINTN *ImplVersion > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSION); > + *ImplVersion = (UINTN) ret.value; > +} > + > +/** > + Probe whether an SBI extension is available > + > + ProbeResult is set to 0 if the extension is not available or to an extension > + specified value if it is available. > + > + @param[in] ExtensionId The extension ID. > + @param[out] ProbeResult The return value of the probe. > +**/ > +VOID > +EFIAPI > +SbiProbeExtension ( > + IN INTN ExtensionId, > + OUT INTN *ProbeResult > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT); > + *ProbeResult = (UINTN) ret.value; > +} > + > +/** > + Get the CPU's vendor ID > + > + Reads the mvendorid CSR. > + > + @param[out] MvendorId The CPU's vendor ID. > +**/ > +VOID > +EFIAPI > +SbiGetMvendorId ( > + OUT UINTN *MvendorId > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID); > + *MvendorId = (UINTN) ret.value; > +} > + > +/** > + Get the CPU's vendor ID > + > + Reads the mvendorid CSR. > + > + @param[out] MvendorId The CPU's vendor ID. > +**/ > +VOID > +EFIAPI > +SbiGetMarchId ( > + OUT UINTN *MarchId > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MARCHID); > + *MarchId = (UINTN) ret.value; > +} > + > +/** > + Get the CPU's architecture ID > + > + Reads the marchid CSR. > + > + @param[out] MarchId The CPU's architecture ID. > +**/ > +VOID > +EFIAPI > +SbiGetMimpId ( > + OUT UINTN *MimpId > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MIMPID); > + *MimpId = (UINTN) ret.value; > +} > + > +// > +// SBI interface function for the hart state management extension > +// > + > +/** > + Politely ask the SBI to start a given hart. > + > + This call may return before the hart has actually started executing, if the > + SBI implementation can guarantee that the hart is actually going to start. > + > + Before the hart jumps to StartAddr, the hart MUST configure PMP if present > + and switch to S-mode. > + > + @param[in] HartId The id of the hart to start. > + @param[in] StartAddr The physical address, where the hart starts > + executing from. > + @param[in] Priv An XLEN-bit value, which will be in register > + a1 when the hart starts. > + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. > + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: > + - It is not a valid physical address. > + - The address is prohibited by PMP to run in > + supervisor mode. > + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id > + @retval EFI_ALREADY_STARTED The hart is already running. > + @retval other The start request failed for unknown reasons. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartStart ( > + IN UINTN HartId, > + IN UINTN StartAddr, > + IN UINTN Priv > + ) > +{ > + struct sbiret ret = SbiCall3 (SBI_EXT_HSM, > + SBI_EXT_HSM_HART_START, > + HartId, > + StartAddr, > + Priv); > + return TranslateError(ret.error); > +} > + > +/** > + Return execution of the calling hart to SBI. > + > + MUST be called in S-Mode with user interrupts disabled. > + This call is not expected to return, unless a failure occurs. > + > + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. > + @retval other Failed to stop hard for an unknown reason. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartStop ( > + ) > +{ > + struct sbiret Ret = SbiCall0 (SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP); > + return TranslateError(Ret.error); > +} > + > +/** > + Get the current status of a hart. > + > + Since harts can transition between states at any time, the status retrieved > + by this function may already be out of date, once it returns. > + > + Possible values for HartStatus are: > + 0: STARTED > + 1: STOPPED > + 2: START_REQUEST_PENDING > + 3: STOP_REQUEST_PENDING > + > + @param[out] HartStatus The pointer in which the hart's status is > + stored. > + @retval EFI_SUCCESS The operation succeeds. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > +**/ > +EFI_STATUS > +EFIAPI > +SbiHartGetStatus ( > + IN UINTN HartId, > + OUT UINTN *HartStatus > + ) > +{ > + struct sbiret ret = SbiCall1 (SBI_EXT_HSM, SBI_EXT_HSM_HART_GET_STATUS, HartId); > + > + if (!ret.error) { > + *HartStatus = (UINTN) ret.value; > + } > + > + return TranslateError(ret.error); > +} > + > +/** > + Clear pending timer interrupt bit and set timer for next event after StimeValue. > + > + To clear the timer without scheduling a timer event, set StimeValue to a > + practically infinite value or mask the timer interrupt by clearing sie.STIE. > + > + @param[in] StimeValue The time offset to the next scheduled timer interrupt. > +**/ > +VOID > +EFIAPI > +SbiSetTimer ( > + IN UINT64 StimeValue > + ) > +{ > + SbiCall1 (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, StimeValue); > +} > + > +EFI_STATUS > +EFIAPI > +SbiSendIpi ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase > + ) > +{ > + struct sbiret ret = SbiCall2 (SBI_EXT_IPI, > + SBI_EXT_IPI_SEND_IPI, > + (UINTN) HartMask, > + HartMaskBase); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs remote harts to execute a FENCE.I instruction. > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteFenceI ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase > + ) > +{ > + struct sbiret ret = SbiCall2 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_FENCE_I, > + (UINTN) HartMask, > + HartMaskBase); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VMA instructions. > + > + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteSfenceVma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ) > +{ > + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VMA instructions. > + > + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given ASID. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteSfenceVmaAsid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Asid > + ) > +{ > + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size, > + Asid); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given VMID. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHFenceGvmaVmid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Vmid > + ) > +{ > + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size, > + Vmid); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHFenceGvma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ) > +{ > + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + Covers only the given ASID. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHFenceVvmaAsid ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size, > + IN UINTN Asid > + ) > +{ > + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size, > + Asid); > + return TranslateError(ret.error); > +} > + > +/** > + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. > + > + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. > + This function call is only valid for harts implementing the hypervisor extension. > + > + The remote fence function acts as a full tlb flush if * StartAddr and size > + are both 0 * size is equal to 2^XLEN-1 > + > + @param[in] HartMask Scalar bit-vector containing hart ids > + @param[in] HartMaskBase The starting hartid from which the bit-vector > + must be computed. If set to -1, HartMask is > + ignored and all harts are considered. > + @param[in] StartAddr The first address of the affected range. > + @param[in] Size How many addresses are affected. > + @retval EFI_SUCCESS IPI was sent to all the targeted harts. > + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. > + @retval EFI_UNSUPPORTED SBI does not implement this function or one > + of the target harts does not support the > + hypervisor extension. > + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid > + from hart_mask is not valid i.e. either the > + hartid is not enabled by the platform or is > + not available to the supervisor. > +**/ > +EFI_STATUS > +EFIAPI > +SbiRemoteHFenceVvma ( > + IN UINTN *HartMask, > + IN UINTN HartMaskBase, > + IN UINTN StartAddr, > + IN UINTN Size > + ) > +{ > + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, > + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, > + (UINTN) HartMask, > + HartMaskBase, > + StartAddr, > + Size); > + return TranslateError(ret.error); > +} > + > +// > +// SBI interface function for the vendor extension > +// > + > +/** > + Call a function in a vendor defined SBI extension > + > + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension > + Space. > + > + @param[in] ExtensionId The SBI vendor extension ID. > + @param[in] FunctionId The function ID to call in this extension. > + @param[in] NumArgs How many arguments are passed. > + @param[in] ... Actual Arguments to the function. > + @retval EFI_SUCCESS if the SBI function was called and it was successful > + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 > + @retval others if the called SBI function returns an error > +**/ > +EFI_STATUS > +EFIAPI > +SbiVendorCall ( > + IN UINTN ExtensionId, > + IN UINTN FunctionId, > + IN UINTN NumArgs, > + ... > + ) > +{ > + struct sbiret ret; > + VA_LIST Args; > + VA_START(Args, NumArgs); > + > + ASSERT (ExtensionId >= 0x09000000 && ExtensionId <= 0x09FFFFFF); > + > + switch (NumArgs) { > + case 0: > + ret = SbiCall0 (ExtensionId, FunctionId); > + break; > + case 1: > + ret = SbiCall1 (ExtensionId, FunctionId, VA_ARG(Args, UINTN)); > + break; > + case 2: > + ret = SbiCall2 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); > + break; > + case 3: > + ret = SbiCall3 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); > + break; > + case 4: > + ret = SbiCall4 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); > + break; > + case 5: > + ret = SbiCall5 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); > + break; > + case 6: > + ret = SbiCall6 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); > + break; > + default: > + // Too many args. In theory SBI can handle more arguments when they are > + // passed on the stack but no SBI extension uses this, therefore it's > + // not yet implemented here. > + return EFI_INVALID_PARAMETER; > + } > + > + VA_END(Args); > + return TranslateError(ret.error); > +} > + > +// > +// SBI Firmware extension > +// > + > +/** > + Get scratch space of the current hart. > + > + Please consider using the wrapper SbiGetFirmwareContext if you only need to > + access the firmware context. > + > + @param[out] ScratchSpace The scratch space pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetMscratch ( > + OUT struct sbi_scratch **ScratchSpace > + ) > +{ > + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); > + > + if (!ret.error) { > + *ScratchSpace = (struct sbi_scratch *) ret.value; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Get scratch space of the given hart id. > + > + @param[in] HartId The hart id. > + @param[out] ScratchSpace The scratch space pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetMscratchHartid ( > + IN UINTN HartId, > + OUT struct sbi_scratch **ScratchSpace > + ) > +{ > + struct sbiret ret = SbiCall1 (SBI_EDK2_FW_EXT, > + SBI_EXT_FW_MSCRATCH_HARTID_FUNC, > + HartId); > + > + if (!ret.error) { > + *ScratchSpace = (struct sbi_scratch *) ret.value; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Get firmware context of the calling hart. > + > + @param[out] FirmwareContext The firmware context pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiGetFirmwareContext ( > + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext > + ) > +{ > + struct sbi_scratch *ScratchSpace; > + struct sbi_platform *SbiPlatform; > + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); > + > + if (!ret.error) { > + ScratchSpace = (struct sbi_scratch *) ret.value; > + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); > + *FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *) SbiPlatform->firmware_context; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Set firmware context of the calling hart. > + > + @param[in] FirmwareContext The firmware context pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +EFI_STATUS > +EFIAPI > +SbiSetFirmwareContext ( > + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext > + ) > +{ > + struct sbi_scratch *ScratchSpace; > + struct sbi_platform *SbiPlatform; > + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); > + > + if (!ret.error) { > + ScratchSpace = (struct sbi_scratch *) ret.value; > + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); > + SbiPlatform->firmware_context = (long unsigned int) FirmwareContext; UINT64? / Leif > + } > + > + return EFI_SUCCESS; > +} > -- > 2.26.1 > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib 2020-05-20 18:27 ` Leif Lindholm @ 2020-05-29 12:43 ` Daniel Schaefer 2020-05-29 13:15 ` Leif Lindholm 0 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-29 12:43 UTC (permalink / raw) To: devel, leif; +Cc: Abner Chang, Gilbert Chen, Michael D Kinney Hi Leif, thanks for this super careful review! Comments and one question inline. - Daniel On 5/20/20 8:27 PM, Leif Lindholm wrote: > On Fri, May 15, 2020 at 15:39:37 +0200, Daniel Schaefer wrote: >> Library provides interfaces to invoke SBI extensions. >> >> Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> >> >> Cc: Abner Chang <abner.chang@hpe.com> >> Cc: Gilbert Chen <gilbert.chen@hpe.com> >> Cc: Michael D Kinney <michael.k.kinney@intel.com> >> Cc: Leif Lindholm <leif@nuviainc.com> >> --- >> Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + >> Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 43 +- >> Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ >> Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ >> 4 files changed, 1466 insertions(+), 25 deletions(-) >> >> diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf >> new file mode 100644 >> index 000000000000..665dcbf40e01 >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf >> @@ -0,0 +1,28 @@ >> +## @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 = RiscVEdk2SbiLib >> + FILE_GUID = 0DF1BBBD-F7E5-4E8A-BCF1-9D63D2DD9FDD >> + MODULE_TYPE = BASE >> + VERSION_STRING = 1.0 >> + LIBRARY_CLASS = RiscVEdk2SbiLib >> + >> +[Sources] >> + RiscVEdk2SbiLib.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec >> + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> + RiscVOpensbiLib >> diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h >> index c5c0bd6d9b01..18a85e2238d2 100644 >> --- a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h >> +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h >> @@ -10,42 +10,35 @@ >> #ifndef EDK2_SBI_H_ >> #define EDK2_SBI_H_ >> >> -#include <include/sbi/riscv_asm.h> // Reference to header file in opensbi >> #include <RiscVImpl.h> >> +#include <sbi/riscv_asm.h> // Reference to header file in opensbi > > I don't see anything in *this* patch requiring this change - does this > belong squashed into 2/3? Yes... I'll fix it in the next patchset. > >> +#include <sbi/sbi_ecall_interface.h> >> +#include <sbi/sbi_error.h> >> #include <sbi/sbi_types.h> // Reference to header file wrapper >> >> -#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 >> +// Translation from OpenSBI constants to SBI names >> +#define SBI_SUCCESS SBI_OK >> +#define SBI_ERR_FAILED SBI_EFAIL >> +#define SBI_ERR_NOT_SUPPORTED SBI_ENOTSUPP >> +#define SBI_ERR_INVALID_PARAM SBI_EINVAL >> +#define SBI_ERR_DENIED SBI_DENIED >> +#define SBI_ERR_INVALID_ADDRESS SBI_INVALID_ADDR >> +#define SBI_ERR_ALREADY_AVAILABLE -6 > > Ah, right, see my confusion from reviewing 2/3. > Please move this to 2/3, adding a comment on why > SBI_ERR_ALREADY_AVAILABLE needs to be locally defined here. See above, comment added. > >> >> -#define SBI_BASE_EXT 0x10 >> -#define SBI_HSM_EXT 0x48534D >> -#define SBI_TIME_EXT 0x54494D45 >> -#define SBI_IPI_EXT 0x735049 >> -#define SBI_RFNC_EXT 0x52464E43 > > Why do we add these in 2/3 only to delete them again here? See above. > >> +// Included in OpenSBI 0.7 >> +// Can be removed, once we upgrade >> +#define SBI_EXT_HSM 0x48534D >> +#define SBI_EXT_HSM_HART_START 0x0 >> +#define SBI_EXT_HSM_HART_STOP 0x1 >> +#define SBI_EXT_HSM_HART_GET_STATUS 0x2 >> >> // >> // Below two definitions should be defined in OpenSBI. >> +// Submitted to upstream, waiting for merge and release. > > Good call out. This isn't pretty, but it is the right thing to do. > >> // >> #define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000 >> #define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF >> >> -#define SBI_GET_SPEC_VERSION_FUNC 0 >> -#define SBI_GET_IMPL_ID_FUNC 1 >> -#define SBI_GET_IMPL_VERSION_FUNC 2 >> -#define SBI_PROBE_EXTENSION_FUNC 3 >> -#define SBI_GET_MVENDORID_FUNC 4 >> -#define SBI_GET_MARCHID_FUNC 5 >> -#define SBI_GET_MIMPID_FUNC 6 >> - >> -#define SBI_HART_START_FUNC 0 >> -#define SBI_HART_STOP_FUNC 1 >> -#define SBI_HART_GET_STATUS_FUNC 2 >> - > > Why do we add these in 2/3 only to delete them again here? See above. > >> #define RISC_V_MAX_HART_SUPPORTED 16 >> >> typedef >> diff --git a/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h >> new file mode 100644 >> index 000000000000..cf77814e3bbc >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h >> @@ -0,0 +1,631 @@ >> +/** @file Defines the PPIs to let PEIMs call SBI >> + >> +Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> >> + >> +SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef RISCV_SBI_LIB_H_ >> +#define RISCV_SBI_LIB_H_ >> + >> +#include <Uefi.h> >> +#include <IndustryStandard/RiscVOpensbi.h> >> +#include <sbi/sbi_scratch.h> >> +#include <sbi/sbi_platform.h> >> + >> +// >> +// EDK2 OpenSBI Firmware extension. >> +// >> +#define SBI_EDK2_FW_EXT (SBI_EXT_FIRMWARE_CODE_BASE_START | SBI_OPENSBI_IMPID) >> +// >> +// EDK2 OpenSBI Firmware extension functions. >> +// >> +#define SBI_EXT_FW_MSCRATCH_FUNC 0 >> +#define SBI_EXT_FW_MSCRATCH_HARTID_FUNC 1 >> + >> +// >> +// EDK2 OpenSBI firmware extension return status. >> +// >> +struct sbiret { > > This struct appears only to be referenceed outside the opensbi > submodule, so name should conform to EDK2 coding style (and preferably > with a typedef). Okidoki. > >> + long error; ///< SBI status code >> + long value; ///< Value returned > > This looks like a maintenance hazard (means different things to GCC > and VS for example). Can we use UINT32? I'll use UINTN because it's bigger than 32bits on RISCV64 > >> +}; >> + >> +#define SbiCall0(ext_id, func_id) \ >> + SbiCall(ext_id, func_id, 0, 0, 0, 0, 0, 0) >> +#define SbiCall1(ext_id, func_id, arg0) \ >> + SbiCall(ext_id, func_id, arg0, 0, 0, 0, 0, 0) >> +#define SbiCall2(ext_id, func_id, arg0, arg1) \ >> + SbiCall(ext_id, func_id, arg0, arg1, 0, 0, 0, 0) >> +#define SbiCall3(ext_id, func_id, arg0, arg1, arg2) \ >> + SbiCall(ext_id, func_id, arg0, arg1, arg2, 0, 0, 0) >> +#define SbiCall4(ext_id, func_id, arg0, arg1, arg2, arg3) \ >> + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, 0, 0) >> +#define SbiCall5(ext_id, func_id, arg0, arg1, arg2, arg3, arg4) \ >> + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, 0) >> +#define SbiCall6(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) \ >> + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) > > Ugh. This looks way too much like pre-EFIAPI x86 code. > > Is this a pattern used across multiple codebases? > If not, could we make this a simple argc/argv instead and do the > unpacking inside SbiCall()? Hmm, maybe that would make the call sites > even worse. > > If we need to keep these, coding style says all macros should use > UPPERCASE_AND_UNDERSCORES. > Yeah, I think argc/argv is going to make the callsites worse. What about vararg, like I used in SbiVendorCall in Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c ? Or does that have a performance impact? Maybe an architecture specific one? >> + >> +/** >> + EDK2 SbiCall to invoke SBI extensions. >> + >> + @param[in] ext_id Sbi extension ID. >> + @param[in] func_id Sbi functions ID. >> + @param[in] arg0 Arg0 to function. >> + @param[in] arg1 Arg1 to function. >> + @param[in] arg2 Arg2 to function. >> + @param[in] arg3 Arg3 to function. >> + @param[in] arg4 Arg4 to function. >> + @param[in] arg5 Arg5 to function. >> + >> + @retval Returns sbiret structure. >> + >> +**/ >> +inline >> +EFIAPI >> +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, > > Function name starts in the first column of a new line. > But please drop the entire forward-declaration. > >> + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) >> +__attribute__((always_inline)); >> + >> +/** >> + EDK2 SbiCall to invoke SBI extensions. >> + >> + @param[in] ext_id Sbi extension ID. >> + @param[in] func_id Sbi functions ID. >> + @param[in] arg0 Arg0 to function. >> + @param[in] arg1 Arg1 to function. >> + @param[in] arg2 Arg2 to function. >> + @param[in] arg3 Arg3 to function. >> + @param[in] arg4 Arg4 to function. >> + @param[in] arg5 Arg5 to function. >> + >> + @retval Returns sbiret structure. >> + >> +**/ >> +inline > > Technically, the coding standard bans function definitions in header > files[1]. If you can give me a good reason for why this function > should be here, I may consider to consider making an exception. > If I do, make it just STATIC (let the compiler worry about the > inlining). When I first wrote this library, it was necessary but it's not anymore. I moved it to the .c file, because it's not used anywhere else. > > If it is just by habit from other projects of putting helper functions > into headers, please move them to a .c file. > > [1] https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/53_include_files#5-3-7-include-files-shall-not-generate-code-or-define-data-variables > >> +EFIAPI >> +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1, >> + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5) { >> + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); >> + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); >> + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); >> + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); >> + register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); >> + register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); >> + register uintptr_t a6 asm ("a6") = (uintptr_t)(func_id); >> + register uintptr_t a7 asm ("a7") = (uintptr_t)(ext_id); > > I would *prefer* UINTN over uintptr_t here. > >> + asm volatile ("ecall" \ >> + : "+r" (a0) \ > > Isn't a1 also an input/output operand here? Yes, you're right. > >> + : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \ >> + : "memory"); \ >> + struct sbiret ret = { a0, a1 }; >> + return ret; > > CamelCase naming. Will change it everywhere. > >> +} >> + >> +/** >> + Get the implemented SBI specification version >> + >> + The minor number of the SBI specification is encoded in the low 24 bits, >> + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is >> + reserved for future expansion. >> + >> + @param[out] SpecVersion The Version of the SBI specification. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetSpecVersion ( >> + OUT UINTN *SpecVersion >> + ); >> + >> +/** >> + Get the SBI implementation ID >> + >> + This ID is used to idenetify a specific SBI implementation in order to work >> + around any quirks it might have. >> + >> + @param[out] ImplId The ID of the SBI implementation. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetImplId ( >> + OUT UINTN *ImplId >> + ); >> + >> +/** >> + Get the SBI implementation version >> + >> + The version of this SBI implementation. >> + The encoding of this number is determined by the specific SBI implementation. >> + >> + @param[out] ImplVersion The version of the SBI implementation. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetImplversion ( > > Uppercase V for CamelCase (and matching the argument name below). Oops. > >> + OUT UINTN *ImplVersion >> + ); >> + >> +/** >> + Probe whether an SBI extension is available >> + >> + ProbeResult is set to 0 if the extension is not available or to an extension >> + specified value if it is available. >> + >> + @param[in] ExtensionId The extension ID. >> + @param[out] ProbeResult The return value of the probe. >> +**/ >> +VOID >> +EFIAPI >> +SbiProbeExtension ( >> + IN INTN ExtensionId, >> + OUT INTN *ProbeResult >> + ); >> + >> +/** >> + Get the CPU's vendor ID >> + >> + Reads the mvendorid CSR. > > What is an MvendorId? MachineVendorId? > Even if an official register name, I would prefer function and > arguments to be given proper descriptive CamelCase names. Yes, it's the official register name. Alright, will change it. > >> + >> + @param[out] MvendorId The CPU's vendor ID. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMvendorId ( >> + OUT UINTN *MvendorId >> + ); >> + >> +/** >> + Get the CPU's architecture ID >> + >> + Reads the marchid CSR. >> + >> + @param[out] MarchId The CPU's architecture ID. > > This should probebly be MArchId (or MachineArchId?)? Yes, changed it to MachineArchId. > >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMarchId ( >> + OUT UINTN *MarchId >> + ); >> + >> +/** >> + Get the CPU's implementation ID >> + >> + Reads the mimpid CSR. >> + >> + @param[out] MimpId The CPU's implementation ID. > > Above "Impl" is used for "Impelentation". *Strictly* speaking, "Impl" > doesn't fall in the pretty small group of abbreviations permitted > without a glossary section in the source file, but it's clear enough > to me I'll let it slip. > The same cannot be said for "Imp". > MachineImplId? Sounds good. Should it be added to the permitted abbreviations? If I spell it out fully here, it becomes quite long. > >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMimpId ( >> + OUT UINTN *Mimpid >> + ); >> + >> +/** >> + Politely ask the SBI to start a given hart. > > I know hart is a pretty fundamental concept in RISC-V. > Still, I would request to have it added in a glossary section in the > top-of-file comment header. Cool, didn't know that existed! Will do. > >> + >> + This call may return before the hart has actually started executing, if the >> + SBI implementation can guarantee that the hart is actually going to start. >> + >> + Before the hart jumps to StartAddr, the hart MUST configure PMP if present >> + and switch to S-mode. >> + >> + @param[in] HartId The id of the hart to start. >> + @param[in] StartAddr The physical address, where the hart starts >> + executing from. >> + @param[in] Priv An XLEN-bit value, which will be in register >> + a1 when the hart starts. >> + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. >> + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: >> + - It is not a valid physical address. >> + - The address is prohibited by PMP to run in >> + supervisor mode. >> + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id >> + @retval EFI_ALREADY_STARTED The hart is already running. >> + @retval other The start request failed for unknown reasons. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartStart ( > > (With great effort, I suppress a Mötley Crüe joke.) > >> + IN UINTN HartId, >> + IN UINTN StartAddr, >> + IN UINTN Priv >> + ); >> + >> +/** >> + Return execution of the calling hart to SBI. >> + >> + MUST be called in S-Mode with user interrupts disabled. >> + This call is not expected to return, unless a failure occurs. >> + >> + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. >> + @retval other Failed to stop hard for an unknown reason. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartStop ( >> + ); >> + >> +/** >> + Get the current status of a hart. >> + >> + Since harts can transition between states at any time, the status retrieved >> + by this function may already be out of date, once it returns. >> + >> + Possible values for HartStatus are: >> + 0: STARTED >> + 1: STOPPED >> + 2: START_REQUEST_PENDING >> + 3: STOP_REQUEST_PENDING >> + >> + @param[out] HartStatus The pointer in which the hart's status is >> + stored. >> + @retval EFI_SUCCESS The operation succeeds. >> + @retval EFI_INVALID_PARAMETER A parameter is invalid. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartGetStatus ( >> + IN UINTN HartId, >> + OUT UINTN *HartStatus >> + ); >> + >> +/// >> +/// Timer extension >> +/// >> + >> +/** >> + Clear pending timer interrupt bit and set timer for next event after StimeValue. > > What does the S stand for in Stime? That's what they call it in the spec: stime_value. I guess it stands for supervisor. Should we change it to just `Time`? > >> + >> + To clear the timer without scheduling a timer event, set StimeValue to a >> + practically infinite value or mask the timer interrupt by clearing sie.STIE. >> + >> + @param[in] StimeValue The time offset to the next scheduled timer interrupt. >> +**/ >> +VOID >> +EFIAPI >> +SbiSetTimer ( >> + IN UINT64 StimeValue >> + ); >> + >> +/// >> +/// IPI extension >> +/// >> + >> +/** >> + Send IPI to all harts specified in the mask. >> + >> + The interrupts are registered as supervisor software interrupts at the >> + receiving hart. >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiSendIpi ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase >> + ); >> + >> +/// >> +/// Remote fence extension >> +/// >> + >> +/** >> + Instructs remote harts to execute a FENCE.I instruction. >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteFenceI ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VMA instructions. >> + >> + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteSfenceVma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VMA instructions. >> + >> + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given ASID. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteSfenceVmaAsid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Asid >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given VMID. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHfenceGvmaVmid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Vmid >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHfenceGvma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given ASID. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHfenceVvmaAsid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Asid >> + ); >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHfenceVvma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ); >> + >> +/// >> +/// Vendor Specific extension space: Extension Ids 0x09000000 through 0x09FFFFFF >> +/// >> + >> +/** >> + Call a function in a vendor defined SBI extension >> + >> + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension >> + Space. >> + >> + @param[in] ExtensionId The SBI vendor extension ID. >> + @param[in] FunctionId The function ID to call in this extension. >> + @param[in] NumArgs How many arguments are passed. >> + @param[in] ... Actual Arguments to the function. >> + @retval EFI_SUCCESS if the SBI function was called and it was successful >> + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 >> + @retval others if the called SBI function returns an error >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiVendorCall ( >> + IN UINTN ExtensionId, >> + IN UINTN FunctionId, >> + IN UINTN NumArgs, >> + ... >> + ); >> + >> +/// >> +/// Firmware SBI Extension >> +/// >> +/// This SBI Extension is defined and used by EDK2 only in order to be able to >> +/// run PI and DXE phase in S-Mode. >> +/// >> + >> +/** >> + Get scratch space of the current hart. >> + >> + Please consider using the wrapper SbiGetFirmwareContext if you only need to >> + access the firmware context. >> + >> + @param[out] ScratchSpace The scratch space pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetMscratch ( >> + OUT struct sbi_scratch **ScratchSpace > > Could we add a typedef for "struct sbi_scratch" to make the code more > style compliant? Yeah, will do. Then I'll also do one for `struct sbi_platform`, which is used in the .c file. > >> + ); >> + >> +/** >> + Get scratch space of the given hart id. >> + >> + @param[in] HartId The hart id. >> + @param[out] ScratchSpace The scratch space pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetMscratchHartid ( >> + IN UINTN HartId, >> + OUT struct sbi_scratch **ScratchSpace >> + ); >> + >> +/** >> + Get firmware context of the calling hart. >> + >> + @param[out] FirmwareContext The firmware context pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetFirmwareContext ( >> + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext >> + ); >> + >> +/** >> + Set firmware context of the calling hart. >> + >> + @param[in] FirmwareContext The firmware context pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiSetFirmwareContext ( >> + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext >> + ); >> + >> +#endif >> diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c >> new file mode 100644 >> index 000000000000..bbe006a78af8 >> --- /dev/null >> +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c >> @@ -0,0 +1,789 @@ >> +/** @file >> + Instance of the SBI ecall library. >> + >> + It allows calling an SBI function via an ecall from S-Mode. >> + >> + The legacy extensions are not included because they are not necessary. >> + They would be: >> + - SbiLegacySetTimer -> Use SbiSetTimer >> + - SbiLegacyConsolePutChar -> No replacement - Use regular UEFI functions >> + - SbiLegacyConsoleGetChar -> No replacement - Use regular UEFI functions >> + - SbiLegacyClearIpi -> Write 0 to SSIP >> + - SbiLegacySendIpi -> Use SbiSendIpi >> + - SbiLegacyRemoteFenceI -> Use SbiRemoteFenceI >> + - SbiLegacyRemoteSfenceVma -> Use SbiRemoteSfenceVma >> + - SbiLegacyRemoteSfenceVmaAsid -> Use SbiRemoteSfenceVmaAsid >> + - SbiLegacyShutdown -> Wait for new System Reset extension >> + >> + Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.<BR> >> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> +**/ >> + >> +#include <IndustryStandard/RiscVOpensbi.h> >> +#include <Library/BaseMemoryLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/RiscVEdk2SbiLib.h> >> +#include <sbi/riscv_asm.h> >> +#include <sbi/sbi_hart.h> >> +#include <sbi/sbi_types.h> >> +#include <sbi/sbi_platform.h> >> +#include <sbi/sbi_init.h> >> + >> +/** >> + Translate SBI error code to EFI status. >> + >> + @param[in] SbiError SBI error code >> + @retval EFI_STATUS >> +**/ >> + >> +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; >> + } >> +} >> + >> +// >> +// OpenSBI libraary interface function for the base extension >> +// >> + >> +/** >> + Get the implemented SBI specification version >> + >> + The minor number of the SBI specification is encoded in the low 24 bits, >> + with the major number encoded in the next 7 bits. Bit 32 must be 0 and is >> + reserved for future expansion. >> + >> + @param[out] SpecVersion The Version of the SBI specification. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetSpecVersion ( >> + OUT UINTN *SpecVersion >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION); >> + >> + if (!ret.error) { >> + *SpecVersion = (UINTN) ret.value; >> + } >> + >> + //return TranslateError(ret.error); >> +} >> + >> +/** >> + Get the SBI implementation ID >> + >> + This ID is used to idenetify a specific SBI implementation in order to work >> + around any quirks it might have. >> + >> + @param[out] ImplId The ID of the SBI implementation. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetImplId ( >> + OUT UINTN *ImplId >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID); >> + *ImplId = (UINTN) ret.value; >> +} >> + >> +/** >> + Get the SBI implementation version >> + >> + The version of this SBI implementation. >> + The encoding of this number is determined by the specific SBI implementation. >> + >> + @param[out] ImplVersion The version of the SBI implementation. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetImplVersion ( >> + OUT UINTN *ImplVersion >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSION); >> + *ImplVersion = (UINTN) ret.value; >> +} >> + >> +/** >> + Probe whether an SBI extension is available >> + >> + ProbeResult is set to 0 if the extension is not available or to an extension >> + specified value if it is available. >> + >> + @param[in] ExtensionId The extension ID. >> + @param[out] ProbeResult The return value of the probe. >> +**/ >> +VOID >> +EFIAPI >> +SbiProbeExtension ( >> + IN INTN ExtensionId, >> + OUT INTN *ProbeResult >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT); >> + *ProbeResult = (UINTN) ret.value; >> +} >> + >> +/** >> + Get the CPU's vendor ID >> + >> + Reads the mvendorid CSR. >> + >> + @param[out] MvendorId The CPU's vendor ID. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMvendorId ( >> + OUT UINTN *MvendorId >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID); >> + *MvendorId = (UINTN) ret.value; >> +} >> + >> +/** >> + Get the CPU's vendor ID >> + >> + Reads the mvendorid CSR. >> + >> + @param[out] MvendorId The CPU's vendor ID. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMarchId ( >> + OUT UINTN *MarchId >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MARCHID); >> + *MarchId = (UINTN) ret.value; >> +} >> + >> +/** >> + Get the CPU's architecture ID >> + >> + Reads the marchid CSR. >> + >> + @param[out] MarchId The CPU's architecture ID. >> +**/ >> +VOID >> +EFIAPI >> +SbiGetMimpId ( >> + OUT UINTN *MimpId >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MIMPID); >> + *MimpId = (UINTN) ret.value; >> +} >> + >> +// >> +// SBI interface function for the hart state management extension >> +// >> + >> +/** >> + Politely ask the SBI to start a given hart. >> + >> + This call may return before the hart has actually started executing, if the >> + SBI implementation can guarantee that the hart is actually going to start. >> + >> + Before the hart jumps to StartAddr, the hart MUST configure PMP if present >> + and switch to S-mode. >> + >> + @param[in] HartId The id of the hart to start. >> + @param[in] StartAddr The physical address, where the hart starts >> + executing from. >> + @param[in] Priv An XLEN-bit value, which will be in register >> + a1 when the hart starts. >> + @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr. >> + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons: >> + - It is not a valid physical address. >> + - The address is prohibited by PMP to run in >> + supervisor mode. >> + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id >> + @retval EFI_ALREADY_STARTED The hart is already running. >> + @retval other The start request failed for unknown reasons. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartStart ( >> + IN UINTN HartId, >> + IN UINTN StartAddr, >> + IN UINTN Priv >> + ) >> +{ >> + struct sbiret ret = SbiCall3 (SBI_EXT_HSM, >> + SBI_EXT_HSM_HART_START, >> + HartId, >> + StartAddr, >> + Priv); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Return execution of the calling hart to SBI. >> + >> + MUST be called in S-Mode with user interrupts disabled. >> + This call is not expected to return, unless a failure occurs. >> + >> + @retval EFI_SUCCESS Never occurs. When successful, the call does not return. >> + @retval other Failed to stop hard for an unknown reason. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartStop ( >> + ) >> +{ >> + struct sbiret Ret = SbiCall0 (SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP); >> + return TranslateError(Ret.error); >> +} >> + >> +/** >> + Get the current status of a hart. >> + >> + Since harts can transition between states at any time, the status retrieved >> + by this function may already be out of date, once it returns. >> + >> + Possible values for HartStatus are: >> + 0: STARTED >> + 1: STOPPED >> + 2: START_REQUEST_PENDING >> + 3: STOP_REQUEST_PENDING >> + >> + @param[out] HartStatus The pointer in which the hart's status is >> + stored. >> + @retval EFI_SUCCESS The operation succeeds. >> + @retval EFI_INVALID_PARAMETER A parameter is invalid. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiHartGetStatus ( >> + IN UINTN HartId, >> + OUT UINTN *HartStatus >> + ) >> +{ >> + struct sbiret ret = SbiCall1 (SBI_EXT_HSM, SBI_EXT_HSM_HART_GET_STATUS, HartId); >> + >> + if (!ret.error) { >> + *HartStatus = (UINTN) ret.value; >> + } >> + >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Clear pending timer interrupt bit and set timer for next event after StimeValue. >> + >> + To clear the timer without scheduling a timer event, set StimeValue to a >> + practically infinite value or mask the timer interrupt by clearing sie.STIE. >> + >> + @param[in] StimeValue The time offset to the next scheduled timer interrupt. >> +**/ >> +VOID >> +EFIAPI >> +SbiSetTimer ( >> + IN UINT64 StimeValue >> + ) >> +{ >> + SbiCall1 (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, StimeValue); >> +} >> + >> +EFI_STATUS >> +EFIAPI >> +SbiSendIpi ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase >> + ) >> +{ >> + struct sbiret ret = SbiCall2 (SBI_EXT_IPI, >> + SBI_EXT_IPI_SEND_IPI, >> + (UINTN) HartMask, >> + HartMaskBase); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs remote harts to execute a FENCE.I instruction. >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteFenceI ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase >> + ) >> +{ >> + struct sbiret ret = SbiCall2 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_FENCE_I, >> + (UINTN) HartMask, >> + HartMaskBase); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VMA instructions. >> + >> + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteSfenceVma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ) >> +{ >> + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VMA instructions. >> + >> + The SFENCE.VMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given ASID. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteSfenceVmaAsid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Asid >> + ) >> +{ >> + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size, >> + Asid); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given VMID. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHFenceGvmaVmid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Vmid >> + ) >> +{ >> + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size, >> + Vmid); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.GVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHFenceGvma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ) >> +{ >> + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + Covers only the given ASID. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHFenceVvmaAsid ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size, >> + IN UINTN Asid >> + ) >> +{ >> + struct sbiret ret = SbiCall5 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size, >> + Asid); >> + return TranslateError(ret.error); >> +} >> + >> +/** >> + Instructs the remote harts to execute one or more SFENCE.VVMA instructions. >> + >> + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr and Size. >> + This function call is only valid for harts implementing the hypervisor extension. >> + >> + The remote fence function acts as a full tlb flush if * StartAddr and size >> + are both 0 * size is equal to 2^XLEN-1 >> + >> + @param[in] HartMask Scalar bit-vector containing hart ids >> + @param[in] HartMaskBase The starting hartid from which the bit-vector >> + must be computed. If set to -1, HartMask is >> + ignored and all harts are considered. >> + @param[in] StartAddr The first address of the affected range. >> + @param[in] Size How many addresses are affected. >> + @retval EFI_SUCCESS IPI was sent to all the targeted harts. >> + @retval EFI_LOAD_ERROR StartAddr or Size is not valid. >> + @retval EFI_UNSUPPORTED SBI does not implement this function or one >> + of the target harts does not support the >> + hypervisor extension. >> + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid >> + from hart_mask is not valid i.e. either the >> + hartid is not enabled by the platform or is >> + not available to the supervisor. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiRemoteHFenceVvma ( >> + IN UINTN *HartMask, >> + IN UINTN HartMaskBase, >> + IN UINTN StartAddr, >> + IN UINTN Size >> + ) >> +{ >> + struct sbiret ret = SbiCall4 (SBI_EXT_RFENCE, >> + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, >> + (UINTN) HartMask, >> + HartMaskBase, >> + StartAddr, >> + Size); >> + return TranslateError(ret.error); >> +} >> + >> +// >> +// SBI interface function for the vendor extension >> +// >> + >> +/** >> + Call a function in a vendor defined SBI extension >> + >> + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension >> + Space. >> + >> + @param[in] ExtensionId The SBI vendor extension ID. >> + @param[in] FunctionId The function ID to call in this extension. >> + @param[in] NumArgs How many arguments are passed. >> + @param[in] ... Actual Arguments to the function. >> + @retval EFI_SUCCESS if the SBI function was called and it was successful >> + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6 >> + @retval others if the called SBI function returns an error >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiVendorCall ( >> + IN UINTN ExtensionId, >> + IN UINTN FunctionId, >> + IN UINTN NumArgs, >> + ... >> + ) >> +{ >> + struct sbiret ret; >> + VA_LIST Args; >> + VA_START(Args, NumArgs); >> + >> + ASSERT (ExtensionId >= 0x09000000 && ExtensionId <= 0x09FFFFFF); >> + >> + switch (NumArgs) { >> + case 0: >> + ret = SbiCall0 (ExtensionId, FunctionId); >> + break; >> + case 1: >> + ret = SbiCall1 (ExtensionId, FunctionId, VA_ARG(Args, UINTN)); >> + break; >> + case 2: >> + ret = SbiCall2 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); >> + break; >> + case 3: >> + ret = SbiCall3 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); >> + break; >> + case 4: >> + ret = SbiCall4 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); >> + break; >> + case 5: >> + ret = SbiCall5 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); >> + break; >> + case 6: >> + ret = SbiCall6 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN)); >> + break; >> + default: >> + // Too many args. In theory SBI can handle more arguments when they are >> + // passed on the stack but no SBI extension uses this, therefore it's >> + // not yet implemented here. >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + VA_END(Args); >> + return TranslateError(ret.error); >> +} >> + >> +// >> +// SBI Firmware extension >> +// >> + >> +/** >> + Get scratch space of the current hart. >> + >> + Please consider using the wrapper SbiGetFirmwareContext if you only need to >> + access the firmware context. >> + >> + @param[out] ScratchSpace The scratch space pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetMscratch ( >> + OUT struct sbi_scratch **ScratchSpace >> + ) >> +{ >> + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); >> + >> + if (!ret.error) { >> + *ScratchSpace = (struct sbi_scratch *) ret.value; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Get scratch space of the given hart id. >> + >> + @param[in] HartId The hart id. >> + @param[out] ScratchSpace The scratch space pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetMscratchHartid ( >> + IN UINTN HartId, >> + OUT struct sbi_scratch **ScratchSpace >> + ) >> +{ >> + struct sbiret ret = SbiCall1 (SBI_EDK2_FW_EXT, >> + SBI_EXT_FW_MSCRATCH_HARTID_FUNC, >> + HartId); >> + >> + if (!ret.error) { >> + *ScratchSpace = (struct sbi_scratch *) ret.value; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Get firmware context of the calling hart. >> + >> + @param[out] FirmwareContext The firmware context pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiGetFirmwareContext ( >> + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext >> + ) >> +{ >> + struct sbi_scratch *ScratchSpace; >> + struct sbi_platform *SbiPlatform; >> + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); >> + >> + if (!ret.error) { >> + ScratchSpace = (struct sbi_scratch *) ret.value; >> + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); >> + *FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *) SbiPlatform->firmware_context; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Set firmware context of the calling hart. >> + >> + @param[in] FirmwareContext The firmware context pointer. >> + @retval EFI_SUCCESS The operation succeeds. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SbiSetFirmwareContext ( >> + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext >> + ) >> +{ >> + struct sbi_scratch *ScratchSpace; >> + struct sbi_platform *SbiPlatform; >> + struct sbiret ret = SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC); >> + >> + if (!ret.error) { >> + ScratchSpace = (struct sbi_scratch *) ret.value; >> + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); >> + SbiPlatform->firmware_context = (long unsigned int) FirmwareContext; > > UINT64? UINTN for compatibility with 32bits. > > / > Leif > >> + } >> + >> + return EFI_SUCCESS; >> +} >> -- >> 2.26.1 >> > > > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib 2020-05-29 12:43 ` [edk2-devel] " Daniel Schaefer @ 2020-05-29 13:15 ` Leif Lindholm 0 siblings, 0 replies; 19+ messages in thread From: Leif Lindholm @ 2020-05-29 13:15 UTC (permalink / raw) To: Daniel Schaefer; +Cc: devel, Abner Chang, Gilbert Chen, Michael D Kinney On Fri, May 29, 2020 at 14:43:43 +0200, Daniel Schaefer wrote: > Hi Leif, > > thanks for this super careful review! > Comments and one question inline. > > - Daniel > > On 5/20/20 8:27 PM, Leif Lindholm wrote: > > On Fri, May 15, 2020 at 15:39:37 +0200, Daniel Schaefer wrote: > > > Library provides interfaces to invoke SBI extensions. > > > > > > Signed-off-by: Daniel Schaefer <daniel.schaefer@hpe.com> > > > > > > Cc: Abner Chang <abner.chang@hpe.com> > > > Cc: Gilbert Chen <gilbert.chen@hpe.com> > > > Cc: Michael D Kinney <michael.k.kinney@intel.com> > > > Cc: Leif Lindholm <leif@nuviainc.com> > > > --- > > > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + > > > Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 43 +- > > > Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ > > > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ > > > 4 files changed, 1466 insertions(+), 25 deletions(-) > > > > > > diff --git a/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > > > new file mode 100644 > > > index 000000000000..cf77814e3bbc > > > --- /dev/null > > > +++ b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > > > > > + long error; ///< SBI status code > > > + long value; ///< Value returned > > > > This looks like a maintenance hazard (means different things to GCC > > and VS for example). Can we use UINT32? > > I'll use UINTN because it's bigger than 32bits on RISCV64 Oh, then definitely that, yes. > > > > > +}; > > > + > > > +#define SbiCall0(ext_id, func_id) \ > > > + SbiCall(ext_id, func_id, 0, 0, 0, 0, 0, 0) > > > +#define SbiCall1(ext_id, func_id, arg0) \ > > > + SbiCall(ext_id, func_id, arg0, 0, 0, 0, 0, 0) > > > +#define SbiCall2(ext_id, func_id, arg0, arg1) \ > > > + SbiCall(ext_id, func_id, arg0, arg1, 0, 0, 0, 0) > > > +#define SbiCall3(ext_id, func_id, arg0, arg1, arg2) \ > > > + SbiCall(ext_id, func_id, arg0, arg1, arg2, 0, 0, 0) > > > +#define SbiCall4(ext_id, func_id, arg0, arg1, arg2, arg3) \ > > > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, 0, 0) > > > +#define SbiCall5(ext_id, func_id, arg0, arg1, arg2, arg3, arg4) \ > > > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, 0) > > > +#define SbiCall6(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) \ > > > + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) > > > > Ugh. This looks way too much like pre-EFIAPI x86 code. > > > > Is this a pattern used across multiple codebases? > > If not, could we make this a simple argc/argv instead and do the > > unpacking inside SbiCall()? Hmm, maybe that would make the call sites > > even worse. > > > > If we need to keep these, coding style says all macros should use > > UPPERCASE_AND_UNDERSCORES. > > > > Yeah, I think argc/argv is going to make the callsites worse. What about > vararg, like I used in SbiVendorCall in > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > ? Or does that have a performance impact? Maybe an architecture specific > one? It *might* have a performance impact, but I'd be astonished if it is noticeable. Yes please, if you don't mind, I think that would really improve the readability. > > > +/** > > > + Get the CPU's vendor ID > > > + > > > + Reads the mvendorid CSR. > > > > What is an MvendorId? MachineVendorId? > > Even if an official register name, I would prefer function and > > arguments to be given proper descriptive CamelCase names. > > Yes, it's the official register name. Alright, will change it. If it *is* the official register name, adding it to the glossary section is also OK. > > > +**/ > > > +VOID > > > +EFIAPI > > > +SbiGetMarchId ( > > > + OUT UINTN *MarchId > > > + ); > > > + > > > +/** > > > + Get the CPU's implementation ID > > > + > > > + Reads the mimpid CSR. > > > + > > > + @param[out] MimpId The CPU's implementation ID. > > > > Above "Impl" is used for "Impelentation". *Strictly* speaking, "Impl" > > doesn't fall in the pretty small group of abbreviations permitted > > without a glossary section in the source file, but it's clear enough > > to me I'll let it slip. > > The same cannot be said for "Imp". > > MachineImplId? > > Sounds good. Should it be added to the permitted abbreviations? > If I spell it out fully here, it becomes quite long. I'm OK with Impl. We should consider adding it to the list. > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +SbiHartGetStatus ( > > > + IN UINTN HartId, > > > + OUT UINTN *HartStatus > > > + ); > > > + > > > +/// > > > +/// Timer extension > > > +/// > > > + > > > +/** > > > + Clear pending timer interrupt bit and set timer for next event after StimeValue. > > > > What does the S stand for in Stime? > > That's what they call it in the spec: stime_value. > I guess it stands for supervisor. Should we change it to just `Time`? That would be a valid thing to do. Another would be to add it to the glossary. > > > + if (!ret.error) { > > > + ScratchSpace = (struct sbi_scratch *) ret.value; > > > + SbiPlatform = (struct sbi_platform *) sbi_platform_ptr(ScratchSpace); > > > + SbiPlatform->firmware_context = (long unsigned int) FirmwareContext; > > > > UINT64? > > UINTN for compatibility with 32bits. Of course. Thanks! / Leif ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches 2020-05-15 13:39 [PATCH v2 0/3] New RISC-V Patches Daniel Schaefer ` (2 preceding siblings ...) 2020-05-15 13:39 ` [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Daniel Schaefer @ 2020-05-20 11:43 ` Leif Lindholm 2020-05-20 16:03 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms Daniel Schaefer 3 siblings, 1 reply; 19+ messages in thread From: Leif Lindholm @ 2020-05-20 11:43 UTC (permalink / raw) To: devel, daniel.schaefer; +Cc: Abner Chang, Gilbert Chen, Michael D Kinney On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > In this updated version I addressed Leif's comments and made the following > changes: > > - Refactor sbi_call* to SbiCall* (EDKII style) > - Use OpenSBI constants if possible > - Include Base.h in OpensbiTypes.h > - Only use __builtin_expect with Clang and GCC (not MSVC) > > I'm sorry, I hadn't explained the new branches properly. > Previously we had all code going to EDK2 via the RISC-V-V2 branch. > > Now we're only making the least amount of necessary changes in edk2 and > everything else in edk2-platforms. > Those changes to edk2 can be grouped into different categories: > > - Patches for RISC-V EDK2 CI enablement > - Patches for edk2 modules other than RISC-V ones, to allow building them with the RISC-V toolchain > - Other RISC-V enablement like PE/COFF relocation > > Those have all been reviewed and merged to edk2 master. > > Previously we had two packages just for RISC-V on our edk2 branch: > RiscVPkg and RiscVPlatformPkg > They are now under > Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg > in edk2-platforms. Understood. I took my eye off the ball there for a while, but I'm a bit confused as to why RiscVPkg isn't going into EDK2. That is very counterintuitive. And clearly it will need revisiting if we are to add first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. > You, Leif, have previously reviewed those. In addition to this old code, which > was moved, we need some more patches to allow running PEI in S-Mode and > building in edk2-platforms. That's what this patch series is about. I *did* have some outstanding comments specifically with regards to large amounts of code duplication between the SMBIOS implementation of some closely related RISC-V platforms. That now needs to be revisited. > In the previous version of this patchseries I forgot to attach the biggest new > commit, which adds RiscVEdk2SbiLib. It wraps the ecall interface for calling > SBI in a C API and lets PEI and DXE call SBI interfaces. Because we need more > M-Mode capabilities in PEI and DXE than SBI gives us, we register another SBI > extension, that gives us access to the mscratch register. Without looking at it yet, it sounds like that may resolve the only remaining major issue I had with RiscVPkg. > I hope now it makes more sense. It is more clear, as per above I am not sure it makes more sense :) Thanks! Best Regards, Leif > - Daniel > > Cc: Abner Chang <abner.chang@hpe.com> > Cc: Gilbert Chen <gilbert.chen@hpe.com> > Cc: Michael D Kinney <michael.k.kinney@intel.com> > Cc: Leif Lindholm <leif@nuviainc.com> > > Abner Chang (1): > ProcessorPkg/Library: Add RiscVOpensbiLib > > Daniel Schaefer (2): > ProcessorPkg/RiscVOpensbLib: Add opensbi submodule > ProcessorPkg/Library: Add RiscVEdk2SbiLib > > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | 28 + > Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 60 ++ > Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | 72 ++ > Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | 631 ++++++++++++++++ > Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h | 73 ++ > Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | 789 ++++++++++++++++++++ > .gitmodules | 3 + > Readme.md | 36 + > Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi | 1 + > 9 files changed, 1693 insertions(+) > create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf > create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf > create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h > create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > create mode 100644 Silicon/RISC-V/ProcessorPkg/Include/OpensbiTypes.h > create mode 100644 Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > create mode 100644 .gitmodules > create mode 160000 Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/opensbi > > -- > 2.26.1 > > > > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-20 11:43 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches Leif Lindholm @ 2020-05-20 16:03 ` Daniel Schaefer 2020-05-20 16:07 ` Daniel Schaefer 0 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-20 16:03 UTC (permalink / raw) To: Leif Lindholm, devel Cc: Abner Chang, Gilbert Chen, Michael D Kinney, Bret.Barkelew, sean.brogan On 5/20/20 1:43 PM, Leif Lindholm wrote: > On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: >> Previously we had two packages just for RISC-V on our edk2 branch: >> RiscVPkg and RiscVPlatformPkg >> They are now under >> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg >> in edk2-platforms. > > Understood. I took my eye off the ball there for a while, but I'm a > bit confused as to why RiscVPkg isn't going into EDK2. That is very > counterintuitive. And clearly it will need revisiting if we are to add > first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. Yes, I understand your concern. Personally I'd like it also to be in EDK2 straight away, however Mike, Bret and Sean have raised valid concerns: 1. RISC-V is very new and potentially unstable - it's quicker to make changes in edk2-platforms. 2. If we define new interfaces and libraries in edk2, we can't remove them easily because it would be a backwards-incompatible change. edk2-platforms isn't quite as strict. 3. Long-term, I think many agree, we should aim to move much of the RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would need coordination with ARM maintainers because it might make sense to move their code there as well. Maybe Mike, Bret or Sean would like to provide some more comments? > I *did* have some outstanding comments specifically with regards to > large amounts of code duplication between the SMBIOS implementation of > some closely related RISC-V platforms. That now needs to be revisited. The SMBIOS code hasn't changed. It has moved to Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib You're referring to this library, right? They build the SMBIOS entries for a particular processor. Yes, the values do have a lot of overlap but these files are like configuration files. They don't do much, they only set the values of the properties. Currently it is not possible to let the UEFI firmware get this information from the hardware at runtime, especially now, since we're running in S-Mode. To allow that, we created a RISC-V working group to be able to retrieve all of this information dynamically from the processor (among other goals). Then the vendor will not have to modify these files and hardcode the values anymore. Which enables us to create a single library for all processors. See: https://github.com/riscv/configuration-structure I hope I described everything properly, please correct me otherwise, Abner. > >> In the previous version of this patchseries I forgot to attach the biggest new >> commit, which adds RiscVEdk2SbiLib. It wraps the ecall interface for calling >> SBI in a C API and lets PEI and DXE call SBI interfaces. Because we need more >> M-Mode capabilities in PEI and DXE than SBI gives us, we register another SBI >> extension, that gives us access to the mscratch register. > > Without looking at it yet, it sounds like that may resolve the only > remaining major issue I had with RiscVPkg. > >> I hope now it makes more sense. > > It is more clear, as per above I am not sure it makes more sense :) > Thanks! Your concerns are very valid, however due to the mentioned trade-offs it might not make sense to address them. - Daniel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-20 16:03 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms Daniel Schaefer @ 2020-05-20 16:07 ` Daniel Schaefer 2020-05-20 16:17 ` Daniel Schaefer 0 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-20 16:07 UTC (permalink / raw) To: Leif Lindholm, devel Cc: Abner Chang, Gilbert Chen, Michael D Kinney, Bret.Barkelew, sean.brogan please reply here, fixed Mike's email address, sorry... On 5/20/20 6:03 PM, Daniel Schaefer wrote: > On 5/20/20 1:43 PM, Leif Lindholm wrote: >> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: >>> Previously we had two packages just for RISC-V on our edk2 branch: >>> RiscVPkg and RiscVPlatformPkg >>> They are now under >>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg >>> in edk2-platforms. >> >> Understood. I took my eye off the ball there for a while, but I'm a >> bit confused as to why RiscVPkg isn't going into EDK2. That is very >> counterintuitive. And clearly it will need revisiting if we are to add >> first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. > > Yes, I understand your concern. Personally I'd like it also to be in > EDK2 straight away, however Mike, Bret and Sean have raised valid concerns: > > 1. RISC-V is very new and potentially unstable - it's quicker to make > changes in edk2-platforms. > > 2. If we define new interfaces and libraries in edk2, we can't remove > them easily because it would be a backwards-incompatible change. > edk2-platforms isn't quite as strict. > > 3. Long-term, I think many agree, we should aim to move much of the > RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would need > coordination with ARM maintainers because it might make sense to move > their code there as well. > > Maybe Mike, Bret or Sean would like to provide some more comments? > >> I *did* have some outstanding comments specifically with regards to >> large amounts of code duplication between the SMBIOS implementation of >> some closely related RISC-V platforms. That now needs to be revisited. > > The SMBIOS code hasn't changed. It has moved to > Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib > You're referring to this library, right? > > They build the SMBIOS entries for a particular processor. Yes, the > values do have a lot of overlap but these files are like configuration > files. They don't do much, they only set the values of the properties. > > Currently it is not possible to let the UEFI firmware get this > information from the hardware at runtime, especially now, since we're > running in S-Mode. > To allow that, we created a RISC-V working group to be able to retrieve > all of this information dynamically from the processor (among other > goals). Then the vendor will not have to modify these files and hardcode > the values anymore. Which enables us to create a single library for all > processors. > See: https://github.com/riscv/configuration-structure > > I hope I described everything properly, please correct me otherwise, Abner. > >> >>> In the previous version of this patchseries I forgot to attach the >>> biggest new >>> commit, which adds RiscVEdk2SbiLib. It wraps the ecall interface for >>> calling >>> SBI in a C API and lets PEI and DXE call SBI interfaces. Because we >>> need more >>> M-Mode capabilities in PEI and DXE than SBI gives us, we register >>> another SBI >>> extension, that gives us access to the mscratch register. >> >> Without looking at it yet, it sounds like that may resolve the only >> remaining major issue I had with RiscVPkg. >> >>> I hope now it makes more sense. >> >> It is more clear, as per above I am not sure it makes more sense :) >> Thanks! > > Your concerns are very valid, however due to the mentioned trade-offs it > might not make sense to address them. > > - Daniel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-20 16:07 ` Daniel Schaefer @ 2020-05-20 16:17 ` Daniel Schaefer 2020-05-21 6:59 ` Abner Chang 0 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-05-20 16:17 UTC (permalink / raw) To: Leif Lindholm, devel Cc: Abner Chang, Gilbert Chen, Kinney, Michael D, Bret.Barkelew, sean.brogan On 5/20/20 6:07 PM, Daniel Schaefer wrote: > please reply here, fixed Mike's email address, sorry... > > On 5/20/20 6:03 PM, Daniel Schaefer wrote: >> On 5/20/20 1:43 PM, Leif Lindholm wrote: >>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: >>>> Previously we had two packages just for RISC-V on our edk2 branch: >>>> RiscVPkg and RiscVPlatformPkg >>>> They are now under >>>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg >>>> in edk2-platforms. >>> >>> Understood. I took my eye off the ball there for a while, but I'm a >>> bit confused as to why RiscVPkg isn't going into EDK2. That is very >>> counterintuitive. And clearly it will need revisiting if we are to add >>> first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. >> >> Yes, I understand your concern. Personally I'd like it also to be in >> EDK2 straight away, however Mike, Bret and Sean have raised valid >> concerns: >> >> 1. RISC-V is very new and potentially unstable - it's quicker to make >> changes in edk2-platforms. >> >> 2. If we define new interfaces and libraries in edk2, we can't remove >> them easily because it would be a backwards-incompatible change. >> edk2-platforms isn't quite as strict. >> >> 3. Long-term, I think many agree, we should aim to move much of the >> RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would >> need coordination with ARM maintainers because it might make sense to >> move their code there as well. >> >> Maybe Mike, Bret or Sean would like to provide some more comments? >> >>> I *did* have some outstanding comments specifically with regards to >>> large amounts of code duplication between the SMBIOS implementation of >>> some closely related RISC-V platforms. That now needs to be revisited. >> >> The SMBIOS code hasn't changed. It has moved to >> Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib >> You're referring to this library, right? >> >> They build the SMBIOS entries for a particular processor. Yes, the >> values do have a lot of overlap but these files are like configuration >> files. They don't do much, they only set the values of the properties. >> >> Currently it is not possible to let the UEFI firmware get this >> information from the hardware at runtime, especially now, since we're >> running in S-Mode. >> To allow that, we created a RISC-V working group to be able to >> retrieve all of this information dynamically from the processor (among >> other goals). Then the vendor will not have to modify these files and >> hardcode the values anymore. Which enables us to create a single >> library for all processors. >> See: https://github.com/riscv/configuration-structure >> >> I hope I described everything properly, please correct me otherwise, >> Abner. >> >>> >>>> In the previous version of this patchseries I forgot to attach the >>>> biggest new >>>> commit, which adds RiscVEdk2SbiLib. It wraps the ecall interface for >>>> calling >>>> SBI in a C API and lets PEI and DXE call SBI interfaces. Because we >>>> need more >>>> M-Mode capabilities in PEI and DXE than SBI gives us, we register >>>> another SBI >>>> extension, that gives us access to the mscratch register. >>> >>> Without looking at it yet, it sounds like that may resolve the only >>> remaining major issue I had with RiscVPkg. >>> >>>> I hope now it makes more sense. >>> >>> It is more clear, as per above I am not sure it makes more sense :) >>> Thanks! >> >> Your concerns are very valid, however due to the mentioned trade-offs >> it might not make sense to address them. >> >> - Daniel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-20 16:17 ` Daniel Schaefer @ 2020-05-21 6:59 ` Abner Chang 2020-05-28 11:54 ` Leif Lindholm 0 siblings, 1 reply; 19+ messages in thread From: Abner Chang @ 2020-05-21 6:59 UTC (permalink / raw) To: Schaefer, Daniel (DualStudy), Leif Lindholm, devel@edk2.groups.io Cc: Chen, Gilbert, Kinney, Michael D, Bret.Barkelew@microsoft.com, sean.brogan@microsoft.com > -----Original Message----- > From: Schaefer, Daniel (DualStudy) > Sent: Thursday, May 21, 2020 12:18 AM > To: Leif Lindholm <leif@nuviainc.com>; devel@edk2.groups.io > Cc: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>; > Chen, Gilbert <gilbert.chen@hpe.com>; Kinney, Michael D > <michael.d.kinney@intel.com>; Bret.Barkelew@microsoft.com; > sean.brogan@microsoft.com > Subject: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2- > platforms > > > > On 5/20/20 6:07 PM, Daniel Schaefer wrote: > > please reply here, fixed Mike's email address, sorry... > > > > On 5/20/20 6:03 PM, Daniel Schaefer wrote: > >> On 5/20/20 1:43 PM, Leif Lindholm wrote: > >>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > >>>> Previously we had two packages just for RISC-V on our edk2 branch: > >>>> RiscVPkg and RiscVPlatformPkg > >>>> They are now under > >>>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg in > >>>> edk2-platforms. > >>> > >>> Understood. I took my eye off the ball there for a while, but I'm a > >>> bit confused as to why RiscVPkg isn't going into EDK2. That is very > >>> counterintuitive. And clearly it will need revisiting if we are to > >>> add first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. > >> > >> Yes, I understand your concern. Personally I'd like it also to be in > >> EDK2 straight away, however Mike, Bret and Sean have raised valid > >> concerns: > >> > >> 1. RISC-V is very new and potentially unstable - it's quicker to make > >> changes in edk2-platforms. > >> > >> 2. If we define new interfaces and libraries in edk2, we can't remove > >> them easily because it would be a backwards-incompatible change. > >> edk2-platforms isn't quite as strict. > >> > >> 3. Long-term, I think many agree, we should aim to move much of the > >> RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would > >> need coordination with ARM maintainers because it might make sense to > >> move their code there as well. > >> > >> Maybe Mike, Bret or Sean would like to provide some more comments? > >> > >>> I *did* have some outstanding comments specifically with regards to > >>> large amounts of code duplication between the SMBIOS implementation > >>> of some closely related RISC-V platforms. That now needs to be revisited. > >> > >> The SMBIOS code hasn't changed. It has moved to > >> Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib > >> You're referring to this library, right? > >> > >> They build the SMBIOS entries for a particular processor. Yes, the > >> values do have a lot of overlap but these files are like > >> configuration files. They don't do much, they only set the values of the > properties. > >> > >> Currently it is not possible to let the UEFI firmware get this > >> information from the hardware at runtime, especially now, since we're > >> running in S-Mode. > >> To allow that, we created a RISC-V working group to be able to > >> retrieve all of this information dynamically from the processor > >> (among other goals). Then the vendor will not have to modify these > >> files and hardcode the values anymore. Which enables us to create a > >> single library for all processors. > >> See: https://github.com/riscv/configuration-structure > >> > >> I hope I described everything properly, please correct me otherwise, > >> Abner. [Abner] Yes almost. Thanks Daniel. One thing I would like to add, If you take a look on SiFive Core IP https://www.sifive.com/risc-v-core-ip you can see there are different SKUs of RISC-V core. Just take some as example, S51 - Single core U54 - Single core S76 - Single core U74- single core U54-MC - Multicore which is 4*U54 cores +1*S51 core U74-MC - Multicore which is 4*U74 core + 1*S7 core Those are the combinations of core IP. Silicon vendor can get those core IPs and combine them to the RISC-V processor. To have CoreInfoHobLib libraries for each different core (not multicore) to build up the core capability is reasonable and makes sense. For the multicore, it just pulling the single core CoreInfoHobLib to build up the SMBIOS table for the multicore processor. Those libraries look duplicate in logically, however only one instance of CoreInfoHobLib is built in for multiple identical cores in physically view. Maybe we still can move some identical core into the core-specific library but it is not worthwhile. Abner > >> > >>> > >>>> In the previous version of this patchseries I forgot to attach the > >>>> biggest new commit, which adds RiscVEdk2SbiLib. It wraps the ecall > >>>> interface for calling SBI in a C API and lets PEI and DXE call SBI > >>>> interfaces. Because we need more M-Mode capabilities in PEI and DXE > >>>> than SBI gives us, we register another SBI extension, that gives us > >>>> access to the mscratch register. > >>> > >>> Without looking at it yet, it sounds like that may resolve the only > >>> remaining major issue I had with RiscVPkg. > >>> > >>>> I hope now it makes more sense. > >>> > >>> It is more clear, as per above I am not sure it makes more sense :) > >>> Thanks! > >> > >> Your concerns are very valid, however due to the mentioned trade-offs > >> it might not make sense to address them. > >> > >> - Daniel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-21 6:59 ` Abner Chang @ 2020-05-28 11:54 ` Leif Lindholm 2020-05-29 14:41 ` Abner Chang [not found] ` <b55ee3ec-74de-532e-01f7-bd24a327d00b@hpe.com> 0 siblings, 2 replies; 19+ messages in thread From: Leif Lindholm @ 2020-05-28 11:54 UTC (permalink / raw) To: Chang, Abner (HPS SW/FW Technologist) Cc: Schaefer, Daniel (DualStudy), devel@edk2.groups.io, Chen, Gilbert, Kinney, Michael D, Bret.Barkelew@microsoft.com, sean.brogan@microsoft.com Hi Abner, Sorry, I should have followed up on this sooner. On Thu, May 21, 2020 at 06:59:20 +0000, Chang, Abner (HPS SW/FW Technologist) wrote: > > On 5/20/20 6:07 PM, Daniel Schaefer wrote: > > > please reply here, fixed Mike's email address, sorry... > > > > > > On 5/20/20 6:03 PM, Daniel Schaefer wrote: > > >> On 5/20/20 1:43 PM, Leif Lindholm wrote: > > >>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > > >>>> Previously we had two packages just for RISC-V on our edk2 branch: > > >>>> RiscVPkg and RiscVPlatformPkg > > >>>> They are now under > > >>>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg in > > >>>> edk2-platforms. > > >>> > > >>> Understood. I took my eye off the ball there for a while, but I'm a > > >>> bit confused as to why RiscVPkg isn't going into EDK2. That is very > > >>> counterintuitive. And clearly it will need revisiting if we are to > > >>> add first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. > > >> > > >> Yes, I understand your concern. Personally I'd like it also to be in > > >> EDK2 straight away, however Mike, Bret and Sean have raised valid > > >> concerns: Can you point me to the conversation I have missed? > > >> 1. RISC-V is very new and potentially unstable - it's quicker to make > > >> changes in edk2-platforms. I don't see this as a valid argument. It's not edk2-unstable, it is edk2-platforms. edk2-platforms exists because there used to be strong feelings against holding *real* platforms in edk2, with edk2 being originally intended only as a code library for IBV/ISV to cherry-pick from. But fundamentally, if code is too immature to go into the master branch of edk2, it is too immature to go into the master branch of edk2-platforms. If we want edk2-might-be-a-bit-shaky-but-who-cares, then someone will have to create it. > > >> 2. If we define new interfaces and libraries in edk2, we can't remove > > >> them easily because it would be a backwards-incompatible change. > > >> edk2-platforms isn't quite as strict. Yes it is. The only thing making it less strict is its contents - platform ports and device drivers. The changes tend to be self-contained. Where they are not, they need to be carefully managed. > > >> 3. Long-term, I think many agree, we should aim to move much of the > > >> RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would > > >> need coordination with ARM maintainers because it might make sense to > > >> move their code there as well. I don't think there is any need to tie the two together. Yes, UefiCpuPkg should be a generic place where not only x86 support can be contained, but the paths for ARM* and RISC-V into there do not have any interdependencies. > > >>> I *did* have some outstanding comments specifically with regards to > > >>> large amounts of code duplication between the SMBIOS implementation > > >>> of some closely related RISC-V platforms. That now needs to be revisited. > > >> > > >> The SMBIOS code hasn't changed. It has moved to > > >> Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib > > >> You're referring to this library, right? > > >> > > >> They build the SMBIOS entries for a particular processor. Yes, the > > >> values do have a lot of overlap but these files are like > > >> configuration files. They don't do much, they only set the values of the > > properties. > > >> > > >> Currently it is not possible to let the UEFI firmware get this > > >> information from the hardware at runtime, especially now, since we're > > >> running in S-Mode. > > >> To allow that, we created a RISC-V working group to be able to > > >> retrieve all of this information dynamically from the processor > > >> (among other goals). Then the vendor will not have to modify these > > >> files and hardcode the values anymore. Which enables us to create a > > >> single library for all processors. > > >> See: https://github.com/riscv/configuration-structure > > >> > > >> I hope I described everything properly, please correct me otherwise, > > >> Abner. > [Abner] Yes almost. Thanks Daniel. > One thing I would like to add, > If you take a look on SiFive Core IP > > >> https://www.sifive.com/risc-v-core-ip you can see there are > > >> different SKUs of RISC-V core. Just take some as exampl,e > S51 - Single core > U54 - Single core > S76 - Single core > U74- single core > U54-MC - Multicore which is 4*U54 cores +1*S51 core > U74-MC - Multicore which is 4*U74 core + 1*S7 core > > Those are the combinations of core IP. Silicon vendor can get those > core IPs and combine them to the RISC-V processor. To have > CoreInfoHobLib libraries for each different core (not multicore) to > build up the core capability is reasonable and makes sense. For the > multicore, it just pulling the single core CoreInfoHobLib to build > up the SMBIOS table for the multicore processor. Those libraries > look duplicate in logically, however only one instance of > CoreInfoHobLib is built in for multiple identical cores in > physically view. Maybe we still can move some identical core into > the core-specific library but it is not worthwhile. OK, lets start with the *full* diff of E51 and U54 from the (admittedly slightly dated) devel-riscvplatforms branch: <<< --- ./E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c 2020-05-28 12:12:11.211028141 +0100 +++ ./U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c 2020-05-28 12:12:11.211028141 +0100 @@ -7,6 +7,8 @@ **/ +#include <IndustryStandard/RiscVOpensbi.h> + [LL] U54 inserts this file in a different location, this is not actual divergence. // // The package level header files this module uses // @@ -19,21 +21,15 @@ #include <Library/DebugLib.h> #include <Library/FirmwareContextProcessorSpecificLib.h> #include <Library/HobLib.h> -#include <Library/PcdLib.h> [LL] Interestingly, only E51 actually includes this, but both files *use* it - this is a bug in U54 caused by the separation. -#include <IndustryStandard/RiscVOpensbi.h> [LL] This is the other end of the files placing this inlude in a different location. -#include <Library/ResourcePublicationLib.h> - [LL] This header is irrelevant and unused. Present only in E51. #include <Library/RiscVEdk2SbiLib.h> -#include <ProcessorSpecificHobData.h> -#include <RiscVImpl.h> [LL] Included in different location for E51/U54. #include <sbi/sbi_hart.h> -#include <sbi/sbi_scratch.h> #include <sbi/sbi_platform.h> +#include <sbi/sbi_scratch.h> [LL] sbi_scratch.h included in different order between platforms. +#include <RiscVImpl.h> [LL] Included in different location for E51/U54 (other end of). #include <SmbiosProcessorSpecificData.h> /** - Function to build core specific information HOB. RISC-V SMBIOS DXE driver collect - this information and build SMBIOS Type44. + Function to build core specific information HOB. [LL] Different documentation description for the otherwise identical functions. @param ParentProcessorGuid Parent processor od this core. ParentProcessorGuid could be the same as CoreGuid if one processor has @@ -41,19 +37,19 @@ @param ParentProcessorUid Unique ID of pysical processor which owns this core. @param HartId Hart ID of this core. @param IsBootHart TRUE means this is the boot HART. - @param GuidHobData Pointer to receive EFI_HOB_GUID_TYPE. + @param GuidHobdata Pointer to RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. [LL] Different capitalisation of input variable and different documentation for the same parameter in the identical functions. E51 gets the former correct, U54 the latter. @return EFI_SUCCESS The PEIM initialized successfully. **/ EFI_STATUS EFIAPI -CreateE51CoreProcessorSpecificDataHob ( +CreateU54CoreProcessorSpecificDataHob ( [LL] We reach the first *real* difference between the two - the name of the function. This could have been addressed with different .inf files with different -D cflags. IN EFI_GUID *ParentProcessorGuid, IN UINTN ParentProcessorUid, IN UINTN HartId, IN BOOLEAN IsBootHart, - OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobData + OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobdata [LL] Again, difference only in capitalisation. ) { RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *CoreGuidHob; @@ -64,7 +60,7 @@ DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); - if (GuidHobData == NULL) { + if (GuidHobdata == NULL) { [LL] Again, difference only in capitalisation. return EFI_INVALID_PARAMETER; } @@ -80,7 +76,7 @@ FirmwareContextHartSpecific, ParentProcessorGuid, ParentProcessorUid, - (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid), + (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid), [LL] Different Pcd names. HartId, IsBootHart, &ProcessorSpecDataHob @@ -109,7 +105,7 @@ DEBUG ((DEBUG_INFO, " *MachineImplId = 0x%x\n", ProcessorSpecDataHob.ProcessorSpecificData.MachineImplId.Value64_L)); // - // Build GUID HOB for E51 core, this is for SMBIOS type 44 + // Build GUID HOB for U54 core. [LL] Different comments for identical code. // ProcessorSpecDataHobGuid = PcdGetPtr (PcdProcessorSpecificDataGuidHobGuid); CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID *)&ProcessorSpecDataHob, sizeof (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA)); @@ -117,7 +113,7 @@ DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core.\n")); ASSERT (FALSE); } - *GuidHobData = CoreGuidHob; + *GuidHobdata = CoreGuidHob; [LL] Again, difference only in capitalisation. return EFI_SUCCESS; } @@ -135,17 +131,21 @@ **/ EFI_STATUS EFIAPI -CreateE51ProcessorSmbiosDataHob ( +CreateU54ProcessorSmbiosDataHob ( [LL] Difference in name only. IN UINTN ProcessorUid, - OUT RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr + IN RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr [LL] I am going to go out on a limb here and suggest one of the above is incorrect, and once that is corrected, these two lines would be identical. ) { EFI_GUID *GuidPtr; RISC_V_PROCESSOR_TYPE4_HOB_DATA ProcessorDataHob; RISC_V_PROCESSOR_TYPE7_HOB_DATA L1InstCacheDataHob; + RISC_V_PROCESSOR_TYPE7_HOB_DATA L1DataCacheDataHob; + RISC_V_PROCESSOR_TYPE7_HOB_DATA L2CacheDataHob; [LL] Here is the first functional difference. RISC_V_PROCESSOR_SMBIOS_HOB_DATA SmbiosDataHob; RISC_V_PROCESSOR_TYPE4_HOB_DATA *ProcessorDataHobPtr; RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1InstCacheDataHobPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1DataCacheDataHobPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L2CacheDataHobPtr; [LL] Which could be merged with this inside an ifdef. RISC_V_PROCESSOR_SMBIOS_HOB_DATA *SmbiosDataHobPtr; if (SmbiosHobPtr == NULL) { @@ -155,7 +155,7 @@ // Build up SMBIOS type 7 L1 instruction cache record. // ZeroMem((VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); - CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid)); + CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid)); [LL] Difference in name only. L1InstCacheDataHob.ProcessorUid = ProcessorUid; L1InstCacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; L1InstCacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ @@ -173,7 +173,59 @@ GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); L1InstCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L1InstCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); if (L1InstCacheDataHobPtr == NULL) { - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core L1 instruction cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 instruction cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); [LL] Difference in name only. + ASSERT (FALSE); + } + [LL] Below starts the fundamental difference between the two: + // + // Build up SMBIOS type 7 L1 data cache record. + // + ZeroMem((VOID *)&L1DataCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + CopyGuid (&L1DataCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid)); + L1DataCacheDataHob.ProcessorUid = ProcessorUid; + L1DataCacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; + L1DataCacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ + RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \ + RISC_V_CACHE_CONFIGURATION_ENABLED | \ + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; + L1DataCacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR; + L1DataCacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR; + L1DataCacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; + L1DataCacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; + L1DataCacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR; + L1DataCacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR; + L1DataCacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeData; + L1DataCacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR; + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); + L1DataCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L1DataCacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + if (L1DataCacheDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 data cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); + ASSERT (FALSE); + } + + // + // Build up SMBIOS type 7 L2 cache record. + // + ZeroMem((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + CopyGuid (&L2CacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid)); + L2CacheDataHob.ProcessorUid = ProcessorUid; + L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \ + RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \ + RISC_V_CACHE_CONFIGURATION_ENABLED | \ + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; + L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; + L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; + L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified; + L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR; + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); + L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + if (L2CacheDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L2 cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); ASSERT (FALSE); } [LL] And the funamental difference ends here. @@ -181,7 +233,7 @@ // Build up SMBIOS type 4 record. // ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); - CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid)); + CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid)); [LL] Differ in name only. ProcessorDataHob.ProcessorUid = ProcessorUid; ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor; @@ -196,7 +248,7 @@ ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE; ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; - ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = 0xffff; + ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; [LL] Real diff. ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff; ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE; ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR; @@ -212,24 +264,23 @@ GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid); ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); if (ProcessorDataHobPtr == NULL) { - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); [LL] Difference in name only. ASSERT (FALSE); } ZeroMem((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); SmbiosDataHob.Processor = ProcessorDataHobPtr; SmbiosDataHob.L1InstCache = L1InstCacheDataHobPtr; - SmbiosDataHob.L1DataCache = NULL; - SmbiosDataHob.L2Cache = NULL; + SmbiosDataHob.L1DataCache = L1DataCacheDataHobPtr; + SmbiosDataHob.L2Cache = L2CacheDataHobPtr; [LL] Real diff. SmbiosDataHob.L3Cache = NULL; GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid); SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); if (SmbiosDataHobPtr == NULL) { - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n")); + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n")); [LL] Difference in name only. ASSERT (FALSE); } *SmbiosHobPtr = SmbiosDataHobPtr; return EFI_SUCCESS; } - >>> The meat of the difference between these two is less than 20% of the lines of code in each file - and it is mutually exclusive, not some horrific tangle of interdependencies. The story with the difference between U54 and U54MCCoreplex isn't much better, only works along a different axis. "It isn't worthwhile" in an open source project isn't a question of "how quickly can I create *one* new platform by copying instead of refactoring/reusing", but a judgement call between: - How many mistakes do I risk inserting while editing a new file as opposed to being directly able to see the differences I have caused while editing an existing file. - How much do I increase reviewing effort by doing this? - How much do I increase ongoing maintainership (or affect quality) by requiring bugs to be fixed in multiple places instead of one. Not to mention: - How many common pattern that could be broken out into common helper libraries do we miss when we need to compare every SoC/platform combination ever created, as opposed to being able to look at least at implementations covering families. If it isn't important enough to take that into consideration, it isn't important enough to upstream the SMBIOS support. / Leif ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms 2020-05-28 11:54 ` Leif Lindholm @ 2020-05-29 14:41 ` Abner Chang [not found] ` <b55ee3ec-74de-532e-01f7-bd24a327d00b@hpe.com> 1 sibling, 0 replies; 19+ messages in thread From: Abner Chang @ 2020-05-29 14:41 UTC (permalink / raw) To: Leif Lindholm Cc: Schaefer, Daniel (DualStudy), devel@edk2.groups.io, Chen, Gilbert, Kinney, Michael D, Bret.Barkelew@microsoft.com, sean.brogan@microsoft.com > -----Original Message----- > From: Leif Lindholm [mailto:leif@nuviainc.com] > Sent: Thursday, May 28, 2020 7:55 PM > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com> > Cc: Schaefer, Daniel (DualStudy) <daniel.schaefer@hpe.com>; > devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>; Kinney, > Michael D <michael.d.kinney@intel.com>; Bret.Barkelew@microsoft.com; > sean.brogan@microsoft.com > Subject: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2- > platforms > > Hi Abner, > > Sorry, I should have followed up on this sooner. > > On Thu, May 21, 2020 at 06:59:20 +0000, Chang, Abner (HPS SW/FW > Technologist) wrote: > > > On 5/20/20 6:07 PM, Daniel Schaefer wrote: > > > > please reply here, fixed Mike's email address, sorry... > > > > > > > > On 5/20/20 6:03 PM, Daniel Schaefer wrote: > > > >> On 5/20/20 1:43 PM, Leif Lindholm wrote: > > > >>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > > > >>>> Previously we had two packages just for RISC-V on our edk2 branch: > > > >>>> RiscVPkg and RiscVPlatformPkg They are now under > > > >>>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg > > > >>>> in edk2-platforms. > > > >>> > > > >>> Understood. I took my eye off the ball there for a while, but > > > >>> I'm a bit confused as to why RiscVPkg isn't going into EDK2. > > > >>> That is very counterintuitive. And clearly it will need > > > >>> revisiting if we are to add first-class CI checks like those we do with > OvmfPkg/ArmVirtPkg. > > > >> > > > >> Yes, I understand your concern. Personally I'd like it also to be > > > >> in > > > >> EDK2 straight away, however Mike, Bret and Sean have raised valid > > > >> concerns: > > Can you point me to the conversation I have missed? > > > > >> 1. RISC-V is very new and potentially unstable - it's quicker to > > > >> make changes in edk2-platforms. > > I don't see this as a valid argument. > It's not edk2-unstable, it is edk2-platforms. > > edk2-platforms exists because there used to be strong feelings against > holding *real* platforms in edk2, with edk2 being originally intended only as > a code library for IBV/ISV to cherry-pick from. > > But fundamentally, if code is too immature to go into the master branch of > edk2, it is too immature to go into the master branch of edk2-platforms. If > we want edk2-might-be-a-bit-shaky-but-who-cares, > then someone will have to create it. > > > > >> 2. If we define new interfaces and libraries in edk2, we can't > > > >> remove them easily because it would be a backwards-incompatible > change. > > > >> edk2-platforms isn't quite as strict. > > Yes it is. > The only thing making it less strict is its contents - platform ports and device > drivers. The changes tend to be self-contained. Where they are not, they > need to be carefully managed. > > > > >> 3. Long-term, I think many agree, we should aim to move much of > > > >> the RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that > > > >> would need coordination with ARM maintainers because it might > > > >> make sense to move their code there as well. > > I don't think there is any need to tie the two together. > Yes, UefiCpuPkg should be a generic place where not only x86 support can be > contained, but the paths for ARM* and RISC-V into there do not have any > interdependencies. > > > > >>> I *did* have some outstanding comments specifically with regards > > > >>> to large amounts of code duplication between the SMBIOS > > > >>> implementation of some closely related RISC-V platforms. That now > needs to be revisited. > > > >> > > > >> The SMBIOS code hasn't changed. It has moved to > > > >> > > > >> Silicon/SiFive/{E51,U54,U54MCCoreplex}/Library/PeiCoreInfoHobLib > > > >> You're referring to this library, right? > > > >> > > > >> They build the SMBIOS entries for a particular processor. Yes, > > > >> the values do have a lot of overlap but these files are like > > > >> configuration files. They don't do much, they only set the values > > > >> of the > > > properties. > > > >> > > > >> Currently it is not possible to let the UEFI firmware get this > > > >> information from the hardware at runtime, especially now, since > > > >> we're running in S-Mode. > > > >> To allow that, we created a RISC-V working group to be able to > > > >> retrieve all of this information dynamically from the processor > > > >> (among other goals). Then the vendor will not have to modify > > > >> these files and hardcode the values anymore. Which enables us to > > > >> create a single library for all processors. > > > >> See: https://github.com/riscv/configuration-structure > > > >> > > > >> I hope I described everything properly, please correct me > > > >> otherwise, Abner. > > [Abner] Yes almost. Thanks Daniel. > > One thing I would like to add, > > If you take a look on SiFive Core IP > > > >> INVALID URI REMOVED > > > >> om_risc-2Dv-2Dcore- > 2Dip&d=DwIDAw&c=C5b8zRQO1miGmBeVZ2LFWg&r=_SN6F > > > >> > ZBN4Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=CYgLjPyxDUeKYpXV_283 > 3iYF > > > >> > 0_kR2PGdGoEVD7Qare0&s=OQvDbn7xhejlUpQrBMNReCLl1WGUoPKdIp5Y3 > 6-6e8E > > > >> &e= you can see there are different SKUs of RISC-V core. Just > > > >> take some as exampl,e > > S51 - Single core > > U54 - Single core > > S76 - Single core > > U74- single core > > U54-MC - Multicore which is 4*U54 cores +1*S51 core U74-MC - Multicore > > which is 4*U74 core + 1*S7 core > > > > Those are the combinations of core IP. Silicon vendor can get those > > core IPs and combine them to the RISC-V processor. To have > > CoreInfoHobLib libraries for each different core (not multicore) to > > build up the core capability is reasonable and makes sense. For the > > multicore, it just pulling the single core CoreInfoHobLib to build up > > the SMBIOS table for the multicore processor. Those libraries look > > duplicate in logically, however only one instance of CoreInfoHobLib is > > built in for multiple identical cores in physically view. Maybe we > > still can move some identical core into the core-specific library but > > it is not worthwhile. > > OK, lets start with the *full* diff of E51 and U54 from the (admittedly slightly > dated) devel-riscvplatforms branch: > > <<< > --- ./E51/Library/PeiCoreInfoHobLib/CoreInfoHob.c 2020-05-28 > 12:12:11.211028141 +0100 > +++ ./U54/Library/PeiCoreInfoHobLib/CoreInfoHob.c 2020-05-28 > 12:12:11.211028141 +0100 > @@ -7,6 +7,8 @@ > > **/ > > +#include <IndustryStandard/RiscVOpensbi.h> > + > > [LL] > U54 inserts this file in a different location, this is not actual divergence. > > // > // The package level header files this module uses // @@ -19,21 +21,15 @@ > #include <Library/DebugLib.h> #include > <Library/FirmwareContextProcessorSpecificLib.h> > #include <Library/HobLib.h> > -#include <Library/PcdLib.h> > > [LL] > Interestingly, only E51 actually includes this, but both files *use* it - this is a > bug in U54 caused by the separation. > > -#include <IndustryStandard/RiscVOpensbi.h> > > [LL] > This is the other end of the files placing this inlude in a different location. > > -#include <Library/ResourcePublicationLib.h> > - > > [LL] > This header is irrelevant and unused. Present only in E51. > > #include <Library/RiscVEdk2SbiLib.h> > -#include <ProcessorSpecificHobData.h> > -#include <RiscVImpl.h> > > [LL] > Included in different location for E51/U54. > > #include <sbi/sbi_hart.h> > -#include <sbi/sbi_scratch.h> > #include <sbi/sbi_platform.h> > +#include <sbi/sbi_scratch.h> > > [LL] > sbi_scratch.h included in different order between platforms. > > +#include <RiscVImpl.h> > > [LL] > Included in different location for E51/U54 (other end of). > > #include <SmbiosProcessorSpecificData.h> > > /** > - Function to build core specific information HOB. RISC-V SMBIOS DXE driver > collect > - this information and build SMBIOS Type44. > + Function to build core specific information HOB. > > [LL] > Different documentation description for the otherwise identical functions. > > > @param ParentProcessorGuid Parent processor od this core. > ParentProcessorGuid > could be the same as CoreGuid if one processor has @@ - > 41,19 +37,19 @@ > @param ParentProcessorUid Unique ID of pysical processor which owns > this core. > @param HartId Hart ID of this core. > @param IsBootHart TRUE means this is the boot HART. > - @param GuidHobData Pointer to receive EFI_HOB_GUID_TYPE. > + @param GuidHobdata Pointer to > RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. > > [LL] > Different capitalisation of input variable and different documentation for the > same parameter in the identical functions. E51 gets the former correct, U54 > the latter. > > > @return EFI_SUCCESS The PEIM initialized successfully. > > **/ > EFI_STATUS > EFIAPI > -CreateE51CoreProcessorSpecificDataHob ( > +CreateU54CoreProcessorSpecificDataHob ( > > [LL] > We reach the first *real* difference between the two - the name of the > function. > This could have been addressed with different .inf files with different -D > cflags. > > IN EFI_GUID *ParentProcessorGuid, > IN UINTN ParentProcessorUid, > IN UINTN HartId, > IN BOOLEAN IsBootHart, > - OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobData > + OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobdata > > [LL] > Again, difference only in capitalisation. > > ) > { > RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *CoreGuidHob; @@ -64,7 +60,7 > @@ > > DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); > > - if (GuidHobData == NULL) { > + if (GuidHobdata == NULL) { > > [LL] > Again, difference only in capitalisation. > > return EFI_INVALID_PARAMETER; > } > > @@ -80,7 +76,7 @@ > FirmwareContextHartSpecific, > ParentProcessorGuid, > ParentProcessorUid, > - (EFI_GUID *)PcdGetPtr (PcdSiFiveE51CoreGuid), > + (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid), > > [LL] > Different Pcd names. > > HartId, > IsBootHart, > &ProcessorSpecDataHob > @@ -109,7 +105,7 @@ > DEBUG ((DEBUG_INFO, " *MachineImplId = 0x%x\n", > ProcessorSpecDataHob.ProcessorSpecificData.MachineImplId.Value64_L)); > > // > - // Build GUID HOB for E51 core, this is for SMBIOS type 44 > + // Build GUID HOB for U54 core. > > [LL] > Different comments for identical code. > > // > ProcessorSpecDataHobGuid = PcdGetPtr > (PcdProcessorSpecificDataGuidHobGuid); > CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA > *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID > *)&ProcessorSpecDataHob, sizeof > (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA)); > @@ -117,7 +113,7 @@ > DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core.\n")); > ASSERT (FALSE); > } > - *GuidHobData = CoreGuidHob; > + *GuidHobdata = CoreGuidHob; > > [LL] > Again, difference only in capitalisation. > > return EFI_SUCCESS; > } > > @@ -135,17 +131,21 @@ > **/ > EFI_STATUS > EFIAPI > -CreateE51ProcessorSmbiosDataHob ( > +CreateU54ProcessorSmbiosDataHob ( > > [LL] > Difference in name only. > > IN UINTN ProcessorUid, > - OUT RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr > + IN RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr > > [LL] > I am going to go out on a limb here and suggest one of the above is incorrect, > and once that is corrected, these two lines would be identical. > > ) > { > EFI_GUID *GuidPtr; > RISC_V_PROCESSOR_TYPE4_HOB_DATA ProcessorDataHob; > RISC_V_PROCESSOR_TYPE7_HOB_DATA L1InstCacheDataHob; > + RISC_V_PROCESSOR_TYPE7_HOB_DATA L1DataCacheDataHob; > + RISC_V_PROCESSOR_TYPE7_HOB_DATA L2CacheDataHob; > > [LL] > Here is the first functional difference. > > RISC_V_PROCESSOR_SMBIOS_HOB_DATA SmbiosDataHob; > RISC_V_PROCESSOR_TYPE4_HOB_DATA *ProcessorDataHobPtr; > RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1InstCacheDataHobPtr; > + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1DataCacheDataHobPtr; > + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L2CacheDataHobPtr; > > [LL] > Which could be merged with this inside an ifdef. > > RISC_V_PROCESSOR_SMBIOS_HOB_DATA *SmbiosDataHobPtr; > > if (SmbiosHobPtr == NULL) { > @@ -155,7 +155,7 @@ > // Build up SMBIOS type 7 L1 instruction cache record. > // > ZeroMem((VOID *)&L1InstCacheDataHob, sizeof > (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > - CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > (PcdSiFiveE51CoreGuid)); > + CopyGuid (&L1InstCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > + (PcdSiFiveU54CoreGuid)); > > [LL] > Difference in name only. > > L1InstCacheDataHob.ProcessorUid = ProcessorUid; > L1InstCacheDataHob.SmbiosType7Cache.SocketDesignation = > TO_BE_FILLED_BY_VENDOR; > L1InstCacheDataHob.SmbiosType7Cache.CacheConfiguration = > RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ @@ -173,7 +173,59 > @@ > GuidPtr = (EFI_GUID *)PcdGetPtr > (PcdProcessorSmbiosType7GuidHobGuid); > L1InstCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA > *)BuildGuidDataHob (GuidPtr, (VOID *)&L1InstCacheDataHob, sizeof > (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > if (L1InstCacheDataHobPtr == NULL) { > - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core L1 > instruction cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); > + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 > + instruction cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); > > [LL] > Difference in name only. > > + ASSERT (FALSE); > + } > + > > [LL] > Below starts the fundamental difference between the two: > > + // > + // Build up SMBIOS type 7 L1 data cache record. > + // > + ZeroMem((VOID *)&L1DataCacheDataHob, sizeof > + (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > + CopyGuid (&L1DataCacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > + (PcdSiFiveU54CoreGuid)); L1DataCacheDataHob.ProcessorUid = > + ProcessorUid; > L1DataCacheDataHob.SmbiosType7Cache.SocketDesignation = > + TO_BE_FILLED_BY_VENDOR; > L1DataCacheDataHob.SmbiosType7Cache.CacheConfiguration = > RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ > + RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \ > + RISC_V_CACHE_CONFIGURATION_ENABLED | \ > + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; > + L1DataCacheDataHob.SmbiosType7Cache.MaximumCacheSize = > + TO_BE_FILLED_BY_VENDOR; > + L1DataCacheDataHob.SmbiosType7Cache.InstalledSize = > + TO_BE_FILLED_BY_VENDOR; > + L1DataCacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown > = 1; > + L1DataCacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; > + L1DataCacheDataHob.SmbiosType7Cache.CacheSpeed = > + TO_BE_FILLED_BY_VENDOR; > + L1DataCacheDataHob.SmbiosType7Cache.ErrorCorrectionType = > + TO_BE_FILLED_BY_VENDOR; > + L1DataCacheDataHob.SmbiosType7Cache.SystemCacheType = > CacheTypeData; > + L1DataCacheDataHob.SmbiosType7Cache.Associativity = > + TO_BE_FILLED_BY_VENDOR; GuidPtr = (EFI_GUID *)PcdGetPtr > + (PcdProcessorSmbiosType7GuidHobGuid); > + L1DataCacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA > + *)BuildGuidDataHob (GuidPtr, (VOID *)&L1DataCacheDataHob, sizeof > + (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > + if (L1DataCacheDataHobPtr == NULL) { > + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L1 > data cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); > + ASSERT (FALSE); > + } > + > + // > + // Build up SMBIOS type 7 L2 cache record. > + // > + ZeroMem((VOID *)&L2CacheDataHob, sizeof > + (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > + CopyGuid (&L2CacheDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > + (PcdSiFiveU54CoreGuid)); L2CacheDataHob.ProcessorUid = ProcessorUid; > + L2CacheDataHob.SmbiosType7Cache.SocketDesignation = > + TO_BE_FILLED_BY_VENDOR; > L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = > RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \ > + RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \ > + RISC_V_CACHE_CONFIGURATION_ENABLED | \ > + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; > + L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = > + TO_BE_FILLED_BY_VENDOR; > L2CacheDataHob.SmbiosType7Cache.InstalledSize > + = TO_BE_FILLED_BY_VENDOR; > + L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; > + L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; > + L2CacheDataHob.SmbiosType7Cache.CacheSpeed = > TO_BE_FILLED_BY_VENDOR; > + L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = > + TO_BE_FILLED_BY_VENDOR; > + L2CacheDataHob.SmbiosType7Cache.SystemCacheType = > CacheTypeUnified; > + L2CacheDataHob.SmbiosType7Cache.Associativity = > + TO_BE_FILLED_BY_VENDOR; GuidPtr = (EFI_GUID *)PcdGetPtr > + (PcdProcessorSmbiosType7GuidHobGuid); > + L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA > + *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof > + (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); > + if (L2CacheDataHobPtr == NULL) { > + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core L2 > + cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); > ASSERT (FALSE); > } > > > [LL] > And the funamental difference ends here. > > @@ -181,7 +233,7 @@ > // Build up SMBIOS type 4 record. > // > ZeroMem((VOID *)&ProcessorDataHob, sizeof > (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); > - CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > (PcdSiFiveE51CoreGuid)); > + CopyGuid (&ProcessorDataHob.PrcessorGuid, (EFI_GUID *)PcdGetPtr > + (PcdSiFiveU54CoreGuid)); > > [LL] > Differ in name only. > > ProcessorDataHob.ProcessorUid = ProcessorUid; > ProcessorDataHob.SmbiosType4Processor.Socket = > TO_BE_FILLED_BY_VENDOR; > ProcessorDataHob.SmbiosType4Processor.ProcessorType = > CentralProcessor; @@ -196,7 +248,7 @@ > ProcessorDataHob.SmbiosType4Processor.Status = > TO_BE_FILLED_BY_CODE; > ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = > TO_BE_FILLED_BY_VENDOR; > ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = > TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; > - ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = 0xffff; > + ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = > + TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; > > [LL] > Real diff. > > ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff; > ProcessorDataHob.SmbiosType4Processor.SerialNumber = > TO_BE_FILLED_BY_CODE; > ProcessorDataHob.SmbiosType4Processor.AssetTag = > TO_BE_FILLED_BY_VENDOR; @@ -212,24 +264,23 @@ > GuidPtr = (EFI_GUID *)PcdGetPtr > (PcdProcessorSmbiosType4GuidHobGuid); > ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_HOB_DATA > *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof > (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); > if (ProcessorDataHobPtr == NULL) { > - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core > RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); > + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core > + RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); > > [LL] > Difference in name only. > > ASSERT (FALSE); > } > > ZeroMem((VOID *)&SmbiosDataHob, sizeof > (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); > SmbiosDataHob.Processor = ProcessorDataHobPtr; > SmbiosDataHob.L1InstCache = L1InstCacheDataHobPtr; > - SmbiosDataHob.L1DataCache = NULL; > - SmbiosDataHob.L2Cache = NULL; > + SmbiosDataHob.L1DataCache = L1DataCacheDataHobPtr; > + SmbiosDataHob.L2Cache = L2CacheDataHobPtr; > > [LL] > Real diff. > > SmbiosDataHob.L3Cache = NULL; > GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid); > SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_HOB_DATA > *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof > (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); > if (SmbiosDataHobPtr == NULL) { > - DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive E51 core > RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n")); > + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core > + RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n")); > > [LL] > Difference in name only. > > ASSERT (FALSE); > } > *SmbiosHobPtr = SmbiosDataHobPtr; > return EFI_SUCCESS; > } > > - > > >>> > > The meat of the difference between these two is less than 20% of the lines > of code in each file - and it is mutually exclusive, not some horrific tangle of > interdependencies. > > The story with the difference between U54 and U54MCCoreplex isn't much > better, only works along a different axis. > > "It isn't worthwhile" in an open source project isn't a question of "how > quickly can I create *one* new platform by copying instead of > refactoring/reusing", but a judgement call between: > - How many mistakes do I risk inserting while editing a new file as > opposed to being directly able to see the differences I have caused > while editing an existing file. > - How much do I increase reviewing effort by doing this? > - How much do I increase ongoing maintainership (or affect quality) by > requiring bugs to be fixed in multiple places instead of one. > > Not to mention: > - How many common pattern that could be broken out into common helper > libraries do we miss when we need to compare every SoC/platform > combination ever created, as opposed to being able to look at least > at implementations covering families. > > If it isn't important enough to take that into consideration, it isn't important > enough to upstream the SMBIOS support. Ok Leif, Daniel will evaluate which code could be leveraged and put it in the library under either Silicon vendor's folder or under RiscVPlatformPkg base on the functionality. Many thanks for this. Abner > > / > Leif ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <b55ee3ec-74de-532e-01f7-bd24a327d00b@hpe.com>]
[parent not found: <CY4PR21MB0743421F39A05298FBCFBAA0EF8F0@CY4PR21MB0743.namprd21.prod.outlook.com>]
[parent not found: <MN2PR11MB4461D8666DE6DA1E7D4B5B9BD28F0@MN2PR11MB4461.namprd11.prod.outlook.com>]
[parent not found: <TU4PR8401MB1182F755F76709FF1D46D3F2FF8F0@TU4PR8401MB1182.NAMPRD84.PROD.OUTLOOK.COM>]
[parent not found: <MN2PR11MB4461442E7462457D6C20F6F2D28F0@MN2PR11MB4461.namprd11.prod.outlook.com>]
[parent not found: <MW2PR2101MB092494AB8318628E06B62089E18F0@MW2PR2101MB0924.namprd21.prod.outlook.com>]
* [edk2-devel] Where to put RISC-V packages [not found] ` <MW2PR2101MB092494AB8318628E06B62089E18F0@MW2PR2101MB0924.namprd21.prod.outlook.com> @ 2020-06-03 11:57 ` Daniel Schaefer 2020-06-03 15:02 ` Abner Chang 0 siblings, 1 reply; 19+ messages in thread From: Daniel Schaefer @ 2020-06-03 11:57 UTC (permalink / raw) To: Sean Brogan, Kinney, Michael D, Chang, Abner (HPS SW/FW Technologist), Bret Barkelew, Ard Biesheuvel (ard.biesheuvel@linaro.org), Zimmer, Vincent, Leif Lindholm Cc: devel@edk2.groups.io Hi all, (CC edk2 devel ML - shouldn't be a private discussion again) let me try to summarize the points of each: - edk2-platforms isn't a less stable edk2 per se - edk2-platforms can be used for architectural decisions that are not stable yet and therefore different platforms might implement them differently - Still we'd rather put unstable things in edk2-platforms for now - In the future CPU Init shouldn't be totally separate packages but the overlapping code should be combined in UefiCpuPkg/MdePkg/MdeModulePkg/... - This applies to RISC-V, as well as ARM - UefiCpuPkg is too x86 focused -> needs lots of work and RISC-V shouldn't wait for that - RISC-V changes should preferably be integrated into existing packages instead of building an entirely separate hierarchy -> We have done this. For example DxeIpl is now in edk2 in MdeModulePkg. I hope everyone can agree with this summary. I suggest that we do the following: - Merge all of the RISC-V code to edk2-platforms - Evaluate the packages individually and move them to edk2 one by one, or to merge them into existing edk2 packages - In the end in edk2-platforms should only remain code for specific platforms, like the SiFive Unleashed board. No generic RISC-V code, right? I'm not experienced enough with EDK2 to evaluate whether packages might fit into EDK2 directly. Maybe we should have a call and have a look at each on individually? Below I looked into the libraries and drivers of every package that we want to upstream with our branch. I describe, what they do and if they are platform specific. Then I issue my guess for where it would belong. I hope that gives everyone a bit more insight into all of the code we'd like to merge. Again: Would it be okay to merge everything as is into edk2-platforms. (DxeIpl was previously merged into edk2). And then slowly migrate them over into edk2? Or should be evaluate each package individually now instead of merging everything at once. - Platform/RISC-V/PlatformPkg - FirmwareContextProcessorSpecificLib Take processors specific data from SMBIOS and put in HOB => edk2 - OpensbiPlatformLibNull Null library for platform provided OpenSBI functions. Those functions are defined in the SiFive directories => edk2 - PlatformBootManagerLib I'm not sure why this is there. It doesn't look RISC-V specific. cc: Abner => ??? - PlatformMemoryTestLibNull Same as above => ??? - PlatformUpdateProgressLibNull Same as above => ??? - RiscVPlatformTempMemoryInitLibNull Initialize temporary RAM on stack. Same on every RISC-V CPU Depends on platform's PCD values => edk2 - Sec SEC Phase, same for every RISC-V CPU => edk2 - Silicon/RISC-V/ProcessorPkg - PeiServicesTablePointerLibOpenSbi Saving/loading PeiServicesTable in RISC-V scratch space with OpenSBI On every RISC-V CPU => edk2 - RiscVCpuLib ASM functions to read RISC-V CSRs on every RISC-V CPU For UefiCpuPkg? => edk2 - RiscVEdk2SbiLib Wrapper library to call the SBI ecalls on every RISC-V CPU => edk2 - RiscVExceptionLib CpuExceptionHandlerLib implementation for RISC-V Currently only uses CSR accesses cc Abner: Will this be platform specific with the CLIC proposals? => edk2/edk2-platforms?? - RiscVOpensbiLib OpenSBI library Needs to be called in early init on every RISC-V CPU => edk2? - RiscVPlatformTimerLibNull,RiscVTimerLib TimerLib implementation for RISC-V Depends on platform specific PCDs only => edk2? - CpuDxe Produces: gEfiCpuArchProtocolGuid Would go into UefiCpuPkg => edk2 - SmbiosDxe Create SMBIOS entries type 4, type 7 and type 44 Values need to be set by platform => edk2-platforms All packages under edk2-platforms/{Silicon,Platform}/SiFive/ are not included here, as they are obviously platform specific and need to go into edk2-platforms. Thanks, Daniel On 5/29/20 7:25 AM, Sean Brogan wrote: > Sorry was just getting to this. You guys are fast. This is mostly to > Daniel’s original email but I think it lines up with Abner’s questions > and Mike’s response. > > Daniel, > > I think both Mike and Bret said most everything needed but I'll clarify > just in case. > > I don't think the conversations below (Daniels) is accurate for my > concerns about RiscV support or my view of edk2-platforms. > > In my view Edk2 packages are best when they are functionality based. > This allows for proper code base layering and makes sure that > abstractions are created in a way that will facilitate cross platform > core development. For packages that are based on other characteristics, > like architecture, dependencies at the package level usually become > tangled and brittle which slowly leaks out into the rest of the code > base and then makes the entire repository harder to work with. > > For that reason I advocated that the RiscV support be integrated into > the appropriate packages and modules. Where there is unique > functionality that then needs to be evaluated to determine if its core > functionality or platform functionality. Depending on that it would then > land in the appropriate edk2 package or something in edk2-platforms. > > Thanks > > Sean > > *From:* Kinney, Michael D <michael.d.kinney@intel.com> > *Sent:* Thursday, May 28, 2020 10:18 PM > *To:* Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>; Bret > Barkelew <Bret.Barkelew@microsoft.com>; Schaefer, Daniel (DualStudy) > <daniel.schaefer@hpe.com>; Sean Brogan <sean.brogan@microsoft.com>; Ard > Biesheuvel (ard.biesheuvel@linaro.org) <ard.biesheuvel@linaro.org>; > Zimmer, Vincent <vincent.zimmer@intel.com>; Kinney, Michael D > <michael.d.kinney@intel.com> > *Cc:* Leif Lindholm <leif@nuviainc.com> > *Subject:* [EXTERNAL] RE: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > Patches - Why in edk2-platforms > > Abner, > > The architectural RISCV CPU content that does not change between RISCV > CPU implementations would be a candidate for MdePkg, MdeModulePkg, or > UefiCpuPkg. We would need to do another review of the content along > with the ARM/AARCH64 content to see how best to organize the CPU related > content for now and future. > > RISCV platform content would still need to go into edk2-platforms. > Non-architectural RISCV CPU content would also need to go into > edk2-platforms. > > Mike > > *From:* Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > <mailto:abner.chang@hpe.com>> > *Sent:* Thursday, May 28, 2020 10:01 PM > *To:* Kinney, Michael D <michael.d.kinney@intel.com > <mailto:michael.d.kinney@intel.com>>; Bret Barkelew > <Bret.Barkelew@microsoft.com <mailto:Bret.Barkelew@microsoft.com>>; > Schaefer, Daniel (DualStudy) <daniel.schaefer@hpe.com > <mailto:daniel.schaefer@hpe.com>>; Sean Brogan > <sean.brogan@microsoft.com <mailto:sean.brogan@microsoft.com>>; Ard > Biesheuvel (ard.biesheuvel@linaro.org > <mailto:ard.biesheuvel@linaro.org>) <ard.biesheuvel@linaro.org > <mailto:ard.biesheuvel@linaro.org>>; Zimmer, Vincent > <vincent.zimmer@intel.com <mailto:vincent.zimmer@intel.com>> > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>> > *Subject:* RE: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why > in edk2-platforms > > *From:* Kinney, Michael D [mailto:michael.d.kinney@intel.com] > *Sent:* Friday, May 29, 2020 12:36 PM > *To:* Bret Barkelew <Bret.Barkelew@microsoft.com > <mailto:Bret.Barkelew@microsoft.com>>; Schaefer, Daniel (DualStudy) > <daniel.schaefer@hpe.com <mailto:daniel.schaefer@hpe.com>>; Sean Brogan > <sean.brogan@microsoft.com <mailto:sean.brogan@microsoft.com>>; Ard > Biesheuvel (ard.biesheuvel@linaro.org > <mailto:ard.biesheuvel@linaro.org>) <ard.biesheuvel@linaro.org > <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D > <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>; > Zimmer, Vincent <vincent.zimmer@intel.com <mailto:vincent.zimmer@intel.com>> > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>>; > Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > <mailto:abner.chang@hpe.com>> > *Subject:* RE: [EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > Patches - Why in edk2-platforms > > We did a community review meeting. I recall Ard and Vincent being present. > > We discuss the CPU execution mode for PEI and DXE and there was a > discussion that RISCV has 2 modes and they want flexibility to use > both. This choice is not defined in the PI spec yet. We suggested that > it could follow the ARM/Thumb model and RISCV could choose a single mode > for all PEIMs and DXE drivers and choose to go into the other mode in > the module implementation as needed. > > */[Abner] Yes. we done this as we discussed in the community meeting. > Those code are belong to RiscV*pkg and currently lay on > devel-riscvplatfoms which Leif is reviewing now./* > > Given that these fundamental CPU execution mode design choices were > still in flux, it did not seem like it was ready for edk2 yet. > > */[Abner] The current implementation is PEI/DXE are in the same mode./* > > edk2-staging or an edk2-platforms branch seemed more appropriate until > all that was worked out. > > */[Abner] Seems like that work is done. Maybe I have to review PI/UEFI > spec for the necessary changes./* > > edk2-platforms/master seemed ok as well if different RISCV CPU modes > would be used for different platform solutions until a unified approach > by the RISCV vendors could be determined Once that was solidified, > promoting to edk2 would be possible. > > */[Abner] this means RicsVPkg and RicsVPlatformPkg eventually will be > located in edk2 but not edk2-platforms if above issues are addressed? We > don’t have to consider UefiCpuPkg for each arch now? We are good with > this though./* > > Hopefully this clarifies for Leif why there was some resistance to edk2 > repo right now. Still on deck for the future. > > Mike > > *From:* Bret Barkelew <Bret.Barkelew@microsoft.com > <mailto:Bret.Barkelew@microsoft.com>> > *Sent:* Thursday, May 28, 2020 8:11 PM > *To:* Daniel Schaefer <daniel.schaefer@hpe.com > <mailto:daniel.schaefer@hpe.com>>; Kinney, Michael D > <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>; Sean > Brogan <sean.brogan@microsoft.com <mailto:sean.brogan@microsoft.com>> > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>>; > Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > <mailto:abner.chang@hpe.com>> > *Subject:* RE: [EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > Patches - Why in edk2-platforms > > I think Sean has his own feedback, but my response to Abner was that > that I didn’t like the idea of continuing a pattern of separate packages > for significant portions of the CPU init. There have been a few times > where it has created unnecessary divergence that made it very difficult > to write cross-architecture code. I, personally, wasn’t fighting the > code landing in edk2 (except for RiscVPlatform, because it had platform > in the name), but I was inquiring to see whether it made more sense to > break things up among Mde, UefiCpu, and a couple other packages to > encourage adhering to similar patterns and interfaces between all the > different architectures. I’ve previously wondered openly whether it made > sense to do the same with the Arm packages. > > I’ll be honest about not being super familiar with the RISCV code and it > would be easy for me to just shrug and say put it wherever, but I know > that architecture mobility/agility is important for us and wouldn’t be > surprised if I had to use RISCV in the future, and so wanted to make > sure that it was as close to what I was familiar with as possible. > > - Bret > > *From: *Daniel Schaefer <mailto:daniel.schaefer@hpe.com> > *Sent: *Thursday, May 28, 2020 8:44 AM > *To: *Kinney, Michael D <mailto:michael.d.kinney@intel.com>; Bret > Barkelew <mailto:Bret.Barkelew@microsoft.com>; Sean Brogan > <mailto:sean.brogan@microsoft.com> > *Cc: *Leif Lindholm <mailto:leif@nuviainc.com>; Chang, Abner (HPS SW/FW > Technologist) <mailto:abner.chang@hpe.com> > *Subject: *[EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches > - Why in edk2-platforms > > Hi Mike, Bret and Sean, > > you have previously expressed concern about merging HPE's RISC-V code > into edk2 and suggested merging it into edk2-platforms. Apparently you > discussed this with Abner in a private email thread. According to that > information I tried to summarize your points in an email on the edk2 ML. > I hope I got it right. > > As you can see, we have followed that suggestion and sent the new > patches required for that to the ML. > > Leif, and I, are still not convinced it's the right choice to not > include it in edk2 proper. > We would appreciate if you could address the concerns Leif has mentioned > in the below email on the public ML. > > Thanks! > Daniel > > On 5/28/20 1:54 PM, Leif Lindholm wrote: > > Hi Abner, > > > > Sorry, I should have followed up on this sooner. > > > > On Thu, May 21, 2020 at 06:59:20 +0000, Chang, Abner (HPS SW/FW > Technologist) wrote: > >>> On 5/20/20 6:07 PM, Daniel Schaefer wrote: > >>>> please reply here, fixed Mike's email address, sorry... > >>>> > >>>> On 5/20/20 6:03 PM, Daniel Schaefer wrote: > >>>>> On 5/20/20 1:43 PM, Leif Lindholm wrote: > >>>>>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > >>>>>>> Previously we had two packages just for RISC-V on our edk2 branch: > >>>>>>> RiscVPkg and RiscVPlatformPkg > >>>>>>> They are now under > >>>>>>> Platform/RISC-V/PlatformPkg and Silicon/RISC-V/ProcessorPkg in > >>>>>>> edk2-platforms. > >>>>>> > >>>>>> Understood. I took my eye off the ball there for a while, but I'm a > >>>>>> bit confused as to why RiscVPkg isn't going into EDK2. That is very > >>>>>> counterintuitive. And clearly it will need revisiting if we are to > >>>>>> add first-class CI checks like those we do with OvmfPkg/ArmVirtPkg. > >>>>> > >>>>> Yes, I understand your concern. Personally I'd like it also to be in > >>>>> EDK2 straight away, however Mike, Bret and Sean have raised valid > >>>>> concerns: > > > > Can you point me to the conversation I have missed? > > > >>>>> 1. RISC-V is very new and potentially unstable - it's quicker to make > >>>>> changes in edk2-platforms. > > > > I don't see this as a valid argument. > > It's not edk2-unstable, it is edk2-platforms. > > > > edk2-platforms exists because there used to be strong feelings against > > holding *real* platforms in edk2, with edk2 being originally intended > > only as a code library for IBV/ISV to cherry-pick from. > > > > But fundamentally, if code is too immature to go into the master > > branch of edk2, it is too immature to go into the master branch of > > edk2-platforms. If we want edk2-might-be-a-bit-shaky-but-who-cares, > > then someone will have to create it. > > > >>>>> 2. If we define new interfaces and libraries in edk2, we can't remove > >>>>> them easily because it would be a backwards-incompatible change. > >>>>> edk2-platforms isn't quite as strict. > > > > Yes it is. > > The only thing making it less strict is its contents - platform ports > > and device drivers. The changes tend to be self-contained. Where they > > are not, they need to be carefully managed. > > > >>>>> 3. Long-term, I think many agree, we should aim to move much of the > >>>>> RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned that would > >>>>> need coordination with ARM maintainers because it might make sense to > >>>>> move their code there as well. > > > > I don't think there is any need to tie the two together. > > Yes, UefiCpuPkg should be a generic place where not only x86 support > > can be contained, but the paths for ARM* and RISC-V into there do not > > have any interdependencies. > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [edk2-devel] Where to put RISC-V packages 2020-06-03 11:57 ` [edk2-devel] Where to put RISC-V packages Daniel Schaefer @ 2020-06-03 15:02 ` Abner Chang 0 siblings, 0 replies; 19+ messages in thread From: Abner Chang @ 2020-06-03 15:02 UTC (permalink / raw) To: Schaefer, Daniel (DualStudy), Sean Brogan, Kinney, Michael D, Bret Barkelew, Ard Biesheuvel (ard.biesheuvel@linaro.org), Zimmer, Vincent, Leif Lindholm Cc: devel@edk2.groups.io > -----Original Message----- > From: Schaefer, Daniel (DualStudy) > Sent: Wednesday, June 3, 2020 7:57 PM > To: Sean Brogan <sean.brogan@microsoft.com>; Kinney, Michael D > <michael.d.kinney@intel.com>; Chang, Abner (HPS SW/FW Technologist) > <abner.chang@hpe.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; > Ard Biesheuvel (ard.biesheuvel@linaro.org) <ard.biesheuvel@linaro.org>; > Zimmer, Vincent <vincent.zimmer@intel.com>; Leif Lindholm > <leif@nuviainc.com> > Cc: devel@edk2.groups.io > Subject: [edk2-devel] Where to put RISC-V packages > > Hi all, > > (CC edk2 devel ML - shouldn't be a private discussion again) > > let me try to summarize the points of each: > > - edk2-platforms isn't a less stable edk2 per se > - edk2-platforms can be used for architectural decisions that are not > stable yet and therefore different platforms might implement them > differently > - Still we'd rather put unstable things in edk2-platforms for now > - In the future CPU Init shouldn't be totally separate packages but the > overlapping code should be combined in > UefiCpuPkg/MdePkg/MdeModulePkg/... > - This applies to RISC-V, as well as ARM > - UefiCpuPkg is too x86 focused > -> needs lots of work and RISC-V shouldn't wait for that > - RISC-V changes should preferably be integrated into existing packages > instead of building an entirely separate hierarchy > -> We have done this. For example DxeIpl is now in edk2 in > MdeModulePkg. > > I hope everyone can agree with this summary. > I suggest that we do the following: > > - Merge all of the RISC-V code to edk2-platforms Agree. This is the first step after those new changes get "Reviewed-by". > - Evaluate the packages individually and move them to edk2 one by one, > or to merge them into existing edk2 packages > - In the end in edk2-platforms should only remain code for specific > platforms, like the SiFive Unleashed board. No generic RISC-V code, > right? I agree with above. But those architecture-specific drivers may still stay in their own package. > > I'm not experienced enough with EDK2 to evaluate whether packages might > fit into EDK2 directly. Maybe we should have a call and have a look at each on > individually? Below I looked into the libraries and drivers of every package > that we want to upstream with our branch. I describe, what they do and if > they are platform specific. Then I issue my guess for where it would belong. > I hope that gives everyone a bit more insight into all of the code we'd like to > merge. > > Again: Would it be okay to merge everything as is into edk2-platforms. > (DxeIpl > was previously merged into edk2). And then slowly migrate them over into > edk2? > Or should be evaluate each package individually now instead of merging > everything at once. > > - Platform/RISC-V/PlatformPkg > - FirmwareContextProcessorSpecificLib > Take processors specific data from SMBIOS and put in HOB > => edk2 > - OpensbiPlatformLibNull > Null library for platform provided OpenSBI functions. > Those functions are defined in the SiFive directories > => edk2 > - PlatformBootManagerLib > I'm not sure why this is there. It doesn't look RISC-V specific. > cc: Abner > => ??? > - PlatformMemoryTestLibNull > Same as above > => ??? > - PlatformUpdateProgressLibNull > Same as above > => ??? > - RiscVPlatformTempMemoryInitLibNull > Initialize temporary RAM on stack. Same on every RISC-V CPU > Depends on platform's PCD values > => edk2 > - Sec > SEC Phase, same for every RISC-V CPU > => edk2 > - Silicon/RISC-V/ProcessorPkg > - PeiServicesTablePointerLibOpenSbi > Saving/loading PeiServicesTable in RISC-V scratch space with OpenSBI > On every RISC-V CPU > => edk2 > - RiscVCpuLib > ASM functions to read RISC-V CSRs on every RISC-V CPU > For UefiCpuPkg? > => edk2 > - RiscVEdk2SbiLib > Wrapper library to call the SBI ecalls on every RISC-V CPU > => edk2 > - RiscVExceptionLib > CpuExceptionHandlerLib implementation for RISC-V > Currently only uses CSR accesses > cc Abner: Will this be platform specific with the CLIC proposals? > => edk2/edk2-platforms?? > - RiscVOpensbiLib > OpenSBI library > Needs to be called in early init on every RISC-V CPU > => edk2? > - RiscVPlatformTimerLibNull,RiscVTimerLib > TimerLib implementation for RISC-V > Depends on platform specific PCDs only > => edk2? > - CpuDxe > Produces: gEfiCpuArchProtocolGuid > Would go into UefiCpuPkg > => edk2 > - SmbiosDxe > Create SMBIOS entries type 4, type 7 and type 44 > Values need to be set by platform > => edk2-platforms Yes, we will have to review above modules and move those to UefiCpuPkg/MdePkg/MdeModulePkg as many as we can. But I guess some maybe still have to stay in RiscVPkg under edk2, unless we can move those RISC-V specific definitions to MdePkg/Include. We can discuss this later and create another branch as POC code based on edk2/edk2-platform RISC-V port. > > All packages under edk2-platforms/{Silicon,Platform}/SiFive/ are not > included here, as they are obviously platform specific and need to go into > edk2-platforms. > > Thanks, > Daniel > > > > On 5/29/20 7:25 AM, Sean Brogan wrote: > > Sorry was just getting to this. You guys are fast. This is mostly to > > Daniel’s original email but I think it lines up with Abner’s questions > > and Mike’s response. > > > > Daniel, > > > > I think both Mike and Bret said most everything needed but I'll > > clarify just in case. > > > > I don't think the conversations below (Daniels) is accurate for my > > concerns about RiscV support or my view of edk2-platforms. > > > > In my view Edk2 packages are best when they are functionality based. > > This allows for proper code base layering and makes sure that > > abstractions are created in a way that will facilitate cross platform > > core development. For packages that are based on other > > characteristics, like architecture, dependencies at the package level > > usually become tangled and brittle which slowly leaks out into the > > rest of the code base and then makes the entire repository harder to work > with. > > > > For that reason I advocated that the RiscV support be integrated into > > the appropriate packages and modules. Where there is unique > > functionality that then needs to be evaluated to determine if its core > > functionality or platform functionality. Depending on that it would > > then land in the appropriate edk2 package or something in edk2-platforms. > > > > Thanks > > > > Sean > > > > *From:* Kinney, Michael D <michael.d.kinney@intel.com> > > *Sent:* Thursday, May 28, 2020 10:18 PM > > *To:* Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>; > > Bret Barkelew <Bret.Barkelew@microsoft.com>; Schaefer, Daniel > > (DualStudy) <daniel.schaefer@hpe.com>; Sean Brogan > > <sean.brogan@microsoft.com>; Ard Biesheuvel > > (ard.biesheuvel@linaro.org) <ard.biesheuvel@linaro.org>; Zimmer, > > Vincent <vincent.zimmer@intel.com>; Kinney, Michael D > > <michael.d.kinney@intel.com> > > *Cc:* Leif Lindholm <leif@nuviainc.com> > > *Subject:* [EXTERNAL] RE: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > > Patches - Why in edk2-platforms > > > > Abner, > > > > The architectural RISCV CPU content that does not change between RISCV > > CPU implementations would be a candidate for MdePkg, MdeModulePkg, > or > > UefiCpuPkg. We would need to do another review of the content along > > with the ARM/AARCH64 content to see how best to organize the CPU > > related content for now and future. > > > > RISCV platform content would still need to go into edk2-platforms. > > Non-architectural RISCV CPU content would also need to go into > > edk2-platforms. > > > > Mike > > > > *From:* Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > > <mailto:abner.chang@hpe.com>> > > *Sent:* Thursday, May 28, 2020 10:01 PM > > *To:* Kinney, Michael D <michael.d.kinney@intel.com > > <mailto:michael.d.kinney@intel.com>>; Bret Barkelew > > <Bret.Barkelew@microsoft.com <mailto:Bret.Barkelew@microsoft.com>>; > > Schaefer, Daniel (DualStudy) <daniel.schaefer@hpe.com > > <mailto:daniel.schaefer@hpe.com>>; Sean Brogan > > <sean.brogan@microsoft.com <mailto:sean.brogan@microsoft.com>>; > Ard > > Biesheuvel (ard.biesheuvel@linaro.org > > <mailto:ard.biesheuvel@linaro.org>) <ard.biesheuvel@linaro.org > > <mailto:ard.biesheuvel@linaro.org>>; Zimmer, Vincent > > <vincent.zimmer@intel.com <mailto:vincent.zimmer@intel.com>> > > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>> > > *Subject:* RE: Re: [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - > > Why in edk2-platforms > > > > *From:* Kinney, Michael D [mailto:michael.d.kinney@intel.com] > > *Sent:* Friday, May 29, 2020 12:36 PM > > *To:* Bret Barkelew <Bret.Barkelew@microsoft.com > > <mailto:Bret.Barkelew@microsoft.com>>; Schaefer, Daniel (DualStudy) > > <daniel.schaefer@hpe.com <mailto:daniel.schaefer@hpe.com>>; Sean > > Brogan <sean.brogan@microsoft.com > <mailto:sean.brogan@microsoft.com>>; > > Ard Biesheuvel (ard.biesheuvel@linaro.org > > <mailto:ard.biesheuvel@linaro.org>) <ard.biesheuvel@linaro.org > > <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D > > <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>; > > Zimmer, Vincent <vincent.zimmer@intel.com > > <mailto:vincent.zimmer@intel.com>> > > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>>; > > Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > > <mailto:abner.chang@hpe.com>> > > *Subject:* RE: [EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > > Patches - Why in edk2-platforms > > > > We did a community review meeting. I recall Ard and Vincent being > present. > > > > We discuss the CPU execution mode for PEI and DXE and there was a > > discussion that RISCV has 2 modes and they want flexibility to use > > both. This choice is not defined in the PI spec yet. We suggested > > that it could follow the ARM/Thumb model and RISCV could choose a > > single mode for all PEIMs and DXE drivers and choose to go into the > > other mode in the module implementation as needed. > > > > */[Abner] Yes. we done this as we discussed in the community meeting. > > Those code are belong to RiscV*pkg and currently lay on > > devel-riscvplatfoms which Leif is reviewing now./* > > > > Given that these fundamental CPU execution mode design choices were > > still in flux, it did not seem like it was ready for edk2 yet. > > > > */[Abner] The current implementation is PEI/DXE are in the same > > mode./* > > > > edk2-staging or an edk2-platforms branch seemed more appropriate until > > all that was worked out. > > > > */[Abner] Seems like that work is done. Maybe I have to review PI/UEFI > > spec for the necessary changes./* > > > > edk2-platforms/master seemed ok as well if different RISCV CPU modes > > would be used for different platform solutions until a unified > > approach by the RISCV vendors could be determined Once that was > > solidified, promoting to edk2 would be possible. > > > > */[Abner] this means RicsVPkg and RicsVPlatformPkg eventually will be > > located in edk2 but not edk2-platforms if above issues are addressed? > > We don’t have to consider UefiCpuPkg for each arch now? We are good > > with this though./* > > > > Hopefully this clarifies for Leif why there was some resistance to > > edk2 repo right now. Still on deck for the future. > > > > Mike > > > > *From:* Bret Barkelew <Bret.Barkelew@microsoft.com > > <mailto:Bret.Barkelew@microsoft.com>> > > *Sent:* Thursday, May 28, 2020 8:11 PM > > *To:* Daniel Schaefer <daniel.schaefer@hpe.com > > <mailto:daniel.schaefer@hpe.com>>; Kinney, Michael D > > <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>; > Sean > > Brogan <sean.brogan@microsoft.com > <mailto:sean.brogan@microsoft.com>> > > *Cc:* Leif Lindholm <leif@nuviainc.com <mailto:leif@nuviainc.com>>; > > Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com > > <mailto:abner.chang@hpe.com>> > > *Subject:* RE: [EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > > Patches - Why in edk2-platforms > > > > I think Sean has his own feedback, but my response to Abner was that > > that I didn’t like the idea of continuing a pattern of separate > > packages for significant portions of the CPU init. There have been a > > few times where it has created unnecessary divergence that made it > > very difficult to write cross-architecture code. I, personally, wasn’t > > fighting the code landing in edk2 (except for RiscVPlatform, because > > it had platform in the name), but I was inquiring to see whether it > > made more sense to break things up among Mde, UefiCpu, and a couple > > other packages to encourage adhering to similar patterns and > > interfaces between all the different architectures. I’ve previously > > wondered openly whether it made sense to do the same with the Arm > packages. > > > > I’ll be honest about not being super familiar with the RISCV code and > > it would be easy for me to just shrug and say put it wherever, but I > > know that architecture mobility/agility is important for us and > > wouldn’t be surprised if I had to use RISCV in the future, and so > > wanted to make sure that it was as close to what I was familiar with as > possible. > > > > - Bret > > > > *From: *Daniel Schaefer <mailto:daniel.schaefer@hpe.com> > > *Sent: *Thursday, May 28, 2020 8:44 AM > > *To: *Kinney, Michael D <mailto:michael.d.kinney@intel.com>; Bret > > Barkelew <mailto:Bret.Barkelew@microsoft.com>; Sean Brogan > > <mailto:sean.brogan@microsoft.com> > > *Cc: *Leif Lindholm <mailto:leif@nuviainc.com>; Chang, Abner (HPS > > SW/FW > > Technologist) <mailto:abner.chang@hpe.com> > > *Subject: *[EXTERNAL] Re: [edk2-devel] [PATCH v2 0/3] New RISC-V > > Patches > > - Why in edk2-platforms > > > > Hi Mike, Bret and Sean, > > > > you have previously expressed concern about merging HPE's RISC-V code > > into edk2 and suggested merging it into edk2-platforms. Apparently you > > discussed this with Abner in a private email thread. According to that > > information I tried to summarize your points in an email on the edk2 ML. > > I hope I got it right. > > > > As you can see, we have followed that suggestion and sent the new > > patches required for that to the ML. > > > > Leif, and I, are still not convinced it's the right choice to not > > include it in edk2 proper. > > We would appreciate if you could address the concerns Leif has > > mentioned in the below email on the public ML. > > > > Thanks! > > Daniel > > > > On 5/28/20 1:54 PM, Leif Lindholm wrote: > > > Hi Abner, > > > > > > Sorry, I should have followed up on this sooner. > > > > > > On Thu, May 21, 2020 at 06:59:20 +0000, Chang, Abner (HPS SW/FW > > Technologist) wrote: > > >>> On 5/20/20 6:07 PM, Daniel Schaefer wrote: > > >>>> please reply here, fixed Mike's email address, sorry... > > >>>> > > >>>> On 5/20/20 6:03 PM, Daniel Schaefer wrote: > > >>>>> On 5/20/20 1:43 PM, Leif Lindholm wrote: > > >>>>>> On Fri, May 15, 2020 at 15:39:34 +0200, Daniel Schaefer wrote: > > >>>>>>> Previously we had two packages just for RISC-V on our edk2 > branch: > > >>>>>>> RiscVPkg and RiscVPlatformPkg >>>>>>> They are now under > > >>>>>>> Platform/RISC-V/PlatformPkg and > > Silicon/RISC-V/ProcessorPkg in >>>>>>> edk2-platforms. > > >>>>>> > > >>>>>> Understood. I took my eye off the ball there for a while, but > > I'm a >>>>>> bit confused as to why RiscVPkg isn't going into EDK2. > > That is very >>>>>> counterintuitive. And clearly it will need > > revisiting if we are to >>>>>> add first-class CI checks like those we do with > OvmfPkg/ArmVirtPkg. > > >>>>> > > >>>>> Yes, I understand your concern. Personally I'd like it also to > > be in >>>>> EDK2 straight away, however Mike, Bret and Sean have > > raised valid >>>>> concerns: > > > > > > Can you point me to the conversation I have missed? > > > > > >>>>> 1. RISC-V is very new and potentially unstable - it's quicker > > to make >>>>> changes in edk2-platforms. > > > > > > I don't see this as a valid argument. > > > It's not edk2-unstable, it is edk2-platforms. > > > > > > edk2-platforms exists because there used to be strong feelings > > against > holding *real* platforms in edk2, with edk2 being > > originally intended > only as a code library for IBV/ISV to cherry-pick from. > > > > > > But fundamentally, if code is too immature to go into the master > > > branch of edk2, it is too immature to go into the master branch of > > > edk2-platforms. If we want edk2-might-be-a-bit-shaky-but-who-cares, > > > then someone will have to create it. > > > > > >>>>> 2. If we define new interfaces and libraries in edk2, we can't > > remove >>>>> them easily because it would be a backwards-incompatible > change. > > >>>>> edk2-platforms isn't quite as strict. > > > > > > Yes it is. > > > The only thing making it less strict is its contents - platform > > ports > and device drivers. The changes tend to be self-contained. > > Where they > are not, they need to be carefully managed. > > > > > >>>>> 3. Long-term, I think many agree, we should aim to move much of > > the >>>>> RISC-V code into UefiCpuPkg and OvmfPkg. Mike mentioned > > that would >>>>> need coordination with ARM maintainers because it > > might make sense to >>>>> move their code there as well. > > > > > > I don't think there is any need to tie the two together. > > > Yes, UefiCpuPkg should be a generic place where not only x86 > > support > can be contained, but the paths for ARM* and RISC-V into > > there do not > have any interdependencies. > > ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2020-06-03 15:02 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-05-15 13:39 [PATCH v2 0/3] New RISC-V Patches Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 1/3] ProcessorPkg/RiscVOpensbLib: Add opensbi submodule Daniel Schaefer 2020-05-20 11:51 ` Leif Lindholm 2020-05-15 13:39 ` [PATCH v2 2/3] ProcessorPkg/Library: Add RiscVOpensbiLib Daniel Schaefer 2020-05-20 12:00 ` Leif Lindholm 2020-05-20 14:44 ` Daniel Schaefer 2020-05-15 13:39 ` [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Daniel Schaefer 2020-05-20 18:27 ` Leif Lindholm 2020-05-29 12:43 ` [edk2-devel] " Daniel Schaefer 2020-05-29 13:15 ` Leif Lindholm 2020-05-20 11:43 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches Leif Lindholm 2020-05-20 16:03 ` [edk2-devel] [PATCH v2 0/3] New RISC-V Patches - Why in edk2-platforms Daniel Schaefer 2020-05-20 16:07 ` Daniel Schaefer 2020-05-20 16:17 ` Daniel Schaefer 2020-05-21 6:59 ` Abner Chang 2020-05-28 11:54 ` Leif Lindholm 2020-05-29 14:41 ` Abner Chang [not found] ` <b55ee3ec-74de-532e-01f7-bd24a327d00b@hpe.com> [not found] ` <CY4PR21MB0743421F39A05298FBCFBAA0EF8F0@CY4PR21MB0743.namprd21.prod.outlook.com> [not found] ` <MN2PR11MB4461D8666DE6DA1E7D4B5B9BD28F0@MN2PR11MB4461.namprd11.prod.outlook.com> [not found] ` <TU4PR8401MB1182F755F76709FF1D46D3F2FF8F0@TU4PR8401MB1182.NAMPRD84.PROD.OUTLOOK.COM> [not found] ` <MN2PR11MB4461442E7462457D6C20F6F2D28F0@MN2PR11MB4461.namprd11.prod.outlook.com> [not found] ` <MW2PR2101MB092494AB8318628E06B62089E18F0@MW2PR2101MB0924.namprd21.prod.outlook.com> 2020-06-03 11:57 ` [edk2-devel] Where to put RISC-V packages Daniel Schaefer 2020-06-03 15:02 ` Abner Chang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox