gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  * Authors: Ali Saidi
41  */
42 
43 #ifndef __ARCH_ARM_INTERRUPT_HH__
44 #define __ARCH_ARM_INTERRUPT_HH__
45 
46 #include "arch/arm/faults.hh"
47 #include "arch/arm/isa_traits.hh"
48 #include "arch/arm/miscregs.hh"
49 #include "arch/arm/registers.hh"
50 #include "arch/arm/utility.hh"
51 #include "cpu/thread_context.hh"
52 #include "debug/Interrupt.hh"
53 #include "params/ArmInterrupts.hh"
54 #include "sim/sim_object.hh"
55 
56 namespace ArmISA
57 {
58 
59 class Interrupts : public SimObject
60 {
61  private:
63 
65  uint64_t intStatus;
66 
67  public:
68 
69  void
70  setCPU(BaseCPU * _cpu)
71  {
72  cpu = _cpu;
73  }
74 
75  typedef ArmInterruptsParams Params;
76 
77  const Params *
78  params() const
79  {
80  return dynamic_cast<const Params *>(_params);
81  }
82 
83  Interrupts(Params * p) : SimObject(p), cpu(NULL)
84  {
85  clearAll();
86  }
87 
88 
89  void
90  post(int int_num, int index)
91  {
92  DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
93 
94  if (int_num < 0 || int_num >= NumInterruptTypes)
95  panic("int_num out of bounds\n");
96 
97  if (index != 0)
98  panic("No support for other interrupt indexes\n");
99 
100  interrupts[int_num] = true;
101  intStatus |= ULL(1) << int_num;
102  }
103 
104  void
105  clear(int int_num, int index)
106  {
107  DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
108 
109  if (int_num < 0 || int_num >= NumInterruptTypes)
110  panic("int_num out of bounds\n");
111 
112  if (index != 0)
113  panic("No support for other interrupt indexes\n");
114 
115  interrupts[int_num] = false;
116  intStatus &= ~(ULL(1) << int_num);
117  }
118 
119  void
121  {
122  DPRINTF(Interrupt, "Interrupts all cleared\n");
123  intStatus = 0;
124  memset(interrupts, 0, sizeof(interrupts));
125  }
126 
128  INT_MASK_M, // masked (subject to PSTATE.{A,I,F} mask bit
129  INT_MASK_T, // taken regardless of mask
130  INT_MASK_P // pending
131  };
132 
133  bool takeInt(ThreadContext *tc, InterruptTypes int_type) const;
134 
135  bool
137  {
138  HCR hcr = tc->readMiscReg(MISCREG_HCR);
139 
140  if (!(intStatus || hcr.va || hcr.vi || hcr.vf))
141  return false;
142 
143  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
144 
145  bool isHypMode = cpsr.mode == MODE_HYP;
146  bool isSecure = inSecureState(tc);
147  bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
148  bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
149  bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
150 
151  if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
152  (hcr.va && allowVAbort)) )
153  return false;
154 
155  bool take_irq = takeInt(tc, INT_IRQ);
156  bool take_fiq = takeInt(tc, INT_FIQ);
157  bool take_ea = takeInt(tc, INT_ABT);
158 
159  return ((interrupts[INT_IRQ] && take_irq) ||
160  (interrupts[INT_FIQ] && take_fiq) ||
161  (interrupts[INT_ABT] && take_ea) ||
162  ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) ||
163  ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) ||
164  (hcr.va && allowVAbort) ||
165  (interrupts[INT_RST]) ||
167  );
168  }
169 
175  bool
176  checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
177  {
178  uint64_t maskedIntStatus;
179  bool virtWake;
180 
181  maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) |
182  (1 << INT_VIRT_FIQ));
183  virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo;
184  virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo;
185  virtWake |= hcr.va && hcr.amo;
186  virtWake &= (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr);
187  return maskedIntStatus || virtWake;
188  }
189 
190  uint32_t
191  getISR(HCR hcr, CPSR cpsr, SCR scr)
192  {
193  bool useHcrMux;
194  CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR
195 
196  useHcrMux = (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr);
197  isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi)
198  : interrupts[INT_IRQ];
199  isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf)
200  : interrupts[INT_FIQ];
201  isr.a = (useHcrMux & hcr.amo) ? hcr.va : interrupts[INT_ABT];
202  return isr;
203  }
204 
215  bool
217  {
218  if (interrupt >= NumInterruptTypes)
219  panic("Interrupt number out of range.\n");
220 
221  return interrupts[interrupt];
222  }
223 
224  Fault
226  {
227  assert(checkInterrupts(tc));
228 
229  HCR hcr = tc->readMiscReg(MISCREG_HCR);
230  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
231 
232  // Calculate a few temp vars so we can work out if there's a pending
233  // virtual interrupt, and if its allowed to happen
234  // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
235  bool isHypMode = cpsr.mode == MODE_HYP;
236  bool isSecure = inSecureState(tc);
237  bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
238  bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
239  bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
240 
241  bool take_irq = takeInt(tc, INT_IRQ);
242  bool take_fiq = takeInt(tc, INT_FIQ);
243  bool take_ea = takeInt(tc, INT_ABT);
244 
245  if (interrupts[INT_IRQ] && take_irq)
246  return std::make_shared<Interrupt>();
247  if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
248  return std::make_shared<VirtualInterrupt>();
249  if (interrupts[INT_FIQ] && take_fiq)
250  return std::make_shared<FastInterrupt>();
251  if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
252  return std::make_shared<VirtualFastInterrupt>();
253  if (interrupts[INT_ABT] && take_ea)
254  return std::make_shared<SystemError>();
255  if (hcr.va && allowVAbort)
256  return std::make_shared<VirtualDataAbort>(
259  if (interrupts[INT_RST])
260  return std::make_shared<Reset>();
261  if (interrupts[INT_SEV])
262  return std::make_shared<ArmSev>();
263 
264  panic("intStatus and interrupts not in sync\n");
265  }
266 
267  void
269  {
270  ; // nothing to do
271  }
272 
273  void
275  {
278  }
279 
280  void
282  {
285  }
286 };
287 } // namespace ARM_ISA
288 
289 #endif // __ARCH_ARM_INTERRUPT_HH__
#define DPRINTF(x,...)
Definition: trace.hh:212
Bitfield< 30, 0 > index
void post(int int_num, int index)
Definition: interrupts.hh:90
Interrupts(Params *p)
Definition: interrupts.hh:83
void clear(int int_num, int index)
Definition: interrupts.hh:105
bool interrupts[NumInterruptTypes]
Definition: interrupts.hh:64
#define panic(...)
Definition: misc.hh:153
void unserialize(CheckpointIn &cp)
Unserialize an object.
Definition: interrupts.hh:281
void setCPU(BaseCPU *_cpu)
Definition: interrupts.hh:70
InterruptTypes
Definition: isa_traits.hh:112
ThreadContext is the external interface to all thread state for anything outside of the CPU...
bool takeInt(ThreadContext *tc, InterruptTypes int_type) const
Definition: interrupts.cc:51
Fault getInterrupt(ThreadContext *tc)
Definition: interrupts.hh:225
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
bool checkInterrupts(ThreadContext *tc) const
Definition: interrupts.hh:136
uint64_t intStatus
Definition: interrupts.hh:65
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:158
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
Definition: interrupts.hh:216
bool checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
This function is used to check if a wfi operation should sleep.
Definition: interrupts.hh:176
#define ULL(N)
uint64_t constant
Definition: types.hh:50
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
virtual MiscReg readMiscReg(int misc_reg)=0
cbk_int func interrupt
Definition: gpu_nomali.cc:94
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:161
void serialize(CheckpointOut &cp) const
Serialize an object.
Definition: interrupts.hh:274
std::ostream CheckpointOut
Definition: serialize.hh:67
uint32_t getISR(HCR hcr, CPSR cpsr, SCR scr)
Definition: interrupts.hh:191
void updateIntrInfo(ThreadContext *tc)
Definition: interrupts.hh:268
const SimObjectParams * _params
Cached copy of the object parameters.
Definition: sim_object.hh:107
ArmInterruptsParams Params
Definition: interrupts.hh:75
const Params * params() const
Definition: interrupts.hh:78
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:176
Bitfield< 0 > p
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
Abstract superclass for simulation objects.
Definition: sim_object.hh:94

Generated on Fri Jun 9 2017 13:03:34 for gem5 by doxygen 1.8.6