gem5 v25.0.0.1
Loading...
Searching...
No Matches
interrupts.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Google
3 * Copyright (c) 2024 University of Rostock
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
32
33namespace gem5
34{
35
36namespace RiscvISA
37{
38
40 ip(0),
41 ie(0),
42 hvip(0),
44{
45 for (uint8_t i = 0;
46 i < p.port_local_interrupt_pins_connection_count;
47 ++i) {
48 uint8_t interruptID = p.local_interrupt_ids[i];
49 assert(interruptID <= 47);
50 std::string pinName =
51 csprintf("%s.local_interrupt_pins[%d]", p.name, i);
53 new IntSinkPin<Interrupts>(pinName,i, this, interruptID);
54 localInterruptPins.push_back(pin);
55 }
56}
57
58
59std::bitset<NumInterruptTypes>
61{
62 INTERRUPT mask = 0;
63 STATUS status = tc->readMiscReg(MISCREG_STATUS);
64 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
65 INTERRUPT mideleg = 0;
66 if (misa.rvs) {
67 mideleg = tc->readMiscReg(MISCREG_MIDELEG);
68 }
69 PrivilegeMode prv = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
70 switch (prv) {
71 case PRV_U:
72 if (misa.rvh && virtualizationEnabled(tc)) {
73 STATUS vsstatus = tc->readMiscReg(MISCREG_VSSTATUS);
74 INTERRUPT hideleg = tc->readMiscReg(MISCREG_HIDELEG);
75
76 mask.local = ~hideleg.local | ~mideleg.local;
77
78 mask.vsei = (~hideleg.vsei)|(hideleg.vsei & vsstatus.sie);
79 mask.vssi = (~hideleg.vssi)|(hideleg.vssi & vsstatus.sie);
80 mask.vsti = (~hideleg.vsti)|(hideleg.vsti & vsstatus.sie);
81
82 mask.mei = (~mideleg.mei | ~hideleg.mei)
83 | (mideleg.mei & hideleg.mei & vsstatus.sie);
84
85 mask.mti = (~mideleg.mti | ~hideleg.mti)
86 | (mideleg.mti & hideleg.mti & vsstatus.sie);
87
88 mask.msi = (~mideleg.msi | ~hideleg.msi)
89 | (mideleg.msi & hideleg.msi & vsstatus.sie);
90
91 mask.sei = (~mideleg.sei | ~hideleg.sei)
92 | (mideleg.sei & hideleg.sei & vsstatus.sie);
93
94 mask.sti = (~mideleg.sti | ~hideleg.sti)
95 | (mideleg.sti & hideleg.sti & vsstatus.sie);
96
97 mask.ssi = (~mideleg.ssi | ~hideleg.ssi)
98 | (mideleg.ssi & hideleg.ssi & vsstatus.sie);
99 } else {
100 mask.local = gem5::mask(48);
101 mask.mei = 1;
102 mask.mti = 1;
103 mask.msi = 1;
104 mask.sei = 1;
105 mask.sti = 1;
106 mask.ssi = 1;
107 }
108 break;
109 case PRV_S:
110 if (misa.rvh && virtualizationEnabled(tc)) {
111 STATUS vsstatus = tc->readMiscReg(MISCREG_VSSTATUS);
112 INTERRUPT hideleg = tc->readMiscReg(MISCREG_HIDELEG);
113
114 mask.local = ~hideleg.local | ~mideleg.local;
115 if (status.sie) {
116 mask.local = mask.local | (hideleg.local & mideleg.local);
117 }
118
119 mask.vsei = (~hideleg.vsei)|(hideleg.vsei & vsstatus.sie);
120 mask.vssi = (~hideleg.vssi)|(hideleg.vssi & vsstatus.sie);
121 mask.vsti = (~hideleg.vsti)|(hideleg.vsti & vsstatus.sie);
122
123 // status.sie is always 0 if misa.rvn is disabled
124 mask.mei = (~mideleg.mei | ~hideleg.mei)
125 | (mideleg.mei & hideleg.mei & vsstatus.sie);
126
127 mask.mti = (~mideleg.mti | ~hideleg.mti)
128 | (mideleg.mti & hideleg.mti & vsstatus.sie);
129
130 mask.msi = (~mideleg.msi | ~hideleg.msi)
131 | (mideleg.msi & hideleg.msi & vsstatus.sie);
132
133
134 mask.sei = (~mideleg.sei | ~hideleg.sei)
135 | (mideleg.sei & hideleg.sei & vsstatus.sie);
136
137 mask.sti = (~mideleg.sti | ~hideleg.sti)
138 | (mideleg.sti & hideleg.sti & vsstatus.sie);
139
140 mask.ssi = (~mideleg.ssi | ~hideleg.ssi)
141 | (mideleg.ssi & hideleg.ssi & vsstatus.sie);
142 } else {
143 mask.local = ~mideleg.local;
144 mask.mei = (~mideleg.mei) | (mideleg.mei & status.sie);
145 mask.mti = (~mideleg.mti) | (mideleg.mti & status.sie);
146 mask.msi = (~mideleg.msi) | (mideleg.msi & status.sie);
147 if (status.sie) {
148 mask.sei = mask.sti = mask.ssi = 1;
149 mask.local = mask.local | mideleg.local;
150 }
151 }
152
153 break;
154 case PRV_M:
155 if (status.mie) {
156 mask.local = gem5::mask(48);
157 mask.mei = mask.mti = mask.msi = 1;
158 }
159 mask.sei = mask.sti = mask.ssi = 0;
160 break;
161 default:
162 panic("Unknown privilege mode %d.", prv);
163 break;
164 }
165
166 return std::bitset<NumInterruptTypes>(mask);
167}
168
169Fault
171{
172 assert(checkInterrupts());
174 return std::make_shared<NonMaskableInterruptFault>(nmi_cause);
175 std::bitset<NumInterruptTypes> mask = globalMask();
176 if (((ISA*) tc->getIsaPtr())->rvType() == RV64) {
177 const std::vector<int> interrupt_order {
190 //Table 5.1 from riscv-interrupts-1.0-RC3.pdf
191 //https://github.com/riscv/riscv-aia
196 };
197 for (const int &id : interrupt_order) {
198 if (checkInterrupt(id) && mask[id]) {
199 return std::make_shared<InterruptFault>(id);
200 }
201 }
202 } else if (((ISA*) tc->getIsaPtr())->rvType() == RV32) {
203 const std::vector<int> interrupt_order {
210 };
211 for (const int &id : interrupt_order) {
212 if (checkInterrupt(id) && mask[id]) {
213 return std::make_shared<InterruptFault>(id);
214 }
215 }
216 }
217 return NoFault;
218}
219
220void
221Interrupts::post(int int_num, int index)
222{
223 DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
224 if (int_num != INT_NMI) {
225 ip[int_num] = true;
226 } else {
227 postNMI();
228 }
229}
230
231void
232Interrupts::clear(int int_num, int index)
233{
234 DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
235 if (int_num != INT_NMI) {
236 ip[int_num] = false;
237 } else {
238 clearNMI();
239 }
240}
241
242void
244{
245 DPRINTF(Interrupt, "All interrupts cleared\n");
246 ip = 0;
247 clearNMI();
248}
249
250void
252{
253 tc->getCpuPtr()->postInterrupt(tc->threadId(), num + 16, 0);
254}
255
256void
258{
259 unsigned long ip_ulong = ip.to_ulong();
260 unsigned long hvip_ulong = hvip.to_ulong();
261 unsigned long ie_ulong = ie.to_ulong();
262 SERIALIZE_SCALAR(ip_ulong);
263 SERIALIZE_SCALAR(hvip_ulong);
264 SERIALIZE_SCALAR(ie_ulong);
265}
266
267void
269{
270 unsigned long ip_ulong;
271 unsigned long hvip_ulong;
272 unsigned long ie_ulong;
273 UNSERIALIZE_SCALAR(ip_ulong);
274 ip = ip_ulong;
275 UNSERIALIZE_SCALAR(hvip_ulong);
276 hvip = hvip_ulong;
277 UNSERIALIZE_SCALAR(ie_ulong);
278 ie = ie_ulong;
279}
280
281Port &
282Interrupts::getPort(const std::string &if_name, PortID idx)
283{
284
285 if (if_name == "local_interrupt_pins" && idx < localInterruptPins.size()) {
286 return *localInterruptPins[idx];
287 } else {
288 return BaseInterrupts::getPort(if_name, idx);
289 }
290}
291
292} // namespace RiscvISA
293
294} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
ThreadContext * tc
Definition interrupts.hh:44
BaseInterrupts(const Params &p)
Definition interrupts.hh:49
Ports are used to interface objects to each other.
Definition port.hh:62
std::vector< gem5::IntSinkPin< Interrupts > * > localInterruptPins
Definition interrupts.hh:68
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Interrupts(const Params &p)
Definition interrupts.cc:39
void clear(int int_num, int index) override
bool checkInterrupts() const override
Definition interrupts.hh:89
bool checkNonMaskableInterrupt() const
Definition interrupts.hh:80
void post(int int_num, int index) override
void serialize(CheckpointOut &cp) const override
Serialize an object.
void raiseInterruptPin(uint32_t num)
Port & getPort(const std::string &if_name, PortID idx) override
Get a port with a given name and index.
std::bitset< NumInterruptTypes > hvip
Definition interrupts.hh:66
RiscvInterruptsParams Params
Definition interrupts.hh:73
std::bitset< NumInterruptTypes > globalMask() const
Definition interrupts.cc:60
std::bitset< NumInterruptTypes > ip
Definition interrupts.hh:62
bool checkInterrupt(int num) const
Definition interrupts.hh:85
Fault getInterrupt() override
std::bitset< NumInterruptTypes > ie
Definition interrupts.hh:63
STL vector class.
Definition stl.hh:37
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 5, 0 > status
Bitfield< 0 > p
constexpr enums::RiscvType RV32
Definition pcstate.hh:56
Bitfield< 30, 0 > index
Bitfield< 2 > i
bool virtualizationEnabled(ExecContext *xc)
Definition isa.cc:1331
constexpr enums::RiscvType RV64
Definition pcstate.hh:57
@ MISCREG_STATUS
Definition misc.hh:78
@ MISCREG_HIDELEG
Definition misc.hh:215
@ MISCREG_MIDELEG
Definition misc.hh:151
@ MISCREG_VSSTATUS
Definition misc.hh:227
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
std::ostream CheckpointOut
Definition serialize.hh:66
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
IntSinkPinBase IntSinkPin
Definition intpin.hh:77
constexpr decltype(nullptr) NoFault
Definition types.hh:253
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568

Generated on Sat Oct 18 2025 08:06:37 for gem5 by doxygen 1.14.0