gem5  v21.1.0.2
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;
72  INTERRUPT mideleg = tc->readMiscReg(MISCREG_MIDELEG);
73  INTERRUPT sideleg = tc->readMiscReg(MISCREG_SIDELEG);
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 checkInterrupt(int num) const { return ip[num] && ie[num]; }
109  bool checkInterrupts() const
110  {
111  return (ip & ie & globalMask()).any();
112  }
113 
114  Fault
116  {
117  assert(checkInterrupts());
118  std::bitset<NumInterruptTypes> mask = globalMask();
119  const std::vector<int> interrupt_order {
123  };
124  for (const int &id : interrupt_order)
125  if (checkInterrupt(id) && mask[id])
126  return std::make_shared<InterruptFault>(id);
127  return NoFault;
128  }
129 
130  void updateIntrInfo() {}
131 
132  void
133  post(int int_num, int index)
134  {
135  DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
136  ip[int_num] = true;
137  }
138 
139  void
140  clear(int int_num, int index)
141  {
142  DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
143  ip[int_num] = false;
144  }
145 
146  void
148  {
149  DPRINTF(Interrupt, "All interrupts cleared\n");
150  ip = 0;
151  }
152 
153  uint64_t readIP() const { return (uint64_t)ip.to_ulong(); }
154  uint64_t readIE() const { return (uint64_t)ie.to_ulong(); }
155  void setIP(const uint64_t& val) { ip = val; }
156  void setIE(const uint64_t& val) { ie = val; }
157 
158  void
160  {
161  unsigned long ip_ulong = ip.to_ulong();
162  unsigned long ie_ulong = ie.to_ulong();
163  SERIALIZE_SCALAR(ip_ulong);
164  SERIALIZE_SCALAR(ie_ulong);
165  }
166 
167  void
169  {
170  unsigned long ip_ulong;
171  unsigned long ie_ulong;
172  UNSERIALIZE_SCALAR(ip_ulong);
173  ip = ip_ulong;
174  UNSERIALIZE_SCALAR(ie_ulong);
175  ie = ie_ulong;
176  }
177 };
178 
179 } // namespace RiscvISA
180 } // namespace gem5
181 
182 #endif // __ARCH_RISCV_INTERRUPT_HH__
gem5::RiscvISA::PRV_S
@ PRV_S
Definition: isa.hh:55
gem5::RiscvISA::MISCREG_STATUS
@ MISCREG_STATUS
Definition: misc.hh:71
gem5::RiscvISA::INT_EXT_MACHINE
@ INT_EXT_MACHINE
Definition: faults.hh:95
gem5::RiscvISA::Interrupts::clear
void clear(int int_num, int index)
Definition: interrupts.hh:140
gem5::RiscvISA::Interrupts::readIE
uint64_t readIE() const
Definition: interrupts.hh:154
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::RiscvISA::INT_TIMER_USER
@ INT_TIMER_USER
Definition: faults.hh:90
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::RiscvISA::INT_TIMER_SUPER
@ INT_TIMER_SUPER
Definition: faults.hh:91
gem5::RiscvISA::PRV_M
@ PRV_M
Definition: isa.hh:56
faults.hh
gem5::RiscvISA::Interrupts::serialize
void serialize(CheckpointOut &cp) const
Serialize an object.
Definition: interrupts.hh:159
gem5::RiscvISA::Interrupts::ip
std::bitset< NumInterruptTypes > ip
Definition: interrupts.hh:59
gem5::RiscvISA::MISCREG_SIDELEG
@ MISCREG_SIDELEG
Definition: misc.hh:173
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::BaseInterrupts::tc
ThreadContext * tc
Definition: interrupts.hh:44
gem5::RiscvISA::Interrupts::checkInterrupt
bool checkInterrupt(int num) const
Definition: interrupts.hh:108
gem5::RiscvISA::INT_EXT_USER
@ INT_EXT_USER
Definition: faults.hh:93
gem5::RiscvISA::Interrupts::getInterrupt
Fault getInterrupt()
Definition: interrupts.hh:115
gem5::BaseInterrupts
Definition: interrupts.hh:41
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::RiscvISA::Interrupts::checkInterrupts
bool checkInterrupts() const
Definition: interrupts.hh:109
gem5::RiscvISA::Interrupts::setIE
void setIE(const uint64_t &val)
Definition: interrupts.hh:156
gem5::RiscvISA::PrivilegeMode
PrivilegeMode
Definition: isa.hh:52
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:775
gem5::RiscvISA::INT_SOFTWARE_USER
@ INT_SOFTWARE_USER
Definition: faults.hh:87
std::vector< int >
misc.hh
gem5::RiscvISA::INT_EXT_SUPER
@ INT_EXT_SUPER
Definition: faults.hh:94
gem5::RiscvISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:47
gem5::RiscvISA::Interrupts::clearAll
void clearAll()
Definition: interrupts.hh:147
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::RiscvISA::INT_TIMER_MACHINE
@ INT_TIMER_MACHINE
Definition: faults.hh:92
sim_object.hh
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::RiscvISA::Interrupts::updateIntrInfo
void updateIntrInfo()
Definition: interrupts.hh:130
gem5::RiscvISA::INT_SOFTWARE_SUPER
@ INT_SOFTWARE_SUPER
Definition: faults.hh:88
gem5::RiscvISA::Interrupts::globalMask
std::bitset< NumInterruptTypes > globalMask() const
Definition: interrupts.hh:68
gem5::RiscvISA::Interrupts::unserialize
void unserialize(CheckpointIn &cp)
Unserialize an object.
Definition: interrupts.hh:168
gem5::RiscvISA::Interrupts::Interrupts
Interrupts(const Params &p)
Definition: interrupts.hh:65
gem5::RiscvISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::RiscvISA::mask
mask
Definition: pra_constants.hh:73
gem5::RiscvISA::Interrupts
Definition: interrupts.hh:56
gem5::RiscvISA::INT_SOFTWARE_MACHINE
@ INT_SOFTWARE_MACHINE
Definition: faults.hh:89
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::RiscvISA::Interrupts::setIP
void setIP(const uint64_t &val)
Definition: interrupts.hh:155
gem5::RiscvISA::Interrupts::readIP
uint64_t readIP() const
Definition: interrupts.hh:153
gem5::RiscvISA::Interrupts::ie
std::bitset< NumInterruptTypes > ie
Definition: interrupts.hh:60
interrupts.hh
logging.hh
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::RiscvISA::MISCREG_MIDELEG
@ MISCREG_MIDELEG
Definition: misc.hh:144
gem5::RiscvISA::Interrupts::post
void post(int int_num, int index)
Definition: interrupts.hh:133
gem5::RiscvISA::PRV_U
@ PRV_U
Definition: isa.hh:54
gem5::BaseInterrupts::Params
BaseInterruptsParams Params
Definition: interrupts.hh:47
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::RiscvISA::MISCREG_PRV
@ MISCREG_PRV
Definition: misc.hh:65
gem5::ArmISA::Interrupt
Definition: faults.hh:557
thread_context.hh
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ArmISA::status
Bitfield< 5, 0 > status
Definition: misc_types.hh:422

Generated on Tue Sep 21 2021 12:24:24 for gem5 by doxygen 1.8.17