diff --git a/arch/risc-v/include/types.h b/arch/risc-v/include/types.h index 74a5babb25..29fe8d56a6 100644 --- a/arch/risc-v/include/types.h +++ b/arch/risc-v/include/types.h @@ -81,8 +81,10 @@ typedef int _wchar_t; /* Use uintreg_t for register-width integers */ #ifdef CONFIG_ARCH_RV32 +typedef _int32_t intreg_t; typedef _uint32_t uintreg_t; #else +typedef _int64_t intreg_t; typedef _uint64_t uintreg_t; #endif diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index 1f55e0a44e..154f8dfb54 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -37,6 +37,7 @@ #include +#include "riscv_sbi.h" #include "riscv_common_memorymap.h" /**************************************************************************** @@ -209,40 +210,6 @@ static inline void putreg64(uint64_t v, const volatile uintreg_t a) #endif -/* SBI Extension IDs */ - -#define SBI_EXT_HSM 0x48534D -#define SBI_EXT_IPI 0x735049 -#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 HSM extension */ - -#define SBI_EXT_HSM_HART_START 0x0 - -/* SBI function IDs for IPI extension */ - -#define SBI_EXT_IPI_SEND_IPI 0x0 - -/* SBI function IDs for SRST extension */ - -#define SBI_EXT_SRST_SYS_RESET 0x0 - -/* SBI system reset type */ - -#define SBI_SRST_TYPE_SHUTDOWN 0 -#define SBI_SRST_TYPE_REBOOT_COLD 1 -#define SBI_SRST_TYPE_REBOOT_WARM 1 - -/* SBI system reset reason */ - -#define SBI_SRST_REASON_NONE 0 -#define SBI_SRST_REASON_FAILURE 1 - /**************************************************************************** * Public Types ****************************************************************************/ @@ -372,17 +339,6 @@ int riscv_check_pmp_access(uintptr_t attr, uintptr_t base, uintptr_t size); int riscv_configured_pmp_regions(void); int riscv_next_free_pmp_region(void); -/* RISC-V SBI wrappers ******************************************************/ - -#ifdef CONFIG_ARCH_USE_S_MODE -uintptr_t riscv_sbi_send_ipi(uint32_t hmask, uintptr_t hbase); -void riscv_sbi_set_timer(uint64_t stime_value); -uint64_t riscv_sbi_get_time(void); -uintptr_t riscv_sbi_boot_secondary(uint32_t hartid, uintptr_t addr, - uintptr_t a1); -uintptr_t riscv_sbi_system_reset(uint32_t type, uint32_t reason); -#endif - /* Power management *********************************************************/ #ifdef CONFIG_PM diff --git a/arch/risc-v/src/common/riscv_sbi.h b/arch/risc-v/src/common/riscv_sbi.h new file mode 100644 index 0000000000..ff33464c65 --- /dev/null +++ b/arch/risc-v/src/common/riscv_sbi.h @@ -0,0 +1,284 @@ +/**************************************************************************** + * arch/risc-v/src/common/riscv_sbi.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_COMMON_RISCV_SBI_H +#define __ARCH_RISCV_SRC_COMMON_RISCV_SBI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* SBI Extension IDs */ + +#define SBI_EXT_BASE 0x00000010 +#define SBI_EXT_IPI 0x00735049 +#define SBI_EXT_TIME 0x54494D45 +#define SBI_EXT_RFENCE 0x52464E43 +#define SBI_EXT_HSM 0x0048534D +#define SBI_EXT_SRST 0x53525354 +#define SBI_EXT_PMU 0x00504D55 +#define SBI_EXT_DBCN 0x4442434E +#define SBI_EXT_SUSP 0x53555350 + +/* SBI function IDs for BASE extension */ + +#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0 +#define SBI_EXT_BASE_GET_IMP_ID 0x1 +#define SBI_EXT_BASE_GET_IMP_VERSION 0x2 +#define SBI_EXT_BASE_PROBE_EXT 0x3 +#define SBI_EXT_BASE_GET_MVENDORID 0x4 +#define SBI_EXT_BASE_GET_MARCHID 0x5 +#define SBI_EXT_BASE_GET_MIMPID 0x6 + +/* SBI function IDs for TIME extension */ + +#define SBI_EXT_TIME_SET_TIMER 0x0 + +/* SBI function IDs for IPI extension */ + +#define SBI_EXT_IPI_SEND_IPI 0x0 + +/* SBI function IDs for RFENCE extension */ +#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0 +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1 +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x3 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x4 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x5 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x6 + +/* SBI function IDs for HSM extension */ + +#define SBI_EXT_HSM_HART_START 0x0 +#define SBI_EXT_HSM_HART_STOP 0x1 +#define SBI_EXT_HSM_HART_GET_STATUS 0x2 +#define SBI_EXT_HSM_HART_SUSPEND 0x3 + +#define SBI_HSM_STATE_STARTED 0x0 +#define SBI_HSM_STATE_STOPPED 0x1 +#define SBI_HSM_STATE_START_PENDING 0x2 +#define SBI_HSM_STATE_STOP_PENDING 0x3 +#define SBI_HSM_STATE_SUSPENDED 0x4 +#define SBI_HSM_STATE_SUSPEND_PENDING 0x5 +#define SBI_HSM_STATE_RESUME_PENDING 0x6 + +/* SBI function IDs for SRST extension */ + +#define SBI_EXT_SRST_SYS_RESET 0x0 + +/* SBI system reset type */ + +#define SBI_SRST_TYPE_SHUTDOWN 0 +#define SBI_SRST_TYPE_REBOOT_COLD 1 +#define SBI_SRST_TYPE_REBOOT_WARM 1 + +/* SBI system reset reason */ + +#define SBI_SRST_REASON_NONE 0 +#define SBI_SRST_REASON_FAILURE 1 + +/* SBI function IDs for PMU extension */ + +#define SBI_EXT_PMU_NUM_COUNTERS 0x0 +#define SBI_EXT_PMU_COUNTER_GET_INFO 0x1 +#define SBI_EXT_PMU_COUNTER_CFG_MATCH 0x2 +#define SBI_EXT_PMU_COUNTER_START 0x3 +#define SBI_EXT_PMU_COUNTER_STOP 0x4 +#define SBI_EXT_PMU_COUNTER_FW_READ 0x5 +#define SBI_EXT_PMU_COUNTER_FW_READ_HI 0x6 +#define SBI_EXT_PMU_SNAPSHOT_SET_SHMEM 0x7 + +/* SBI PMU counter config match flags */ + +#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0) +#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1) +#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2) +#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3) +#define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4) +#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5) +#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6) +#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7) + +/* SBI PMU counter start flags */ + +#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0) +#define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1) + +/* SBI PMU counter stop flags */ + +#define SBI_PMU_STOP_FLAG_RESET (1 << 0) +#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT (1 << 1) + +/* SBI function IDs for DBCN extension */ + +#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0 +#define SBI_EXT_DBCN_CONSOLE_READ 0x1 +#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2 + +/* SBI function IDs for SUSP extension */ + +#define SBI_EXT_SUSP_SUSPEND 0x0 + +/* SBI system suspend type */ + +#define SBI_SUSP_SLEEP_TYPE_SUSPEND 0x0 + +/* 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_ERR_NO_SHMEM -9 +#define SBI_ERR_INVALID_STATE -10 +#define SBI_ERR_BAD_RANGE -11 + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct sbiret_s +{ + intreg_t error; + uintreg_t value; +}; +typedef struct sbiret_s sbiret_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* RISC-V SBI wrappers ******************************************************/ + +#ifdef CONFIG_ARCH_USE_S_MODE + +/**************************************************************************** + * Name: sbi_err_map_errno + * + * Description: + * Convert SBI error value to posix error value + * + * Input Parameters: + * err - error value of SBI function + * + * Return: + * Posix error value representing the input + * + ****************************************************************************/ + +int sbi_err_map_errno(intreg_t err); + +/**************************************************************************** + * Name: riscv_sbi_send_ipi + * + * Description: + * Send a ipi to the target harts + * + * Input Parameters: + * hmask - bit mask for target harts + * hbase - the start hart id to send + * + ****************************************************************************/ + +void riscv_sbi_send_ipi(uintreg_t hmask, uintreg_t hbase); + +/**************************************************************************** + * Name: riscv_sbi_set_timer + * + * Description: + * Set new compare match value for timer + * + * Input Parameters: + * stime_value - Value to set + * + ****************************************************************************/ + +void riscv_sbi_set_timer(uint64_t stime_value); + +/**************************************************************************** + * Name: riscv_sbi_get_time + * + * Description: + * Get value of mtime + * + * Return: + * Value of mtime + * + ****************************************************************************/ + +uint64_t riscv_sbi_get_time(void); + +/**************************************************************************** + * Name: riscv_sbi_boot_secondary + * + * Description: + * Start the target hart + * + * Input Parameters: + * hartid - hart id to start + * addr - start address for the hart + * a1 - opaque parameter for the hart + * + ****************************************************************************/ + +int riscv_sbi_boot_secondary(uintreg_t hartid, uintreg_t addr, + uintreg_t a1); + +/**************************************************************************** + * Name: riscv_sbi_system_reset + * + * Description: + * Reset the system with specific type and reason. + * + ****************************************************************************/ + +int riscv_sbi_system_reset(uint32_t type, uint32_t reason); + +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_RISCV_SRC_COMMON_RISCV_SBI_H */ diff --git a/arch/risc-v/src/common/supervisor/riscv_sbi.c b/arch/risc-v/src/common/supervisor/riscv_sbi.c index 865a4a6f9c..0daceece06 100644 --- a/arch/risc-v/src/common/supervisor/riscv_sbi.c +++ b/arch/risc-v/src/common/supervisor/riscv_sbi.c @@ -31,6 +31,7 @@ #include +#include "riscv_sbi.h" #include "riscv_internal.h" #ifdef CONFIG_NUTTSBI @@ -41,10 +42,10 @@ * Private Functions ****************************************************************************/ -static inline uintptr_t sbi_ecall(unsigned int extid, unsigned int fid, - uintptr_t parm0, uintptr_t parm1, - uintptr_t parm2, uintptr_t parm3, - uintptr_t parm4, uintptr_t parm5) +static inline sbiret_t sbi_ecall(unsigned int extid, unsigned int fid, + uintreg_t parm0, uintreg_t parm1, + uintreg_t parm2, uintreg_t parm3, + uintreg_t parm4, uintreg_t parm5) { register long r0 asm("a0") = (long)(parm0); register long r1 asm("a1") = (long)(parm1); @@ -54,6 +55,7 @@ static inline uintptr_t sbi_ecall(unsigned int extid, unsigned int fid, register long r5 asm("a5") = (long)(parm5); register long r6 asm("a6") = (long)(fid); register long r7 asm("a7") = (long)(extid); + sbiret_t ret; asm volatile ( @@ -63,23 +65,34 @@ static inline uintptr_t sbi_ecall(unsigned int extid, unsigned int fid, : "memory" ); - return r1; + ret.error = r0; + ret.value = (uintreg_t)r1; + + return ret; } /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: riscv_sbi_set_timer - * - * Description: - * Set new compare match value for timer - * - * Input Parameters: - * stime_value - Value to set - * - ****************************************************************************/ +int sbi_err_map_errno(intreg_t err) +{ + switch (err) + { + case SBI_SUCCESS: + return 0; + case SBI_ERR_DENIED: + return -EPERM; + case SBI_ERR_INVALID_PARAM: + return -EINVAL; + case SBI_ERR_INVALID_ADDRESS: + return -EFAULT; + case SBI_ERR_NOT_SUPPORTED: + case SBI_ERR_FAILED: + default: + return -ENOTSUP; + }; +} void riscv_sbi_set_timer(uint64_t stime_value) { @@ -92,22 +105,13 @@ void riscv_sbi_set_timer(uint64_t stime_value) #endif } -/**************************************************************************** - * Name: riscv_sbi_get_time - * - * Description: - * Get value of mtime - * - * Return: - * Value of mtime - * - ****************************************************************************/ - uint64_t riscv_sbi_get_time(void) { #ifdef CONFIG_NUTTSBI - return sbi_ecall(SBI_EXT_FIRMWARE, SBI_EXT_FIRMWARE_GET_MTIME, 0, 0, - 0, 0, 0, 0); + sbiret_t ret = sbi_ecall(SBI_EXT_FIRMWARE, SBI_EXT_FIRMWARE_GET_MTIME, + 0, 0, 0, 0, 0, 0); + + return ret.value; #elif defined(CONFIG_ARCH_RV64) return READ_CSR(CSR_TIME); #else @@ -125,23 +129,37 @@ uint64_t riscv_sbi_get_time(void) #endif } -uintptr_t riscv_sbi_send_ipi(uint32_t hmask, uintptr_t hbase) +void riscv_sbi_send_ipi(uintreg_t hmask, uintreg_t hbase) { - return sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, - hmask, hbase, 0, 0, 0, 0); + sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, + hmask, hbase, 0, 0, 0, 0); } #ifndef CONFIG_NUTTSBI -uintptr_t riscv_sbi_system_reset(uint32_t type, uint32_t reason) +int riscv_sbi_boot_secondary(uintreg_t hartid, uintreg_t addr, + uintreg_t a1) { - return sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_SYS_RESET, - type, reason, 0, 0, 0, 0); + sbiret_t ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, + hartid, addr, a1, 0, 0, 0); + + if (ret.error < 0) + { + return sbi_err_map_errno(ret.error); + } + + return 0; } -uintptr_t riscv_sbi_boot_secondary(uint32_t hartid, uintptr_t addr, - uintptr_t a1) +int riscv_sbi_system_reset(uint32_t type, uint32_t reason) { - return sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, - hartid, addr, a1, 0, 0, 0); + sbiret_t ret = sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_SYS_RESET, + type, reason, 0, 0, 0, 0); + + if (ret.error < 0) + { + return sbi_err_map_errno(ret.error); + } + + return 0; } #endif /* CONFIG_NUTTSBI */