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

Generated on Tue Jun 22 2021 15:28:19 for gem5 by doxygen 1.8.17