1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
//! Chapter 17. Supervisor Software Events Extension (EID #0x535345 "SSE").
use crate;
use ;
/// Read a range of event attribute values from a software event.
///
/// The `event_id` parameter specifies the software event ID whereas `base_attr_id`
/// and `attr_count` parameters specifies the range of event attribute IDs.
///
/// The event attribute values are written to a output shared memory which is specified
/// by the `output` parameter where:
///
/// - The `output` parameter MUST be `XLEN / 8` bytes aligned
/// - The size of output shared memory is assumed to be `(XLEN / 8) * attr_count`
/// - The value of event attribute with ID `base_attr_id + i` should be read from offset `(XLEN / 8) * (base_attr_id + i)`
///
/// The possible error codes returned in sbiret.error are shown below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event attribute values read successfully.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_param()` | `event_id` is invalid or `attr_count` is zero.
/// | `SbiRet::bad_range()` | One of the event attribute IDs in the range specified by `base_attr_id` and `attr_count` is reserved.
/// | `SbiRet::invalid_address()` | The shared memory pointed to by the `output` parameter does not satisfy the requirements.
/// | `SbiRet::failed()` | The read failed for unspecified or unknown other reasons.
/// Write a range of event attribute values to a software event.
///
/// The event_id parameter specifies the software event ID whereas `base_attr_id` and
/// `attr_count` parameters specifies the range of event attribute IDs.
///
/// The event attribute values are read from a input shared memory which is specified
/// by the `input` parameter where:
///
/// - The `input` parameter MUST be `XLEN / 8` bytes aligned
/// - The size of input shared memory is assumed to be `(XLEN / 8) * attr_count`
/// - The value of event attribute with ID `base_attr_id + i` should be read from offset `(XLEN / 8) * (base_attr_id + i)`
///
/// For local events, the event attributes are updated only for the calling hart.
/// For global events, the event attributes are updated for all the harts.
/// The possible error codes returned in sbiret.error are shown below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event attribute values written successfully.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_param()` | `event_id` is invalid or `attr_count` is zero.
/// | `SbiRet::bad_range()` | One of the event attribute IDs in the range specified by `base_attr_id` and `attr_count` is reserved or is read-only.
/// | `SbiRet::invalid_address()` | The shared memory pointed to by the `input` parameter does not satisfy the requirements.
/// | `SbiRet::failed()` | The write failed for unspecified or unknown other reasons.
/// Register an event handler for the software event.
///
/// The `event_id` parameter specifies the event ID for which an event handler is being registered.
/// The `handler_entry_pc` parameter MUST be 2-bytes aligned and specifies the `ENTRY_PC` event
/// attribute of the software event whereas the `handler_entry_arg` parameter specifies the
/// `ENTRY_ARG` event attribute of the software event.
///
/// For local events, the event is registered only for the calling hart.
/// For global events, the event is registered for all the harts.
///
/// The event MUST be in `UNUSED` state otherwise this function will fail.
///
/// Upon success, the event state moves from `UNUSED` to `REGISTERED`. In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event handler is registered successfully.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_state()` | `event_id` is valid but the event is not in `UNUSED` state.
/// | `SbiRet::invalid_param()` | `event_id` is invalid or `handler_entry_pc` is not 2-bytes aligned.
/// Unregister the event handler for given `event_id`.
///
/// For local events, the event is unregistered only for the calling hart.
/// For global events, the event is unregistered for all the harts.
///
/// The event MUST be in `REGISTERED` state otherwise this function will fail.
///
/// Upon success, the event state moves from `REGISTERED` to `UNUSED`. In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event handler is unregistered successfully.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_state()` | `event_id` is valid but the event is not in `REGISTERED` state.
/// | `SbiRet::invalid_param()` | `event_id` is invalid.
/// Enable the software event specified by the `event_id` parameter.
///
/// For local events, the event is enabled only for the calling hart.
/// For global events, the event is enabled for all the harts.
///
/// The event MUST be in `REGISTERED` state otherwise this function will fail.
///
/// Upon success, the event state moves from `REGISTERED` to `ENABLED`. In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event is successfully enabled.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_param()` | `event_id` is invalid.
/// | `SbiRet::invalid_state()` | `event_id` is valid but the event is not in `REGISTERED` state.
/// Disable the software event specified by the `event_id` parameter.
///
/// For local events, the event is disabled only for the calling hart.
/// For global events, the event is disabled for all the harts.
///
/// The event MUST be in `ENABLED` state otherwise this function will fail.
///
/// Upon success, the event state moves from `ENABLED` to `REGISTERED`. In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event is successfully disabled.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_param()` | `event_id` is invalid.
/// | `SbiRet::invalid_state()` | `event_id` is valid but the event is not in `ENABLED` state.
/// Complete the supervisor event handling for the highest priority event in `RUNNING` state on the calling hart.
///
/// If there were no events in `RUNNING` state on the calling hart then this function does nothing and returns `SBI_SUCCESS`
/// otherwise it moves the highest priority event in `RUNNING` state to:
///
/// - `REGISTERED` if the event is configured as one-shot
/// - `ENABLED` state otherwise
///
/// It then resumes the interrupted supervisor state.
/// The supervisor software can inject a software event with this function.
///
/// The `event_id` parameter refers to the ID of the event to be injected.
///
/// For local events, the `hart_id` parameter refers to the hart on which the event is to be injected.
/// For global events, the `hart_id` parameter is ignored.
///
/// An event can only be injected if it is allowed by the event attribute.
///
/// If an event is injected from within an SSE event handler, if it is ready to be run,
/// it will be handled according to the priority rules
///
/// - If it has a higher priority than the one currently running, then it will be handled immediately, effectively preempting the currently running one.
/// - If it has a lower priority, it will be run after the one that is currently running completes.
///
/// In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Event is successfully injected.
/// | `SbiRet::not_supported()` | `event_id` is not reserved and valid, but the platform does not support it due to one or more missing dependencies (Hardware or SBI implementation).
/// | `SbiRet::invalid_param()` | `event_id` is invalid or `hart_id` is invalid.
/// | `SbiRet::failed()` | The injection failed for unspecified or unknown other reasons.
/// Start receiving (or unmask) software events on the calling hart.
/// In other words, the calling hart is ready to receive software events from the SBI implementation.
///
/// The software events are masked initially on all harts so the supervisor software must
/// explicitly unmask software events on relevant harts at boot-time.
///
/// In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Software events unmasked successfully on the calling hart.
/// | `SbiRet::already_started()` | Software events were already unmasked on the calling hart.
/// | `SbiRet::failed()` | The request failed for unspecified or unknown other reasons.
/// Stop receiving (or mask) software events on the calling hart.
/// In other words, the calling hart will no longer be ready to receive software events from the SBI implementation.
///
/// In case of an error, possible error codes are listed below.
///
/// # Return value
///
/// | Error code | Description
/// |:----------------------------|:---------------------------------
/// | `SbiRet::success()` | Software events masked successfully on the calling hart.
/// | `SbiRet::already_stopped()` | Software events were already masked on the calling hart.
/// | `SbiRet::failed()` | The request failed for unspecified or unknown other reasons.