gem5  v21.2.1.0
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 "params/ArmInterrupts.hh"
51 
52 namespace gem5
53 {
54 
55 namespace ArmISA
56 {
57 
59 {
64  INT_SEV, // Special interrupt for recieving SEV's
68 };
69 
70 class Interrupts : public BaseInterrupts
71 {
72  private:
74  uint64_t intStatus;
75 
76  public:
77  using Params = ArmInterruptsParams;
78 
80  {
81  clearAll();
82  }
83 
84 
85  void
86  post(int int_num, int index) override
87  {
88  DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
89 
90  if (int_num < 0 || int_num >= NumInterruptTypes)
91  panic("int_num out of bounds\n");
92 
93  if (index != 0)
94  panic("No support for other interrupt indexes\n");
95 
96  interrupts[int_num] = true;
97  intStatus |= 1ULL << int_num;
98  }
99 
100  void
101  clear(int int_num, int index) override
102  {
103  DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
104 
105  if (int_num < 0 || int_num >= NumInterruptTypes)
106  panic("int_num out of bounds\n");
107 
108  if (index != 0)
109  panic("No support for other interrupt indexes\n");
110 
111  interrupts[int_num] = false;
112  intStatus &= ~(1ULL << int_num);
113  }
114 
115  void
116  clearAll() override
117  {
118  DPRINTF(Interrupt, "Interrupts all cleared\n");
119  intStatus = 0;
120  memset(interrupts, 0, sizeof(interrupts));
121  }
122 
124  {
125  INT_MASK_M, // masked (subject to PSTATE.{A,I,F} mask bit
126  INT_MASK_T, // taken regardless of mask
127  INT_MASK_P // pending
128  };
129 
130  bool takeInt(InterruptTypes int_type) const;
131 
132  bool
133  checkInterrupts() const override
134  {
135  HCR hcr = tc->readMiscReg(MISCREG_HCR);
136 
137  if (!(intStatus || hcr.va || hcr.vi || hcr.vf))
138  return false;
139 
140  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
141 
142  bool no_vhe = !HaveVirtHostExt(tc);
143  bool amo, fmo, imo;
144  if (hcr.tge == 1){
145  amo = (no_vhe || hcr.e2h == 0);
146  fmo = (no_vhe || hcr.e2h == 0);
147  imo = (no_vhe || hcr.e2h == 0);
148  } else {
149  amo = hcr.amo;
150  fmo = hcr.fmo;
151  imo = hcr.imo;
152  }
153 
154  bool isHypMode = currEL(tc) == EL2;
155  bool isSecure = ArmISA::isSecure(tc);
156  bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode;
157  bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode;
158  bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;
159 
160  if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
161  (hcr.va && allowVAbort)) )
162  return false;
163 
164  bool take_irq = takeInt(INT_IRQ);
165  bool take_fiq = takeInt(INT_FIQ);
166  bool take_ea = takeInt(INT_ABT);
167 
168  return ((interrupts[INT_IRQ] && take_irq) ||
169  (interrupts[INT_FIQ] && take_fiq) ||
170  (interrupts[INT_ABT] && take_ea) ||
171  ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) ||
172  ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) ||
173  (hcr.va && allowVAbort) ||
174  (interrupts[INT_RST]) ||
176  );
177  }
178 
184  bool
185  checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
186  {
187  uint64_t maskedIntStatus;
188  bool virtWake;
189 
190  maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) |
191  (1 << INT_VIRT_FIQ));
192  virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo;
193  virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo;
194  virtWake |= hcr.va && hcr.amo;
195  virtWake &= (cpsr.mode != MODE_HYP) && !isSecure(tc);
196  return maskedIntStatus || virtWake;
197  }
198 
199  uint32_t
200  getISR(HCR hcr, CPSR cpsr, SCR scr)
201  {
202  bool useHcrMux;
203  CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR
204 
205  useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc);
206  isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi)
207  : interrupts[INT_IRQ];
208  isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf)
209  : interrupts[INT_FIQ];
210  isr.a = (useHcrMux & hcr.amo) ? hcr.va : interrupts[INT_ABT];
211  return isr;
212  }
213 
224  bool
225  checkRaw(InterruptTypes interrupt) const
226  {
227  if (interrupt >= NumInterruptTypes)
228  panic("Interrupt number out of range.\n");
229 
230  return interrupts[interrupt];
231  }
232 
233  Fault
234  getInterrupt() override
235  {
236  assert(checkInterrupts());
237 
238  HCR hcr = tc->readMiscReg(MISCREG_HCR);
239  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
240 
241  bool no_vhe = !HaveVirtHostExt(tc);
242  bool amo, fmo, imo;
243  if (hcr.tge == 1){
244  amo = (no_vhe || hcr.e2h == 0);
245  fmo = (no_vhe || hcr.e2h == 0);
246  imo = (no_vhe || hcr.e2h == 0);
247  } else {
248  amo = hcr.amo;
249  fmo = hcr.fmo;
250  imo = hcr.imo;
251  }
252 
253  // Calculate a few temp vars so we can work out if there's a pending
254  // virtual interrupt, and if its allowed to happen
255  // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
256  bool isHypMode = currEL(tc) == EL2;
257  bool isSecure = ArmISA::isSecure(tc);
258  bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode;
259  bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode;
260  bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;
261 
262  bool take_irq = takeInt(INT_IRQ);
263  bool take_fiq = takeInt(INT_FIQ);
264  bool take_ea = takeInt(INT_ABT);
265 
266  if (interrupts[INT_IRQ] && take_irq)
267  return std::make_shared<Interrupt>();
268  if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
269  return std::make_shared<VirtualInterrupt>();
270  if (interrupts[INT_FIQ] && take_fiq)
271  return std::make_shared<FastInterrupt>();
272  if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
273  return std::make_shared<VirtualFastInterrupt>();
274  if (interrupts[INT_ABT] && take_ea)
275  return std::make_shared<SystemError>();
276  if (hcr.va && allowVAbort)
277  return std::make_shared<VirtualDataAbort>(
280  if (interrupts[INT_RST])
281  return std::make_shared<Reset>();
282  if (interrupts[INT_SEV])
283  return std::make_shared<ArmSev>();
284 
285  panic("intStatus and interrupts not in sync\n");
286  }
287 
288  void updateIntrInfo() override {} // nothing to do
289 
290  void
291  serialize(CheckpointOut &cp) const override
292  {
295  }
296 
297  void
298  unserialize(CheckpointIn &cp) override
299  {
302  }
303 };
304 
305 } // namespace ARM_ISA
306 } // namespace gem5
307 
308 #endif // __ARCH_ARM_INTERRUPT_HH__
gem5::ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: misc.hh:61
gem5::ArmISA::Interrupts::INT_MASK_M
@ INT_MASK_M
Definition: interrupts.hh:125
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:47
gem5::BaseInterrupts::tc
ThreadContext * tc
Definition: interrupts.hh:44
gem5::BaseInterrupts
Definition: interrupts.hh:41
gem5::ArmISA::TlbEntry::DomainType::NoAccess
@ NoAccess
gem5::CheckpointIn
Definition: serialize.hh:68
sc_dt::int_type
int64 int_type
Definition: sc_nbdefs.hh:240
gem5::ArmISA::INT_VIRT_FIQ
@ INT_VIRT_FIQ
Definition: interrupts.hh:66
gem5::ArmISA::INT_FIQ
@ INT_FIQ
Definition: interrupts.hh:63
gem5::ArmISA::INT_VIRT_IRQ
@ INT_VIRT_IRQ
Definition: interrupts.hh:65
gem5::ArmISA::Interrupts::post
void post(int int_num, int index) override
Definition: interrupts.hh:86
gem5::ArmISA::Interrupts::clearAll
void clearAll() override
Definition: interrupts.hh:116
gem5::ArmISA::Interrupts::checkWfiWake
bool checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
This function is used to check if a wfi operation should sleep.
Definition: interrupts.hh:185
gem5::ArmISA::ArmFault::AsynchronousExternalAbort
@ AsynchronousExternalAbort
Definition: faults.hh:109
gem5::ArmISA::Interrupts::checkInterrupts
bool checkInterrupts() const override
Definition: interrupts.hh:133
gem5::ArmISA::Interrupts::InterruptMask
InterruptMask
Definition: interrupts.hh:123
gem5::ArmISA::INT_ABT
@ INT_ABT
Definition: interrupts.hh:61
gem5::ArmISA::amo
Bitfield< 5 > amo
Definition: misc_types.hh:280
gem5::ArmISA::Interrupts
Definition: interrupts.hh:70
gem5::ArmISA::MODE_HYP
@ MODE_HYP
Definition: types.hh:287
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::ArmISA::HaveVirtHostExt
bool HaveVirtHostExt(ThreadContext *tc)
Definition: utility.cc:232
gem5::ArmISA::Interrupts::interrupts
bool interrupts[NumInterruptTypes]
Definition: interrupts.hh:73
gem5::ArmISA::Interrupts::INT_MASK_P
@ INT_MASK_P
Definition: interrupts.hh:127
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::ArmISA::Interrupts::takeInt
bool takeInt(InterruptTypes int_type) const
Definition: interrupts.cc:46
gem5::ArmISA::EL2
@ EL2
Definition: types.hh:268
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ArmISA::InterruptTypes
InterruptTypes
Definition: interrupts.hh:58
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
gem5::ArmISA::Interrupts::updateIntrInfo
void updateIntrInfo() override
Definition: interrupts.hh:288
gem5::ArmISA::Interrupts::Interrupts
Interrupts(const Params &p)
Definition: interrupts.hh:79
faults.hh
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::ArmISA::isSecure
bool isSecure(ThreadContext *tc)
Definition: utility.cc:73
gem5::ArmISA::fmo
Bitfield< 3 > fmo
Definition: misc_types.hh:282
utility.hh
gem5::ArmISA::currEL
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition: utility.cc:128
gem5::ArmISA::Interrupts::getInterrupt
Fault getInterrupt() override
Definition: interrupts.hh:234
gem5::ArmISA::MISCREG_HCR
@ MISCREG_HCR
Definition: misc.hh:248
gem5::ArmISA::INT_IRQ
@ INT_IRQ
Definition: interrupts.hh:62
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
gem5::ArmISA::imo
Bitfield< 4 > imo
Definition: misc_types.hh:281
misc.hh
gem5::ArmISA::Interrupts::Params
ArmInterruptsParams Params
Definition: interrupts.hh:77
gem5::ArmISA::INT_RST
@ INT_RST
Definition: interrupts.hh:60
interrupts.hh
gem5::ArmISA::Interrupts::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: interrupts.hh:298
gem5::ArmISA::Interrupts::clear
void clear(int int_num, int index) override
Definition: interrupts.hh:101
gem5::ArmISA::NumInterruptTypes
@ NumInterruptTypes
Definition: interrupts.hh:67
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::ArmISA::Interrupts::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: interrupts.hh:291
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: tlb.cc:60
gem5::ArmISA::Interrupts::checkRaw
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
Definition: interrupts.hh:225
gem5::ArmISA::Interrupt
Definition: faults.hh:556
gem5::ArmISA::Interrupts::INT_MASK_T
@ INT_MASK_T
Definition: interrupts.hh:126
thread_context.hh
gem5::ArmISA::Interrupts::getISR
uint32_t getISR(HCR hcr, CPSR cpsr, SCR scr)
Definition: interrupts.hh:200
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::ArmISA::INT_SEV
@ INT_SEV
Definition: interrupts.hh:64
gem5::ArmISA::Interrupts::intStatus
uint64_t intStatus
Definition: interrupts.hh:74

Generated on Tue Feb 8 2022 11:46:55 for gem5 by doxygen 1.8.17