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.web12.13333.1589550000658377494 for ; Fri, 15 May 2020 06:40:00 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: hpe.com, ip: 148.163.143.35, mailfrom: prvs=04045502dd=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 04FDbO1Z002134; Fri, 15 May 2020 13:40:00 GMT Received: from g9t5009.houston.hpe.com (g9t5009.houston.hpe.com [15.241.48.73]) by mx0b-002e3701.pphosted.com with ESMTP id 310yxpn4fy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 15 May 2020 13:39:59 +0000 Received: from G4W9119.americas.hpqcorp.net (g4w9119.houston.hp.com [16.210.20.214]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g9t5009.houston.hpe.com (Postfix) with ESMTPS id 4F1B651; Fri, 15 May 2020 13:39:59 +0000 (UTC) Received: from G9W8456.americas.hpqcorp.net (2002:10d8:a15f::10d8:a15f) by G4W9119.americas.hpqcorp.net (2002:10d2:14d6::10d2:14d6) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 15 May 2020 13:39:58 +0000 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (15.241.52.13) by G9W8456.americas.hpqcorp.net (16.216.161.95) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Fri, 15 May 2020 13:39:58 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oO9XbvhFa4yj8izCozaaMOn7Isga+4Us5tEe+MlBgvx4EbgIa3WDkmZUL/5Qc9j8P7WE9EkhcTDQLxo5yNtBp9KVPwau/KQDuYJ9+nacaqlaldsHspNrKy+BrwlqSQMlRWwU8GMXTSJ5JxL++2WgnSN3o9JMeuRawR5Ci6hXtWo9YbZk4iSNDs0NNFQfX5uK473uNRkmbUnbUbyR7i3L34wL8sHN1fELzrNU+4qV5Ak4CRNnn8lM6yNU/tAN+4fdbtBv+ugXKjRGbzMLznefxc4780yqhcCE6mIs+w40KREGmfrDwTA0Mgd0uxb/VGBczdiHEJ653egk74zMv2R6Bg== 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=GNlSeqjXGOBwnm5hZ1ss2ft83D84Wz1znh4BelWqAPE=; b=lyIcaAFysbtlhhWCsxAZFmoXBotAVLOhRfhU/e7eGw37PtxjH97f9bidTE9LUc42gfzMnGkm0B9MDTbrPl/D9TA3m8bb4gYXKk9Bqb8W7Bd/OtbgOQXk0Ma4DB4nOyYortDYyl5nqd3gh6u0eLWZERc7RpuDNZIUcU4CxbB0Llh0psZEDtnwvEnKKzW4swUSbRyoFnzajXw3oFr+XosIiC+GLBtL87lMOIwtW6tzoekWjOCbVQlmj2X5IuoMnavjNkmZ3StODxcxbR1kYQgm8PfkIgwn06XQbJpWrXNFeLI5nolbZVaRqorymeuqb3FeNkWj0OzqHUQbovolCe7jPA== 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 CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:750c::23) by CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:750c::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3000.20; Fri, 15 May 2020 13:39:56 +0000 Received: from CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM ([fe80::6d01:dcc0:65e:ef77]) by CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM ([fe80::6d01:dcc0:65e:ef77%7]) with mapi id 15.20.3000.022; Fri, 15 May 2020 13:39:56 +0000 From: "Daniel Schaefer" To: CC: Abner Chang , Gilbert Chen , Michael D Kinney , Leif Lindholm Subject: [PATCH v2 3/3] ProcessorPkg/Library: Add RiscVEdk2SbiLib Date: Fri, 15 May 2020 15:39:37 +0200 Message-ID: <20200515133937.29909-4-daniel.schaefer@hpe.com> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200515133937.29909-1-daniel.schaefer@hpe.com> References: <20200515133937.29909-1-daniel.schaefer@hpe.com> X-ClientProxiedBy: AM0P190CA0007.EURP190.PROD.OUTLOOK.COM (2603:10a6:208:190::17) To CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:750c::23) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from x360-nix.fritz.box (93.215.201.203) by AM0P190CA0007.EURP190.PROD.OUTLOOK.COM (2603:10a6:208:190::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3000.20 via Frontend Transport; Fri, 15 May 2020 13:39:54 +0000 X-Mailer: git-send-email 2.26.1 X-Originating-IP: [93.215.201.203] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 2842a954-5da3-4c28-4931-08d7f8d57419 X-MS-TrafficTypeDiagnostic: CS1PR8401MB0726: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:4941; X-Forefront-PRVS: 04041A2886 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: kzKoVb15FF4OpzXVDsPHIGPNoBHZss5yaXT+I3A94raSfJFE/Xm6ygy4mhXDdWUxxKuS+aVvc0sHt/Rr5GeLSDWGCBCOPqvrmaQzTxPjT0qsRh0NuLddg8bCEiKu5cbb+3FMw6fu/K0Ssco65Ch9x7QOeG7dzdJzg4/cKb7iVLunQS9jA8FNCJQLo32cr6YejWycdNgzhPsNJEPqVTmIaUu/X4viulHgdwPWBNzotCyMnVOKsknbInAfdacPwG04QqDubKyvJxyABY0vxPYOp1+SUmoMFvPooO//yekPU7n1bKTBgV/ts0bSJQkNUY2hGflyqSnOLU+jr27cUFZGOFxBZ5CYT+rQingAiwYpOK01okZYWmlZ1XmmizB3POC9m+VhGO11zWfScJzX163+2hluw1Lw+2Ebislx6f+lzbdUOCEGGlB7xQZ0Cq4HHiJn X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CS1PR8401MB0726.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFTY:;SFS:(376002)(396003)(346002)(366004)(39860400002)(136003)(5660300002)(2906002)(6666004)(478600001)(54906003)(316002)(1076003)(30864003)(6916009)(956004)(36756003)(6506007)(6486002)(52116002)(16526019)(86362001)(26005)(2616005)(186003)(6512007)(8936002)(4326008)(66556008)(66946007)(44832011)(8676002)(66476007)(559001)(579004);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: tqgPeJRrGK50ffIZg7cVf0uzOB+Y7wV2nQOZxiRaVpC3vtgJ87zydJVSzFjXedZkAJkO/KsBdxyWZoGzK3duVXFHUhJE5dwVSpR24R5Dwk2Uy7EISnqIHG7AidrrJOubL9OD0a8YF578E3D6HqTYyRb+uMb+m0MRe0S5RdVlKMr2Zw/M+4r8X4hYNlQwepmb0/wu9P+u8a53pKysRx6/WucHEF24GfmDTD2sibI5Noc2flZYkME4IoJnru3XP/DB0HMZ9anNkA+aPHyG0BJNTmae1dPa6QLwcFVgK2IYGwwFk11SnF/sz1RZTRo1h3xdSIxECrcBFa91WUOVzFSWzB+8gfkznWGiWCk4wntf2Lx5AC6+2Wv8plEbv2rCD0PeztJTOGQsFI/z9YFfr5OO4HJRFXvBw460bAVz/iCwn2msmJbdsr7IFCN5Z8af2BhE5/QMj3VrFjuT9zMuhxvEt5+efcSlBjyU4vdSIUk7TQxxEoGwvwJlgKJwONQqC/ov X-MS-Exchange-CrossTenant-Network-Message-Id: 2842a954-5da3-4c28-4931-08d7f8d57419 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2020 13:39:55.9139 (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: XRnWdIVnVa8JqRBv+PgZy9qWQmLjacdr7sp0vyffKRfaMzLZX0obogNYpHUuySWPE0ApYojiVco3aRt/ZMA2/w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CS1PR8401MB0726 X-OriginatorOrg: hpe.com X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-15_05:2020-05-15,2020-05-15 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 phishscore=0 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 adultscore=0 bulkscore=0 impostorscore=0 clxscore=1015 suspectscore=4 priorityscore=1501 cotscore=-2147483648 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005150117 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain Library provides interfaces to invoke SBI extensions. Signed-off-by: Daniel Schaefer Cc: Abner Chang Cc: Gilbert Chen Cc: Michael D Kinney Cc: Leif Lindholm --- Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf | = 28 + Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h | = 43 +- Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h | = 631 ++++++++++++++++ Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c | = 789 ++++++++++++++++++++ 4 files changed, 1466 insertions(+), 25 deletions(-) diff --git a/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/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/IndustryStandard/RiscVOpen= sbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h index c5c0bd6d9b01..18a85e2238d2 100644 --- a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h @@ -10,42 +10,35 @@ #ifndef EDK2_SBI_H_=0D #define EDK2_SBI_H_=0D =0D -#include // Reference to header file in opensbi= =0D #include =0D +#include // Reference to header file in opensbi=0D +#include =0D +#include =0D #include // Reference to header file wrapper=0D =0D -#define SBI_SUCCESS 0=0D -#define SBI_ERR_FAILED -1=0D -#define SBI_ERR_NOT_SUPPORTED -2=0D -#define SBI_ERR_INVALID_PARAM -3=0D -#define SBI_ERR_DENIED -4=0D -#define SBI_ERR_INVALID_ADDRESS -5=0D -#define SBI_ERR_ALREADY_AVAILABLE -6=0D +// Translation from OpenSBI constants to SBI names=0D +#define SBI_SUCCESS SBI_OK=0D +#define SBI_ERR_FAILED SBI_EFAIL=0D +#define SBI_ERR_NOT_SUPPORTED SBI_ENOTSUPP=0D +#define SBI_ERR_INVALID_PARAM SBI_EINVAL=0D +#define SBI_ERR_DENIED SBI_DENIED=0D +#define SBI_ERR_INVALID_ADDRESS SBI_INVALID_ADDR=0D +#define SBI_ERR_ALREADY_AVAILABLE -6=0D =0D -#define SBI_BASE_EXT 0x10=0D -#define SBI_HSM_EXT 0x48534D=0D -#define SBI_TIME_EXT 0x54494D45=0D -#define SBI_IPI_EXT 0x735049=0D -#define SBI_RFNC_EXT 0x52464E43=0D +// Included in OpenSBI 0.7=0D +// Can be removed, once we upgrade=0D +#define SBI_EXT_HSM 0x48534D=0D +#define SBI_EXT_HSM_HART_START 0x0=0D +#define SBI_EXT_HSM_HART_STOP 0x1=0D +#define SBI_EXT_HSM_HART_GET_STATUS 0x2=0D =0D //=0D // Below two definitions should be defined in OpenSBI.=0D +// Submitted to upstream, waiting for merge and release.=0D //=0D #define SBI_EXT_FIRMWARE_CODE_BASE_START 0x0A000000=0D #define SBI_EXT_FIRMWARE_CODE_BASE_END 0x0AFFFFFF=0D =0D -#define SBI_GET_SPEC_VERSION_FUNC 0=0D -#define SBI_GET_IMPL_ID_FUNC 1=0D -#define SBI_GET_IMPL_VERSION_FUNC 2=0D -#define SBI_PROBE_EXTENSION_FUNC 3=0D -#define SBI_GET_MVENDORID_FUNC 4=0D -#define SBI_GET_MARCHID_FUNC 5=0D -#define SBI_GET_MIMPID_FUNC 6=0D -=0D -#define SBI_HART_START_FUNC 0=0D -#define SBI_HART_STOP_FUNC 1=0D -#define SBI_HART_GET_STATUS_FUNC 2=0D -=0D #define RISC_V_MAX_HART_SUPPORTED 16=0D =0D typedef=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..cf77814e3bbc --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Include/Library/RiscVEdk2SbiLib.h @@ -0,0 +1,631 @@ +/** @file Defines the PPIs to let PEIMs call SBI=0D +=0D +Copyright (c) 2020, Hewlett Packard Development LP. All rights reserved.=0D +=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=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 +struct sbiret {=0D + long error; ///< SBI status code=0D + long value; ///< Value returned=0D +};=0D +=0D +#define SbiCall0(ext_id, func_id) \=0D + SbiCall(ext_id, func_id, 0, 0, 0, 0, 0, 0)=0D +#define SbiCall1(ext_id, func_id, arg0) \=0D + SbiCall(ext_id, func_id, arg0, 0, 0, 0, 0, 0)=0D +#define SbiCall2(ext_id, func_id, arg0, arg1) \=0D + SbiCall(ext_id, func_id, arg0, arg1, 0, 0, 0, 0)=0D +#define SbiCall3(ext_id, func_id, arg0, arg1, arg2) \=0D + SbiCall(ext_id, func_id, arg0, arg1, arg2, 0, 0, 0)=0D +#define SbiCall4(ext_id, func_id, arg0, arg1, arg2, arg3) \=0D + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, 0, 0)=0D +#define SbiCall5(ext_id, func_id, arg0, arg1, arg2, arg3, arg4) \=0D + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, 0)=0D +#define SbiCall6(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5) \=0D + SbiCall(ext_id, func_id, arg0, arg1, arg2, arg3, arg4, arg5)=0D +=0D +/**=0D + EDK2 SbiCall to invoke SBI extensions.=0D +=0D + @param[in] ext_id Sbi extension ID.=0D + @param[in] func_id Sbi functions ID.=0D + @param[in] arg0 Arg0 to function.=0D + @param[in] arg1 Arg1 to function.=0D + @param[in] arg2 Arg2 to function.=0D + @param[in] arg3 Arg3 to function.=0D + @param[in] arg4 Arg4 to function.=0D + @param[in] arg5 Arg5 to function.=0D +=0D + @retval Returns sbiret structure.=0D +=0D +**/=0D +inline=0D +EFIAPI=0D +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1,= =0D + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5)= =0D +__attribute__((always_inline));=0D +=0D +/**=0D + EDK2 SbiCall to invoke SBI extensions.=0D +=0D + @param[in] ext_id Sbi extension ID.=0D + @param[in] func_id Sbi functions ID.=0D + @param[in] arg0 Arg0 to function.=0D + @param[in] arg1 Arg1 to function.=0D + @param[in] arg2 Arg2 to function.=0D + @param[in] arg3 Arg3 to function.=0D + @param[in] arg4 Arg4 to function.=0D + @param[in] arg5 Arg5 to function.=0D +=0D + @retval Returns sbiret structure.=0D +=0D +**/=0D +inline=0D +EFIAPI=0D +struct sbiret SbiCall(UINTN ext_id, UINTN func_id, UINTN arg0, UINTN arg1,= =0D + UINTN arg2, UINTN arg3, UINTN arg4, UINTN arg5)= {=0D + register uintptr_t a0 asm ("a0") =3D (uintptr_t)(arg0);=0D + register uintptr_t a1 asm ("a1") =3D (uintptr_t)(arg1);=0D + register uintptr_t a2 asm ("a2") =3D (uintptr_t)(arg2);=0D + register uintptr_t a3 asm ("a3") =3D (uintptr_t)(arg3);=0D + register uintptr_t a4 asm ("a4") =3D (uintptr_t)(arg4);=0D + register uintptr_t a5 asm ("a5") =3D (uintptr_t)(arg5);=0D + register uintptr_t a6 asm ("a6") =3D (uintptr_t)(func_id);=0D + register uintptr_t a7 asm ("a7") =3D (uintptr_t)(ext_id);=0D + asm volatile ("ecall" \=0D + : "+r" (a0) \=0D + : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r"= (a7) \=0D + : "memory"); \=0D + struct sbiret ret =3D { a0, a1 };=0D + return ret;=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 +/**=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] MvendorId The CPU's vendor ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMvendorId (=0D + OUT UINTN *MvendorId=0D + );=0D +=0D +/**=0D + Get the CPU's architecture ID=0D +=0D + Reads the marchid CSR.=0D +=0D + @param[out] MarchId The CPU's architecture ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMarchId (=0D + OUT UINTN *MarchId=0D + );=0D +=0D +/**=0D + Get the CPU's implementation ID=0D +=0D + Reads the mimpid CSR.=0D +=0D + @param[out] MimpId The CPU's implementation ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMimpId (=0D + OUT UINTN *Mimpid=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 Sti= meValue.=0D +=0D + To clear the timer without scheduling a timer event, set StimeValue to a= =0D + practically infinite value or mask the timer interrupt by clearing sie.S= TIE.=0D +=0D + @param[in] StimeValue The time offset to the next scheduled t= imer interrupt.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiSetTimer (=0D + IN UINT64 StimeValue=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 struct 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 struct 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..bbe006a78af8 --- /dev/null +++ b/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.c @@ -0,0 +1,789 @@ +/** @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 +#include =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 +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 + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERS= ION);=0D +=0D + if (!ret.error) {=0D + *SpecVersion =3D (UINTN) ret.value;=0D + }=0D +=0D + //return TranslateError(ret.error);=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 + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID);= =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 + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSI= ON);=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 + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT);=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] MvendorId The CPU's vendor ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMvendorId (=0D + OUT UINTN *MvendorId=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MVENDORID= );=0D + *MvendorId =3D (UINTN) ret.value;=0D +}=0D +=0D +/**=0D + Get the CPU's vendor ID=0D +=0D + Reads the mvendorid CSR.=0D +=0D + @param[out] MvendorId The CPU's vendor ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMarchId (=0D + OUT UINTN *MarchId=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MARCHID);= =0D + *MarchId =3D (UINTN) ret.value;=0D +}=0D +=0D +/**=0D + Get the CPU's architecture ID=0D +=0D + Reads the marchid CSR.=0D +=0D + @param[out] MarchId The CPU's architecture ID.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiGetMimpId (=0D + OUT UINTN *MimpId=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall0 (SBI_EXT_BASE, SBI_EXT_BASE_GET_MIMPID);= =0D + *MimpId =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 + struct sbiret ret =3D SbiCall3 (SBI_EXT_HSM,=0D + SBI_EXT_HSM_HART_START,=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 + struct sbiret Ret =3D SbiCall0 (SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP);=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 + struct sbiret ret =3D SbiCall1 (SBI_EXT_HSM, SBI_EXT_HSM_HART_GET_STATUS= , HartId);=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 Sti= meValue.=0D +=0D + To clear the timer without scheduling a timer event, set StimeValue to a= =0D + practically infinite value or mask the timer interrupt by clearing sie.S= TIE.=0D +=0D + @param[in] StimeValue The time offset to the next scheduled t= imer interrupt.=0D +**/=0D +VOID=0D +EFIAPI=0D +SbiSetTimer (=0D + IN UINT64 StimeValue=0D + )=0D +{=0D + SbiCall1 (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, StimeValue);=0D +}=0D +=0D +EFI_STATUS=0D +EFIAPI=0D +SbiSendIpi (=0D + IN UINTN *HartMask,=0D + IN UINTN HartMaskBase=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall2 (SBI_EXT_IPI,=0D + SBI_EXT_IPI_SEND_IPI,=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 + struct sbiret ret =3D SbiCall2 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_FENCE_I,=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 + struct sbiret ret =3D SbiCall4 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,=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 + struct sbiret ret =3D SbiCall5 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID,=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 + struct sbiret ret =3D SbiCall5 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA,=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 + struct sbiret ret =3D SbiCall4 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID,=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 + struct sbiret ret =3D SbiCall5 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA,=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 + struct sbiret ret =3D SbiCall4 (SBI_EXT_RFENCE,=0D + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID,=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 + struct 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 SbiCall0 (ExtensionId, FunctionId);=0D + break;=0D + case 1:=0D + ret =3D SbiCall1 (ExtensionId, FunctionId, VA_ARG(Args, UINTN));=0D + break;=0D + case 2:=0D + ret =3D SbiCall2 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA= _ARG(Args, UINTN));=0D + break;=0D + case 3:=0D + ret =3D SbiCall3 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA= _ARG(Args, UINTN), VA_ARG(Args, UINTN));=0D + break;=0D + case 4:=0D + ret =3D SbiCall4 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA= _ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN));=0D + break;=0D + case 5:=0D + ret =3D SbiCall5 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA= _ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, U= INTN));=0D + break;=0D + case 6:=0D + ret =3D SbiCall6 (ExtensionId, FunctionId, VA_ARG(Args, UINTN), VA= _ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, UINTN), VA_ARG(Args, U= INTN), 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 struct sbi_scratch **ScratchSpace=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUN= C);=0D +=0D + if (!ret.error) {=0D + *ScratchSpace =3D (struct 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 struct sbi_scratch **ScratchSpace=0D + )=0D +{=0D + struct sbiret ret =3D SbiCall1 (SBI_EDK2_FW_EXT,=0D + SBI_EXT_FW_MSCRATCH_HARTID_FUNC,=0D + HartId);=0D +=0D + if (!ret.error) {=0D + *ScratchSpace =3D (struct 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 + struct sbi_scratch *ScratchSpace;=0D + struct sbi_platform *SbiPlatform;=0D + struct sbiret ret =3D SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUN= C);=0D +=0D + if (!ret.error) {=0D + ScratchSpace =3D (struct sbi_scratch *) ret.value;=0D + SbiPlatform =3D (struct 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 + struct sbi_scratch *ScratchSpace;=0D + struct sbi_platform *SbiPlatform;=0D + struct sbiret ret =3D SbiCall0 (SBI_EDK2_FW_EXT, SBI_EXT_FW_MSCRATCH_FUN= C);=0D +=0D + if (!ret.error) {=0D + ScratchSpace =3D (struct sbi_scratch *) ret.value;=0D + SbiPlatform =3D (struct sbi_platform *) sbi_platform_ptr(ScratchSpace)= ;=0D + SbiPlatform->firmware_context =3D (long unsigned int) FirmwareContext;= =0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D --=20 2.26.1