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

Generated on Wed Sep 30 2020 14:01:58 for gem5 by doxygen 1.8.17