gem5 v24.0.0.0
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{
43 for (uint8_t i = 0;
44 i < p.port_local_interrupt_pins_connection_count;
45 ++i) {
46 uint8_t interruptID = p.local_interrupt_ids[i];
47 assert(interruptID <= 47);
48 std::string pinName =
49 csprintf("%s.local_interrupt_pins[%d]", p.name, i);
51 new IntSinkPin<Interrupts>(pinName,i, this, interruptID);
52 localInterruptPins.push_back(pin);
53 }
54}
55
56
57std::bitset<NumInterruptTypes>
59{
60 INTERRUPT mask = 0;
63 INTERRUPT mideleg = 0;
64 if (misa.rvs || misa.rvn) {
65 mideleg = tc->readMiscReg(MISCREG_MIDELEG);
66 }
67 INTERRUPT sideleg = 0;
68 if (misa.rvs && misa.rvn) {
69 sideleg = tc->readMiscReg(MISCREG_SIDELEG);
70 }
72 switch (prv) {
73 case PRV_U:
74 // status.uie is always 0 if misa.rvn is disabled
75 if (misa.rvs) {
76 mask.local = ~sideleg.local;
77 if (status.uie)
78 mask.local = mask.local | sideleg.local;
79 mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie);
80 mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie);
81 mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie);
82 mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie);
83 mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie);
84 mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie);
85 } else {
86 // According to the RISC-V privilege spec v1.10, if the
87 // S privilege mode is not implemented and user-trap
88 // support, setting mideleg/medeleg bits will delegate the
89 // trap to U-mode trap handler
90 mask.local = ~mideleg.local;
91 if (status.uie)
92 mask.local = mask.local | mideleg.local;
93 mask.mei = (!mideleg.mei) | (mideleg.mei & status.uie);
94 mask.mti = (!mideleg.mti) | (mideleg.mti & status.uie);
95 mask.msi = (!mideleg.msi) | (mideleg.msi & status.uie);
96 mask.sei = mask.sti = mask.ssi = 0;
97 }
98 if (status.uie)
99 mask.uei = mask.uti = mask.usi = 1;
100 break;
101 case PRV_S:
102 mask.local = ~mideleg.local;
103 mask.mei = (!mideleg.mei) | (mideleg.mei & status.sie);
104 mask.mti = (!mideleg.mti) | (mideleg.mti & status.sie);
105 mask.msi = (!mideleg.msi) | (mideleg.msi & status.sie);
106 if (status.sie) {
107 mask.sei = mask.sti = mask.ssi = 1;
108 mask.local = mask.local | mideleg.local;
109 }
110 mask.uei = mask.uti = mask.usi = 0;
111 break;
112 case PRV_M:
113
114 if (status.mie) {
115 mask.local = gem5::mask(48);
116 mask.mei = mask.mti = mask.msi = 1;
117 }
118 mask.sei = mask.sti = mask.ssi = 0;
119 mask.uei = mask.uti = mask.usi = 0;
120 break;
121 default:
122 panic("Unknown privilege mode %d.", prv);
123 break;
124 }
125
126 return std::bitset<NumInterruptTypes>(mask);
127}
128
129Fault
131{
132 assert(checkInterrupts());
134 return std::make_shared<NonMaskableInterruptFault>();
135 std::bitset<NumInterruptTypes> mask = globalMask();
136 if (((ISA*) tc->getIsaPtr())->rvType() == RV64) {
137 const std::vector<int> interrupt_order {
153 };
154 for (const int &id : interrupt_order) {
155 if (checkInterrupt(id) && mask[id]) {
156 return std::make_shared<InterruptFault>(id);
157 }
158 }
159 } else if (((ISA*) tc->getIsaPtr())->rvType() == RV32) {
160 const std::vector<int> interrupt_order {
168 };
169 for (const int &id : interrupt_order) {
170 if (checkInterrupt(id) && mask[id]) {
171 return std::make_shared<InterruptFault>(id);
172 }
173 }
174 }
175 return NoFault;
176}
177
178void
179Interrupts::post(int int_num, int index)
180{
181 DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
182 if (int_num != INT_NMI) {
183 ip[int_num] = true;
184 } else {
185 postNMI();
186 }
187}
188
189void
190Interrupts::clear(int int_num, int index)
191{
192 DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
193 if (int_num != INT_NMI) {
194 ip[int_num] = false;
195 } else {
196 clearNMI();
197 }
198}
199
200void
202{
203 DPRINTF(Interrupt, "All interrupts cleared\n");
204 ip = 0;
205 clearNMI();
206}
207
208void
210{
211 tc->getCpuPtr()->postInterrupt(tc->threadId(), num + 16, 0);
212}
213
214void
216{
217 unsigned long ip_ulong = ip.to_ulong();
218 unsigned long ie_ulong = ie.to_ulong();
219 SERIALIZE_SCALAR(ip_ulong);
220 SERIALIZE_SCALAR(ie_ulong);
221}
222
223void
225{
226 unsigned long ip_ulong;
227 unsigned long ie_ulong;
228 UNSERIALIZE_SCALAR(ip_ulong);
229 ip = ip_ulong;
230 UNSERIALIZE_SCALAR(ie_ulong);
231 ie = ie_ulong;
232}
233
234Port &
235Interrupts::getPort(const std::string &if_name, PortID idx)
236{
237
238 if (if_name == "local_interrupt_pins" && idx < localInterruptPins.size()) {
239 return *localInterruptPins[idx];
240 } else {
241 return BaseInterrupts::getPort(if_name, idx);
242 }
243}
244
245} // namespace RiscvISA
246
247} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
void postInterrupt(ThreadID tid, int int_num, int index)
Definition base.cc:231
ThreadContext * tc
Definition interrupts.hh:44
Ports are used to interface objects to each other.
Definition port.hh:62
std::vector< gem5::IntSinkPin< Interrupts > * > localInterruptPins
Definition interrupts.hh:65
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:80
bool checkNonMaskableInterrupt() const
Definition interrupts.hh:74
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.
RiscvInterruptsParams Params
Definition interrupts.hh:67
std::bitset< NumInterruptTypes > globalMask() const
Definition interrupts.cc:58
std::bitset< NumInterruptTypes > ip
Definition interrupts.hh:62
bool checkInterrupt(int num) const
Definition interrupts.hh:79
Fault getInterrupt() override
std::bitset< NumInterruptTypes > ie
Definition interrupts.hh:63
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual BaseISA * getIsaPtr() const =0
virtual BaseCPU * getCpuPtr()=0
virtual int threadId() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
STL vector class.
Definition stl.hh:37
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
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< 33 > id
Bitfield< 5, 0 > status
Bitfield< 0 > p
constexpr enums::RiscvType RV32
Definition pcstate.hh:56
Bitfield< 0 > ie
Bitfield< 30, 0 > index
Bitfield< 2 > i
constexpr enums::RiscvType RV64
Definition pcstate.hh:57
@ MISCREG_SIDELEG
Definition misc.hh:178
@ MISCREG_STATUS
Definition misc.hh:76
@ MISCREG_MIDELEG
Definition misc.hh:149
@ INT_TIMER_MACHINE
Definition faults.hh:93
@ INT_SOFTWARE_SUPER
Definition faults.hh:89
@ INT_SOFTWARE_MACHINE
Definition faults.hh:90
@ INT_SOFTWARE_USER
Definition faults.hh:88
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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:75
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 Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0