13
13
unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT ;
14
14
EXPORT_SYMBOL (sbi_spec_version );
15
15
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
+
16
22
struct sbiret sbi_ecall (int ext , int fid , unsigned long arg0 ,
17
23
unsigned long arg1 , unsigned long arg2 ,
18
24
unsigned long arg3 , unsigned long arg4 ,
@@ -57,6 +63,7 @@ static int sbi_err_map_linux_errno(int err)
57
63
};
58
64
}
59
65
66
+ #ifdef CONFIG_RISCV_SBI_V01
60
67
/**
61
68
* sbi_console_putchar() - Writes given character to the console device.
62
69
* @ch: The data to be written to the console.
@@ -85,12 +92,34 @@ int sbi_console_getchar(void)
85
92
EXPORT_SYMBOL (sbi_console_getchar );
86
93
87
94
/**
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.
89
118
* @stime_value: The value after which next timer event should fire.
90
119
*
91
120
* Return: None
92
121
*/
93
- void sbi_set_timer (uint64_t stime_value )
122
+ static void __sbi_set_timer_v01 (uint64_t stime_value )
94
123
{
95
124
#if __riscv_xlen == 32
96
125
sbi_ecall (SBI_EXT_0_1_SET_TIMER , 0 , stime_value ,
@@ -99,27 +128,78 @@ void sbi_set_timer(uint64_t stime_value)
99
128
sbi_ecall (SBI_EXT_0_1_SET_TIMER , 0 , stime_value , 0 , 0 , 0 , 0 , 0 );
100
129
#endif
101
130
}
102
- EXPORT_SYMBOL (sbi_set_timer );
103
131
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 )
110
133
{
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 ;
112
137
}
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 */
114
193
115
194
/**
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.
117
197
*
118
198
* Return: None
119
199
*/
120
- void sbi_clear_ipi ( void )
200
+ void sbi_set_timer ( uint64_t stime_value )
121
201
{
122
- sbi_ecall ( SBI_EXT_0_1_CLEAR_IPI , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
202
+ __sbi_set_timer ( stime_value );
123
203
}
124
204
125
205
/**
@@ -130,8 +210,7 @@ void sbi_clear_ipi(void)
130
210
*/
131
211
void sbi_send_ipi (const unsigned long * hart_mask )
132
212
{
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 );
135
214
}
136
215
EXPORT_SYMBOL (sbi_send_ipi );
137
216
@@ -143,8 +222,8 @@ EXPORT_SYMBOL(sbi_send_ipi);
143
222
*/
144
223
void sbi_remote_fence_i (const unsigned long * hart_mask )
145
224
{
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 );
148
227
}
149
228
EXPORT_SYMBOL (sbi_remote_fence_i );
150
229
@@ -161,8 +240,8 @@ void sbi_remote_sfence_vma(const unsigned long *hart_mask,
161
240
unsigned long start ,
162
241
unsigned long size )
163
242
{
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 );
166
245
}
167
246
EXPORT_SYMBOL (sbi_remote_sfence_vma );
168
247
@@ -182,8 +261,8 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
182
261
unsigned long size ,
183
262
unsigned long asid )
184
263
{
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 );
187
266
}
188
267
EXPORT_SYMBOL (sbi_remote_sfence_vma_asid );
189
268
@@ -249,8 +328,15 @@ int __init sbi_init(void)
249
328
250
329
pr_info ("SBI specification v%lu.%lu detected\n" ,
251
330
sbi_major_version (), sbi_minor_version ());
252
- if (!sbi_spec_is_0_1 ())
331
+
332
+ if (!sbi_spec_is_0_1 ()) {
253
333
pr_info ("SBI implementation ID=0x%lx Version=0x%lx\n" ,
254
334
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
+
255
341
return 0 ;
256
342
}
0 commit comments