gem5  v20.0.0.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 
57 class Interrupts : public BaseInterrupts
58 {
59  private:
61 
63  uint64_t intStatus;
64 
65  public:
66 
67  void
68  setCPU(BaseCPU * _cpu)
69  {
70  cpu = _cpu;
71  }
72 
73  typedef ArmInterruptsParams Params;
74 
75  const Params *
76  params() const
77  {
78  return dynamic_cast<const Params *>(_params);
79  }
80 
81  Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
82  {
83  clearAll();
84  }
85 
86 
87  void
88  post(int int_num, int index)
89  {
90  DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
91 
92  if (int_num < 0 || int_num >= NumInterruptTypes)
93  panic("int_num out of bounds\n");
94 
95  if (index != 0)
96  panic("No support for other interrupt indexes\n");
97 
98  interrupts[int_num] = true;
99  intStatus |= ULL(1) << int_num;
100  }
101 
102  void
103  clear(int int_num, int index)
104  {
105  DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
106 
107  if (int_num < 0 || int_num >= NumInterruptTypes)
108  panic("int_num out of bounds\n");
109 
110  if (index != 0)
111  panic("No support for other interrupt indexes\n");
112 
113  interrupts[int_num] = false;
114  intStatus &= ~(ULL(1) << int_num);
115  }
116 
117  void
119  {
120  DPRINTF(Interrupt, "Interrupts all cleared\n");
121  intStatus = 0;
122  memset(interrupts, 0, sizeof(interrupts));
123  }
124 
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(ThreadContext *tc, InterruptTypes int_type) const;
132 
133  bool
135  {
136  HCR hcr = tc->readMiscReg(MISCREG_HCR);
137 
138  if (!(intStatus || hcr.va || hcr.vi || hcr.vf))
139  return false;
140 
141  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
142 
143  bool isHypMode = currEL(tc) == EL2;
144  bool isSecure = inSecureState(tc);
145  bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
146  bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
147  bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
148 
149  if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
150  (hcr.va && allowVAbort)) )
151  return false;
152 
153  bool take_irq = takeInt(tc, INT_IRQ);
154  bool take_fiq = takeInt(tc, INT_FIQ);
155  bool take_ea = takeInt(tc, INT_ABT);
156 
157  return ((interrupts[INT_IRQ] && take_irq) ||
158  (interrupts[INT_FIQ] && take_fiq) ||
159  (interrupts[INT_ABT] && take_ea) ||
160  ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) ||
161  ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) ||
162  (hcr.va && allowVAbort) ||
163  (interrupts[INT_RST]) ||
164  (interrupts[INT_SEV])
165  );
166  }
167 
173  bool
174  checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
175  {
176  uint64_t maskedIntStatus;
177  bool virtWake;
178 
179  maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) |
180  (1 << INT_VIRT_FIQ));
181  virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo;
182  virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo;
183  virtWake |= hcr.va && hcr.amo;
184  virtWake &= (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr);
185  return maskedIntStatus || virtWake;
186  }
187 
188  uint32_t
189  getISR(HCR hcr, CPSR cpsr, SCR scr)
190  {
191  bool useHcrMux;
192  CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR
193 
194  useHcrMux = (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr);
195  isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi)
196  : interrupts[INT_IRQ];
197  isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf)
198  : interrupts[INT_FIQ];
199  isr.a = (useHcrMux & hcr.amo) ? hcr.va : interrupts[INT_ABT];
200  return isr;
201  }
202 
213  bool
214  checkRaw(InterruptTypes interrupt) const
215  {
216  if (interrupt >= NumInterruptTypes)
217  panic("Interrupt number out of range.\n");
218 
219  return interrupts[interrupt];
220  }
221 
222  Fault
224  {
225  assert(checkInterrupts(tc));
226 
227  HCR hcr = tc->readMiscReg(MISCREG_HCR);
228  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
229 
230  // Calculate a few temp vars so we can work out if there's a pending
231  // virtual interrupt, and if its allowed to happen
232  // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
233  bool isHypMode = currEL(tc) == EL2;
234  bool isSecure = inSecureState(tc);
235  bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
236  bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
237  bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
238 
239  bool take_irq = takeInt(tc, INT_IRQ);
240  bool take_fiq = takeInt(tc, INT_FIQ);
241  bool take_ea = takeInt(tc, INT_ABT);
242 
243  if (interrupts[INT_IRQ] && take_irq)
244  return std::make_shared<Interrupt>();
245  if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
246  return std::make_shared<VirtualInterrupt>();
247  if (interrupts[INT_FIQ] && take_fiq)
248  return std::make_shared<FastInterrupt>();
249  if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
250  return std::make_shared<VirtualFastInterrupt>();
251  if (interrupts[INT_ABT] && take_ea)
252  return std::make_shared<SystemError>();
253  if (hcr.va && allowVAbort)
254  return std::make_shared<VirtualDataAbort>(
257  if (interrupts[INT_RST])
258  return std::make_shared<Reset>();
259  if (interrupts[INT_SEV])
260  return std::make_shared<ArmSev>();
261 
262  panic("intStatus and interrupts not in sync\n");
263  }
264 
265  void
267  {
268  ; // nothing to do
269  }
270 
271  void
273  {
274  SERIALIZE_ARRAY(interrupts, NumInterruptTypes);
275  SERIALIZE_SCALAR(intStatus);
276  }
277 
278  void
280  {
282  UNSERIALIZE_SCALAR(intStatus);
283  }
284 };
285 } // namespace ARM_ISA
286 
287 #endif // __ARCH_ARM_INTERRUPT_HH__
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
#define DPRINTF(x,...)
Definition: trace.hh:225
Bitfield< 30, 0 > index
void post(int int_num, int index)
Definition: interrupts.hh:88
Interrupts(Params *p)
Definition: interrupts.hh:81
bool takeInt(ThreadContext *tc, InterruptTypes int_type) const
Definition: interrupts.cc:49
void clear(int int_num, int index)
Definition: interrupts.hh:103
void serialize(CheckpointOut &cp) const
Serialize an object.
Definition: interrupts.hh:272
bool interrupts[NumInterruptTypes]
Definition: interrupts.hh:62
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
Definition: interrupts.hh:214
void unserialize(CheckpointIn &cp)
Unserialize an object.
Definition: interrupts.hh:279
Definition: ccregs.hh:41
void setCPU(BaseCPU *_cpu)
Definition: interrupts.hh:68
Definition: cprintf.cc:40
InterruptTypes
Definition: isa_traits.hh:101
ThreadContext is the external interface to all thread state for anything outside of the CPU...
static ExceptionLevel currEL(const ThreadContext *tc)
Definition: utility.hh:141
Fault getInterrupt(ThreadContext *tc)
Definition: interrupts.hh:223
bool checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
This function is used to check if a wfi operation should sleep.
Definition: interrupts.hh:174
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:770
uint64_t intStatus
Definition: interrupts.hh:63
int64 int_type
Definition: sc_nbdefs.hh:206
const Params * params() const
Definition: interrupts.hh:76
bool checkInterrupts(ThreadContext *tc) const
Definition: interrupts.hh:134
#define ULL(N)
uint64_t constant
Definition: types.hh:48
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:805
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:763
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:813
std::ostream CheckpointOut
Definition: serialize.hh:63
const SimObjectParams * _params
Cached copy of the object parameters.
Definition: sim_object.hh:111
uint32_t getISR(HCR hcr, CPSR cpsr, SCR scr)
Definition: interrupts.hh:189
void updateIntrInfo(ThreadContext *tc)
Definition: interrupts.hh:266
ArmInterruptsParams Params
Definition: interrupts.hh:73
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:174
Bitfield< 0 > p
virtual RegVal readMiscReg(RegIndex misc_reg)=0
std::shared_ptr< FaultBase > Fault
Definition: types.hh:238

Generated on Thu May 28 2020 16:11:02 for gem5 by doxygen 1.8.13