From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by mx.groups.io with SMTP id smtpd.web11.1197.1590772003422380037 for ; Fri, 29 May 2020 10:06:43 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: hpe.com, ip: 148.163.147.86, mailfrom: prvs=041837a23b=daniel.schaefer@hpe.com) Received: from pps.filterd (m0134420.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04TGwPml020403; Fri, 29 May 2020 17:06:43 GMT Received: from g9t5008.houston.hpe.com (g9t5008.houston.hpe.com [15.241.48.72]) by mx0b-002e3701.pphosted.com with ESMTP id 31b1swjef0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2020 17:06:42 +0000 Received: from G9W8456.americas.hpqcorp.net (g9w8456.houston.hp.com [16.216.161.95]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g9t5008.houston.hpe.com (Postfix) with ESMTPS id 1F23C62; Fri, 29 May 2020 17:06:42 +0000 (UTC) Received: from G1W8107.americas.hpqcorp.net (2002:10c1:483b::10c1:483b) by G9W8456.americas.hpqcorp.net (2002:10d8:a15f::10d8:a15f) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 29 May 2020 17:06:41 +0000 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (15.241.52.13) by G1W8107.americas.hpqcorp.net (16.193.72.59) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Fri, 29 May 2020 17:06:41 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=m5Dp5tg6WT7F2ov0D38PpDZP5SrIk26FR09ee3lJDlQ7V2BREd4XJRPYoiH+pyGu6GhRpaD/B/mdIrGuGUmQMN3v3fR31pXIM/poMPIYEGT63ytZmMTg4HzvGeQ1Xl7Y5A3p9cGEsJN+tbzLFofPgPocNKs3sAkMpBwHUsdW5ey/hFUb5Xl17OTOhKh99bNLLfH2q2+Gw6FGpGUzIRL5XqvUNKjH33JVdrKBjuOjTb55NAzAaGp879nWRWR8LD94b3uiS94xNCBoTpLx2DN/4awl3pxw/OJmf2cBQL7gqz+7BkB7/xlXSwL8Rh5gWCqgSbhCDCqgENpd173qD71GYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=o77TKZLgWPQb/AqhTjIzFqoFeO381xB6ilpqMv8r8T0=; b=ArP9nUb50+DkH1hx5lNHMWetCrGdzywtjdTJ6qwH4CxuxQeqe98VcOq+b8pp1MPzDXK664qPxNUpoLprJOBpFJ3BiwSmQEuGYi+RGOWSGpvjkcOfFD0jc8X1CzSJsOYU17PMOSTk5bEDoY/7ypE1Lh/HUWZoplfGhhlMsTzK0aE/t8tIj4gaSGKmhNAeu9A1eCQ78UrSVAsH/5m1O1MfeIG8zdMyXl3gpecU55OWoHXAu06aNum+3AGMaUDQ3J3xG8ENPmhG1ieBIRE7WOHRpD2jeI1w3CSgasT5xtNzQgZA9K+HRu8hy4Hd9cUA/eZF9Z+9VUbrs2IRA6K3JEOZpA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hpe.com; dmarc=pass action=none header.from=hpe.com; dkim=pass header.d=hpe.com; arc=none Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=hpe.com; Received: from DF4PR8401MB0474.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7607::10) by DF4PR8401MB0441.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7607::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.19; Fri, 29 May 2020 17:06:38 +0000 Received: from DF4PR8401MB0474.NAMPRD84.PROD.OUTLOOK.COM ([fe80::c4c5:a5a7:6deb:da30]) by DF4PR8401MB0474.NAMPRD84.PROD.OUTLOOK.COM ([fe80::c4c5:a5a7:6deb:da30%9]) with mapi id 15.20.3021.030; Fri, 29 May 2020 17:06:38 +0000 From: "Daniel Schaefer" To: CC: Leif Lindholm , Gilbert Chen , Abner Chang , Michael D Kinney Subject: [PATCH v3 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Date: Fri, 29 May 2020 19:06:22 +0200 Message-ID: <20200529170622.32610-4-daniel.schaefer@hpe.com> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200529170622.32610-1-daniel.schaefer@hpe.com> References: <20200529170622.32610-1-daniel.schaefer@hpe.com> X-ClientProxiedBy: AM0PR10CA0057.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:150::37) To DF4PR8401MB0474.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7607::10) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from x360-nix.fritz.box (93.215.216.32) by AM0PR10CA0057.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:150::37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.17 via Frontend Transport; Fri, 29 May 2020 17:06:37 +0000 X-Mailer: git-send-email 2.26.1 X-Originating-IP: [93.215.216.32] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 46f047c3-27e8-4b1c-a5c2-08d803f2a670 X-MS-TrafficTypeDiagnostic: DF4PR8401MB0441: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:4125; X-Forefront-PRVS: 04180B6720 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: K99A4hmWsjtg/wy4bGPhC5JH4Hv6a44UNhF+OiJIVavZDdAXLbaIOapLuIaCyeTAvWhnSA/b0XT3NKD4znDQWEh/XT4HaZi/QYGcbTycsmS0GbAYeYhAt5Z2xiH7C2Nd2I/rmdQljDYdtC+ryBDjl0Dyk7SJ158dJPw+e/BDp/497z0bYQkJskpuxcj+N+kddovYg5EBOcUEZ0U71A0nuLxRtcKLns1UatxFe+mGeqymM/kTu6JcJNKVXacmLCH+uLSrIPzZi+M9ojnULqJ8F0w3qTgW1ZKfaoNomca5BxeJAWyUvvRHbWsakNpVsrwldVT1J2g0mjvya7bu5hIyBA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DF4PR8401MB0474.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFTY:;SFS:(346002)(136003)(39860400002)(376002)(396003)(366004)(52116002)(186003)(16526019)(316002)(54906003)(6916009)(478600001)(5660300002)(83380400001)(2906002)(956004)(2616005)(6486002)(44832011)(8936002)(6666004)(1076003)(30864003)(36756003)(4326008)(6512007)(86362001)(6506007)(8676002)(26005)(66556008)(66476007)(66946007)(579004)(559001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: t/KzX+jf/k9ya2DCvYzLDAAjf9bWBjgPPDnWMQ0+Vw2xWR6uB5X3a+LrM57QnwRhC50ChpHX35gXGonNCBYSNKrfqOdwkjGTmdtElhhiM93stzSAlaC0v0CDR3a2XJlGqtiRQYJonCsAjANFEWs7nC3AG+6zUF9BHM7OM9kCYnasW3KtzfrAgHXv4YyKnWnBKBYkAagr8u53gzy5xu2eWQffQBgB7wL2VRa8i03akronEm1zO34ehz38WrncNO5Q2SBNP9vbv+opQRpuCY8g3EJjgnUatuvpz4msCDHlr1WpBXSCfAPnVSuNhpgvWlDraIMikpCdMZeFq2L0aqrxeL/ii7YEyXdfjFPq9C6SPdpZJiHxRglEmesRs6dTCnDyNJWT88DXCeiW1LLu3iZ1Rg9HUXd4Iqs5jxg5ZOMQspIKtGLgnBB1BKjj/rEZT8EcZSvpUgIcjmetc2YkBoPbz0kAnMmvAUxwZORv8wqFYBsTLWRduJojca+kp90Q/mC4 X-MS-Exchange-CrossTenant-Network-Message-Id: 46f047c3-27e8-4b1c-a5c2-08d803f2a670 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 May 2020 17:06:38.5862 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: LlqS7GFZwI65Gh71lcRrPiRE+wUfftouWIDec1kqUblRi11TEBWmpujqslO7ZfFYH1UJ/ij/GegO+TcQXQu6Vg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DF4PR8401MB0441 X-OriginatorOrg: hpe.com X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.687 definitions=2020-05-29_08:2020-05-28,2020-05-29 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxscore=0 phishscore=0 spamscore=0 clxscore=1015 cotscore=-2147483648 suspectscore=4 bulkscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 adultscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005290129 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain Library provides interfaces to invoke SBI ecalls. Signed-off-by: Daniel Schaefer Cc: Leif Lindholm Cc: Gilbert Chen Cc: Abner Chang Cc: Michael D Kinney --- Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | = 28 + Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | = 563 +++++++++++++ Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | = 860 ++++++++++++++++++++ 3 files changed, 1451 insertions(+) diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2S= biLib.inf b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2Sb= iLib.inf new file mode 100644 index 000000000000..665dcbf40e01 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.i= nf @@ -0,0 +1,28 @@ +## @file=0D +# RISC-V Library to call SBI ecalls=0D +#=0D +# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All righ= ts reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001b=0D + BASE_NAME =3D RiscVEdk2SbiLib=0D + FILE_GUID =3D 0DF1BBBD-F7E5-4E8A-BCF1-9D63D2DD9FDD=0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D RiscVEdk2SbiLib=0D +=0D +[Sources]=0D + RiscVEdk2SbiLib.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec=0D + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + RiscVOpensbiLib=0D 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=0D + Library to call the RISC-V SBI ecalls=0D +=0D + Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.=
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D + @par Glossary:=0D + - Hart - Hardware Thread, similar to a CPU core=0D +**/=0D +=0D +#ifndef RISCV_SBI_LIB_H_=0D +#define RISCV_SBI_LIB_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +//=0D +// EDK2 OpenSBI Firmware extension.=0D +//=0D +#define SBI_EDK2_FW_EXT (SBI_EXT_FIRMWARE_CODE_BASE_START | SBI_OPENSBI_IM= PID)=0D +//=0D +// EDK2 OpenSBI Firmware extension functions.=0D +//=0D +#define SBI_EXT_FW_MSCRATCH_FUNC 0=0D +#define SBI_EXT_FW_MSCRATCH_HARTID_FUNC 1=0D +=0D +//=0D +// EDK2 OpenSBI firmware extension return status.=0D +//=0D +typedef struct {=0D + UINTN Error; ///< SBI status code=0D + UINTN Value; ///< Value returned=0D +} SbiRet;=0D +=0D +/**=0D + Get the implemented SBI specification version=0D +=0D + The minor number of the SBI specification is encoded in the low 24 bits,= =0D + with the major number encoded in the next 7 bits. Bit 32 must be 0 and = is=0D + reserved for future expansion.=0D +=0D + @param[out] SpecVersion The Version of the SBI specification.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetSpecVersion (=0D + OUT UINTN *SpecVersion=0D + );=0D +=0D +/**=0D + Get the SBI implementation ID=0D +=0D + This ID is used to idenetify a specific SBI implementation in order to w= ork=0D + around any quirks it might have.=0D +=0D + @param[out] ImplId The ID of the SBI implementation.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetImplId (=0D + OUT UINTN *ImplId=0D + );=0D +=0D +/**=0D + Get the SBI implementation version=0D +=0D + The version of this SBI implementation.=0D + The encoding of this number is determined by the specific SBI implementa= tion.=0D +=0D + @param[out] ImplVersion The version of the SBI implementation.= =0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetImplVersion (=0D + OUT UINTN *ImplVersion=0D + );=0D +=0D +/**=0D + Probe whether an SBI extension is available=0D +=0D + ProbeResult is set to 0 if the extension is not available or to an exten= sion=0D + specified value if it is available.=0D +=0D + @param[in] ExtensionId The extension ID.=0D + @param[out] ProbeResult The return value of the probe.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiProbeExtension (=0D + IN INTN ExtensionId,=0D + OUT INTN *ProbeResult=0D + );=0D +=0D +/**=0D + Get the CPU's vendor ID=0D +=0D + Reads the mvendorid CSR.=0D +=0D + @param[out] MachineVendorId The CPU's vendor ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineVendorId (=0D + OUT UINTN *MachineVendorId=0D + );=0D +=0D +/**=0D + Get the CPU's architecture ID=0D +=0D + Reads the marchid CSR.=0D +=0D + @param[out] MachineArchId The CPU's architecture ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineArchId (=0D + OUT UINTN *MachineArchId=0D + );=0D +=0D +/**=0D + Get the CPU's implementation ID=0D +=0D + Reads the mimpid CSR.=0D +=0D + @param[out] MachineImplId The CPU's implementation ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineImplId (=0D + OUT UINTN *MachineImplId=0D + );=0D +=0D +/**=0D + Politely ask the SBI to start a given hart.=0D +=0D + This call may return before the hart has actually started executing, if = the=0D + SBI implementation can guarantee that the hart is actually going to star= t.=0D +=0D + Before the hart jumps to StartAddr, the hart MUST configure PMP if prese= nt=0D + and switch to S-mode.=0D +=0D + @param[in] HartId The id of the hart to start.=0D + @param[in] StartAddr The physical address, where the hart st= arts=0D + executing from.=0D + @param[in] Priv An XLEN-bit value, which will be in reg= ister=0D + a1 when the hart starts.=0D + @retval EFI_SUCCESS Hart was stopped and will start executi= ng from StartAddr.=0D + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to= following reasons:=0D + - It is not a valid physical address.= =0D + - The address is prohibited by PMP to = run in=0D + supervisor mode.=0D + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id=0D + @retval EFI_ALREADY_STARTED The hart is already running.=0D + @retval other The start request failed for unknown re= asons.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartStart (=0D + IN UINTN HartId,=0D + IN UINTN StartAddr,=0D + IN UINTN Priv=0D + );=0D +=0D +/**=0D + Return execution of the calling hart to SBI.=0D +=0D + MUST be called in S-Mode with user interrupts disabled.=0D + This call is not expected to return, unless a failure occurs.=0D +=0D + @retval EFI_SUCCESS Never occurs. When successful, the call= does not return.=0D + @retval other Failed to stop hard for an unknown reas= on.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartStop (=0D + );=0D +=0D +/**=0D + Get the current status of a hart.=0D +=0D + Since harts can transition between states at any time, the status retrie= ved=0D + by this function may already be out of date, once it returns.=0D +=0D + Possible values for HartStatus are:=0D + 0: STARTED=0D + 1: STOPPED=0D + 2: START_REQUEST_PENDING=0D + 3: STOP_REQUEST_PENDING=0D +=0D + @param[out] HartStatus The pointer in which the hart's status = is=0D + stored.=0D + @retval EFI_SUCCESS The operation succeeds.=0D + @retval EFI_INVALID_PARAMETER A parameter is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartGetStatus (=0D + IN UINTN HartId,=0D + OUT UINTN *HartStatus=0D + );=0D +=0D +///=0D +/// Timer extension=0D +///=0D +=0D +/**=0D + Clear pending timer interrupt bit and set timer for next event after Tim= e.=0D +=0D + To clear the timer without scheduling a timer event, set Time to a=0D + practically infinite value or mask the timer interrupt by clearing sie.S= TIE.=0D +=0D + @param[in] Time The time offset to the next scheduled t= imer interrupt.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiSetTimer (=0D + IN UINT64 Time=0D + );=0D +=0D +///=0D +/// IPI extension=0D +///=0D +=0D +/**=0D + Send IPI to all harts specified in the mask.=0D +=0D + The interrupts are registered as supervisor software interrupts at the=0D + receiving hart.=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiSendIpi (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase=0D + );=0D +=0D +///=0D +/// Remote fence extension=0D +///=0D +=0D +/**=0D + Instructs remote harts to execute a FENCE.I instruction.=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteFenceI (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VMA instruction= s.=0D +=0D + The SFENCE.VMA covers the range of virtual addresses between StartAaddr = and Size.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteSfenceVma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VMA instruction= s.=0D +=0D + The SFENCE.VMA covers the range of virtual addresses between StartAaddr = and Size.=0D + Covers only the given ASID.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteSfenceVmaAsid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Asid=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.GVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + Covers only the given VMID.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHfenceGvmaVmid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Vmid=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.GVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHfenceGvma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + Covers only the given ASID.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHfenceVvmaAsid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Asid=0D + );=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHfenceVvma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + );=0D +=0D +///=0D +/// Vendor Specific extension space: Extension Ids 0x09000000 through 0x09= FFFFFF=0D +///=0D +=0D +/**=0D + Call a function in a vendor defined SBI extension=0D +=0D + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extensio= n=0D + Space.=0D +=0D + @param[in] ExtensionId The SBI vendor extension ID.=0D + @param[in] FunctionId The function ID to call in this extensi= on.=0D + @param[in] NumArgs How many arguments are passed.=0D + @param[in] ... Actual Arguments to the function.=0D + @retval EFI_SUCCESS if the SBI function was called and it was successful= =0D + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6=0D + @retval others if the called SBI function returns an error=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiVendorCall (=0D + IN UINTN ExtensionId,=0D + IN UINTN FunctionId,=0D + IN UINTN NumArgs,=0D + ...=0D + );=0D +=0D +///=0D +/// Firmware SBI Extension=0D +///=0D +/// This SBI Extension is defined and used by EDK2 only in order to be abl= e to=0D +/// run PI and DXE phase in S-Mode.=0D +///=0D +=0D +/**=0D + Get scratch space of the current hart.=0D +=0D + Please consider using the wrapper SbiGetFirmwareContext if you only need= to=0D + access the firmware context.=0D +=0D + @param[out] ScratchSpace The scratch space pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetMscratch (=0D + OUT SBI_SCRATCH **ScratchSpace=0D + );=0D +=0D +/**=0D + Get scratch space of the given hart id.=0D +=0D + @param[in] HartId The hart id.=0D + @param[out] ScratchSpace The scratch space pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetMscratchHartid (=0D + IN UINTN HartId,=0D + OUT SBI_SCRATCH **ScratchSpace=0D + );=0D +=0D +/**=0D + Get firmware context of the calling hart.=0D +=0D + @param[out] FirmwareContext The firmware context pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetFirmwareContext (=0D + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext=0D + );=0D +=0D +/**=0D + Set firmware context of the calling hart.=0D +=0D + @param[in] FirmwareContext The firmware context pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiSetFirmwareContext (=0D + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext=0D + );=0D +=0D +#endif=0D diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2S= biLib.c b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiL= ib.c new file mode 100644 index 000000000000..d26adaa37ce7 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c @@ -0,0 +1,860 @@ +/** @file=0D + Instance of the SBI ecall library.=0D +=0D + It allows calling an SBI function via an ecall from S-Mode.=0D +=0D + The legacy extensions are not included because they are not necessary.=0D + They would be:=0D + - SbiLegacySetTimer -> Use SbiSetTimer=0D + - SbiLegacyConsolePutChar -> No replacement - Use regular UEFI func= tions=0D + - SbiLegacyConsoleGetChar -> No replacement - Use regular UEFI func= tions=0D + - SbiLegacyClearIpi -> Write 0 to SSIP=0D + - SbiLegacySendIpi -> Use SbiSendIpi=0D + - SbiLegacyRemoteFenceI -> Use SbiRemoteFenceI=0D + - SbiLegacyRemoteSfenceVma -> Use SbiRemoteSfenceVma=0D + - SbiLegacyRemoteSfenceVmaAsid -> Use SbiRemoteSfenceVmaAsid=0D + - SbiLegacyShutdown -> Wait for new System Reset extension=0D +=0D + Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.=
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +=0D +/**=0D + Call SBI call using ecall instruction.=0D +=0D + @param[in] ExtId SBI extension ID.=0D + @param[in] FuncId SBI function ID.=0D + @param[in] NumAargs Number of arguments to pass to the ecall.=0D + @param[in] ... Argument list for the ecall.=0D +=0D + @retval Returns SbiRet structure with value and error code.=0D +=0D +**/=0D +STATIC=0D +SbiRet=0D +EFIAPI=0D +SbiCall(=0D + IN UINTN ExtId,=0D + IN UINTN FuncId,=0D + IN UINTN NumArgs,=0D + ...=0D +) {=0D + UINTN I;=0D + SbiRet Ret;=0D + UINTN Args[6];=0D + VA_LIST ArgList;=0D + VA_START(ArgList, NumArgs);=0D +=0D + for (I =3D 0; I < 6; I++) {=0D + if (I < NumArgs) {=0D + Args[I] =3D VA_ARG(ArgList, UINTN);=0D + } else {=0D + // Default to 0 for all arguments that are not given=0D + Args[I] =3D 0;=0D + }=0D + }=0D +=0D + VA_END(ArgList);=0D +=0D + register UINTN a0 asm ("a0") =3D Args[0];=0D + register UINTN a1 asm ("a1") =3D Args[1];=0D + register UINTN a2 asm ("a2") =3D Args[2];=0D + register UINTN a3 asm ("a3") =3D Args[3];=0D + register UINTN a4 asm ("a4") =3D Args[4];=0D + register UINTN a5 asm ("a5") =3D Args[5];=0D + register UINTN a6 asm ("a6") =3D (UINTN)(FuncId);=0D + register UINTN a7 asm ("a7") =3D (UINTN)(ExtId);=0D + asm volatile ("ecall" \=0D + : "+r" (a0), "+r" (a1) \=0D + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \=0D + : "memory"); \=0D + Ret.Error =3D a0;=0D + Ret.Value =3D a1;=0D + return Ret;=0D +}=0D +=0D +/**=0D + Translate SBI error code to EFI status.=0D +=0D + @param[in] SbiError SBI error code=0D + @retval EFI_STATUS=0D +**/=0D +=0D +STATIC=0D +EFI_STATUS=0D +EFIAPI=0D +TranslateError(=0D + IN UINTN SbiError=0D + ) {=0D + switch (SbiError) {=0D + case SBI_SUCCESS:=0D + return EFI_SUCCESS;=0D + case SBI_ERR_FAILED:=0D + return EFI_DEVICE_ERROR;=0D + break;=0D + case SBI_ERR_NOT_SUPPORTED:=0D + return EFI_UNSUPPORTED;=0D + break;=0D + case SBI_ERR_INVALID_PARAM:=0D + return EFI_INVALID_PARAMETER;=0D + break;=0D + case SBI_ERR_DENIED:=0D + return EFI_ACCESS_DENIED;=0D + break;=0D + case SBI_ERR_INVALID_ADDRESS:=0D + return EFI_LOAD_ERROR;=0D + break;=0D + case SBI_ERR_ALREADY_AVAILABLE:=0D + return EFI_ALREADY_STARTED;=0D + break;=0D + default:=0D + //=0D + // Reaches here only if SBI has defined a new error type=0D + //=0D + ASSERT (FALSE);=0D + return EFI_UNSUPPORTED;=0D + break;=0D + }=0D +}=0D +=0D +//=0D +// OpenSBI libraary interface function for the base extension=0D +//=0D +=0D +/**=0D + Get the implemented SBI specification version=0D +=0D + The minor number of the SBI specification is encoded in the low 24 bits,= =0D + with the major number encoded in the next 7 bits. Bit 32 must be 0 and = is=0D + reserved for future expansion.=0D +=0D + @param[out] SpecVersion The Version of the SBI specification.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetSpecVersion (=0D + OUT UINTN *SpecVersion=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION, 0);= =0D +=0D + if (!Ret.Error) {=0D + *SpecVersion =3D (UINTN) Ret.Value;=0D + }=0D +}=0D +=0D +/**=0D + Get the SBI implementation ID=0D +=0D + This ID is used to idenetify a specific SBI implementation in order to w= ork=0D + around any quirks it might have.=0D +=0D + @param[out] ImplId The ID of the SBI implementation.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetImplId (=0D + OUT UINTN *ImplId=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID, 0);=0D + *ImplId =3D (UINTN) Ret.Value;=0D +}=0D +=0D +/**=0D + Get the SBI implementation version=0D +=0D + The version of this SBI implementation.=0D + The encoding of this number is determined by the specific SBI implementa= tion.=0D +=0D + @param[out] ImplVersion The version of the SBI implementation.= =0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetImplVersion (=0D + OUT UINTN *ImplVersion=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSION, 0);= =0D + *ImplVersion =3D (UINTN) Ret.Value;=0D +}=0D +=0D +/**=0D + Probe whether an SBI extension is available=0D +=0D + ProbeResult is set to 0 if the extension is not available or to an exten= sion=0D + specified value if it is available.=0D +=0D + @param[in] ExtensionId The extension ID.=0D + @param[out] ProbeResult The return value of the probe.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiProbeExtension (=0D + IN INTN ExtensionId,=0D + OUT INTN *ProbeResult=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, 0);=0D + *ProbeResult =3D (UINTN) Ret.Value;=0D +}=0D +=0D +/**=0D + Get the CPU's vendor ID=0D +=0D + Reads the mvendorid CSR.=0D +=0D + @param[out] MachineVendorId The CPU's vendor ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineVendorId (=0D + OUT UINTN *MachineVendorId=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID, 0);=0D + *MachineVendorId =3D (UINTN) Ret.Value;=0D +}=0D +=0D +/**=0D + Get the CPU's architecture ID=0D +=0D + Reads the marchid CSR.=0D +=0D + @param[out] MachineArchId The CPU's architecture ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineArchId (=0D + OUT UINTN *MachineArchId=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_MARCHID, 0);=0D + *MachineArchId =3D (UINTN) Ret.Value;=0D +}=0D +=0D +/**=0D + Get the CPU's architecture ID=0D +=0D + Reads the marchid CSR.=0D +=0D + @param[out] MachineImplId The CPU's implementation ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMachineImplId (=0D + OUT UINTN *MachineImplId=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_BASE, SBI_EXT_BASE_GET_MIMPID, 0);=0D + *MachineImplId =3D (UINTN) Ret.Value;=0D +}=0D +=0D +//=0D +// SBI interface function for the hart state management extension=0D +//=0D +=0D +/**=0D + Politely ask the SBI to start a given hart.=0D +=0D + This call may return before the hart has actually started executing, if = the=0D + SBI implementation can guarantee that the hart is actually going to star= t.=0D +=0D + Before the hart jumps to StartAddr, the hart MUST configure PMP if prese= nt=0D + and switch to S-mode.=0D +=0D + @param[in] HartId The id of the hart to start.=0D + @param[in] StartAddr The physical address, where the hart st= arts=0D + executing from.=0D + @param[in] Priv An XLEN-bit value, which will be in reg= ister=0D + a1 when the hart starts.=0D + @retval EFI_SUCCESS Hart was stopped and will start executi= ng from StartAddr.=0D + @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to= following reasons:=0D + - It is not a valid physical address.= =0D + - The address is prohibited by PMP to= run in=0D + supervisor mode.=0D + @retval EFI_INVALID_PARAMETER HartId is not a valid hart id=0D + @retval EFI_ALREADY_STARTED The hart is already running.=0D + @retval other The start request failed for unknown re= asons.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartStart (=0D + IN UINTN HartId,=0D + IN UINTN StartAddr,=0D + IN UINTN Priv=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_HSM,=0D + SBI_EXT_HSM_HART_START,=0D + 3,=0D + HartId,=0D + StartAddr,=0D + Priv);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Return execution of the calling hart to SBI.=0D +=0D + MUST be called in S-Mode with user interrupts disabled.=0D + This call is not expected to return, unless a failure occurs.=0D +=0D + @retval EFI_SUCCESS Never occurs. When successful, the call= does not return.=0D + @retval other Failed to stop hard for an unknown reas= on.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartStop (=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP, 0);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Get the current status of a hart.=0D +=0D + Since harts can transition between states at any time, the status retrie= ved=0D + by this function may already be out of date, once it returns.=0D +=0D + Possible values for HartStatus are:=0D + 0: STARTED=0D + 1: STOPPED=0D + 2: START_REQUEST_PENDING=0D + 3: STOP_REQUEST_PENDING=0D +=0D + @param[out] HartStatus The pointer in which the hart's status = is=0D + stored.=0D + @retval EFI_SUCCESS The operation succeeds.=0D + @retval EFI_INVALID_PARAMETER A parameter is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiHartGetStatus (=0D + IN UINTN HartId,=0D + OUT UINTN *HartStatus=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_HSM, SBI_EXT_HSM_HART_GET_STATUS, 1, Har= tId);=0D +=0D + if (!Ret.Error) {=0D + *HartStatus =3D (UINTN) Ret.Value;=0D + }=0D +=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Clear pending timer interrupt bit and set timer for next event after Tim= e.=0D +=0D + To clear the timer without scheduling a timer event, set Time to a=0D + practically infinite value or mask the timer interrupt by clearing sie.S= TIE.=0D +=0D + @param[in] Time The time offset to the next scheduled t= imer interrupt.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiSetTimer (=0D + IN UINT64 Time=0D + )=0D +{=0D + SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);=0D +}=0D +=0D +EFI_STATUS=0D +EFIAPI=0D +SbiSendIpi (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_IPI,=0D + SBI_EXT_IPI_SEND_IPI,=0D + 2,=0D + (UINTN) HartMask,=0D + HartMaskBase);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs remote harts to execute a FENCE.I instruction.=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteFenceI (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_FENCE_I,=0D + 2,=0D + (UINTN) HartMask,=0D + HartMaskBase);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VMA instruction= s.=0D +=0D + The SFENCE.VMA covers the range of virtual addresses between StartAaddr = and Size.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteSfenceVma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,=0D + 4,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VMA instruction= s.=0D +=0D + The SFENCE.VMA covers the range of virtual addresses between StartAaddr = and Size.=0D + Covers only the given ASID.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteSfenceVmaAsid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Asid=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID,=0D + 5,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size,=0D + Asid);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.GVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + Covers only the given VMID.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHFenceGvmaVmid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Vmid=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA,=0D + 5,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size,=0D + Vmid);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.GVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHFenceGvma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID,=0D + 4,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + Covers only the given ASID.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHFenceVvmaAsid (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size,=0D + IN UINTN Asid=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA,=0D + 5,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size,=0D + Asid);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +/**=0D + Instructs the remote harts to execute one or more SFENCE.VVMA instructio= ns.=0D +=0D + The SFENCE.GVMA covers the range of virtual addresses between StartAaddr= and Size.=0D + This function call is only valid for harts implementing the hypervisor e= xtension.=0D +=0D + The remote fence function acts as a full tlb flush if * StartAddr and si= ze=0D + are both 0 * size is equal to 2^XLEN-1=0D +=0D + @param[in] HartMask Scalar bit-vector containing hart ids=0D + @param[in] HartMaskBase The starting hartid from which the bit-= vector=0D + must be computed. If set to -1, HartMas= k is=0D + ignored and all harts are considered.=0D + @param[in] StartAddr The first address of the affected range= .=0D + @param[in] Size How many addresses are affected.=0D + @retval EFI_SUCCESS IPI was sent to all the targeted harts.= =0D + @retval EFI_LOAD_ERROR StartAddr or Size is not valid.=0D + @retval EFI_UNSUPPORTED SBI does not implement this function or= one=0D + of the target harts does not support th= e=0D + hypervisor extension.=0D + @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the har= tid=0D + from hart_mask is not valid i.e. either= the=0D + hartid is not enabled by the platform o= r is=0D + not available to the supervisor.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiRemoteHFenceVvma (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase,=0D + IN UINTN StartAddr,=0D + IN UINTN Size=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID,=0D + 4,=0D + (UINTN) HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +//=0D +// SBI interface function for the vendor extension=0D +//=0D +=0D +/**=0D + Call a function in a vendor defined SBI extension=0D +=0D + ASSERT() if the ExtensionId is not in the designated SBI Vendor Extensio= n=0D + Space.=0D +=0D + @param[in] ExtensionId The SBI vendor extension ID.=0D + @param[in] FunctionId The function ID to call in this extensi= on.=0D + @param[in] NumArgs How many arguments are passed.=0D + @param[in] ... Actual Arguments to the function.=0D + @retval EFI_SUCCESS if the SBI function was called and it was successful= =0D + @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6=0D + @retval others if the called SBI function returns an error=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiVendorCall (=0D + IN UINTN ExtensionId,=0D + IN UINTN FunctionId,=0D + IN UINTN NumArgs,=0D + ...=0D + )=0D +{=0D + SbiRet Ret;=0D + VA_LIST Args;=0D + VA_START(Args, NumArgs);=0D +=0D + ASSERT (ExtensionId >=3D 0x09000000 && ExtensionId <=3D 0x09FFFFFF);=0D +=0D + switch (NumArgs) {=0D + case 0:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs);=0D + break;=0D + case 1:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN));=0D + break;=0D + case 2:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN),=0D + VA_ARG(Args, UINTN));=0D + break;=0D + case 3:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN));=0D + break;=0D + case 4:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Ar= gs, UINTN));=0D + break;=0D + case 5:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN));=0D + break;=0D + case 6:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG(Args, UI= NTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN),=0D + VA_ARG(Args, UINTN), VA_ARG(Args, UINTN),=0D + VA_ARG(Args, UINTN));=0D + break;=0D + default:=0D + // Too many args. In theory SBI can handle more arguments when the= y are=0D + // passed on the stack but no SBI extension uses this, therefore i= t's=0D + // not yet implemented here.=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + VA_END(Args);=0D + return TranslateError(Ret.Error);=0D +}=0D +=0D +//=0D +// SBI Firmware extension=0D +//=0D +=0D +/**=0D + Get scratch space of the current hart.=0D +=0D + Please consider using the wrapper SbiGetFirmwareContext if you only need= to=0D + access the firmware context.=0D +=0D + @param[out] ScratchSpace The scratch space pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetMscratch (=0D + OUT SBI_SCRATCH **ScratchSpace=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC, 0);=0D +=0D + if (!Ret.Error) {=0D + *ScratchSpace =3D (SBI_SCRATCH *) Ret.Value;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Get scratch space of the given hart id.=0D +=0D + @param[in] HartId The hart id.=0D + @param[out] ScratchSpace The scratch space pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetMscratchHartid (=0D + IN UINTN HartId,=0D + OUT SBI_SCRATCH **ScratchSpace=0D + )=0D +{=0D + SbiRet Ret =3D SbiCall (SBI_EDK2_FW_EXT,=0D + SBI_EXT_FW_MSCRATCH_HARTID_FUNC,=0D + 1,=0D + HartId);=0D +=0D + if (!Ret.Error) {=0D + *ScratchSpace =3D (SBI_SCRATCH *) Ret.Value;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Get firmware context of the calling hart.=0D +=0D + @param[out] FirmwareContext The firmware context pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiGetFirmwareContext (=0D + OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext=0D + )=0D +{=0D + SBI_SCRATCH *ScratchSpace;=0D + SBI_PLATFORM *SbiPlatform;=0D + SbiRet Ret =3D SbiCall (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC, 0);=0D +=0D + if (!Ret.Error) {=0D + ScratchSpace =3D (SBI_SCRATCH *) Ret.Value;=0D + SbiPlatform =3D (SBI_PLATFORM *) sbi_platform_ptr(ScratchSpace);=0D + *FirmwareContext =3D (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *) SbiPlatfor= m->firmware_context;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Set firmware context of the calling hart.=0D +=0D + @param[in] FirmwareContext The firmware context pointer.=0D + @retval EFI_SUCCESS The operation succeeds.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SbiSetFirmwareContext (=0D + IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext=0D + )=0D +{=0D + SBI_SCRATCH *ScratchSpace;=0D + SBI_PLATFORM *SbiPlatform;=0D + SbiRet Ret =3D SbiCall (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUNC, 0);=0D +=0D + if (!Ret.Error) {=0D + ScratchSpace =3D (SBI_SCRATCH *) Ret.Value;=0D + SbiPlatform =3D (SBI_PLATFORM *) sbi_platform_ptr(ScratchSpace);=0D + SbiPlatform->firmware_context =3D (UINTN) FirmwareContext;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D --=20 2.26.1