gem5
v20.1.0.0
arch
mips
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
32
#include "
arch/mips/pra_constants.hh
"
33
#include "
base/trace.hh
"
34
#include "
cpu/thread_context.hh
"
35
#include "debug/Interrupt.hh"
36
37
namespace
MipsISA
38
{
39
40
enum
InterruptLevels
41
{
42
INTLEVEL_SOFTWARE_MIN
= 4,
43
INTLEVEL_SOFTWARE_MAX
= 19,
44
45
INTLEVEL_EXTERNAL_MIN
= 20,
46
INTLEVEL_EXTERNAL_MAX
= 34,
47
48
INTLEVEL_IRQ0
= 20,
49
INTLEVEL_IRQ1
= 21,
50
INTINDEX_ETHERNET
= 0,
51
INTINDEX_SCSI
= 1,
52
INTLEVEL_IRQ2
= 22,
53
INTLEVEL_IRQ3
= 23,
54
55
INTLEVEL_SERIAL
= 33,
56
57
NumInterruptLevels
=
INTLEVEL_EXTERNAL_MAX
58
};
59
60
static
inline
uint8_t
61
getCauseIP
(
ThreadContext
*tc)
62
{
63
CauseReg cause = tc->
readMiscRegNoEffect
(
MISCREG_CAUSE
);
64
return
cause.ip;
65
}
66
67
static
inline
void
68
setCauseIP
(
ThreadContext
*tc, uint8_t
val
)
69
{
70
CauseReg cause = tc->
readMiscRegNoEffect
(
MISCREG_CAUSE
);
71
cause.ip =
val
;
72
tc->
setMiscRegNoEffect
(
MISCREG_CAUSE
, cause);
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
112
Interrupts::clearAll
()
113
{
114
DPRINTF
(Interrupt,
"Interrupts all cleared\n"
);
115
uint8_t intstatus = 0;
116
setCauseIP
(
tc
, intstatus);
117
}
118
119
120
bool
121
Interrupts::checkInterrupts
()
const
122
{
123
if
(!
interruptsPending
())
124
return
false
;
125
126
//Check if there are any outstanding interrupts
127
StatusReg
status
=
tc
->
readMiscRegNoEffect
(
MISCREG_STATUS
);
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
144
Interrupts::getInterrupt
()
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
157
Interrupts::onCpuTimerInterrupt
()
const
158
{
159
RegVal
compare =
tc
->
readMiscRegNoEffect
(
MISCREG_COMPARE
);
160
RegVal
count
=
tc
->
readMiscRegNoEffect
(
MISCREG_COUNT
);
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
169
Interrupts::interruptsPending
()
const
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
188
MipsISA::Interrupts
*
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