Software APIs
sw
device
lib
dif
dif_rv_plic.h
Go to the documentation of this file.
1
// Copyright lowRISC contributors (OpenTitan project).
2
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
// SPDX-License-Identifier: Apache-2.0
4
5
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_PLIC_H_
6
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_PLIC_H_
7
8
/**
9
* @file
10
* @brief <a href="/hw/ip/rv_plic/doc/">PLIC</a> Device Interface Functions
11
*
12
* The PLIC should be largely compatible with the (currently draft) [RISC-V PLIC
13
* specification][plic], but tailored for the OpenTitan rv_plic register
14
* addresses. We intend to make the addresses compatible with the PLIC
15
* specification in the near future.
16
*
17
* [plic]: https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc
18
*/
19
20
#include <
stdbool.h
>
21
#include <
stdint.h
>
22
23
#include "dt/dt_api.h"
// Generated
24
#include "
sw/device/lib/base/macros.h
"
25
#include "
sw/device/lib/base/mmio.h
"
26
#include "
sw/device/lib/dif/dif_base.h
"
27
28
#include "sw/device/lib/dif/autogen/dif_rv_plic_autogen.h"
29
30
#ifdef __cplusplus
31
extern
"C"
{
32
#endif
// __cplusplus
33
34
/**
35
* The lowest interrupt priority.
36
*/
37
extern
const
uint32_t
kDifRvPlicMinPriority
;
38
39
/**
40
* The highest interrupt priority.
41
*/
42
extern
const
uint32_t
kDifRvPlicMaxPriority
;
43
44
/**
45
* A PLIC interrupt source identifier.
46
*
47
* This corresponds to a specific interrupt, and not the device it originates
48
* from.
49
*
50
* This is an unsigned 32-bit value that is at least zero and is less than the
51
* `NumSrc` instantiation parameter of the `rv_plic` device.
52
*
53
* The value 0 corresponds to "No Interrupt".
54
*/
55
typedef
dt_plic_irq_id_t
dif_rv_plic_irq_id_t
;
56
57
/**
58
* A PLIC interrupt target.
59
*
60
* This corresponds to a specific system that can service an interrupt. In
61
* OpenTitan's case, that is the Ibex core. If there were multiple cores in the
62
* system, each core would have its own specific interrupt target ID.
63
*
64
* This is an unsigned 32-bit value that is at least 0 and is less than the
65
* `NumTarget` instantiation parameter of the `rv_plic` device.
66
*/
67
typedef
uint32_t
dif_rv_plic_target_t
;
68
69
/**
70
* Resets the PLIC to a clean state.
71
*
72
*
73
* This function resets all the relevant PLIC registers, apart from the CC
74
* register. There is no reliable way of knowing the ID of an IRQ that has
75
* claimed the CC register, so we assume that the previous "owner" of the
76
* resource has cleared/completed the CC access.
77
*
78
* @param plic A PLIC handle.
79
* @return The result of the operation.
80
*/
81
OT_WARN_UNUSED_RESULT
82
dif_result_t
dif_rv_plic_reset
(
const
dif_rv_plic_t *plic);
83
84
/**
85
* Returns whether a particular interrupt is currently pending.
86
*
87
* @param plic A PLIC handle.
88
* @param irq An interrupt type.
89
* @param[out] is_pending Out-param for whether the interrupt is pending.
90
* @return The result of the operation.
91
*/
92
OT_WARN_UNUSED_RESULT
93
dif_result_t
dif_rv_plic_irq_is_pending
(
const
dif_rv_plic_t *plic,
94
dif_rv_plic_irq_id_t
irq,
95
bool
*is_pending);
96
97
/**
98
* Checks whether a particular interrupt is currently enabled or disabled.
99
*
100
* @param plic A PLIC handle.
101
* @param irq An interrupt type.
102
* @param target An interrupt target.
103
* @param[out] state Out-param toggle state of the interrupt.
104
* @return The result of the operation.
105
*/
106
OT_WARN_UNUSED_RESULT
107
dif_result_t
dif_rv_plic_irq_get_enabled
(
const
dif_rv_plic_t *plic,
108
dif_rv_plic_irq_id_t
irq,
109
dif_rv_plic_target_t
target,
110
dif_toggle_t
*state);
111
112
/**
113
* Sets whether a particular interrupt is currently enabled or disabled.
114
*
115
* This operation does not affect IRQ generation in `target`, which
116
* must be configured in the corresponding peripheral itself.
117
*
118
* @param plic A PLIC handle.
119
* @param irq An interrupt type.
120
* @param target An interrupt target.
121
* @param state The new toggle state for the interrupt.
122
* @return The result of the operation.
123
*/
124
OT_WARN_UNUSED_RESULT
125
dif_result_t
dif_rv_plic_irq_set_enabled
(
const
dif_rv_plic_t *plic,
126
dif_rv_plic_irq_id_t
irq,
127
dif_rv_plic_target_t
target,
128
dif_toggle_t
state);
129
130
/**
131
* Sets IRQ source priority (0-3).
132
*
133
* In order for the PLIC to set a Claim/Complete register and assert the
134
* external interrupt line to the target (Ibex, ...), the priority of the IRQ
135
* source must be higher than the threshold for this source.
136
*
137
* @param plic A PLIC handle.
138
* @param irq An interrupt type.
139
* @param priority Priority to set.
140
* @return The result of the operation.
141
*/
142
OT_WARN_UNUSED_RESULT
143
dif_result_t
dif_rv_plic_irq_set_priority
(
const
dif_rv_plic_t *plic,
144
dif_rv_plic_irq_id_t
irq,
145
uint32_t priority);
146
147
/**
148
* Sets the target priority threshold.
149
*
150
* Sets the target priority threshold. PLIC will only interrupt a target when
151
* IRQ source priority is set higher than the priority threshold for the
152
* corresponding target.
153
*
154
* @param plic A PLIC handle.
155
* @param target Target to set the IRQ priority threshold for.
156
* @param threshold IRQ priority threshold to be set.
157
* @return The result of the operation.
158
*/
159
OT_WARN_UNUSED_RESULT
160
dif_result_t
dif_rv_plic_target_set_threshold
(
const
dif_rv_plic_t *plic,
161
dif_rv_plic_target_t
target,
162
uint32_t threshold);
163
164
/**
165
* Claims an IRQ and gets the information about the source.
166
*
167
* Claims an IRQ and returns the IRQ related data to the caller. This function
168
* reads a target specific Claim/Complete register. #dif_rv_plic_irq_complete
169
* must be called in order to allow another interrupt with the same source id to
170
* be delivered. This usually would be done once the interrupt has been
171
* serviced.
172
*
173
* Another IRQ can be claimed before a prior IRQ is completed. In this way, this
174
* functionality is compatible with nested interrupt handling. The restriction
175
* is that you must Complete a Claimed IRQ before you will be able to claim an
176
* IRQ with the same ID. This allows a pair of Claim/Complete calls to be
177
* overlapped with another pair -- and there is no requirement that the
178
* interrupts should be Completed in the reverse order of when they were
179
* Claimed.
180
*
181
* @see #dif_rv_plic_irq_complete
182
*
183
* @param plic A PLIC handle.
184
* @param target Target that claimed the IRQ.
185
* @param[out] claim_data Data that describes the origin of the IRQ.
186
* @return The result of the operation.
187
*/
188
OT_WARN_UNUSED_RESULT
189
dif_result_t
dif_rv_plic_irq_claim
(
const
dif_rv_plic_t *plic,
190
dif_rv_plic_target_t
target,
191
dif_rv_plic_irq_id_t
*claim_data);
192
193
/**
194
* Completes the claimed IRQ.
195
*
196
* Finishes servicing of the claimed IRQ by writing the IRQ source ID back to a
197
* target specific Claim/Complete register. This function must be called after
198
* #dif_rv_plic_irq_claim, when the caller is prepared to service another IRQ
199
* with the same source ID. If a source ID is never Completed, then when future
200
* interrupts are Claimed, they will never have the source ID of the uncompleted
201
* IRQ.
202
*
203
* @see #dif_rv_plic_irq_claim
204
*
205
* @param plic A PLIC handle.
206
* @param target Target that claimed the IRQ.
207
* @param complete_data Previously claimed IRQ data that is used to signal
208
* PLIC of the IRQ servicing completion.
209
* @return The result of the operation.
210
*/
211
OT_WARN_UNUSED_RESULT
212
dif_result_t
dif_rv_plic_irq_complete
(
const
dif_rv_plic_t *plic,
213
dif_rv_plic_target_t
target,
214
dif_rv_plic_irq_id_t
complete_data);
215
216
/**
217
* Forces the software interrupt for a particular target.
218
*
219
* This function causes an interrupt to the `target` HART to be serviced as if
220
* hardware had asserted it.
221
*
222
* This function allows to synchronise between the HARTs, which otherwise
223
* would not be possible due to HART being only able to access own CSRs.
224
* NOTE: this is not an issue on Ibex, as it has only one HART.
225
*
226
* An interrupt handler is expected to call
227
* `dif_rv_plic_software_irq_acknowledge` when the interrupt has been handled.
228
*
229
* @param plic PLIC state data.
230
* @param target Target HART.
231
* @return `dif_result_t`.
232
*/
233
OT_WARN_UNUSED_RESULT
234
dif_result_t
dif_rv_plic_software_irq_force
(
const
dif_rv_plic_t *plic,
235
dif_rv_plic_target_t
target);
236
237
/**
238
* Acknowledges the software interrupt for a particular target.
239
*
240
* This function indicates to the hardware that the software interrupt has been
241
* successfully serviced. It is expected to be called from a software interrupt
242
* handler.
243
*
244
* @param plic PLIC state data.
245
* @param target Target HART.
246
* @return `dif_result_t`.
247
*/
248
OT_WARN_UNUSED_RESULT
249
dif_result_t
dif_rv_plic_software_irq_acknowledge
(
const
dif_rv_plic_t *plic,
250
dif_rv_plic_target_t
target);
251
252
/**
253
* Returns software interrupt pending state for a particular target.
254
*
255
* @param plic PLIC state data.
256
* @param target Target HART.
257
* @param[out] is_pending Flag indicating whether the interrupt is pending.
258
* @return `dif_result_t`.
259
*/
260
OT_WARN_UNUSED_RESULT
261
dif_result_t
dif_rv_plic_software_irq_is_pending
(
const
dif_rv_plic_t *plic,
262
dif_rv_plic_target_t
target,
263
bool
*is_pending);
264
265
#ifdef __cplusplus
266
}
// extern "C"
267
#endif
// __cplusplus
268
269
#endif
// OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_PLIC_H_
Return to
OpenTitan Documentation