CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Toggle main menu visibility
Loading...
Searching...
No Matches
sdk
include
platform
generic-riscv
platform-plic.hh
1
// Copyright Microsoft and CHERIoT Contributors.
2
// SPDX-License-Identifier: MIT
3
4
#pragma once
5
#include <
cheri.hh
>
6
#include <
compartment-macros.h
>
7
#include <optional>
8
#include <stdint.h>
9
#include <
utils.hh
>
10
11
/**
12
* Driver for the standard RISC-V Platform-Local Interrupt Controller (PLIC).
13
*
14
* `MaxIntrID` is the largest interrupt number that is used. `SourceID` and
15
* `Priority` are the types used for interrupt source numbers and priorities,
16
* respectively.
17
*/
18
template
<
size_t
MaxIntrID,
typename
SourceID,
typename
Priority>
19
class
StandardPlic
:
private
utils::NoCopyNoMove
20
{
21
public
:
22
/**
23
* Constructor. Initialises the interrupt controller with all interrupts
24
* disabled.
25
*/
26
StandardPlic
()
27
{
28
volatile
uint32_t *range =
MMIO_CAPABILITY
(uint32_t, plic);
29
size_t
nSources = (MaxIntrID + 32U) & ~0x1f;
30
// We program the enable bits in groups of 32.
31
size_t
nSourcesGroups = nSources >> 5;
32
33
auto
setField = [&](
auto
&field,
size_t
offset,
size_t
size) {
34
CHERI::Capability
capability{range};
35
capability.
address
() += offset;
36
capability.
bounds
() = size;
37
field = capability;
38
};
39
setField(plicPrios, PriorityOffset, nSources *
sizeof
(uint32_t));
40
setField(plicPendings, PendingOffset, nSources / 8);
41
setField(plicEnables, EnableOffset, nSources / 8);
42
setField(plicThres, ThresholdOffset,
sizeof
(uint32_t));
43
setField(plicClaim, ClaimOffset,
sizeof
(uint32_t));
44
45
for
(
size_t
i = 0; i < nSourcesGroups; i++)
46
{
47
plicEnables[i] = 0U;
48
}
49
for
(
size_t
i = 1; i <= MaxIntrID; i++)
50
{
51
plicPrios[i] = 0U;
52
}
53
// We don't make use of threshold control. Leave it at 0 so all
54
// configured interrupts can fire.
55
*plicThres = 0U;
56
}
57
58
/**
59
* Enable the specified interrupt.
60
*/
61
void
interrupt_enable
(SourceID src)
62
{
63
size_t
idx = src >> 5;
64
size_t
bitPos = src & 0x1f;
65
66
uint32_t enables = plicEnables[idx] | (1U << bitPos);
67
plicEnables[idx] = enables;
68
}
69
70
/**
71
* Disable the specified interrupt.
72
*/
73
void
interrupt_disable
(SourceID src)
74
{
75
size_t
idx = src >> 5;
76
size_t
bitPos = src & 0x1f;
77
78
uint32_t enables = plicEnables[idx] & ~(1U << bitPos);
79
plicEnables[idx] = enables;
80
}
81
82
/**
83
* Set the priority of the specified interrupt.
84
*/
85
void
priority_set
(SourceID src, Priority prio)
86
{
87
plicPrios[src] = prio;
88
}
89
90
/**
91
* Fetch the interrupt number that fired and prevent it from firing. If
92
* two or more interrupts have fired then this will return the
93
* highest-priority one.
94
*
95
* If no interrupt has fired (for example, because the interrupt line on
96
* the core was raised spuriously) then this returns `stdd:nullopt`.
97
*/
98
std::optional<SourceID>
interrupt_claim
()
99
{
100
uint32_t claim = *plicClaim;
101
// PLIC reserves source ID 0, which means no interrupts.
102
return
claim == 0 ? std::nullopt : std::optional{claim};
103
}
104
105
/**
106
* Tell the interrupt controller we've handled a specified interrupt ID.
107
*/
108
void
interrupt_complete
(SourceID src)
109
{
110
*plicClaim = src;
111
}
112
113
private
:
114
// generic offsets according to spec
115
static
constexpr
size_t
PriorityOffset = 0x0U;
116
static
constexpr
size_t
PendingOffset = 0x1000U;
117
static
constexpr
size_t
EnableOffset = 0x2000U;
118
static
constexpr
size_t
ThresholdOffset = 0x200000U;
119
static
constexpr
size_t
ClaimOffset = 0x200004U;
120
121
// Bounded capabilities to the individual structure fields.
122
// Ideally these should be contained in one volatile struct, but
123
// they are so far apart (and this lets us apply the bounds once).
124
volatile
uint32_t *plicPrios;
125
volatile
uint32_t *plicPendings;
126
volatile
uint32_t *plicEnables;
127
volatile
uint32_t *plicThres;
128
volatile
uint32_t *plicClaim;
129
};
130
131
/**
132
* Type representing no interrupt controller.
133
*
134
* Contains stub implementations of all of the methods.
135
*/
136
template
<
size_t
MaxIntrID,
typename
SourceID,
typename
Priority>
137
class
NoPlic
:
private
utils::NoCopyNoMove
138
{
139
public
:
140
void
interrupt_enable(SourceID) {}
141
void
interrupt_disable(SourceID) {}
142
143
void
priority_set(SourceID, Priority) {}
144
145
std::optional<SourceID> interrupt_claim()
146
{
147
return
std::nullopt;
148
}
149
void
interrupt_complete(SourceID) {}
150
};
151
152
/**
153
* The type for the Programmable Local Interrupt Controller (PLIC) to use.
154
*
155
* If there is no plic device then this provides a stub version.
156
*/
157
template
<
size_t
MaxIntrID,
typename
SourceID,
typename
Priority>
158
using
Plic =
159
#if DEVICE_EXISTS(plic)
160
StandardPlic
161
#else
162
NoPlic
163
#endif
164
<MaxIntrID, SourceID, Priority>;
cheri.hh
C++ helpers for operating on capabilities.
CHERI::Capability
Helper class for accessing capability properties on pointers.
Definition
cheri.hh:482
CHERI::Capability::address
AddressProxy address()
Access the address of the capability.
Definition
cheri.hh:851
CHERI::Capability::bounds
BoundsProxy bounds()
Access (read, set) the capability's bounds.
Definition
cheri.hh:867
NoPlic
Type representing no interrupt controller.
Definition
platform-plic.hh:138
StandardPlic
Driver for the standard RISC-V Platform-Local Interrupt Controller (PLIC).
Definition
platform-plic.hh:20
StandardPlic::interrupt_disable
void interrupt_disable(SourceID src)
Disable the specified interrupt.
Definition
platform-plic.hh:73
StandardPlic::StandardPlic
StandardPlic()
Constructor.
Definition
platform-plic.hh:26
StandardPlic::interrupt_complete
void interrupt_complete(SourceID src)
Tell the interrupt controller we've handled a specified interrupt ID.
Definition
platform-plic.hh:108
StandardPlic::interrupt_claim
std::optional< SourceID > interrupt_claim()
Fetch the interrupt number that fired and prevent it from firing.
Definition
platform-plic.hh:98
StandardPlic::priority_set
void priority_set(SourceID src, Priority prio)
Set the priority of the specified interrupt.
Definition
platform-plic.hh:85
StandardPlic::interrupt_enable
void interrupt_enable(SourceID src)
Enable the specified interrupt.
Definition
platform-plic.hh:61
utils::NoCopyNoMove
Utility class to delete copy and move contructors.
Definition
utils.hh:53
compartment-macros.h
Macros for interacting with the compartmentalisation model in CHERIoT.
MMIO_CAPABILITY
#define MMIO_CAPABILITY(type, name)
Provide a capability of the type volatile type * referring to the MMIO region exported in the linker ...
Definition
compartment-macros.h:90
utils.hh
Miscellaneous utility functions and classes.
Generated by
1.18.0