From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by mx.groups.io with SMTP id smtpd.web10.4791.1670470537621460876 for ; Wed, 07 Dec 2022 19:35:38 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@canonical.com header.s=20210705 header.b=wXk3Oy5u; spf=pass (domain: canonical.com, ip: 185.125.188.122, mailfrom: heinrich.schuchardt@canonical.com) Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 960A044338 for ; Thu, 8 Dec 2022 03:35:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1670470535; bh=CdALw+nNN1yViG14Kkt3tx7nISknay50lFyyeVRW/Y4=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=wXk3Oy5ul4MmZL2bd9ANOThkue8pfdkslMcHVm+qTyJbb+0+vPqAigD03Q1qFxZwy vX4j/tSLAnWsB9T/KdxAWgJT9rxorkWei1yqUDtC8MOl5w8am1hVWwN+jHpAxaI/hQ SxXgA+W7KmGb2ba4WP4+QkaSiHEgmb5g7bRXQx2VsNBv1imGY49CRcdPPznBS3avHW 5o/UEivU27J4p1fuD1fb9/9ERk/Mp85S9jnq7r/soUIoAkPR24roEABxTvtznhzuhL Z+F/TZrxwEvVyvP/WjCZ5jxoFYkVJe2B+GbFobYre6Gee1lXVuh3WXN4olgMo7eLyY UgZVSsi3iKnqA== Received: by mail-ej1-f69.google.com with SMTP id hs18-20020a1709073e9200b007c0f9ac75f9so255750ejc.9 for ; Wed, 07 Dec 2022 19:35:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=CdALw+nNN1yViG14Kkt3tx7nISknay50lFyyeVRW/Y4=; b=UIi+DflSMm3+PTFr0gTdTWEY7sA6tcl4n0Kz/Z0V51fY6YlZ4ms/H+NWE6DA+FDlp5 H+ngoqJ9SzPshYf58bYNGZccKklm+j4fXLdVQvx6LHJBEvPbBQoxOBKl5K0WcIkVVlPw wcwOIFVGfF1r3joeSUK9PClEV1pHg+qoIlP370UChCWYBFYvRaOC1BlR0XEVJO497XtT rNrrUUCFhuPiHjegCIOGKrGZoqbCQ97NHWv+etuzT7Whu2CgDvUmiFV9K9Qw54SlIEc0 2CMtpRjcrbGNVQGbbza4rmgqr1Ft3C3F0I9trnTZBK29SpqQWvop8/+zIBhTNWS62LNx cnbQ== X-Gm-Message-State: ANoB5pnzxAFa+anIhKXnI/3NXT4iuUDDfmKFJCnmVJfiFDZh3uZ2q9RY XpLg7WY1mshQ86ef7bmTrGKonrR/EkvDs/En9QyUotF4yy3OR1vPiS4EUi/KAPh0DyjBDzMNWnE LrTd44Ll0dd1uKRbaD47WZjBiCBnbChk= X-Received: by 2002:a17:906:52cd:b0:7c0:f212:46fc with SMTP id w13-20020a17090652cd00b007c0f21246fcmr13322226ejn.214.1670466156541; Wed, 07 Dec 2022 18:22:36 -0800 (PST) X-Google-Smtp-Source: AA0mqf4AZHv3p7GKzJCJssYTT7LDCx6wE2vUnMY3z9VTOGFUA+l4CHcQ+MnkY0TWfvLzRbXLZv1hEw== X-Received: by 2002:a17:906:52cd:b0:7c0:f212:46fc with SMTP id w13-20020a17090652cd00b007c0f21246fcmr13322218ejn.214.1670466156213; Wed, 07 Dec 2022 18:22:36 -0800 (PST) Received: from [192.168.123.94] (ip-088-152-145-137.um26.pools.vodafone-ip.de. [88.152.145.137]) by smtp.gmail.com with ESMTPSA id c9-20020a170906762900b007be3aa82543sm9117103ejn.35.2022.12.07.18.22.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 07 Dec 2022 18:22:35 -0800 (PST) Message-ID: <450829ba-d883-8ca0-c120-2e23820a3d42@canonical.com> Date: Thu, 8 Dec 2022 03:22:34 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.1 Subject: Re: [RFC PATCH V2 08/19] MdePkg: Add RiscVSbiLib Library for RISC-V To: Sunil V L Cc: Jian J Wang , Liming Gao , Eric Dong , Ray Ni , Rahul Kumar , Debkumar De , Catharine West , Daniel Schaefer , Abner Chang , Leif Lindholm , Andrew Fish , Ard Biesheuvel , Anup Patel , devel@edk2.groups.io References: <20220907113626.540065-1-sunilvl@ventanamicro.com> <20220907113626.540065-9-sunilvl@ventanamicro.com> From: Heinrich Schuchardt In-Reply-To: <20220907113626.540065-9-sunilvl@ventanamicro.com> Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 9/7/22 13:36, Sunil V L wrote: > This library is required to make SBI ecalls from the S-mode EDK2. > > Signed-off-by: Sunil V L > --- > MdePkg/Library/RiscVSbiLib/RiscVSbiLib.inf | 27 +++ > MdePkg/Include/Library/RiscVSbiLib.h | 129 +++++++++++ > MdePkg/Library/RiscVSbiLib/RiscVSbiLib.c | 228 ++++++++++++++++++++ > 3 files changed, 384 insertions(+) > > diff --git a/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.inf b/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.inf > new file mode 100644 > index 000000000000..a621243a1a99 > --- /dev/null > +++ b/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.inf > @@ -0,0 +1,27 @@ > +## @file > +# RISC-V Library to call SBI ecalls > +# > +# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
> +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001b > + BASE_NAME = RiscVSbiLib > + FILE_GUID = D742CF3D-E600-4009-8FB5-318073008508 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = RiscVSbiLib > + > +[Sources] > + RiscVSbiLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + > +[LibraryClasses] > + BaseLib > diff --git a/MdePkg/Include/Library/RiscVSbiLib.h b/MdePkg/Include/Library/RiscVSbiLib.h > new file mode 100644 > index 000000000000..e94adb08fd40 > --- /dev/null > +++ b/MdePkg/Include/Library/RiscVSbiLib.h > @@ -0,0 +1,129 @@ > +/** @file > + Library to call the RISC-V SBI ecalls > + > + Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.
> + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + @par Glossary: > + - Hart - Hardware Thread, similar to a CPU core > + > + Currently, EDK2 needs to call SBI only to set the time and to do system reset. > + > +**/ > + > +#ifndef RISCV_SBI_LIB_H_ > +#define RISCV_SBI_LIB_H_ > + > +#include > + > +/* SBI Extension IDs */ > +#define SBI_EXT_TIME 0x54494D45 > +#define SBI_EXT_SRST 0x53525354 > + > +/* SBI function IDs for TIME extension*/ > +#define SBI_EXT_TIME_SET_TIMER 0x0 > + > +/* SBI function IDs for SRST extension */ > +#define SBI_EXT_SRST_RESET 0x0 > + > +#define SBI_SRST_RESET_TYPE_SHUTDOWN 0x0 > +#define SBI_SRST_RESET_TYPE_COLD_REBOOT 0x1 > +#define SBI_SRST_RESET_TYPE_WARM_REBOOT 0x2 > +#define SBI_SRST_RESET_TYPE_LAST SBI_SRST_RESET_TYPE_WARM_REBOOT I cannot see that SBI_SRST_RESET_TYPE_LAST will ever be used in EDK II. The highest allowed value for a reset type in the current SBI standard is 0xFFFFFFFF. > + > +#define SBI_SRST_RESET_REASON_NONE 0x0 > +#define SBI_SRST_RESET_REASON_SYSFAIL 0x1 > + > +/* SBI return error codes */ > +#define SBI_SUCCESS 0 > +#define SBI_ERR_FAILED -1 > +#define SBI_ERR_NOT_SUPPORTED -2 > +#define SBI_ERR_INVALID_PARAM -3 > +#define SBI_ERR_DENIED -4 > +#define SBI_ERR_INVALID_ADDRESS -5 > +#define SBI_ERR_ALREADY_AVAILABLE -6 > +#define SBI_ERR_ALREADY_STARTED -7 > +#define SBI_ERR_ALREADY_STOPPED -8 > + > +#define SBI_LAST_ERR SBI_ERR_ALREADY_STOPPED > + > +typedef struct { > + UINT64 BootHartId; > + VOID *PeiServiceTable; // PEI Service table > + UINT64 FlattenedDeviceTree; // Pointer to Flattened Device tree > +} EFI_RISCV_FIRMWARE_CONTEXT; > + > + > +// > +// EDK2 OpenSBI firmware extension return status. > +// > +typedef struct { > + UINTN Error; ///< SBI status code > + UINTN Value; ///< Value returned > +} SBI_RET; > + > +VOID > +EFIAPI > +SbiSetTimer ( > + IN UINT64 Time > + ); > + > +EFI_STATUS > +EFIAPI > +SbiSystemReset ( > + IN UINTN ResetType, > + IN UINTN ResetReason > + ); > + > +/** > + Get firmware context of the calling hart. > + > + @param[out] FirmwareContext The firmware context pointer. > +**/ > +VOID > +EFIAPI > +GetFirmwareContext ( > + OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContext > + ); > + > +/** > + Set firmware context of the calling hart. > + > + @param[in] FirmwareContext The firmware context pointer. > +**/ > +VOID > +EFIAPI > +SetFirmwareContext ( > + IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext > + ); > + > +/** > + Get pointer to OpenSBI Firmware Context > + > + Get the pointer of firmware context. > + > + @param FirmwareContextPtr Pointer to retrieve pointer to the > + Firmware Context. > +**/ > +VOID > +EFIAPI > +GetFirmwareContextPointer ( > + IN OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContextPtr > + ); > + > +/** > + Set pointer to OpenSBI Firmware Context > + > + Set the pointer of firmware context. > + > + @param FirmwareContextPtr Pointer to Firmware Context. > +**/ > +VOID > +EFIAPI > +SetFirmwareContextPointer ( > + IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContextPtr > + ); > + > +#endif > diff --git a/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.c b/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.c > new file mode 100644 > index 000000000000..39cc6628be6c > --- /dev/null > +++ b/MdePkg/Library/RiscVSbiLib/RiscVSbiLib.c > @@ -0,0 +1,228 @@ > +/** @file > + Instance of the SBI ecall library. > + > + It allows calling an SBI function via an ecall from S-Mode. > + > + Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.
> + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > + > +// > +// Maximum arguments for SBI ecall > +// It's possible to pass more but no SBI call uses more as of SBI 0.2. SBI 0.2 is obsolete. It was never ratified. > +// The additional arguments would have to be passed on the stack instead of as > +// registers, like it's done now. > +// > +#define SBI_CALL_MAX_ARGS 6 > + > +/** > + Call SBI call using ecall instruction. > + > + Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS. > + > + @param[in] ExtId SBI extension ID. > + @param[in] FuncId SBI function ID. > + @param[in] NumArgs Number of arguments to pass to the ecall. > + @param[in] ... Argument list for the ecall. > + > + @retval Returns SBI_RET structure with value and error code. > + > +**/ > +STATIC > +SBI_RET > +EFIAPI > +SbiCall ( > + IN UINTN ExtId, > + IN UINTN FuncId, > + IN UINTN NumArgs, > + ... > + ) > +{ > + UINTN I; > + SBI_RET Ret; > + UINTN Args[SBI_CALL_MAX_ARGS]; > + VA_LIST ArgList; > + > + VA_START (ArgList, NumArgs); > + > + ASSERT (NumArgs <= SBI_CALL_MAX_ARGS); ASSERT is nice for a debug build but not helpful for a release version. Please, return SBI_ERR_INVALID_PARAM in case NumArgs is too big and don't execute the ecall. VA_START() should be called after check. Best regards Heinrich > + > + for (I = 0; I < SBI_CALL_MAX_ARGS; I++) { > + if (I < NumArgs) { > + Args[I] = VA_ARG (ArgList, UINTN); > + } else { > + // Default to 0 for all arguments that are not given > + Args[I] = 0; > + } > + } > + > + VA_END (ArgList); > + > + register UINTN a0 asm ("a0") = Args[0]; > + register UINTN a1 asm ("a1") = Args[1]; > + register UINTN a2 asm ("a2") = Args[2]; > + register UINTN a3 asm ("a3") = Args[3]; > + register UINTN a4 asm ("a4") = Args[4]; > + register UINTN a5 asm ("a5") = Args[5]; > + register UINTN a6 asm ("a6") = (UINTN)(FuncId); > + register UINTN a7 asm ("a7") = (UINTN)(ExtId); > + > + asm volatile ("ecall" \ > + : "+r" (a0), "+r" (a1) \ > + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) \ > + : "memory"); \ > + Ret.Error = a0; > + Ret.Value = a1; > + return Ret; > +} > + > +/** > + Translate SBI error code to EFI status. > + > + @param[in] SbiError SBI error code > + @retval EFI_STATUS > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +TranslateError ( > + IN UINTN SbiError > + ) > +{ > + switch (SbiError) { > + case SBI_SUCCESS: > + return EFI_SUCCESS; > + case SBI_ERR_FAILED: > + return EFI_DEVICE_ERROR; > + break; > + case SBI_ERR_NOT_SUPPORTED: > + return EFI_UNSUPPORTED; > + break; > + case SBI_ERR_INVALID_PARAM: > + return EFI_INVALID_PARAMETER; > + break; > + case SBI_ERR_DENIED: > + return EFI_ACCESS_DENIED; > + break; > + case SBI_ERR_INVALID_ADDRESS: > + return EFI_LOAD_ERROR; > + break; > + case SBI_ERR_ALREADY_AVAILABLE: > + return EFI_ALREADY_STARTED; > + break; > + default: > + // > + // Reaches here only if SBI has defined a new error type > + // > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + break; > + } > +} > + > +/** > + Clear pending timer interrupt bit and set timer for next event after Time. > + > + To clear the timer without scheduling a timer event, set Time to a > + practically infinite value or mask the timer interrupt by clearing sie.STIE. > + > + @param[in] Time The time offset to the next scheduled timer interrupt. > +**/ > +VOID > +EFIAPI > +SbiSetTimer ( > + IN UINT64 Time > + ) > +{ > + SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time); > +} > + > +EFI_STATUS > +EFIAPI > +SbiSystemReset ( > + IN UINTN ResetType, > + IN UINTN ResetReason > + ) > +{ > + SBI_RET Ret; > + > + Ret = SbiCall ( > + SBI_EXT_SRST, > + SBI_EXT_SRST_RESET, > + 2, > + ResetType, > + ResetReason > + ); > + > + return TranslateError (Ret.Error); > +} > + > +/** > + Get firmware context of the calling hart. > + > + @param[out] FirmwareContext The firmware context pointer. > + @retval EFI_SUCCESS The operation succeeds. > +**/ > +VOID > +EFIAPI > +GetFirmwareContext ( > + OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContext > + ) > +{ > + *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)csr_read(CSR_SSCRATCH); > +} > + > +/** > + Set firmware context of the calling hart. > + > + @param[in] FirmwareContext The firmware context pointer. > +**/ > +VOID > +EFIAPI > +SetFirmwareContext ( > + IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext > + ) > +{ > + csr_write(CSR_SSCRATCH, FirmwareContext); > +} > + > +/** > + Get pointer to OpenSBI Firmware Context > + > + Get the pointer of firmware context through OpenSBI FW Extension SBI. > + > + @param FirmwareContextPtr Pointer to retrieve pointer to the > + Firmware Context. > +**/ > +VOID > +EFIAPI > +GetFirmwareContextPointer ( > + IN OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContextPtr > + ) > +{ > + GetFirmwareContext (FirmwareContextPtr); > +} > + > +/** > + Set the pointer to OpenSBI Firmware Context > + > + Set the pointer of firmware context through OpenSBI FW Extension SBI. > + > + @param FirmwareContextPtr Pointer to Firmware Context. > +**/ > +VOID > +EFIAPI > +SetFirmwareContextPointer ( > + IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContextPtr > + ) > +{ > + SetFirmwareContext (FirmwareContextPtr); > +}