#ifndef _RISCV_SBI_H_
#define _RISCV_SBI_H_
#include <sys/types.h>
struct sbiret {
long error;
long value;
};
#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_EID_BASE 0x10
#define SBI_EID_TIMER 0x54494D45
#define SBI_EID_IPI 0x00735049
#define SBI_EID_RFENCE 0x52464E43
#define SBI_EID_HSM 0x0048534D
#define SBI_EID_SRST 0x53525354
#define SBI_EID_PMU 0x00504D55
#define SBI_FID_BASE_GETSPECVERSION 0
#define SBI_FID_BASE_GETIMPLID 1
#define SBI_FID_BASE_GETIMPLVERSION 2
#define SBI_FID_BASE_PROBEEXTENTION 3
#define SBI_FID_BASE_GETMVENDORID 4
#define SBI_FID_BASE_GETMARCHID 5
#define SBI_FID_BASE_GETMIMPID 6
struct sbiret sbi_get_spec_version(void);
struct sbiret sbi_get_impl_id(void);
struct sbiret sbi_get_impl_version(void);
struct sbiret sbi_probe_extension(long extension_id);
struct sbiret sbi_get_mvendorid(void);
struct sbiret sbi_get_marchid(void);
struct sbiret sbi_get_mimpid(void);
#define SBI_IMPLID_BERKELEY 0
#define SBI_IMPLID_OPENSBI 1
#define SBI_IMPLID_XVISOR 2
#define SBI_IMPLID_KVM 3
#define SBI_IMPLID_RUSTSBI 4
#define SBI_IMPLID_DIOSIX 5
#define SBI_FID_TIMER_SET 0
struct sbiret sbi_set_timer(uint64_t stime_value);
#define SBI_FID_IPI_SEND 0
struct sbiret sbi_send_ipi(unsigned long hart_mask,
unsigned long hart_mask_base);
#define SBI_FID_RFENCE_FENCEI 0
#define SBI_FID_RFENCE_SFENCEVMA 1
#define SBI_FID_RFENCE_SFENCEVMAASID 2
#define SBI_FID_RFENCE_HFENCEGVMAVMID 3
#define SBI_FID_RFENCE_HFENCEGVMA 4
#define SBI_FID_RFENCE_HFENCEVVMAASID 5
#define SBI_FID_RFENCE_HFENCEVVMA 6
struct sbiret sbi_remote_fence_i(unsigned long hart_mask,
unsigned long hart_mask_base);
struct sbiret sbi_remote_sfence_vma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
struct sbiret sbi_remote_sfence_vma_asid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long asid);
struct sbiret sbi_remote_hfence_gvma_vmid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long vmid);
struct sbiret sbi_remote_hfence_gvma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
struct sbiret sbi_remote_hfence_vvma_asid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long asid);
struct sbiret sbi_remote_hfence_vvma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
#define SBI_FID_HSM_START 0
#define SBI_FID_HSM_STOP 1
#define SBI_FID_HSM_GETSTATUS 2
#define SBI_FID_HSM_SUSPEND 3
struct sbiret sbi_hart_start(unsigned long hartid,
unsigned long start_addr,
unsigned long opaque);
struct sbiret sbi_hart_stop(void);
struct sbiret sbi_hart_get_status(unsigned long hartid);
struct sbiret sbi_hart_suspend(uint32_t suspend_type,
unsigned long resume_addr,
unsigned long opaque);
#define SBI_HART_STARTED 0
#define SBI_HART_STOPPED 1
#define SBI_HART_STARTPENDING 2
#define SBI_HART_STOPPENDING 3
#define SBI_HART_SUSPENDED 4
#define SBI_HART_SUSPENDPENDING 5
#define SBI_HART_RESUMEPENDING 6
#define SBI_FID_SRST_SYSTEMRESET 0
struct sbiret sbi_system_reset(uint32_t reset_type, uint32_t reset_reason);
#define SBI_RESET_TYPE_SHUTDOWN 0
#define SBI_RESET_TYPE_COLDREBOOT 1
#define SBI_RESET_TYPE_WARNREBOOT 2
#define SBI_RESET_REASON_NONE 0
#define SBI_RESET_REASON_FAILURE 1
#define SBI_FID_PMU_NUMCOUNTERS 0
#define SBI_FID_PMU_COUNTER_GET_INFO 1
#define SBI_FID_PMU_CONFIG_MATCHING 2
#define SBI_FID_PMU_START 3
#define SBI_FID_PMU_STOP 4
#define SBI_FID_PMU_FW_READ 5
#define SBI_PMU_HW_NO_EVENT 0
#define SBI_PMU_HW_CPU_CYCLES 1
#define SBI_PMU_HW_INSTRUCTIONS 2
#define SBI_PMU_HW_CACHE_REFERENCES 3
#define SBI_PMU_HW_CACHE_MISSES 4
#define SBI_PMU_HW_BRANCH_INSTRUCTIONS 5
#define SBI_PMU_HW_BRANCH_MISSES 6
#define SBI_PMU_HW_BUS_CYCLES 7
#define SBI_PMU_HW_STALLED_CYCLES_FRONTEND 8
#define SBI_PMU_HW_STALLED_CYCLES_BACKEND 9
#define SBI_PMU_HW_REF_CPU_CYCLES 10
#define SBI_PMU_HW_CACHE_L1D 0
#define SBI_PMU_HW_CACHE_L1I 1
#define SBI_PMU_HW_CACHE_LL 2
#define SBI_PMU_HW_CACHE_DTLB 3
#define SBI_PMU_HW_CACHE_ITLB 4
#define SBI_PMU_HW_CACHE_BPU 5
#define SBI_PMU_HW_CACHE_NODE 6
#define SBI_PMU_HW_CACHE_OP_READ 0
#define SBI_PMU_HW_CACHE_OP_WRITE 1
#define SBI_PMU_HW_CACHE_OP_PREFETCH 2
#define SBI_PMU_HW_CACHE_RESULT_ACCESS 0
#define SBI_PMU_HW_CACHE_RESULT_MISS 1
#define SBI_PMU_FW_MISALIGNED_LOAD 0
#define SBI_PMU_FW_MISALIGNED_STORE 1
#define SBI_PMU_FW_ACCESS_LOAD 2
#define SBI_PMU_FW_ACCESS_STORE 3
#define SBI_PMU_FW_ILLEGAL_INSN 4
#define SBI_PMU_FW_SET_TIMER 5
#define SBI_PMU_FW_IPI_SENT 6
#define SBI_PMU_FW_IPI_RECEIVED 7
#define SBI_PMU_FW_FENCE_I_SENT 8
#define SBI_PMU_FW_FENCE_I_RECEIVED 9
#define SBI_PMU_FW_SFENCE_VMA_SENT 10
#define SBI_PMU_FW_SFENCE_VMA_RECEIVED 11
#define SBI_PMU_FW_SFENCE_VMA_ASID_SENT 12
#define SBI_PMU_FW_SFENCE_VMA_ASID_RECEIVED 13
#define SBI_PMU_FW_HFENCE_GVMA_SENT 14
#define SBI_PMU_FW_HFENCE_GVMA_RECEIVED 15
#define SBI_PMU_FW_HFENCE_GVMA_VMID_SENT 16
#define SBI_PMU_FW_HFENCE_GVMA_VMID_RECEIVED 17
#define SBI_PMU_FW_HFENCE_VVMA_SENT 18
#define SBI_PMU_FW_HFENCE_VVMA_RECEIVED 19
#define SBI_PMU_FW_HFENCE_VVMA_ASID_SENT 20
#define SBI_PMU_FW_HFENCE_VVMA_ASID_RECEIVED 21
struct sbiret sbi_pmu_num_counters(void);
struct sbiret sbi_pmu_counter_get_info(unsigned long counter_idx);
struct sbiret sbi_pmu_counter_config_matching(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long config_flags,
unsigned long event_idx,
uint64_t event_data);
struct sbiret sbi_pmu_counter_start(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long start_flags,
uint64_t initial_value);
struct sbiret sbi_pmu_counter_stop(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long stop_flags);
struct sbiret sbi_pmu_counter_fw_read(unsigned long counter_idx);
static inline struct sbiret
sbi_call(int eid, int fid,
unsigned long arg0, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5)
{
struct sbiret ret;
register register_t _a7 __asm ("a7") = eid;
register register_t _a6 __asm ("a6") = fid;
register register_t _a0 __asm ("a0") = arg0;
register register_t _a1 __asm ("a1") = arg1;
register register_t _a2 __asm ("a2") = arg2;
register register_t _a3 __asm ("a3") = arg3;
register register_t _a4 __asm ("a4") = arg4;
register register_t _a5 __asm ("a5") = arg5;
__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;
}
#define SBI_CALL0(eid, fid) sbi_call(eid, fid, 0, 0, 0, 0, 0, 0)
#define SBI_CALL1(eid, fid, a0) sbi_call(eid, fid, a0, 0, 0, 0, 0, 0)
#define SBI_CALL2(eid, fid, a0, a1) sbi_call(eid, fid, a0, a1, 0, 0, 0, 0)
#define SBI_CALL3(eid, fid, a0, a1, a2) sbi_call(eid, fid, a0, a1, a2, 0, 0, 0)
#define SBI_CALL4(eid, fid, a0, a1, a2, a3) sbi_call(eid, fid, a0, a1, a2, a3, 0, 0)
#define SBI_CALL5(eid, fid, a0, a1, a2, a3, a4) sbi_call(eid, fid, a0, a1, a2, a3, a4, 0)
#define SBI_CALL6(eid, fid, a0, a1, a2, a3, a4, a5) sbi_call(eid, fid, a0, a1, a2, a3, a4, a5)
#if defined(__RVSBI_LEGACY)
#define SBI_LEGACY_SET_TIMER 0
#define SBI_LEGACY_CONSOLE_PUTCHAR 1
#define SBI_LEGACY_CONSOLE_GETCHAR 2
#define SBI_LEGACY_CLEAR_IPI 3
#define SBI_LEGACY_SEND_IPI 4
#define SBI_LEGACY_REMOTE_FENCE_I 5
#define SBI_LEGACY_REMOTE_SFENCE_VMA 6
#define SBI_LEGACY_REMOTE_SFENCE_VMA_ASID 7
#define SBI_LEGACY_SHUTDOWN 8
#define SBI_LEGACY_CALL0(eid) sbi_call(eid, 0, 0, 0, 0, 0, 0, 0)
#define SBI_LEGACY_CALL1(eid, a0) sbi_call(eid, 0, a0, 0, 0, 0, 0, 0)
#define SBI_LEGACY_CALL2(eid, a0, a1) sbi_call(eid, 0, a0, a1, 0, 0, 0, 0)
#define SBI_LEGACY_CALL3(eid, a0, a1, a2) sbi_call(eid, 0, a0, a1, a2, 0, 0, 0)
#define SBI_LEGACY_CALL4(eid, a0, a1, a2, a3) sbi_call(eid, 0, a0, a1, a2, a3, 0, 0)
#define SBI_LEGACY_CALL5(eid, a0, a1, a2, a3, a4) sbi_call(eid, 0, a0, a1, a2, a3, a4, 0)
static inline long
sbi_legacy_set_timer(uint64_t stime_value)
{
#ifdef _LP64
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SET_TIMER, stime_value);
#else
struct sbiret ret = SBI_LEGACY_CALL2(SBI_LEGACY_SET_TIMER,
stime_value, stime_value >> 32);
#endif
return ret.error;
}
static inline long
sbi_legacy_console_putchar(int c) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_CONSOLE_PUTCHAR, c);
return ret.error;
}
static inline long
sbi_legacy_console_getchar(void) {
struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CONSOLE_GETCHAR);
return ret.error;
}
static inline long
sbi_legacy_clear_ipi(void) {
struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CLEAR_IPI);
return ret.error;
}
static inline long
sbi_legacy_send_ipi(const unsigned long *hart_mask) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SEND_IPI,
(unsigned long)hart_mask);
return ret.error;
}
static inline long
sbi_legacy_remote_fence_i(const unsigned long *hart_mask) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_REMOTE_FENCE_I,
(unsigned long)hart_mask);
return ret.error;
}
static inline long
sbi_legacy_remote_sfence_vma(const unsigned long *hart_mask,
unsigned long start, unsigned long size)
{
struct sbiret ret = SBI_LEGACY_CALL3(SBI_LEGACY_REMOTE_SFENCE_VMA,
(unsigned long)hart_mask, start, size);
return ret.error;
}
static inline long
sbi_legacy_remote_sfence_vma_asid(const unsigned long *hart_mask,
unsigned long start, unsigned long size, unsigned long asid)
{
struct sbiret ret = SBI_LEGACY_CALL4(SBI_LEGACY_REMOTE_SFENCE_VMA_ASID,
(unsigned long)hart_mask, start, size, asid);
return ret.error;
}
static inline void
sbi_legacy_shutdown(void) {
SBI_LEGACY_CALL0(SBI_LEGACY_SHUTDOWN);
}
#endif
#endif