gem5 v23.0.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
interrupts.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, 2012-2013, 2016 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#ifndef __ARCH_ARM_INTERRUPT_HH__
42#define __ARCH_ARM_INTERRUPT_HH__
43
44#include "arch/arm/faults.hh"
45#include "arch/arm/regs/misc.hh"
46#include "arch/arm/utility.hh"
48#include "cpu/thread_context.hh"
49#include "debug/Interrupt.hh"
50#include "enums/ArmExtension.hh"
51#include "params/ArmInterrupts.hh"
52
53namespace gem5
54{
55
56namespace ArmISA
57{
58
60{
65 INT_SEV, // Special interrupt for recieving SEV's
69};
70
72{
73 private:
75 uint64_t intStatus;
76
77 public:
78 using Params = ArmInterruptsParams;
79
81 {
82 clearAll();
83 }
84
85
86 void
87 post(int int_num, int index) override
88 {
89 DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
90
91 if (int_num < 0 || int_num >= NumInterruptTypes)
92 panic("int_num out of bounds\n");
93
94 if (index != 0)
95 panic("No support for other interrupt indexes\n");
96
97 interrupts[int_num] = true;
98 intStatus |= 1ULL << int_num;
99 }
100
101 void
102 clear(int int_num, int index) override
103 {
104 DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
105
106 if (int_num < 0 || int_num >= NumInterruptTypes)
107 panic("int_num out of bounds\n");
108
109 if (index != 0)
110 panic("No support for other interrupt indexes\n");
111
112 interrupts[int_num] = false;
113 intStatus &= ~(1ULL << int_num);
114 }
115
116 void
117 clearAll() override
118 {
119 DPRINTF(Interrupt, "Interrupts all cleared\n");
120 intStatus = 0;
121 memset(interrupts, 0, sizeof(interrupts));
122 }
123
125 {
126 INT_MASK_M, // masked (subject to PSTATE.{A,I,F} mask bit
127 INT_MASK_T, // taken regardless of mask
128 INT_MASK_P // pending
129 };
130
131 bool takeInt(InterruptTypes int_type) const;
132
133 bool
134 checkInterrupts() const override
135 {
136 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
137
138 if (!(intStatus || hcr.va || hcr.vi || hcr.vf))
139 return false;
140
141 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
142
143 bool no_vhe = !HaveExt(tc, ArmExtension::FEAT_VHE);
144 bool amo, fmo, imo;
145 if (hcr.tge == 1){
146 amo = (no_vhe || hcr.e2h == 0);
147 fmo = (no_vhe || hcr.e2h == 0);
148 imo = (no_vhe || hcr.e2h == 0);
149 } else {
150 amo = hcr.amo;
151 fmo = hcr.fmo;
152 imo = hcr.imo;
153 }
154
155 bool isHypMode = currEL(tc) == EL2;
157 bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode;
158 bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode;
159 bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;
160
161 if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
162 (hcr.va && allowVAbort)) )
163 return false;
164
165 bool take_irq = takeInt(INT_IRQ);
166 bool take_fiq = takeInt(INT_FIQ);
167 bool take_ea = takeInt(INT_ABT);
168
169 return ((interrupts[INT_IRQ] && take_irq) ||
170 (interrupts[INT_FIQ] && take_fiq) ||
171 (interrupts[INT_ABT] && take_ea) ||
172 ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) ||
173 ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) ||
174 (hcr.va && allowVAbort) ||
175 (interrupts[INT_RST]) ||
177 );
178 }
179
185 bool
186 checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
187 {
188 uint64_t maskedIntStatus;
189 bool virtWake;
190
191 maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) |
192 (1 << INT_VIRT_FIQ));
193 virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo;
194 virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo;
195 virtWake |= hcr.va && hcr.amo;
196 virtWake &= (cpsr.mode != MODE_HYP) && !isSecure(tc);
197 return maskedIntStatus || virtWake;
198 }
199
200 uint32_t
201 getISR(HCR hcr, CPSR cpsr, SCR scr)
202 {
203 bool useHcrMux;
204 CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR
205
206 useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc);
207 isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi)
209 isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf)
211 isr.a = (useHcrMux & hcr.amo) ? hcr.va : interrupts[INT_ABT];
212 return isr;
213 }
214
225 bool
226 checkRaw(InterruptTypes interrupt) const
227 {
228 if (interrupt >= NumInterruptTypes)
229 panic("Interrupt number out of range.\n");
230
231 return interrupts[interrupt];
232 }
233
234 Fault
235 getInterrupt() override
236 {
237 assert(checkInterrupts());
238
239 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
240 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
241
242 bool no_vhe = !HaveExt(tc, ArmExtension::FEAT_VHE);
243 bool amo, fmo, imo;
244 if (hcr.tge == 1){
245 amo = (no_vhe || hcr.e2h == 0);
246 fmo = (no_vhe || hcr.e2h == 0);
247 imo = (no_vhe || hcr.e2h == 0);
248 } else {
249 amo = hcr.amo;
250 fmo = hcr.fmo;
251 imo = hcr.imo;
252 }
253
254 // Calculate a few temp vars so we can work out if there's a pending
255 // virtual interrupt, and if its allowed to happen
256 // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
257 bool isHypMode = currEL(tc) == EL2;
259 bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode;
260 bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode;
261 bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;
262
263 bool take_irq = takeInt(INT_IRQ);
264 bool take_fiq = takeInt(INT_FIQ);
265 bool take_ea = takeInt(INT_ABT);
266
267 if (interrupts[INT_IRQ] && take_irq)
268 return std::make_shared<Interrupt>();
269 if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
270 return std::make_shared<VirtualInterrupt>();
271 if (interrupts[INT_FIQ] && take_fiq)
272 return std::make_shared<FastInterrupt>();
273 if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
274 return std::make_shared<VirtualFastInterrupt>();
275 if (interrupts[INT_ABT] && take_ea)
276 return std::make_shared<SystemError>();
277 if (hcr.va && allowVAbort)
278 return std::make_shared<VirtualDataAbort>(
281 if (interrupts[INT_RST])
282 return std::make_shared<Reset>();
283 if (interrupts[INT_SEV])
284 return std::make_shared<ArmSev>();
285
286 panic("intStatus and interrupts not in sync\n");
287 }
288
289 void updateIntrInfo() override {} // nothing to do
290
291 void
292 serialize(CheckpointOut &cp) const override
293 {
296 }
297
298 void
300 {
303 }
304};
305
306} // namespace ARM_ISA
307} // namespace gem5
308
309#endif // __ARCH_ARM_INTERRUPT_HH__
#define DPRINTF(x,...)
Definition trace.hh:210
void clearAll() override
bool checkInterrupts() const override
uint32_t getISR(HCR hcr, CPSR cpsr, SCR scr)
void updateIntrInfo() override
bool takeInt(InterruptTypes int_type) const
Definition interrupts.cc:46
void clear(int int_num, int index) override
bool interrupts[NumInterruptTypes]
Definition interrupts.hh:74
void serialize(CheckpointOut &cp) const override
Serialize an object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void post(int int_num, int index) override
Definition interrupts.hh:87
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
ArmInterruptsParams Params
Definition interrupts.hh:78
bool checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
This function is used to check if a wfi operation should sleep.
Fault getInterrupt() override
Interrupts(const Params &p)
Definition interrupts.hh:80
ThreadContext * tc
Definition interrupts.hh:44
virtual RegVal readMiscReg(RegIndex misc_reg)=0
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:124
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 4 > imo
Bitfield< 3 > fmo
@ MISCREG_CPSR
Definition misc.hh:66
@ MISCREG_HCR_EL2
Definition misc.hh:591
Bitfield< 5 > amo
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Definition utility.cc:222
Bitfield< 30, 0 > index
Bitfield< 0 > p
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
std::ostream CheckpointOut
Definition serialize.hh:66
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568

Generated on Mon Jul 10 2023 15:31:58 for gem5 by doxygen 1.9.7