2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * Copyright (c) 2007-2008 The Florida State University
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.
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.
33 #include "arch/arm/faults.hh"
34 #include "cpu/thread_context.hh"
35 #include "cpu/base.hh"
36 #include "base/trace.hh"
41 template<> ArmFaultBase::FaultVals ArmFault
<Reset
>::vals
=
42 {"reset", 0x00, MODE_SVC
, 0, 0, true, true};
44 template<> ArmFaultBase::FaultVals ArmFault
<UndefinedInstruction
>::vals
=
45 {"Undefined Instruction", 0x04, MODE_UNDEFINED
, 4 ,2, false, false} ;
47 template<> ArmFaultBase::FaultVals ArmFault
<SupervisorCall
>::vals
=
48 {"Supervisor Call", 0x08, MODE_SVC
, 4, 2, false, false};
50 template<> ArmFaultBase::FaultVals ArmFault
<PrefetchAbort
>::vals
=
51 {"Prefetch Abort", 0x0C, MODE_ABORT
, 4, 4, true, false};
53 template<> ArmFaultBase::FaultVals ArmFault
<DataAbort
>::vals
=
54 {"Data Abort", 0x10, MODE_ABORT
, 8, 8, true, false};
56 template<> ArmFaultBase::FaultVals ArmFault
<Interrupt
>::vals
=
57 {"IRQ", 0x18, MODE_IRQ
, 4, 4, true, false};
59 template<> ArmFaultBase::FaultVals ArmFault
<FastInterrupt
>::vals
=
60 {"FIQ", 0x1C, MODE_FIQ
, 4, 4, true, true};
63 ArmFaultBase::getVector(ThreadContext
*tc
)
67 SCTLR sctlr
= tc
->readMiscReg(MISCREG_SCTLR
);
69 // panic if SCTLR.VE because I have no idea what to do with vectored
75 return offset() + HighVecs
;
82 ArmFaultBase::invoke(ThreadContext
*tc
)
85 FaultBase::invoke(tc
);
88 SCTLR sctlr
= tc
->readMiscReg(MISCREG_SCTLR
);
89 CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
90 CPSR saved_cpsr
= tc
->readMiscReg(MISCREG_CPSR
) |
91 tc
->readIntReg(INTREG_CONDCODES
);
94 cpsr
.mode
= nextMode();
95 cpsr
.it1
= cpsr
.it2
= 0;
100 cpsr
.a
= cpsr
.a
| abortDisable();
101 cpsr
.f
= cpsr
.f
| fiqDisable();
103 tc
->setMiscReg(MISCREG_CPSR
, cpsr
);
104 tc
->setIntReg(INTREG_LR
, tc
->readPC() +
105 (saved_cpsr
.t
? thumbPcOffset() : armPcOffset()));
107 switch (nextMode()) {
109 tc
->setMiscReg(MISCREG_SPSR_FIQ
, saved_cpsr
);
112 tc
->setMiscReg(MISCREG_SPSR_IRQ
, saved_cpsr
);
115 tc
->setMiscReg(MISCREG_SPSR_SVC
, saved_cpsr
);
118 tc
->setMiscReg(MISCREG_SPSR_UND
, saved_cpsr
);
121 tc
->setMiscReg(MISCREG_SPSR_ABT
, saved_cpsr
);
124 panic("unknown Mode\n");
127 DPRINTF(Faults
, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr
,
128 tc
->readPC(), tc
->readIntReg(INTREG_LR
));
129 tc
->setPC(getVector(tc
));
130 tc
->setNextPC(getVector(tc
) + cpsr
.t
? 2 : 4 );
132 #endif // FULL_SYSTEM
134 // return via SUBS pc, lr, xxx; rfe, movs, ldm
138 } // namespace ArmISA