From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web11.408.1591116768062780247 for ; Tue, 02 Jun 2020 09:52:48 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: hpe.com, ip: 148.163.143.35, mailfrom: prvs=042218950f=daniel.schaefer@hpe.com) Received: from pps.filterd (m0134424.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 052GpglH029914; Tue, 2 Jun 2020 16:52:47 GMT Received: from g9t5008.houston.hpe.com (g9t5008.houston.hpe.com [15.241.48.72]) by mx0b-002e3701.pphosted.com with ESMTP id 31dtnd807k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 02 Jun 2020 16:52:47 +0000 Received: from G9W8454.americas.hpqcorp.net (exchangepmrr1.us.hpecorp.net [16.216.161.4]) (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 302EEC4; Tue, 2 Jun 2020 16:52:09 +0000 (UTC) Received: from G1W8107.americas.hpqcorp.net (2002:10c1:483b::10c1:483b) by G9W8454.americas.hpqcorp.net (2002:10d8:a104::10d8:a104) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 2 Jun 2020 16:52:08 +0000 Received: from NAM04-BN3-obe.outbound.protection.outlook.com (15.241.52.10) by G1W8107.americas.hpqcorp.net (16.193.72.59) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Tue, 2 Jun 2020 16:52:09 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FCKXJPDQ6M9nPPPwcVh7/zMXBHhABuFelaziwSkKR8MP/ImXnK5gLt8WNUdakuubr3F6NSVYUQsbsrno5y6OQZGSch8g4O1LiARWny4FkxPkR8oOFauF7WvauEjy71U/HZWky0km1u+EfMtaGRfRGF5Jqg47KaIif+mhMlXH4KRvK/VvnKeAh7Cf82xbcyva0UW2jzpxuU8ggIUGy2Il3VozMU9FFFzJsKbsziyJi0qSbLJmfB65/nmscM1IdYQSEStv5KvRb8gHupXpbxEc6oGKlyRQnJdWLOqkEXQLHfEaY2T9R5BYtzqJj++OB1tkKwVrbZfZTgkKzjkqokajdA== 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=Z8b60LqMH3BvdDUFG+fSN5hkJMxbLi43Oy9SH21VeSk=; b=KgEfNOgXbz9gznLN1TFJvMrC9VlDRFTV9sodyqgg88UQ45Oo2IC8h3eBDGfscRgQubtx4fMyL56FomQarUhKzteKSeahGdkogrN+UQmtmQe8kNpb3W0cRX47WN7+Q8mZJQTn52PeG2tTqwkLva7/g2KI9sUpAFklia7Wv6cH/nmKDwWhWozbRvgwXImKJIrkXdsBAn+7i8kQtm9yhpD6Civ39GxQBjid2zY7PcKigcIeszMTTKytQ/PrDJYelto9cYF9nwYghOg5V8Qge+7BHXB5ibXUaxI/oDNdaeW6o5q7n2W57hDvM5D0efjAVuCdBvbSC23AhXskQyYFv97nbw== 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 AT5PR8401MB0466.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:741f::10) by AT5PR8401MB0548.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:741d::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.22; Tue, 2 Jun 2020 16:52:06 +0000 Received: from AT5PR8401MB0466.NAMPRD84.PROD.OUTLOOK.COM ([fe80::70f2:6970:9f7e:6ab6]) by AT5PR8401MB0466.NAMPRD84.PROD.OUTLOOK.COM ([fe80::70f2:6970:9f7e:6ab6%10]) with mapi id 15.20.3066.018; Tue, 2 Jun 2020 16:52:06 +0000 From: "Daniel Schaefer" To: CC: Leif Lindholm , Gilbert Chen , Abner Chang , "Michael D . Kinney" Subject: [PATCH v4 1/1] ProcessorPkg/Library: Add RiscVEdk2SbiLib Date: Tue, 2 Jun 2020 18:51:52 +0200 Message-ID: <20200602165152.9823-2-daniel.schaefer@hpe.com> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200602165152.9823-1-daniel.schaefer@hpe.com> References: <20200602165152.9823-1-daniel.schaefer@hpe.com> X-ClientProxiedBy: SN6PR08CA0003.namprd08.prod.outlook.com (2603:10b6:805:66::16) To AT5PR8401MB0466.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:741f::10) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from x360-nix.fritz.box (93.215.222.127) by SN6PR08CA0003.namprd08.prod.outlook.com (2603:10b6:805:66::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3066.18 via Frontend Transport; Tue, 2 Jun 2020 16:52:03 +0000 X-Mailer: git-send-email 2.26.1 X-Originating-IP: [93.215.222.127] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: e40cfc48-1e29-4ddb-394b-08d8071547b1 X-MS-TrafficTypeDiagnostic: AT5PR8401MB0548: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6108; X-Forefront-PRVS: 0422860ED4 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7g535DQ815ebtrbq/NWo78nT6HO7vwfHxDgjuoUO6m2JxmAXT7oB5YLt/UYc2avnYrGVLxI8gaKzgC6ZBW/AslSLMwRh5eiEkr/KVhcm0mvQOw/7Q/BgcZfBlWEOZ/2ERe9BRG1BTfeKCCRreb4SJOwL1NdbEWuaRBObbqgwn1WeMW89BmyFkVJSup/3wjRIeL1GhwM4swIS967RdM4Cd6Qd8p33FTmz1qPxQfzmP/DgIFtyUW2h8pIowxtXFkDKykzcD/ZtVhrWRcNxAGp3TbMS+q/6Hfzull7gN7zEt9oGWGDcNXtfrFyUkDyUEkT23CSSKzMeTANZqEZoyUsiRA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AT5PR8401MB0466.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFTY:;SFS:(136003)(376002)(39860400002)(346002)(366004)(396003)(6512007)(83380400001)(54906003)(52116002)(478600001)(316002)(86362001)(8936002)(6486002)(4326008)(8676002)(1076003)(30864003)(66946007)(2616005)(26005)(66476007)(5660300002)(956004)(6506007)(66556008)(6916009)(44832011)(36756003)(2906002)(6666004)(186003)(16526019)(579004)(559001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: q7gutsn2wSP5MW5q/w16YisTgJqBwJqHeecWUbsnkiFiW4XEYfUNKCl8eGkKuexILDXPacgH3sl1s3DSD9rGshiG4hcT2kXhzQgJLqYzyLDQiDwd0bFBOl/ovLC3BooSTORmSjtFwKZUo7EMQ0g3MVM9AeD7DFYvbg/fowJUjKbxfcgBS+lAFakWmDgPaD4ynnhrWXsNSOMqfahGJFQ+jzXmIm1mIIsu/vtwzjTVAouw22b2wi9Poa0U95titm6MneAUVIw0xJI7tpGg93FYkG18wvBv8aHI8X+n+Oh05QkykSaIKylxqZfS6/0qKOQn3ScRscPUB9P86kOXdipwm4kq9wUQKoXPT7sEXpLTOTMCCCuD+LVol7tH8Tuwfhkx11WwWA+mn2hGcheNQ9CRDdS4tGlLTJOG792RG6qXZ0PadxT0EZkJuFZgBlSBid0UedZQ2pRfWxkKho3X48qujFJOZ3zWCXC7eOIk+ksTLb4pszJBqFoBhMFInUqIbfCO X-MS-Exchange-CrossTenant-Network-Message-Id: e40cfc48-1e29-4ddb-394b-08d8071547b1 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Jun 2020 16:52:05.7706 (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: O23zCz27MDUbMcnC4oL319weg+7AG7TymZwJIyoUO09oLqPAQHT994EooDPM5NPs5StFwrVAHgBxY53UnXWmgA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AT5PR8401MB0548 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-06-02_13:2020-06-02,2020-06-02 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 cotscore=-2147483648 lowpriorityscore=0 priorityscore=1501 clxscore=1015 impostorscore=0 bulkscore=0 malwarescore=0 mlxscore=0 suspectscore=4 spamscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2006020120 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 | = 897 ++++++++++++++++++++ 3 files changed, 1488 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..0df505d2675b --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c @@ -0,0 +1,897 @@ +/** @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 + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D + @par Revision Reference:=0D + - OpenSBI Version 0.6=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +=0D +//=0D +// Maximum arguments for SBI ecall=0D +// It's possible to pass more but no SBI call uses more as of SBI 0.2.=0D +// The additional arguments would have to be passed on the stack instead o= f as=0D +// registers, like it's done now.=0D +//=0D +#define SBI_CALL_MAX_ARGS 6=0D +=0D +/**=0D + Call SBI call using ecall instruction.=0D +=0D + Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.=0D +=0D + @param[in] ExtId SBI extension ID.=0D + @param[in] FuncId SBI function ID.=0D + @param[in] NumArgs 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 +{=0D + UINTN I;=0D + SbiRet Ret;=0D + UINTN Args[SBI_CALL_MAX_ARGS];=0D + VA_LIST ArgList;=0D + VA_START (ArgList, NumArgs);=0D +=0D + ASSERT (NumArgs <=3D SBI_CALL_MAX_ARGS);=0D +=0D + for (I =3D 0; I < SBI_CALL_MAX_ARGS; 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 +{=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 library 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 (=0D + SBI_EXT_HSM,=0D + SBI_EXT_HSM_HART_START,=0D + 3,=0D + HartId,=0D + StartAddr,=0D + Priv=0D + );=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 (=0D + SBI_EXT_IPI,=0D + SBI_EXT_IPI_SEND_IPI,=0D + 2,=0D + (UINTN)HartMask,=0D + HartMaskBase=0D + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_FENCE_I,=0D + 2,=0D + (UINTN)HartMask,=0D + HartMaskBase=0D + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,=0D + 4,=0D + (UINTN)HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size=0D + );=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 (=0D + 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 + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA,=0D + 5,=0D + (UINTN)HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size,=0D + Vmid=0D + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID,=0D + 4,=0D + (UINTN)HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size=0D + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA,=0D + 5,=0D + (UINTN)HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size,=0D + Asid=0D + );=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 (=0D + SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID,=0D + 4,=0D + (UINTN)HartMask,=0D + HartMaskBase,=0D + StartAddr,=0D + Size=0D + );=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 or NumArgs exceeds SBI_CALL_MAX_ARGS.=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 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 SBI_EXT_VENDOR_START && ExtensionId <=3D SBI_= EXT_VENDOR_END);=0D + ASSERT (NumArgs <=3D SBI_CALL_MAX_ARGS);=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, U= INTN));=0D + break;=0D + case 2:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG (Args, U= INTN),=0D + VA_ARG (Args, UINTN));=0D + break;=0D + case 3:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG (Args, U= INTN),=0D + VA_ARG (Args, UINTN), VA_ARG (Args, UINTN));=0D + break;=0D + case 4:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG (Args, U= INTN),=0D + VA_ARG (Args, UINTN), VA_ARG (Args, UINTN),=0D + VA_ARG (Args, UINTN));=0D + break;=0D + case 5:=0D + Ret =3D SbiCall (ExtensionId, FunctionId, NumArgs, VA_ARG (Args, U= INTN),=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, U= INTN),=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 (=0D + SBI_EDK2_FW_EXT,=0D + SBI_EXT_FW_MSCRATCH_HARTID_FUNC,=0D + 1,=0D + HartId=0D + );=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 *)SbiPlatform= ->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