Skip to content

Commit efca139

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Introduce a new config for SBI v0.1
We now have SBI v0.2 which is more scalable and extendable to handle future needs for RISC-V supervisor interfaces. Introduce a new config and move all SBI v0.1 code under that config. This allows to implement the new replacement SBI extensions cleanly and remove v0.1 extensions easily in future. Currently, the config is enabled by default. Once all M-mode software, with v0.1, is no longer in use, this config option and all relevant code can be easily removed. Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Anup Patel <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent ecbacc2 commit efca139

File tree

3 files changed

+118
-23
lines changed

3 files changed

+118
-23
lines changed

arch/riscv/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ config SECCOMP
314314
and the task is only allowed to execute a few safe syscalls
315315
defined by each seccomp mode.
316316

317+
config RISCV_SBI_V01
318+
bool "SBI v0.1 support"
319+
default y
320+
depends on RISCV_SBI
321+
help
322+
This config allows kernel to use SBI v0.1 APIs. This will be
323+
deprecated in future once legacy M-mode software are no longer in use.
317324
endmenu
318325

319326
menu "Boot options"

arch/riscv/include/asm/sbi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#ifdef CONFIG_RISCV_SBI
1313
enum sbi_ext_id {
14+
#ifdef CONFIG_RISCV_SBI_V01
1415
SBI_EXT_0_1_SET_TIMER = 0x0,
1516
SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
1617
SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
@@ -20,6 +21,7 @@ enum sbi_ext_id {
2021
SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
2122
SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
2223
SBI_EXT_0_1_SHUTDOWN = 0x8,
24+
#endif
2325
SBI_EXT_BASE = 0x10,
2426
SBI_EXT_TIME = 0x54494D45,
2527
SBI_EXT_IPI = 0x735049,

arch/riscv/kernel/sbi.c

Lines changed: 109 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT;
1414
EXPORT_SYMBOL(sbi_spec_version);
1515

16+
static void (*__sbi_set_timer)(uint64_t stime);
17+
static int (*__sbi_send_ipi)(const unsigned long *hart_mask);
18+
static int (*__sbi_rfence)(int fid, const unsigned long *hart_mask,
19+
unsigned long start, unsigned long size,
20+
unsigned long arg4, unsigned long arg5);
21+
1622
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
1723
unsigned long arg1, unsigned long arg2,
1824
unsigned long arg3, unsigned long arg4,
@@ -57,6 +63,7 @@ static int sbi_err_map_linux_errno(int err)
5763
};
5864
}
5965

66+
#ifdef CONFIG_RISCV_SBI_V01
6067
/**
6168
* sbi_console_putchar() - Writes given character to the console device.
6269
* @ch: The data to be written to the console.
@@ -85,12 +92,34 @@ int sbi_console_getchar(void)
8592
EXPORT_SYMBOL(sbi_console_getchar);
8693

8794
/**
88-
* sbi_set_timer() - Program the timer for next timer event.
95+
* sbi_shutdown() - Remove all the harts from executing supervisor code.
96+
*
97+
* Return: None
98+
*/
99+
void sbi_shutdown(void)
100+
{
101+
sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0);
102+
}
103+
EXPORT_SYMBOL(sbi_set_timer);
104+
105+
/**
106+
* sbi_clear_ipi() - Clear any pending IPIs for the calling hart.
107+
*
108+
* Return: None
109+
*/
110+
void sbi_clear_ipi(void)
111+
{
112+
sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0);
113+
}
114+
EXPORT_SYMBOL(sbi_shutdown);
115+
116+
/**
117+
* sbi_set_timer_v01() - Program the timer for next timer event.
89118
* @stime_value: The value after which next timer event should fire.
90119
*
91120
* Return: None
92121
*/
93-
void sbi_set_timer(uint64_t stime_value)
122+
static void __sbi_set_timer_v01(uint64_t stime_value)
94123
{
95124
#if __riscv_xlen == 32
96125
sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value,
@@ -99,27 +128,78 @@ void sbi_set_timer(uint64_t stime_value)
99128
sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, 0, 0, 0, 0, 0);
100129
#endif
101130
}
102-
EXPORT_SYMBOL(sbi_set_timer);
103131

104-
/**
105-
* sbi_shutdown() - Remove all the harts from executing supervisor code.
106-
*
107-
* Return: None
108-
*/
109-
void sbi_shutdown(void)
132+
static int __sbi_send_ipi_v01(const unsigned long *hart_mask)
110133
{
111-
sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0);
134+
sbi_ecall(SBI_EXT_0_1_SEND_IPI, 0, (unsigned long)hart_mask,
135+
0, 0, 0, 0, 0);
136+
return 0;
112137
}
113-
EXPORT_SYMBOL(sbi_shutdown);
138+
139+
static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask,
140+
unsigned long start, unsigned long size,
141+
unsigned long arg4, unsigned long arg5)
142+
{
143+
int result = 0;
144+
145+
/* v0.2 function IDs are equivalent to v0.1 extension IDs */
146+
switch (fid) {
147+
case SBI_EXT_RFENCE_REMOTE_FENCE_I:
148+
sbi_ecall(SBI_EXT_0_1_REMOTE_FENCE_I, 0,
149+
(unsigned long)hart_mask, 0, 0, 0, 0, 0);
150+
break;
151+
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
152+
sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA, 0,
153+
(unsigned long)hart_mask, start, size,
154+
0, 0, 0);
155+
break;
156+
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
157+
sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, 0,
158+
(unsigned long)hart_mask, start, size,
159+
arg4, 0, 0);
160+
break;
161+
default:
162+
pr_err("SBI call [%d]not supported in SBI v0.1\n", fid);
163+
result = -EINVAL;
164+
}
165+
166+
return result;
167+
}
168+
#else
169+
static void __sbi_set_timer_v01(uint64_t stime_value)
170+
{
171+
pr_warn("Timer extension is not available in SBI v%lu.%lu\n",
172+
sbi_major_version(), sbi_minor_version());
173+
}
174+
175+
static int __sbi_send_ipi_v01(const unsigned long *hart_mask)
176+
{
177+
pr_warn("IPI extension is not available in SBI v%lu.%lu\n",
178+
sbi_major_version(), sbi_minor_version());
179+
180+
return 0;
181+
}
182+
183+
static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask,
184+
unsigned long start, unsigned long size,
185+
unsigned long arg4, unsigned long arg5)
186+
{
187+
pr_warn("remote fence extension is not available in SBI v%lu.%lu\n",
188+
sbi_major_version(), sbi_minor_version());
189+
190+
return 0;
191+
}
192+
#endif /* CONFIG_RISCV_SBI_V01 */
114193

115194
/**
116-
* sbi_clear_ipi() - Clear any pending IPIs for the calling hart.
195+
* sbi_set_timer() - Program the timer for next timer event.
196+
* @stime_value: The value after which next timer event should fire.
117197
*
118198
* Return: None
119199
*/
120-
void sbi_clear_ipi(void)
200+
void sbi_set_timer(uint64_t stime_value)
121201
{
122-
sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0);
202+
__sbi_set_timer(stime_value);
123203
}
124204

125205
/**
@@ -130,8 +210,7 @@ void sbi_clear_ipi(void)
130210
*/
131211
void sbi_send_ipi(const unsigned long *hart_mask)
132212
{
133-
sbi_ecall(SBI_EXT_0_1_SEND_IPI, 0, (unsigned long)hart_mask,
134-
0, 0, 0, 0, 0);
213+
__sbi_send_ipi(hart_mask);
135214
}
136215
EXPORT_SYMBOL(sbi_send_ipi);
137216

@@ -143,8 +222,8 @@ EXPORT_SYMBOL(sbi_send_ipi);
143222
*/
144223
void sbi_remote_fence_i(const unsigned long *hart_mask)
145224
{
146-
sbi_ecall(SBI_EXT_0_1_REMOTE_FENCE_I, 0, (unsigned long)hart_mask,
147-
0, 0, 0, 0, 0);
225+
__sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I,
226+
hart_mask, 0, 0, 0, 0);
148227
}
149228
EXPORT_SYMBOL(sbi_remote_fence_i);
150229

@@ -161,8 +240,8 @@ void sbi_remote_sfence_vma(const unsigned long *hart_mask,
161240
unsigned long start,
162241
unsigned long size)
163242
{
164-
sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA, 0,
165-
(unsigned long)hart_mask, start, size, 0, 0, 0);
243+
__sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,
244+
hart_mask, start, size, 0, 0);
166245
}
167246
EXPORT_SYMBOL(sbi_remote_sfence_vma);
168247

@@ -182,8 +261,8 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
182261
unsigned long size,
183262
unsigned long asid)
184263
{
185-
sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, 0,
186-
(unsigned long)hart_mask, start, size, asid, 0, 0);
264+
__sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID,
265+
hart_mask, start, size, asid, 0);
187266
}
188267
EXPORT_SYMBOL(sbi_remote_sfence_vma_asid);
189268

@@ -249,8 +328,15 @@ int __init sbi_init(void)
249328

250329
pr_info("SBI specification v%lu.%lu detected\n",
251330
sbi_major_version(), sbi_minor_version());
252-
if (!sbi_spec_is_0_1())
331+
332+
if (!sbi_spec_is_0_1()) {
253333
pr_info("SBI implementation ID=0x%lx Version=0x%lx\n",
254334
sbi_get_firmware_id(), sbi_get_firmware_version());
335+
}
336+
337+
__sbi_set_timer = __sbi_set_timer_v01;
338+
__sbi_send_ipi = __sbi_send_ipi_v01;
339+
__sbi_rfence = __sbi_rfence_v01;
340+
255341
return 0;
256342
}

0 commit comments

Comments
 (0)