> -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Abner Chang > Sent: Wednesday, June 3, 2020 9:25 AM > To: Kinney, Michael D <michael.d.kin...@intel.com>; devel@edk2.groups.io; > Schaefer, Daniel (DualStudy) <daniel.schae...@hpe.com> > Cc: Leif Lindholm <l...@nuviainc.com>; Chen, Gilbert > <gilbert.c...@hpe.com> > Subject: Re: [edk2-devel] [PATCH v4 1/1] ProcessorPkg/Library: Add > RiscVEdk2SbiLib > > > > > -----Original Message----- > > From: Kinney, Michael D [mailto:michael.d.kin...@intel.com] > > Sent: Wednesday, June 3, 2020 6:00 AM > > To: devel@edk2.groups.io; Schaefer, Daniel (DualStudy) > > <daniel.schae...@hpe.com>; Kinney, Michael D > > <michael.d.kin...@intel.com> > > Cc: Leif Lindholm <l...@nuviainc.com>; Chen, Gilbert > > <gilbert.c...@hpe.com>; Chang, Abner (HPS SW/FW Technologist) > > <abner.ch...@hpe.com> > > Subject: RE: [edk2-devel] [PATCH v4 1/1] ProcessorPkg/Library: Add > > RiscVEdk2SbiLib > > > > Hi Daniel, > > > > I see some inconsistence in the names used in these patches. > > > > For example, there should not be a need to use "Edk2" in the > > name of a library. This library is in an edk2 repo. > We currently have two libraries regards to RISC-V SBI spec. One is the > wrapper to build OpenSBI lib, which is RiscVOpenSbiLib. > Another one is SBI firmware code base extension in which the ABIs are > provided by system firmware other than the standard ABIs defined in SBI > spec. To name it with EDK2 makes sense because that is RISC-V EDK2 > firmware code base SBI extension. More information is in below, https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc - Firmware Code Base Specific SBI Extension Space, Extension Ids 0x0A000000 through 0x0AFFFFFF > > > > I see "RiscV" and "Risk-V" used in file paths. I recommend > > you pick one and use it consistently. In the MdePkg, I see > > RiscV64, and macros using RISCV, RISCV32, RISCV64, and RISCV128. > > which seems consistent and does not use a '-'. Perhaps use > > "RiscV" for content that works for 32, 64, and 128 bit and > > RiscV32, RiscV64, and RiskV128 for content is specific to the > > bit width? > For the folders under Silicon and platform, I prefer to use "RISC-V" which is > the official name of this processor. All other files can use RiscV which > conform the naming rule. RISCV32, RISCV64, and RISCV128 are used for the > architectures. > > > > > Thanks, > > > > Mike > > > > > -----Original Message----- > > > From: devel@edk2.groups.io <devel@edk2.groups.io> On > > > Behalf Of Daniel Schaefer > > > Sent: Tuesday, June 2, 2020 9:52 AM > > > To: devel@edk2.groups.io > > > Cc: Leif Lindholm <l...@nuviainc.com>; Gilbert Chen > > > <gilbert.c...@hpe.com>; Abner Chang > > > <abner.ch...@hpe.com>; Kinney, Michael D > > > <michael.d.kin...@intel.com> > > > Subject: [edk2-devel] [PATCH v4 1/1] > > > ProcessorPkg/Library: Add RiscVEdk2SbiLib > > > > > > Library provides interfaces to invoke SBI ecalls. > > > > > > Signed-off-by: Daniel Schaefer <daniel.schae...@hpe.com> > > > > > > Cc: Leif Lindholm <l...@nuviainc.com> > > > Cc: Gilbert Chen <gilbert.c...@hpe.com> > > > Cc: Abner Chang <abner.ch...@hpe.com> > > > Cc: Michael D. Kinney <michael.d.kin...@intel.com> > > > --- > > > Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.i > > > nf | 28 + > > > Silicon/RISC- > > > V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > > > | 563 ++++++++++++ > > > Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > > > | 897 ++++++++++++++++++++ > > > 3 files changed, 1488 insertions(+) > > > > > > diff --git a/Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.i > > > nf b/Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.i > > > nf > > > new file mode 100644 > > > index 000000000000..665dcbf40e01 > > > --- /dev/null > > > +++ b/Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.i > > > nf > > > @@ -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/Library/RiscVEdk2SbiLib.h > > > b/Silicon/RISC- > > > V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > > > new file mode 100644 > > > index 000000000000..c1ae3176147f > > > --- /dev/null > > > +++ b/Silicon/RISC- > > > V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h > > > @@ -0,0 +1,563 @@ > > > +/** @file > > > > > > > > > + Library to call the RISC-V SBI ecalls > > > > > > > > > + > > > > > > > > > + Copyright (c) 2020, Hewlett Packard Development LP. > > > All rights reserved.<BR> > > > > > > > > > + > > > > > > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > > > + > > > > > > > > > + @par Glossary: > > > > > > > > > + - Hart - Hardware Thread, similar to a CPU core > > > > > > > > > +**/ > > > > > > > > > + > > > > > > > > > +#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. > > > > > > > > > +// > > > > > > > > > +typedef struct { > > > > > > > > > + UINTN Error; ///< SBI status code > > > > > > > > > + UINTN Value; ///< Value returned > > > > > > > > > +} SbiRet; > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + 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] MachineVendorId The CPU's vendor ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineVendorId ( > > > > > > > > > + OUT UINTN *MachineVendorId > > > > > > > > > + ); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Get the CPU's architecture ID > > > > > > > > > + > > > > > > > > > + Reads the marchid CSR. > > > > > > > > > + > > > > > > > > > + @param[out] MachineArchId The CPU's > > > architecture ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineArchId ( > > > > > > > > > + OUT UINTN *MachineArchId > > > > > > > > > + ); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Get the CPU's implementation ID > > > > > > > > > + > > > > > > > > > + Reads the mimpid CSR. > > > > > > > > > + > > > > > > > > > + @param[out] MachineImplId The CPU's > > > implementation ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineImplId ( > > > > > > > > > + OUT UINTN *MachineImplId > > > > > > > > > + ); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + 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 Time. > > > > > > > > > + > > > > > > > > > + To clear the timer without scheduling a timer event, > > > set Time to a > > > > > > > > > + practically infinite value or mask the timer > > > interrupt by clearing sie.STIE. > > > > > > > > > + > > > > > > > > > + @param[in] Time The time offset to > > > the next scheduled timer interrupt. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiSetTimer ( > > > > > > > > > + IN UINT64 Time > > > > > > > > > + ); > > > > > > > > > + > > > > > > > > > +/// > > > > > > > > > +/// 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 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 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..0df505d2675b > > > --- /dev/null > > > +++ b/Silicon/RISC- > > > V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c > > > @@ -0,0 +1,897 @@ > > > +/** @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 > > > > > > > > > + > > > > > > > > > + @par Revision Reference: > > > > > > > > > + - OpenSBI Version 0.6 > > > > > > > > > +**/ > > > > > > > > > + > > > > > > > > > +#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_init.h> > > > > > > > > > + > > > > > > > > > + > > > > > > > > > +// > > > > > > > > > +// Maximum arguments for SBI ecall > > > > > > > > > +// It's possible to pass more but no SBI call uses more > > > as of SBI 0.2. > > > > > > > > > +// The additional arguments would have to be passed on > > > the stack instead of as > > > > > > > > > +// registers, like it's done now. > > > > > > > > > +// > > > > > > > > > +#define SBI_CALL_MAX_ARGS 6 > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Call SBI call using ecall instruction. > > > > > > > > > + > > > > > > > > > + Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS. > > > > > > > > > + > > > > > > > > > + @param[in] ExtId SBI extension ID. > > > > > > > > > + @param[in] FuncId SBI function ID. > > > > > > > > > + @param[in] NumArgs Number of arguments to pass to > > > the ecall. > > > > > > > > > + @param[in] ... Argument list for the ecall. > > > > > > > > > + > > > > > > > > > + @retval Returns SbiRet structure with value and > > > error code. > > > > > > > > > + > > > > > > > > > +**/ > > > > > > > > > +STATIC > > > > > > > > > +SbiRet > > > > > > > > > +EFIAPI > > > > > > > > > +SbiCall( > > > > > > > > > + IN UINTN ExtId, > > > > > > > > > + IN UINTN FuncId, > > > > > > > > > + IN UINTN NumArgs, > > > > > > > > > + ... > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + UINTN I; > > > > > > > > > + SbiRet Ret; > > > > > > > > > + UINTN Args[SBI_CALL_MAX_ARGS]; > > > > > > > > > + VA_LIST ArgList; > > > > > > > > > + VA_START (ArgList, NumArgs); > > > > > > > > > + > > > > > > > > > + ASSERT (NumArgs <= SBI_CALL_MAX_ARGS); > > > > > > > > > + > > > > > > > > > + for (I = 0; I < SBI_CALL_MAX_ARGS; I++) { > > > > > > > > > + if (I < NumArgs) { > > > > > > > > > + Args[I] = VA_ARG (ArgList, UINTN); > > > > > > > > > + } else { > > > > > > > > > + // Default to 0 for all arguments that are not > > > given > > > > > > > > > + Args[I] = 0; > > > > > > > > > + } > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + VA_END(ArgList); > > > > > > > > > + > > > > > > > > > + register UINTN a0 asm ("a0") = Args[0]; > > > > > > > > > + register UINTN a1 asm ("a1") = Args[1]; > > > > > > > > > + register UINTN a2 asm ("a2") = Args[2]; > > > > > > > > > + register UINTN a3 asm ("a3") = Args[3]; > > > > > > > > > + register UINTN a4 asm ("a4") = Args[4]; > > > > > > > > > + register UINTN a5 asm ("a5") = Args[5]; > > > > > > > > > + register UINTN a6 asm ("a6") = (UINTN)(FuncId); > > > > > > > > > + register UINTN a7 asm ("a7") = (UINTN)(ExtId); > > > > > > > > > + asm volatile ("ecall" \ > > > > > > > > > + : "+r" (a0), "+r" (a1) \ > > > > > > > > > + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" > > > (a6), "r" (a7) \ > > > > > > > > > + : "memory"); \ > > > > > > > > > + Ret.Error = a0; > > > > > > > > > + Ret.Value = a1; > > > > > > > > > + return Ret; > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Translate SBI error code to EFI status. > > > > > > > > > + > > > > > > > > > + @param[in] SbiError SBI error code > > > > > > > > > + @retval EFI_STATUS > > > > > > > > > +**/ > > > > > > > > > + > > > > > > > > > +STATIC > > > > > > > > > +EFI_STATUS > > > > > > > > > +EFIAPI > > > > > > > > > +TranslateError( > > > > > > > > > + IN UINTN SbiError > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + switch (SbiError) { > > > > > > > > > + case SBI_SUCCESS: > > > > > > > > > + return EFI_SUCCESS; > > > > > > > > > + case SBI_ERR_FAILED: > > > > > > > > > + return EFI_DEVICE_ERROR; > > > > > > > > > + break; > > > > > > > > > + case SBI_ERR_NOT_SUPPORTED: > > > > > > > > > + return EFI_UNSUPPORTED; > > > > > > > > > + break; > > > > > > > > > + case SBI_ERR_INVALID_PARAM: > > > > > > > > > + return EFI_INVALID_PARAMETER; > > > > > > > > > + break; > > > > > > > > > + case SBI_ERR_DENIED: > > > > > > > > > + return EFI_ACCESS_DENIED; > > > > > > > > > + break; > > > > > > > > > + case SBI_ERR_INVALID_ADDRESS: > > > > > > > > > + return EFI_LOAD_ERROR; > > > > > > > > > + break; > > > > > > > > > + case SBI_ERR_ALREADY_AVAILABLE: > > > > > > > > > + return EFI_ALREADY_STARTED; > > > > > > > > > + break; > > > > > > > > > + default: > > > > > > > > > + // > > > > > > > > > + // Reaches here only if SBI has defined a new > > > error type > > > > > > > > > + // > > > > > > > > > + ASSERT (FALSE); > > > > > > > > > + return EFI_UNSUPPORTED; > > > > > > > > > + break; > > > > > > > > > + } > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +// > > > > > > > > > +// OpenSBI library 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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_SPEC_VERSION, 0); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + *SpecVersion = (UINTN)Ret.Value; > > > > > > > > > + } > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + 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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_IMP_ID, 0); > > > > > > > > > + *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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_IMP_VERSION, 0); > > > > > > > > > + *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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_PROBE_EXT, 0); > > > > > > > > > + *ProbeResult = (UINTN)Ret.Value; > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Get the CPU's vendor ID > > > > > > > > > + > > > > > > > > > + Reads the mvendorid CSR. > > > > > > > > > + > > > > > > > > > + @param[out] MachineVendorId The CPU's vendor ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineVendorId ( > > > > > > > > > + OUT UINTN *MachineVendorId > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_MVENDORID, 0); > > > > > > > > > + *MachineVendorId = (UINTN)Ret.Value; > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Get the CPU's architecture ID > > > > > > > > > + > > > > > > > > > + Reads the marchid CSR. > > > > > > > > > + > > > > > > > > > + @param[out] MachineArchId The CPU's > > > architecture ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineArchId ( > > > > > > > > > + OUT UINTN *MachineArchId > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_MARCHID, 0); > > > > > > > > > + *MachineArchId = (UINTN)Ret.Value; > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Get the CPU's architecture ID > > > > > > > > > + > > > > > > > > > + Reads the marchid CSR. > > > > > > > > > + > > > > > > > > > + @param[out] MachineImplId The CPU's > > > implementation ID. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiGetMachineImplId ( > > > > > > > > > + OUT UINTN *MachineImplId > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_BASE, > > > SBI_EXT_BASE_GET_MIMPID, 0); > > > > > > > > > + *MachineImplId = (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_HSM, > > > > > > > > > + SBI_EXT_HSM_HART_START, > > > > > > > > > + 3, > > > > > > > > > + 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 ( > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_HSM, > > > SBI_EXT_HSM_HART_STOP, 0); > > > > > > > > > + 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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EXT_HSM, > > > SBI_EXT_HSM_HART_GET_STATUS, 1, HartId); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + *HartStatus = (UINTN)Ret.Value; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + return TranslateError (Ret.Error); > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + Clear pending timer interrupt bit and set timer for > > > next event after Time. > > > > > > > > > + > > > > > > > > > + To clear the timer without scheduling a timer event, > > > set Time to a > > > > > > > > > + practically infinite value or mask the timer > > > interrupt by clearing sie.STIE. > > > > > > > > > + > > > > > > > > > + @param[in] Time The time offset to > > > the next scheduled timer interrupt. > > > > > > > > > +**/ > > > > > > > > > +VOID > > > > > > > > > +EFIAPI > > > > > > > > > +SbiSetTimer ( > > > > > > > > > + IN UINT64 Time > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, > > > Time); > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +EFI_STATUS > > > > > > > > > +EFIAPI > > > > > > > > > +SbiSendIpi ( > > > > > > > > > + IN UINTN *HartMask, > > > > > > > > > + IN UINTN HartMaskBase > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_IPI, > > > > > > > > > + SBI_EXT_IPI_SEND_IPI, > > > > > > > > > + 2, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + SBI_EXT_RFENCE_REMOTE_FENCE_I, > > > > > > > > > + 2, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, > > > > > > > > > + 4, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, > > > > > > > > > + 5, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, > > > > > > > > > + 5, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + > > > SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, > > > > > > > > > + 4, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, > > > > > > > > > + 5, > > > > > > > > > + (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EXT_RFENCE, > > > > > > > > > + > > > SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, > > > > > > > > > + 4, > > > > > > > > > + (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 or NumArgs exceeds SBI_CALL_MAX_ARGS. > > > > > > > > > + > > > > > > > > > + @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 others if the called SBI function returns an > > > error > > > > > > > > > +**/ > > > > > > > > > +EFI_STATUS > > > > > > > > > +EFIAPI > > > > > > > > > +SbiVendorCall ( > > > > > > > > > + IN UINTN ExtensionId, > > > > > > > > > + IN UINTN FunctionId, > > > > > > > > > + IN UINTN NumArgs, > > > > > > > > > + ... > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret; > > > > > > > > > + VA_LIST Args; > > > > > > > > > + VA_START (Args, NumArgs); > > > > > > > > > + > > > > > > > > > + ASSERT (ExtensionId >= SBI_EXT_VENDOR_START && > > > ExtensionId <= SBI_EXT_VENDOR_END); > > > > > > > > > + ASSERT (NumArgs <= SBI_CALL_MAX_ARGS); > > > > > > > > > + > > > > > > > > > + switch (NumArgs) { > > > > > > > > > + case 0: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs); > > > > > > > > > + break; > > > > > > > > > + case 1: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, VA_ARG (Args, UINTN)); > > > > > > > > > + break; > > > > > > > > > + case 2: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, VA_ARG (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN)); > > > > > > > > > + break; > > > > > > > > > + case 3: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, VA_ARG (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN), VA_ARG > > > (Args, UINTN)); > > > > > > > > > + break; > > > > > > > > > + case 4: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, VA_ARG (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN), VA_ARG > > > (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN)); > > > > > > > > > + break; > > > > > > > > > + case 5: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, VA_ARG (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN), VA_ARG > > > (Args, UINTN), > > > > > > > > > + VA_ARG (Args, UINTN), VA_ARG > > > (Args, UINTN)); > > > > > > > > > + break; > > > > > > > > > + case 6: > > > > > > > > > + Ret = SbiCall (ExtensionId, FunctionId, > > > NumArgs, 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 SBI_SCRATCH **ScratchSpace > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EDK2_FW_EXT, > > > SBI_EXT_FW_MSCRATCH_FUNC, 0); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + *ScratchSpace = (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 SBI_SCRATCH **ScratchSpace > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SbiRet Ret = SbiCall ( > > > > > > > > > + SBI_EDK2_FW_EXT, > > > > > > > > > + SBI_EXT_FW_MSCRATCH_HARTID_FUNC, > > > > > > > > > + 1, > > > > > > > > > + HartId > > > > > > > > > + ); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + *ScratchSpace = (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SBI_SCRATCH *ScratchSpace; > > > > > > > > > + SBI_PLATFORM *SbiPlatform; > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EDK2_FW_EXT, > > > SBI_EXT_FW_MSCRATCH_FUNC, 0); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + ScratchSpace = (SBI_SCRATCH *)Ret.Value; > > > > > > > > > + SbiPlatform = (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 > > > > > > > > > + ) > > > > > > > > > +{ > > > > > > > > > + SBI_SCRATCH *ScratchSpace; > > > > > > > > > + SBI_PLATFORM *SbiPlatform; > > > > > > > > > + SbiRet Ret = SbiCall (SBI_EDK2_FW_EXT, > > > SBI_EXT_FW_MSCRATCH_FUNC, 0); > > > > > > > > > + > > > > > > > > > + if (!Ret.Error) { > > > > > > > > > + ScratchSpace = (SBI_SCRATCH *)Ret.Value; > > > > > > > > > + SbiPlatform = (SBI_PLATFORM *)sbi_platform_ptr > > > (ScratchSpace); > > > > > > > > > + SbiPlatform->firmware_context = > > > (UINTN)FirmwareContext; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + return EFI_SUCCESS; > > > > > > > > > +} > > > > > > > > > -- > > > 2.26.1 > > > > > > > > > > > >
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#60615): https://edk2.groups.io/g/devel/message/60615 Mute This Topic: https://groups.io/mt/74631942/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-