gem5  v20.1.0.0
interrupts.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 The Regents of The University of Michigan
3  * Copyright (c) 2007 MIPS Technologies, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met: redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer;
10  * redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution;
13  * neither the name of the copyright holders nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "arch/mips/interrupts.hh"
31 
33 #include "base/trace.hh"
34 #include "cpu/thread_context.hh"
35 #include "debug/Interrupt.hh"
36 
37 namespace MipsISA
38 {
39 
41 {
44 
47 
54 
56 
58 };
59 
60 static inline uint8_t
62 {
63  CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
64  return cause.ip;
65 }
66 
67 static inline void
69 {
70  CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
71  cause.ip = val;
73 }
74 
75 void
76 Interrupts::post(int int_num)
77 {
78  DPRINTF(Interrupt, "Interrupt %d posted\n", int_num);
79  if (int_num < 0 || int_num >= NumInterruptLevels)
80  panic("int_num out of bounds\n");
81 
82  uint8_t intstatus = getCauseIP(tc);
83  intstatus |= 1 << int_num;
84  setCauseIP(tc, intstatus);
85 }
86 
87 void
88 Interrupts::post(int int_num, int index)
89 {
90  fatal("Must use Thread Context when posting MIPS Interrupts in M5");
91 }
92 
93 void
94 Interrupts::clear(int int_num)
95 {
96  DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num);
97  if (int_num < 0 || int_num >= NumInterruptLevels)
98  panic("int_num out of bounds\n");
99 
100  uint8_t intstatus = getCauseIP(tc);
101  intstatus &= ~(1 << int_num);
102  setCauseIP(tc, intstatus);
103 }
104 
105 void
106 Interrupts::clear(int int_num, int index)
107 {
108  fatal("Must use Thread Context when clearing MIPS Interrupts in M5");
109 }
110 
111 void
113 {
114  DPRINTF(Interrupt, "Interrupts all cleared\n");
115  uint8_t intstatus = 0;
116  setCauseIP(tc, intstatus);
117 }
118 
119 
120 bool
122 {
123  if (!interruptsPending())
124  return false;
125 
126  //Check if there are any outstanding interrupts
128  // Interrupts must be enabled, error level must be 0 or interrupts
129  // inhibited, and exception level must be 0 or interrupts inhibited
130  if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) {
131  // Software interrupts & hardware interrupts are handled in software.
132  // So if any interrupt that isn't masked is detected, jump to interrupt
133  // handler
134  CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
135  if (status.im && cause.ip)
136  return true;
137 
138  }
139 
140  return false;
141 }
142 
143 Fault
145 {
146  assert(checkInterrupts());
147 
148  StatusReg M5_VAR_USED status = tc->readMiscRegNoEffect(MISCREG_STATUS);
149  CauseReg M5_VAR_USED cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
150  DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n",
151  (unsigned)status.im, (unsigned)cause.ip);
152 
153  return std::make_shared<InterruptFault>();
154 }
155 
156 bool
158 {
161  if (compare == count && count != 0)
162  return true;
163  return false;
164 }
165 
166 void Interrupts::updateIntrInfo() {} // Nothing needs to be done.
167 
168 bool
170 {
171  //if there is a on cpu timer interrupt (i.e. Compare == Count)
172  //update CauseIP before proceeding to interrupt
173  if (onCpuTimerInterrupt()) {
174  DPRINTF(Interrupt, "Interrupts OnCpuTimerInterrupt() == true\n");
175  //determine timer interrupt IP #
176  IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL);
177  uint8_t intStatus = getCauseIP(tc);
178  intStatus |= 1 << intCtl.ipti;
179  setCauseIP(tc, intStatus);
180  }
181 
182  return (getCauseIP(tc) != 0);
183 
184 }
185 
186 }
187 
189 MipsInterruptsParams::create()
190 {
191  return new MipsISA::Interrupts(this);
192 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
MipsISA::Interrupts::post
void post(int int_num)
Definition: interrupts.cc:76
ThreadContext::readMiscRegNoEffect
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
ArmISA::status
Bitfield< 5, 0 > status
Definition: miscregs_types.hh:417
MipsISA::INTLEVEL_EXTERNAL_MAX
@ INTLEVEL_EXTERNAL_MAX
Definition: interrupts.cc:46
MipsISA::Interrupts::interruptsPending
bool interruptsPending() const
Definition: interrupts.cc:169
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
MipsISA::INTLEVEL_SERIAL
@ INTLEVEL_SERIAL
Definition: interrupts.cc:55
pra_constants.hh
MipsISA::getCauseIP
static uint8_t getCauseIP(ThreadContext *tc)
Definition: interrupts.cc:61
MipsISA::MISCREG_INTCTL
@ MISCREG_INTCTL
Definition: registers.hh:180
MipsISA::MISCREG_CAUSE
@ MISCREG_CAUSE
Definition: registers.hh:184
X86ISA::count
count
Definition: misc.hh:703
MipsISA::InterruptLevels
InterruptLevels
Definition: interrupts.cc:40
MipsISA::Interrupts::updateIntrInfo
void updateIntrInfo() override
Definition: interrupts.cc:166
MipsISA::INTLEVEL_IRQ0
@ INTLEVEL_IRQ0
Definition: interrupts.cc:48
MipsISA
Definition: decoder.cc:31
MipsISA::INTLEVEL_EXTERNAL_MIN
@ INTLEVEL_EXTERNAL_MIN
Definition: interrupts.cc:45
MipsISA::MISCREG_STATUS
@ MISCREG_STATUS
Definition: registers.hh:179
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
interrupts.hh
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
MipsISA::INTINDEX_ETHERNET
@ INTINDEX_ETHERNET
Definition: interrupts.cc:50
MipsISA::NumInterruptLevels
@ NumInterruptLevels
Definition: interrupts.cc:57
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
MipsISA::Interrupts::onCpuTimerInterrupt
bool onCpuTimerInterrupt() const
Definition: interrupts.cc:157
MipsISA::Interrupts
Definition: interrupts.hh:47
MipsISA::INTLEVEL_SOFTWARE_MIN
@ INTLEVEL_SOFTWARE_MIN
Definition: interrupts.cc:42
MipsISA::MISCREG_COMPARE
@ MISCREG_COMPARE
Definition: registers.hh:177
MipsISA::Interrupts::checkInterrupts
bool checkInterrupts() const override
Definition: interrupts.cc:121
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
MipsISA::setCauseIP
static void setCauseIP(ThreadContext *tc, uint8_t val)
Definition: interrupts.cc:68
MipsISA::Interrupts::clear
void clear(int int_num)
Definition: interrupts.cc:94
MipsISA::Interrupts::getInterrupt
Fault getInterrupt() override
Definition: interrupts.cc:144
MipsISA::INTLEVEL_IRQ1
@ INTLEVEL_IRQ1
Definition: interrupts.cc:49
MipsISA::INTLEVEL_SOFTWARE_MAX
@ INTLEVEL_SOFTWARE_MAX
Definition: interrupts.cc:43
MipsISA::MISCREG_COUNT
@ MISCREG_COUNT
Definition: registers.hh:173
trace.hh
MipsISA::INTLEVEL_IRQ2
@ INTLEVEL_IRQ2
Definition: interrupts.cc:52
ThreadContext::setMiscRegNoEffect
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
MipsISA::INTLEVEL_IRQ3
@ INTLEVEL_IRQ3
Definition: interrupts.cc:53
BaseInterrupts::tc
ThreadContext * tc
Definition: interrupts.hh:40
MipsISA::Interrupts::clearAll
void clearAll() override
Definition: interrupts.cc:112
thread_context.hh
RegVal
uint64_t RegVal
Definition: types.hh:168
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
MipsISA::INTINDEX_SCSI
@ INTINDEX_SCSI
Definition: interrupts.cc:51

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