faults.hh (8737:770ccf3af571) faults.hh (8738:66bf413b0d5b)
1/*
2 * Copyright (c) 2003-2005 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 * Authors: Gabe Black
30 * Korey Sewell
31 * Jaidev Patwardhan
1/*
2 * Copyright (c) 2003-2005 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 * Authors: Gabe Black
30 * Korey Sewell
31 * Jaidev Patwardhan
32 * Zhengxing Li
33 * Deyuan Guo
34 */
35
36#ifndef __MIPS_FAULTS_HH__
37#define __MIPS_FAULTS_HH__
38
39#include "arch/mips/pra_constants.hh"
40#include "cpu/thread_context.hh"
41#include "debug/MipsPRA.hh"
42#include "sim/faults.hh"
32 */
33
34#ifndef __MIPS_FAULTS_HH__
35#define __MIPS_FAULTS_HH__
36
37#include "arch/mips/pra_constants.hh"
38#include "cpu/thread_context.hh"
39#include "debug/MipsPRA.hh"
40#include "sim/faults.hh"
41#include "sim/full_system.hh"
43
44namespace MipsISA
45{
46
47typedef const Addr FaultVect;
48
49enum ExcCode {
50 // A dummy value to use when the code isn't defined or doesn't matter.
51 ExcCodeDummy = 0,
52
53 ExcCodeInt = 0,
54 ExcCodeMod = 1,
55 ExcCodeTlbL = 2,
56 ExcCodeTlbS = 3,
57 ExcCodeAdEL = 4,
58 ExcCodeAdES = 5,
59 ExcCodeIBE = 6,
60 ExcCodeDBE = 7,
61 ExcCodeSys = 8,
62 ExcCodeBp = 9,
63 ExcCodeRI = 10,
64 ExcCodeCpU = 11,
65 ExcCodeOv = 12,
66 ExcCodeTr = 13,
67 ExcCodeC2E = 18,
68 ExcCodeMDMX = 22,
69 ExcCodeWatch = 23,
70 ExcCodeMCheck = 24,
71 ExcCodeThread = 25,
72 ExcCodeCacheErr = 30
73};
74
75class MipsFaultBase : public FaultBase
76{
77 public:
78 struct FaultVals
79 {
80 const FaultName name;
81 const FaultVect offset;
82 const ExcCode code;
83 };
84
85 void setExceptionState(ThreadContext *, uint8_t);
86
87 virtual FaultVect offset(ThreadContext *tc) const = 0;
88 virtual ExcCode code() const = 0;
89 virtual FaultVect base(ThreadContext *tc) const
90 {
91 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
42
43namespace MipsISA
44{
45
46typedef const Addr FaultVect;
47
48enum ExcCode {
49 // A dummy value to use when the code isn't defined or doesn't matter.
50 ExcCodeDummy = 0,
51
52 ExcCodeInt = 0,
53 ExcCodeMod = 1,
54 ExcCodeTlbL = 2,
55 ExcCodeTlbS = 3,
56 ExcCodeAdEL = 4,
57 ExcCodeAdES = 5,
58 ExcCodeIBE = 6,
59 ExcCodeDBE = 7,
60 ExcCodeSys = 8,
61 ExcCodeBp = 9,
62 ExcCodeRI = 10,
63 ExcCodeCpU = 11,
64 ExcCodeOv = 12,
65 ExcCodeTr = 13,
66 ExcCodeC2E = 18,
67 ExcCodeMDMX = 22,
68 ExcCodeWatch = 23,
69 ExcCodeMCheck = 24,
70 ExcCodeThread = 25,
71 ExcCodeCacheErr = 30
72};
73
74class MipsFaultBase : public FaultBase
75{
76 public:
77 struct FaultVals
78 {
79 const FaultName name;
80 const FaultVect offset;
81 const ExcCode code;
82 };
83
84 void setExceptionState(ThreadContext *, uint8_t);
85
86 virtual FaultVect offset(ThreadContext *tc) const = 0;
87 virtual ExcCode code() const = 0;
88 virtual FaultVect base(ThreadContext *tc) const
89 {
90 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
92 if (!status.bev)
91 if (status.bev)
93 return tc->readMiscReg(MISCREG_EBASE);
94 else
95 return 0xbfc00200;
96 }
97
98 FaultVect
99 vect(ThreadContext *tc) const
100 {
101 return base(tc) + offset(tc);
102 }
103
104 void invoke(ThreadContext * tc,
105 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
106};
107
108template <typename T>
109class MipsFault : public MipsFaultBase
110{
111 protected:
112 static FaultVals vals;
113 public:
114 FaultName name() const { return vals.name; }
115 FaultVect offset(ThreadContext *tc) const { return vals.offset; }
116 ExcCode code() const { return vals.code; }
117};
118
119class SystemCallFault : public MipsFault<SystemCallFault> {};
120class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {};
121class ThreadFault : public MipsFault<ThreadFault> {};
122class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {};
123class TrapFault : public MipsFault<TrapFault> {};
124class BreakpointFault : public MipsFault<BreakpointFault> {};
125class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {};
126
127class MachineCheckFault : public MipsFault<MachineCheckFault>
128{
129 public:
130 bool isMachineCheckFault() { return true; }
131};
132
133class ResetFault : public MipsFault<ResetFault>
134{
135 public:
136 void invoke(ThreadContext * tc,
137 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
138
139};
140
141class SoftResetFault : public MipsFault<SoftResetFault>
142{
143 public:
144 void invoke(ThreadContext * tc,
145 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
146};
147
148class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
149{
150 public:
151 void invoke(ThreadContext * tc,
152 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
153};
154
155class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault>
156{
157 protected:
158 int coProcID;
159 public:
160 CoprocessorUnusableFault(int _procid) : coProcID(_procid)
161 {}
162
163 void
164 invoke(ThreadContext * tc,
165 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
166 {
167 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
92 return tc->readMiscReg(MISCREG_EBASE);
93 else
94 return 0xbfc00200;
95 }
96
97 FaultVect
98 vect(ThreadContext *tc) const
99 {
100 return base(tc) + offset(tc);
101 }
102
103 void invoke(ThreadContext * tc,
104 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
105};
106
107template <typename T>
108class MipsFault : public MipsFaultBase
109{
110 protected:
111 static FaultVals vals;
112 public:
113 FaultName name() const { return vals.name; }
114 FaultVect offset(ThreadContext *tc) const { return vals.offset; }
115 ExcCode code() const { return vals.code; }
116};
117
118class SystemCallFault : public MipsFault<SystemCallFault> {};
119class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {};
120class ThreadFault : public MipsFault<ThreadFault> {};
121class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {};
122class TrapFault : public MipsFault<TrapFault> {};
123class BreakpointFault : public MipsFault<BreakpointFault> {};
124class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {};
125
126class MachineCheckFault : public MipsFault<MachineCheckFault>
127{
128 public:
129 bool isMachineCheckFault() { return true; }
130};
131
132class ResetFault : public MipsFault<ResetFault>
133{
134 public:
135 void invoke(ThreadContext * tc,
136 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
137
138};
139
140class SoftResetFault : public MipsFault<SoftResetFault>
141{
142 public:
143 void invoke(ThreadContext * tc,
144 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
145};
146
147class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
148{
149 public:
150 void invoke(ThreadContext * tc,
151 StaticInstPtr inst = StaticInst::nullStaticInstPtr);
152};
153
154class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault>
155{
156 protected:
157 int coProcID;
158 public:
159 CoprocessorUnusableFault(int _procid) : coProcID(_procid)
160 {}
161
162 void
163 invoke(ThreadContext * tc,
164 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
165 {
166 MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
168 if (FULL_SYSTEM) {
167 if (FullSystem) {
169 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
170 cause.ce = coProcID;
168 CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
169 cause.ce = coProcID;
171 tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
170 tc->setMiscReg(MISCREG_CAUSE, cause);
172 }
173 }
174};
175
176class InterruptFault : public MipsFault<InterruptFault>
177{
178 public:
179 FaultVect
180 offset(ThreadContext *tc) const
181 {
182 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
171 }
172 }
173};
174
175class InterruptFault : public MipsFault<InterruptFault>
176{
177 public:
178 FaultVect
179 offset(ThreadContext *tc) const
180 {
181 CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
183 // offset 0x200 for release 2, 0x180 for release 1.
184 return cause.iv ? 0x200 : 0x180;
182 return cause.iv ? 0x200 : 0x000;
185 }
186};
187
188template <typename T>
189class AddressFault : public MipsFault<T>
190{
191 protected:
192 Addr vaddr;
193 bool store;
194
195 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
196 {}
197
198 void
199 invoke(ThreadContext * tc,
200 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
201 {
202 MipsFault<T>::invoke(tc, inst);
183 }
184};
185
186template <typename T>
187class AddressFault : public MipsFault<T>
188{
189 protected:
190 Addr vaddr;
191 bool store;
192
193 AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
194 {}
195
196 void
197 invoke(ThreadContext * tc,
198 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
199 {
200 MipsFault<T>::invoke(tc, inst);
203 if (FULL_SYSTEM)
201 if (FullSystem)
204 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr);
205 }
206};
207
208class AddressErrorFault : public AddressFault<AddressErrorFault>
209{
210 public:
211 AddressErrorFault(Addr _vaddr, bool _store) :
212 AddressFault<AddressErrorFault>(_vaddr, _store)
213 {}
214
215 ExcCode
216 code() const
217 {
218 return store ? ExcCodeAdES : ExcCodeAdEL;
219 }
220
221};
222
223template <typename T>
224class TlbFault : public AddressFault<T>
225{
226 protected:
227 Addr asid;
228 Addr vpn;
229
230 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) :
231 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn)
232 {}
233
234 void
235 setTlbExceptionState(ThreadContext *tc, uint8_t excCode)
236 {
237 this->setExceptionState(tc, excCode);
238
239 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr);
240 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
241 entryHi.asid = this->asid;
242 entryHi.vpn2 = this->vpn >> 2;
243 entryHi.vpn2x = this->vpn & 0x3;
244 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
245
246 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
247 context.badVPN2 = this->vpn >> 2;
248 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
249 }
250
251 void
252 invoke(ThreadContext * tc,
253 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
254 {
202 tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr);
203 }
204};
205
206class AddressErrorFault : public AddressFault<AddressErrorFault>
207{
208 public:
209 AddressErrorFault(Addr _vaddr, bool _store) :
210 AddressFault<AddressErrorFault>(_vaddr, _store)
211 {}
212
213 ExcCode
214 code() const
215 {
216 return store ? ExcCodeAdES : ExcCodeAdEL;
217 }
218
219};
220
221template <typename T>
222class TlbFault : public AddressFault<T>
223{
224 protected:
225 Addr asid;
226 Addr vpn;
227
228 TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) :
229 AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn)
230 {}
231
232 void
233 setTlbExceptionState(ThreadContext *tc, uint8_t excCode)
234 {
235 this->setExceptionState(tc, excCode);
236
237 tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr);
238 EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
239 entryHi.asid = this->asid;
240 entryHi.vpn2 = this->vpn >> 2;
241 entryHi.vpn2x = this->vpn & 0x3;
242 tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
243
244 ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
245 context.badVPN2 = this->vpn >> 2;
246 tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
247 }
248
249 void
250 invoke(ThreadContext * tc,
251 StaticInstPtr inst = StaticInst::nullStaticInstPtr)
252 {
255 if (FULL_SYSTEM) {
256 DPRINTF(MipsPRA, "Fault %s encountered.\n", this->name());
257 Addr vect = this->vect(tc);
253 if (FullSystem) {
254 DPRINTF(MipsPRA, "Fault %s encountered.\n", name());
255 tc->pcState(this->vect(tc));
258 setTlbExceptionState(tc, this->code());
256 setTlbExceptionState(tc, this->code());
259 tc->pcState(vect);
260 } else {
261 AddressFault<T>::invoke(tc, inst);
262 }
263 }
264
265 ExcCode
266 code() const
267 {
268 return this->store ? ExcCodeTlbS : ExcCodeTlbL;
269 }
270};
271
272class TlbRefillFault : public TlbFault<TlbRefillFault>
273{
274 public:
275 TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
276 TlbFault<TlbRefillFault>(asid, vaddr, vpn, store)
277 {}
278
279 FaultVect
280 offset(ThreadContext *tc) const
281 {
282 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
283 return status.exl ? 0x180 : 0x000;
284 }
285};
286
287class TlbInvalidFault : public TlbFault<TlbInvalidFault>
288{
289 public:
290 TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
291 TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store)
292 {}
293};
294
295class TlbModifiedFault : public TlbFault<TlbModifiedFault>
296{
297 public:
298 TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) :
299 TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false)
300 {}
301
257 } else {
258 AddressFault<T>::invoke(tc, inst);
259 }
260 }
261
262 ExcCode
263 code() const
264 {
265 return this->store ? ExcCodeTlbS : ExcCodeTlbL;
266 }
267};
268
269class TlbRefillFault : public TlbFault<TlbRefillFault>
270{
271 public:
272 TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
273 TlbFault<TlbRefillFault>(asid, vaddr, vpn, store)
274 {}
275
276 FaultVect
277 offset(ThreadContext *tc) const
278 {
279 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
280 return status.exl ? 0x180 : 0x000;
281 }
282};
283
284class TlbInvalidFault : public TlbFault<TlbInvalidFault>
285{
286 public:
287 TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
288 TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store)
289 {}
290};
291
292class TlbModifiedFault : public TlbFault<TlbModifiedFault>
293{
294 public:
295 TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) :
296 TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false)
297 {}
298
302 ExcCode code() const { return MipsFault<TlbModifiedFault>::code(); }
299 ExcCode code() const { return vals.code; }
303};
304
305} // namespace MipsISA
306
307#endif // __MIPS_FAULTS_HH__
300};
301
302} // namespace MipsISA
303
304#endif // __MIPS_FAULTS_HH__