Skip to content

Commit b9dcd9e

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Add basic support for SBI v0.2
The SBI v0.2 introduces a base extension which is backward compatible with v0.1. Implement all helper functions and minimum required SBI calls from v0.2 for now. All other base extension function will be added later as per need. As v0.2 calling convention is backward compatible with v0.1, remove the v0.1 helper functions and just use v0.2 calling convention. Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Anup Patel <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8446923 commit b9dcd9e

File tree

3 files changed

+314
-73
lines changed

3 files changed

+314
-73
lines changed

arch/riscv/include/asm/sbi.h

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,98 +10,95 @@
1010
#include <linux/types.h>
1111

1212
#ifdef CONFIG_RISCV_SBI
13-
#define SBI_EXT_0_1_SET_TIMER 0x0
14-
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
15-
#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
16-
#define SBI_EXT_0_1_CLEAR_IPI 0x3
17-
#define SBI_EXT_0_1_SEND_IPI 0x4
18-
#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
19-
#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
20-
#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
21-
#define SBI_EXT_0_1_SHUTDOWN 0x8
13+
enum sbi_ext_id {
14+
SBI_EXT_0_1_SET_TIMER = 0x0,
15+
SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
16+
SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
17+
SBI_EXT_0_1_CLEAR_IPI = 0x3,
18+
SBI_EXT_0_1_SEND_IPI = 0x4,
19+
SBI_EXT_0_1_REMOTE_FENCE_I = 0x5,
20+
SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
21+
SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
22+
SBI_EXT_0_1_SHUTDOWN = 0x8,
23+
SBI_EXT_BASE = 0x10,
24+
};
2225

23-
#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \
24-
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \
25-
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \
26-
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \
27-
register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \
28-
register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \
29-
asm volatile ("ecall" \
30-
: "+r" (a0) \
31-
: "r" (a1), "r" (a2), "r" (a3), "r" (a7) \
32-
: "memory"); \
33-
a0; \
34-
})
26+
enum sbi_ext_base_fid {
27+
SBI_EXT_BASE_GET_SPEC_VERSION = 0,
28+
SBI_EXT_BASE_GET_IMP_ID,
29+
SBI_EXT_BASE_GET_IMP_VERSION,
30+
SBI_EXT_BASE_PROBE_EXT,
31+
SBI_EXT_BASE_GET_MVENDORID,
32+
SBI_EXT_BASE_GET_MARCHID,
33+
SBI_EXT_BASE_GET_MIMPID,
34+
};
3535

36-
/* Lazy implementations until SBI is finalized */
37-
#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0)
38-
#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0)
39-
#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0)
40-
#define SBI_CALL_3(which, arg0, arg1, arg2) \
41-
SBI_CALL(which, arg0, arg1, arg2, 0)
42-
#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \
43-
SBI_CALL(which, arg0, arg1, arg2, arg3)
36+
#define SBI_SPEC_VERSION_DEFAULT 0x1
37+
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
38+
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
39+
#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
4440

45-
static inline void sbi_console_putchar(int ch)
46-
{
47-
SBI_CALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, ch);
48-
}
41+
/* SBI return error codes */
42+
#define SBI_SUCCESS 0
43+
#define SBI_ERR_FAILURE -1
44+
#define SBI_ERR_NOT_SUPPORTED -2
45+
#define SBI_ERR_INVALID_PARAM -3
46+
#define SBI_ERR_DENIED -4
47+
#define SBI_ERR_INVALID_ADDRESS -5
4948

50-
static inline int sbi_console_getchar(void)
51-
{
52-
return SBI_CALL_0(SBI_EXT_0_1_CONSOLE_GETCHAR);
53-
}
49+
extern unsigned long sbi_spec_version;
50+
struct sbiret {
51+
long error;
52+
long value;
53+
};
5454

55-
static inline void sbi_set_timer(uint64_t stime_value)
56-
{
57-
#if __riscv_xlen == 32
58-
SBI_CALL_2(SBI_EXT_0_1_SET_TIMER, stime_value,
59-
stime_value >> 32);
60-
#else
61-
SBI_CALL_1(SBI_EXT_0_1_SET_TIMER, stime_value);
62-
#endif
63-
}
64-
65-
static inline void sbi_shutdown(void)
66-
{
67-
SBI_CALL_0(SBI_EXT_0_1_SHUTDOWN);
68-
}
55+
int sbi_init(void);
56+
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
57+
unsigned long arg1, unsigned long arg2,
58+
unsigned long arg3, unsigned long arg4,
59+
unsigned long arg5);
6960

70-
static inline void sbi_clear_ipi(void)
71-
{
72-
SBI_CALL_0(SBI_EXT_0_1_CLEAR_IPI);
73-
}
61+
void sbi_console_putchar(int ch);
62+
int sbi_console_getchar(void);
63+
void sbi_set_timer(uint64_t stime_value);
64+
void sbi_shutdown(void);
65+
void sbi_clear_ipi(void);
66+
void sbi_send_ipi(const unsigned long *hart_mask);
67+
void sbi_remote_fence_i(const unsigned long *hart_mask);
68+
void sbi_remote_sfence_vma(const unsigned long *hart_mask,
69+
unsigned long start,
70+
unsigned long size);
7471

75-
static inline void sbi_send_ipi(const unsigned long *hart_mask)
76-
{
77-
SBI_CALL_1(SBI_EXT_0_1_SEND_IPI, hart_mask);
78-
}
72+
void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
73+
unsigned long start,
74+
unsigned long size,
75+
unsigned long asid);
76+
int sbi_probe_extension(int ext);
7977

80-
static inline void sbi_remote_fence_i(const unsigned long *hart_mask)
78+
/* Check if current SBI specification version is 0.1 or not */
79+
static inline int sbi_spec_is_0_1(void)
8180
{
82-
SBI_CALL_1(SBI_EXT_0_1_REMOTE_FENCE_I, hart_mask);
81+
return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT) ? 1 : 0;
8382
}
8483

85-
static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask,
86-
unsigned long start,
87-
unsigned long size)
84+
/* Get the major version of SBI */
85+
static inline unsigned long sbi_major_version(void)
8886
{
89-
SBI_CALL_3(SBI_EXT_0_1_REMOTE_SFENCE_VMA, hart_mask, start, size);
87+
return (sbi_spec_version >> SBI_SPEC_VERSION_MAJOR_SHIFT) &
88+
SBI_SPEC_VERSION_MAJOR_MASK;
9089
}
9190

92-
static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
93-
unsigned long start,
94-
unsigned long size,
95-
unsigned long asid)
91+
/* Get the minor version of SBI */
92+
static inline unsigned long sbi_minor_version(void)
9693
{
97-
SBI_CALL_4(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, hart_mask,
98-
start, size, asid);
94+
return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK;
9995
}
10096
#else /* CONFIG_RISCV_SBI */
10197
/* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
10298
void sbi_set_timer(uint64_t stime_value);
10399
void sbi_clear_ipi(void);
104100
void sbi_send_ipi(const unsigned long *hart_mask);
105101
void sbi_remote_fence_i(const unsigned long *hart_mask);
102+
void sbi_init(void);
106103
#endif /* CONFIG_RISCV_SBI */
107104
#endif /* _ASM_RISCV_SBI_H */

0 commit comments

Comments
 (0)