gem5  v22.1.0.0
interrupts.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Google
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef __ARCH_RISCV_INTERRUPT_HH__
30 #define __ARCH_RISCV_INTERRUPT_HH__
31 
32 #include <bitset>
33 #include <memory>
34 
36 #include "arch/riscv/faults.hh"
37 #include "arch/riscv/regs/misc.hh"
38 #include "base/logging.hh"
39 #include "cpu/thread_context.hh"
40 #include "debug/Interrupt.hh"
41 #include "params/RiscvInterrupts.hh"
42 #include "sim/sim_object.hh"
43 
44 namespace gem5
45 {
46 
47 class BaseCPU;
48 class ThreadContext;
49 
50 namespace RiscvISA {
51 
52 /*
53  * This is based on version 1.10 of the RISC-V privileged ISA reference,
54  * chapter 3.1.14.
55  */
56 class Interrupts : public BaseInterrupts
57 {
58  private:
59  std::bitset<NumInterruptTypes> ip;
60  std::bitset<NumInterruptTypes> ie;
61 
62  public:
63  using Params = RiscvInterruptsParams;
64 
65  Interrupts(const Params &p) : BaseInterrupts(p), ip(0), ie(0) {}
66 
67  std::bitset<NumInterruptTypes>
68  globalMask() const
69  {
70  INTERRUPT mask = 0;
75  switch (prv) {
76  case PRV_U:
77  mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie);
78  mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie);
79  mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie);
80  mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie);
81  mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie);
82  mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie);
83  if (status.uie)
84  mask.uei = mask.uti = mask.usi = 1;
85  break;
86  case PRV_S:
87  mask.mei = (!mideleg.mei) | (mideleg.mei & status.sie);
88  mask.mti = (!mideleg.mti) | (mideleg.mti & status.sie);
89  mask.msi = (!mideleg.msi) | (mideleg.msi & status.sie);
90  if (status.sie)
91  mask.sei = mask.sti = mask.ssi = 1;
92  mask.uei = mask.uti = mask.usi = 0;
93  break;
94  case PRV_M:
95  if (status.mie)
96  mask.mei = mask.mti = mask.msi = 1;
97  mask.sei = mask.sti = mask.ssi = 0;
98  mask.uei = mask.uti = mask.usi = 0;
99  break;
100  default:
101  panic("Unknown privilege mode %d.", prv);
102  break;
103  }
104 
105  return std::bitset<NumInterruptTypes>(mask);
106  }
107 
108  bool
110  {
112  }
113 
114  bool checkInterrupt(int num) const { return ip[num] && ie[num]; }
115  bool checkInterrupts() const
116  {
117  return checkNonMaskableInterrupt() || (ip & ie & globalMask()).any();
118  }
119 
120  Fault
122  {
123  assert(checkInterrupts());
125  return std::make_shared<NonMaskableInterruptFault>();
126  std::bitset<NumInterruptTypes> mask = globalMask();
127  const std::vector<int> interrupt_order {
131  };
132  for (const int &id : interrupt_order)
133  if (checkInterrupt(id) && mask[id])
134  return std::make_shared<InterruptFault>(id);
135  return NoFault;
136  }
137 
138  void updateIntrInfo() {}
139 
140  void
141  post(int int_num, int index)
142  {
143  DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
144  if (int_num != INT_NMI) {
145  ip[int_num] = true;
146  } else {
147  postNMI();
148  }
149  }
150 
151  void
152  clear(int int_num, int index)
153  {
154  DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
155  if (int_num != INT_NMI) {
156  ip[int_num] = false;
157  } else {
158  clearNMI();
159  }
160  }
161 
164 
165  void
167  {
168  DPRINTF(Interrupt, "All interrupts cleared\n");
169  ip = 0;
170  clearNMI();
171  }
172 
173  uint64_t readIP() const { return (uint64_t)ip.to_ulong(); }
174  uint64_t readIE() const { return (uint64_t)ie.to_ulong(); }
175  void setIP(const uint64_t& val) { ip = val; }
176  void setIE(const uint64_t& val) { ie = val; }
177 
178  void
180  {
181  unsigned long ip_ulong = ip.to_ulong();
182  unsigned long ie_ulong = ie.to_ulong();
183  SERIALIZE_SCALAR(ip_ulong);
184  SERIALIZE_SCALAR(ie_ulong);
185  }
186 
187  void
189  {
190  unsigned long ip_ulong;
191  unsigned long ie_ulong;
192  UNSERIALIZE_SCALAR(ip_ulong);
193  ip = ip_ulong;
194  UNSERIALIZE_SCALAR(ie_ulong);
195  ie = ie_ulong;
196  }
197 };
198 
199 } // namespace RiscvISA
200 } // namespace gem5
201 
202 #endif // __ARCH_RISCV_INTERRUPT_HH__
#define DPRINTF(x,...)
Definition: trace.hh:186
BaseInterruptsParams Params
Definition: interrupts.hh:47
ThreadContext * tc
Definition: interrupts.hh:44
void serialize(CheckpointOut &cp) const
Serialize an object.
Definition: interrupts.hh:179
void setIP(const uint64_t &val)
Definition: interrupts.hh:175
void setIE(const uint64_t &val)
Definition: interrupts.hh:176
Interrupts(const Params &p)
Definition: interrupts.hh:65
std::bitset< NumInterruptTypes > globalMask() const
Definition: interrupts.hh:68
uint64_t readIE() const
Definition: interrupts.hh:174
bool checkNonMaskableInterrupt() const
Definition: interrupts.hh:109
uint64_t readIP() const
Definition: interrupts.hh:173
void post(int int_num, int index)
Definition: interrupts.hh:141
bool checkInterrupts() const
Definition: interrupts.hh:115
void clear(int int_num, int index)
Definition: interrupts.hh:152
std::bitset< NumInterruptTypes > ip
Definition: interrupts.hh:59
bool checkInterrupt(int num) const
Definition: interrupts.hh:114
void unserialize(CheckpointIn &cp)
Unserialize an object.
Definition: interrupts.hh:188
std::bitset< NumInterruptTypes > ie
Definition: interrupts.hh:60
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
Bitfield< 5, 0 > status
Definition: misc_types.hh:429
Bitfield< 0 > p
Bitfield< 30, 0 > index
@ MISCREG_SIDELEG
Definition: misc.hh:175
@ MISCREG_NMIE
Definition: misc.hh:198
@ MISCREG_STATUS
Definition: misc.hh:73
@ MISCREG_PRV
Definition: misc.hh:67
@ MISCREG_MIDELEG
Definition: misc.hh:146
@ MISCREG_NMIP
Definition: misc.hh:200
@ INT_TIMER_USER
Definition: faults.hh:90
@ INT_TIMER_SUPER
Definition: faults.hh:91
@ INT_TIMER_MACHINE
Definition: faults.hh:92
@ INT_SOFTWARE_SUPER
Definition: faults.hh:88
@ INT_EXT_MACHINE
Definition: faults.hh:95
@ INT_SOFTWARE_MACHINE
Definition: faults.hh:89
@ INT_SOFTWARE_USER
Definition: faults.hh:87
Bitfield< 63 > val
Definition: misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
std::ostream CheckpointOut
Definition: serialize.hh:66
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568

Generated on Wed Dec 21 2022 10:22:24 for gem5 by doxygen 1.9.1