summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
committerDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
commit279f179babc9e5663156777c533c06edc91bce9a (patch)
treee6718ee514cc81678491b50562ce8c463c0b20fd /src/arch/arm
parent5aa104e072eb20f6aca49b169521b0c2da33c844 (diff)
parent295516a590b6e47c9a881f193027447e500c749c (diff)
downloadgem5-279f179babc9e5663156777c533c06edc91bce9a.tar.xz
merge
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/ArmInterrupts.py33
-rw-r--r--src/arch/arm/ArmSystem.py35
-rw-r--r--src/arch/arm/SConscript13
-rw-r--r--src/arch/arm/faults.cc534
-rw-r--r--src/arch/arm/faults.hh557
-rw-r--r--src/arch/arm/insts/macromem.hh25
-rw-r--r--src/arch/arm/insts/static_inst.cc10
-rw-r--r--src/arch/arm/insts/static_inst.hh50
-rw-r--r--src/arch/arm/interrupts.cc37
-rw-r--r--src/arch/arm/interrupts.hh121
-rw-r--r--src/arch/arm/intregs.hh337
-rw-r--r--src/arch/arm/isa.hh116
-rw-r--r--src/arch/arm/isa/bitfields.isa4
-rw-r--r--src/arch/arm/isa/decoder.isa362
-rw-r--r--src/arch/arm/isa/formats/branch.isa4
-rw-r--r--src/arch/arm/isa/formats/fp.isa4
-rw-r--r--src/arch/arm/isa/formats/macromem.isa126
-rw-r--r--src/arch/arm/isa/formats/pred.isa90
-rw-r--r--src/arch/arm/isa/formats/unimp.isa2
-rw-r--r--src/arch/arm/isa/formats/unknown.isa2
-rw-r--r--src/arch/arm/isa/formats/util.isa6
-rw-r--r--src/arch/arm/isa/operands.isa24
-rw-r--r--src/arch/arm/isa_traits.hh2
-rw-r--r--src/arch/arm/kernel_stats.hh57
-rw-r--r--src/arch/arm/linux/linux.hh16
-rw-r--r--src/arch/arm/linux/process.cc12
-rw-r--r--src/arch/arm/linux/process.hh2
-rw-r--r--src/arch/arm/miscregs.hh42
-rw-r--r--src/arch/arm/nativetrace.cc3
-rw-r--r--src/arch/arm/process.cc4
-rw-r--r--src/arch/arm/process.hh2
-rw-r--r--src/arch/arm/registers.hh45
-rw-r--r--src/arch/arm/stacktrace.cc151
-rw-r--r--src/arch/arm/stacktrace.hh16
-rw-r--r--src/arch/arm/system.cc51
-rw-r--r--src/arch/arm/system.hh56
-rw-r--r--src/arch/arm/tlb.cc10
-rw-r--r--src/arch/arm/types.hh5
-rw-r--r--src/arch/arm/utility.cc76
-rw-r--r--src/arch/arm/utility.hh14
40 files changed, 1756 insertions, 1300 deletions
diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py
new file mode 100644
index 000000000..f21d49e95
--- /dev/null
+++ b/src/arch/arm/ArmInterrupts.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Ali Saidi
+
+from m5.SimObject import SimObject
+
+class ArmInterrupts(SimObject):
+ type = 'ArmInterrupts'
+ cxx_class = 'ArmISA::Interrupts'
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py
new file mode 100644
index 000000000..872776c69
--- /dev/null
+++ b/src/arch/arm/ArmSystem.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Ali Saidi
+
+from m5.params import *
+
+from System import System
+
+class ArmSystem(System):
+ type = 'ArmSystem'
+
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 55ecabdc3..92a4193f1 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -1,6 +1,7 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
+# Copyright (c) 2009 ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Stephen Hines
+# Ali Saidi
Import('*')
@@ -43,15 +45,20 @@ if env['TARGET_ISA'] == 'arm':
Source('pagetable.cc')
Source('tlb.cc')
Source('vtophys.cc')
+ Source('utility.cc')
SimObject('ArmNativeTrace.py')
SimObject('ArmTLB.py')
TraceFlag('Arm')
-
+ TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi")
if env['FULL_SYSTEM']:
- #Insert Full-System Files Here
- pass
+ Source('interrupts.cc')
+ Source('stacktrace.cc')
+ Source('system.cc')
+
+ SimObject('ArmInterrupts.py')
+ SimObject('ArmSystem.py')
else:
Source('process.cc')
Source('linux/linux.cc')
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 3d882c97f..b7dd2d503 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -26,488 +26,114 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
- * Stephen Hines
+ * Authors: Ali Saidi
+ * Gabe Black
*/
#include "arch/arm/faults.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "base/trace.hh"
-#if !FULL_SYSTEM
-#include "sim/process.hh"
-#include "mem/page_table.hh"
-#endif
namespace ArmISA
{
-FaultName MachineCheckFault::_name = "Machine Check";
-FaultVect MachineCheckFault::_vect = 0x0401;
-FaultStat MachineCheckFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
+ {"reset", 0x00, MODE_SVC, 0, 0, true, true};
-FaultName AlignmentFault::_name = "Alignment";
-FaultVect AlignmentFault::_vect = 0x0301;
-FaultStat AlignmentFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
+ {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
-FaultName ResetFault::_name = "Reset Fault";
-#if FULL_SYSTEM
-FaultVect ResetFault::_vect = 0xBFC00000;
-#else
-FaultVect ResetFault::_vect = 0x001;
-#endif
-FaultStat ResetFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
+ {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
-FaultName AddressErrorFault::_name = "Address Error";
-FaultVect AddressErrorFault::_vect = 0x0180;
-FaultStat AddressErrorFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
+ {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
-FaultName StoreAddressErrorFault::_name = "Store Address Error";
-FaultVect StoreAddressErrorFault::_vect = 0x0180;
-FaultStat StoreAddressErrorFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
+ {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
+template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
+ {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
-FaultName SystemCallFault::_name = "Syscall";
-FaultVect SystemCallFault::_vect = 0x0180;
-FaultStat SystemCallFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
+ {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
-FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
-FaultVect CoprocessorUnusableFault::_vect = 0x180;
-FaultStat CoprocessorUnusableFault::_count;
-
-FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
-FaultVect ReservedInstructionFault::_vect = 0x0180;
-FaultStat ReservedInstructionFault::_count;
-
-FaultName ThreadFault::_name = "Thread Fault";
-FaultVect ThreadFault::_vect = 0x00F1;
-FaultStat ThreadFault::_count;
-
-
-FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
-FaultVect ArithmeticFault::_vect = 0x180;
-FaultStat ArithmeticFault::_count;
-
-FaultName UnimplementedOpcodeFault::_name = "opdec";
-FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
-FaultStat UnimplementedOpcodeFault::_count;
-
-FaultName InterruptFault::_name = "interrupt";
-FaultVect InterruptFault::_vect = 0x0180;
-FaultStat InterruptFault::_count;
-
-FaultName TrapFault::_name = "Trap";
-FaultVect TrapFault::_vect = 0x0180;
-FaultStat TrapFault::_count;
-
-FaultName BreakpointFault::_name = "Breakpoint";
-FaultVect BreakpointFault::_vect = 0x0180;
-FaultStat BreakpointFault::_count;
-
-
-FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
-FaultVect ItbInvalidFault::_vect = 0x0180;
-FaultStat ItbInvalidFault::_count;
-
-FaultName ItbPageFault::_name = "itbmiss";
-FaultVect ItbPageFault::_vect = 0x0181;
-FaultStat ItbPageFault::_count;
-
-FaultName ItbMissFault::_name = "itbmiss";
-FaultVect ItbMissFault::_vect = 0x0181;
-FaultStat ItbMissFault::_count;
-
-FaultName ItbAcvFault::_name = "iaccvio";
-FaultVect ItbAcvFault::_vect = 0x0081;
-FaultStat ItbAcvFault::_count;
-
-FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
-FaultVect ItbRefillFault::_vect = 0x0180;
-FaultStat ItbRefillFault::_count;
-
-FaultName NDtbMissFault::_name = "dtb_miss_single";
-FaultVect NDtbMissFault::_vect = 0x0201;
-FaultStat NDtbMissFault::_count;
-
-FaultName PDtbMissFault::_name = "dtb_miss_double";
-FaultVect PDtbMissFault::_vect = 0x0281;
-FaultStat PDtbMissFault::_count;
-
-FaultName DtbPageFault::_name = "dfault";
-FaultVect DtbPageFault::_vect = 0x0381;
-FaultStat DtbPageFault::_count;
-
-FaultName DtbAcvFault::_name = "dfault";
-FaultVect DtbAcvFault::_vect = 0x0381;
-FaultStat DtbAcvFault::_count;
-
-FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
-FaultVect DtbInvalidFault::_vect = 0x0180;
-FaultStat DtbInvalidFault::_count;
-
-FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
-FaultVect DtbRefillFault::_vect = 0x0180;
-FaultStat DtbRefillFault::_count;
-
-FaultName TLBModifiedFault::_name = "TLB Modified Exception";
-FaultVect TLBModifiedFault::_vect = 0x0180;
-FaultStat TLBModifiedFault::_count;
-
-FaultName FloatEnableFault::_name = "float_enable_fault";
-FaultVect FloatEnableFault::_vect = 0x0581;
-FaultStat FloatEnableFault::_count;
-
-FaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
-FaultVect IntegerOverflowFault::_vect = 0x0501;
-FaultStat IntegerOverflowFault::_count;
-
-FaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
-FaultVect DspStateDisabledFault::_vect = 0x001a;
-FaultStat DspStateDisabledFault::_count;
-
-#if FULL_SYSTEM
-void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
-{
- tc->setPC(HandlerBase);
- tc->setNextPC(HandlerBase+sizeof(MachInst));
- tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
-}
-
-void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
-{
- // modify SRS Ctl - Save CSS, put ESS into CSS
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
- {
- // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
- MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl);
- uint8_t CSS,ESS;
- CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
- ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
- // Move CSS to PSS
- replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
- // Move ESS to CSS
- replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
- tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs);
- //tc->setShadowSet(ESS);
- }
-
- // set EXL bit (don't care if it is already set!)
- replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
- tc->setMiscRegNoEffect(ArmISA::Status,stat);
-
- // write EPC
- // warn("Set EPC to %x\n",tc->readPC());
- // CHECK ME or FIXME or FIX ME or POSSIBLE HACK
- // Check to see if the exception occurred in the branch delay slot
- DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
- int C_BD=0;
- if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
- tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst));
- // In the branch delay slot? set CAUSE_31
- C_BD = 1;
- } else {
- tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC());
- // In the branch delay slot? reset CAUSE_31
- C_BD = 0;
- }
-
- // Set Cause_EXCCODE field
- MiscReg cause = tc->readMiscReg(ArmISA::Cause);
- replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
- replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
- replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
- tc->setMiscRegNoEffect(ArmISA::Cause,cause);
-
-}
-
-void ArithmeticFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0xC);
-
- // Set new PC
- Addr HandlerBase;
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Here, the handler is dependent on BEV, which is not modified by setExceptionState()
- if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase);
- }else{
- HandlerBase = 0xBFC00200;
- }
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
-}
-
-void StoreAddressErrorFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x5);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void TrapFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- setExceptionState(tc,0xD);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-}
-
-void BreakpointFault::invoke(ThreadContext *tc)
-{
- setExceptionState(tc,0x9);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void DtbInvalidFault::invoke(ThreadContext *tc)
+Addr
+ArmFaultBase::getVector(ThreadContext *tc)
{
- DPRINTF(Arm,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
- setExceptionState(tc,0x3);
+ // ARM ARM B1-3
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+
+ // panic if SCTLR.VE because I have no idea what to do with vectored
+ // interrupts
+ assert(!sctlr.ve);
+
+ if (!sctlr.v)
+ return offset();
+ return offset() + HighVecs;
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
}
-void AddressErrorFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x4);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
-}
-
-void ItbInvalidFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x2);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-}
-
-void ItbRefillFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr);
- Addr HandlerBase;
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Since handler depends on EXL bit, must check EXL bit before setting it!!
- if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
- }
-
- setExceptionState(tc,0x2);
- setHandlerPC(HandlerBase,tc);
-}
-
-void DtbRefillFault::invoke(ThreadContext *tc)
-{
- // Set new PC
- DPRINTF(Arm,"%s encountered.\n", name());
- Addr HandlerBase;
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Since handler depends on EXL bit, must check EXL bit before setting it!!
- if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
- }
-
-
- setExceptionState(tc,0x3);
-
- setHandlerPC(HandlerBase,tc);
-}
-
-void TLBModifiedFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setExceptionState(tc,0x1);
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void SystemCallFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x8);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void InterruptFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
-
-
- uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV);
- if (IV)// Offset 200 for release 2
- HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
- else//Ofset at 180 for release 1
- HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
-
- setHandlerPC(HandlerBase,tc);
-#endif
-}
-
-#endif // FULL_SYSTEM
-
-void ResetFault::invoke(ThreadContext *tc)
-{
#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- /* All reset activity must be invoked from here */
- tc->setPC(vect());
- tc->setNextPC(vect()+sizeof(MachInst));
- tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
- DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
-#endif
- // Set Coprocessor 1 (Floating Point) To Usable
- //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
-}
-
-void ReservedInstructionFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
-#else
- panic("%s encountered.\n", name());
-#endif
-}
-
-void ThreadFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
-}
-
-void DspStateDisabledFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
+void
+ArmFaultBase::invoke(ThreadContext *tc)
+{
+ // ARM ARM B1.6.3
+ FaultBase::invoke(tc);
+ countStat()++;
+
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+ CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+ CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
+ tc->readIntReg(INTREG_CONDCODES);
+
+
+ cpsr.mode = nextMode();
+ cpsr.it1 = cpsr.it2 = 0;
+ cpsr.j = 0;
+
+ if (sctlr.te)
+ cpsr.t = 1;
+ cpsr.a = cpsr.a | abortDisable();
+ cpsr.f = cpsr.f | fiqDisable();
+ cpsr.i = 1;
+ tc->setMiscReg(MISCREG_CPSR, cpsr);
+ tc->setIntReg(INTREG_LR, tc->readPC() +
+ (saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
+
+ switch (nextMode()) {
+ case MODE_FIQ:
+ tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
+ break;
+ case MODE_IRQ:
+ tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
+ break;
+ case MODE_SVC:
+ tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
+ break;
+ case MODE_UNDEFINED:
+ tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
+ break;
+ case MODE_ABORT:
+ tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
+ break;
+ default:
+ panic("unknown Mode\n");
+ }
+
+ DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr,
+ tc->readPC(), tc->readIntReg(INTREG_LR));
+ tc->setPC(getVector(tc));
+ tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 );
}
+#endif // FULL_SYSTEM
-void CoprocessorUnusableFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0xb);
- /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
- MiscReg cause = tc->readMiscReg(ArmISA::Cause);
- replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
- tc->setMiscRegNoEffect(ArmISA::Cause,cause);
+// return via SUBS pc, lr, xxx; rfe, movs, ldm
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
-#else
- warn("%s (CP%d) encountered.\n", name(), coProcID);
-#endif
-}
} // namespace ArmISA
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 28ecd7591..7f8aa66b6 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -26,548 +26,79 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
- * Stephen Hines
+ * Authors: Ali Saidi
+ * Gabe Black
*/
#ifndef __ARM_FAULTS_HH__
#define __ARM_FAULTS_HH__
+#include "arch/arm/types.hh"
+#include "config/full_system.hh"
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace ArmISA
{
-typedef const Addr FaultVect;
+typedef const Addr FaultOffset;
-class ArmFault : public FaultBase
+class ArmFaultBase : public FaultBase
{
protected:
- virtual bool skipFaultingInstruction() {return false;}
- virtual bool setRestartAddress() {return true;}
- public:
- Addr BadVAddr;
- Addr EntryHi_Asid;
- Addr EntryHi_VPN2;
- Addr EntryHi_VPN2X;
- Addr Context_BadVPN2;
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc) {};
- void setExceptionState(ThreadContext *,uint8_t);
- void setHandlerPC(Addr,ThreadContext *);
-#endif
- virtual FaultVect vect() = 0;
- virtual FaultStat & countStat() = 0;
-};
-
-class MachineCheckFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isMachineCheckFault() {return true;}
-};
-
-class NonMaskableInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isNonMaskableInterrupt() {return true;}
-};
-
-class AlignmentFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isAlignmentFault() {return true;}
-};
-
-class AddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class StoreAddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class UnimplementedOpcodeFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-
-class TLBRefillIFetchFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class TLBInvalidIFetchFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class NDtbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class PDtbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DtbPageFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DtbAcvFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class CacheErrorFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-
-
-
-static inline Fault genMachineCheckFault()
-{
- return new MachineCheckFault;
-}
-
-static inline Fault genAlignmentFault()
-{
- return new AlignmentFault;
-}
-
-class ResetFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-
-};
-class SystemCallFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class SoftResetFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugSingleStep : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class CoprocessorUnusableFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- int coProcID;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
- CoprocessorUnusableFault(int _procid){ coProcID = _procid;}
-};
+ Addr getVector(ThreadContext *tc);
-class ReservedInstructionFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class ThreadFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
+ struct FaultVals
+ {
+ const FaultName name;
+ const FaultOffset offset;
+ const OperatingMode nextMode;
+ const uint8_t armPcOffset;
+ const uint8_t thumbPcOffset;
+ const bool abortDisable;
+ const bool fiqDisable;
+ FaultStat count;
+ };
-
-class ArithmeticFault : public ArmFault
-{
- protected:
- bool skipFaultingInstruction() {return true;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
+ void invoke(ThreadContext *tc);
#endif
+ virtual FaultStat& countStat() = 0;
+ virtual FaultOffset offset() = 0;
+ virtual OperatingMode nextMode() = 0;
+ virtual uint8_t armPcOffset() = 0;
+ virtual uint8_t thumbPcOffset() = 0;
+ virtual bool abortDisable() = 0;
+ virtual bool fiqDisable() = 0;
};
-class InterruptFault : public ArmFault
+template<typename T>
+class ArmFault : public ArmFaultBase
{
protected:
- bool setRestartAddress() {return false;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
- //void invoke(ThreadContext * tc);
-};
-
-class TrapFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class BreakpointFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbRefillFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-class DtbRefillFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbPageFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbInvalidFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class TLBModifiedFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
+ static FaultVals vals;
-class DtbInvalidFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
+ FaultName name() const { return vals.name; }
+ FaultStat & countStat() {return vals.count;}
+ FaultOffset offset() { return vals.offset; }
+ OperatingMode nextMode() { return vals.nextMode; }
+ uint8_t armPcOffset() { return vals.armPcOffset; }
+ uint8_t thumbPcOffset() { return vals.thumbPcOffset; }
+ bool abortDisable() { return vals.abortDisable; }
+ bool fiqDisable() { return vals.fiqDisable; }
};
-class FloatEnableFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-class ItbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
+class Reset : public ArmFault<Reset> {};
+class UndefinedInstruction : public ArmFault<UndefinedInstruction> {};
+class SupervisorCall : public ArmFault<SupervisorCall> {};
+class PrefetchAbort : public ArmFault<PrefetchAbort> {};
+class DataAbort : public ArmFault<DataAbort> {};
+class Interrupt : public ArmFault<Interrupt> {};
+class FastInterrupt : public ArmFault<FastInterrupt> {};
-class ItbAcvFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class IntegerOverflowFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DspStateDisabledFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
} // ArmISA namespace
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index 541c9e3f5..714b8bb7e 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp
*/
class ArmMacroMemoryOp : public PredMacroOp
{
- protected:
+ protected:
/// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags;
uint32_t reglist;
uint32_t ones;
- uint32_t puswl,
- prepost,
- up,
- psruser,
- writeback,
- loadop;
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
- : PredMacroOp(mnem, _machInst, __opClass),
- memAccessFlags(0),
- reglist(machInst.regList), ones(0),
- puswl(machInst.puswl),
- prepost(machInst.puswl.prepost),
- up(machInst.puswl.up),
- psruser(machInst.puswl.psruser),
- writeback(machInst.puswl.writeback),
- loadop(machInst.puswl.loadOp)
+ : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
+ reglist(machInst.regList), ones(0)
{
ones = number_of_ones(reglist);
- numMicroops = ones + writeback + 1;
+ numMicroops = ones + machInst.puswl.writeback + 1;
// Remember that writeback adds a uop
microOps = new StaticInstPtr[numMicroops];
}
@@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp
*/
class ArmMacroFPAOp : public PredMacroOp
{
- protected:
+ protected:
uint32_t puswl,
prepost,
up,
@@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp
*/
class ArmMacroFMOp : public PredMacroOp
{
- protected:
+ protected:
uint32_t punwl,
prepost,
up,
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index df2d5de25..bf7a38c58 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -27,8 +27,10 @@
* Authors: Stephen Hines
*/
+#include "arch/arm/faults.hh"
#include "arch/arm/insts/static_inst.hh"
#include "base/condcodes.hh"
+#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
namespace ArmISA
@@ -62,7 +64,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
else
return (base << (32 - shamt)) | (base >> shamt);
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -101,7 +103,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
else
return (base << (32 - shamt)) | (base >> shamt);
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -141,7 +143,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
else
return (base >> (shamt - 1)) & 1;
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -182,7 +184,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
shamt = 32;
return (base >> (shamt - 1)) & 1;
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh
index c963c1827..f2881c3b6 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst
void printDataInst(std::ostream &os, bool withImm) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ static uint32_t
+ cpsrWriteByInstr(CPSR cpsr, uint32_t val,
+ uint8_t byteMask, bool affectState)
+ {
+ bool privileged = (cpsr.mode != MODE_USER);
+
+ uint32_t bitMask = 0;
+
+ if (bits(byteMask, 3)) {
+ unsigned lowIdx = affectState ? 24 : 27;
+ bitMask = bitMask | mask(31, lowIdx);
+ }
+ if (bits(byteMask, 2)) {
+ bitMask = bitMask | mask(19, 16);
+ }
+ if (bits(byteMask, 1)) {
+ unsigned highIdx = affectState ? 15 : 9;
+ unsigned lowIdx = privileged ? 8 : 9;
+ bitMask = bitMask | mask(highIdx, lowIdx);
+ }
+ if (bits(byteMask, 0)) {
+ if (privileged) {
+ bitMask = bitMask | mask(7, 6);
+ bitMask = bitMask | mask(5);
+ }
+ if (affectState)
+ bitMask = bitMask | (1 << 5);
+ }
+
+ return ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
+ }
+
+ static uint32_t
+ spsrWriteByInstr(uint32_t spsr, uint32_t val,
+ uint8_t byteMask, bool affectState)
+ {
+ uint32_t bitMask = 0;
+
+ if (bits(byteMask, 3))
+ bitMask = bitMask | mask(31, 24);
+ if (bits(byteMask, 2))
+ bitMask = bitMask | mask(19, 16);
+ if (bits(byteMask, 1))
+ bitMask = bitMask | mask(15, 8);
+ if (bits(byteMask, 0))
+ bitMask = bitMask | mask(7, 0);
+
+ return ((spsr & ~bitMask) | (val & bitMask));
+ }
};
}
diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc
new file mode 100644
index 000000000..a47ebc75d
--- /dev/null
+++ b/src/arch/arm/interrupts.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009 ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#include "arch/arm/interrupts.hh"
+
+ArmISA::Interrupts *
+ArmInterruptsParams::create()
+{
+ return new ArmISA::Interrupts(this);
+}
diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh
new file mode 100644
index 000000000..189341d6b
--- /dev/null
+++ b/src/arch/arm/interrupts.hh
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2009 ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#ifndef __ARCH_ARM_INTERRUPT_HH__
+#define __ARCH_ARM_INTERRUPT_HH__
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/registers.hh"
+#include "cpu/thread_context.hh"
+#include "params/ArmInterrupts.hh"
+#include "sim/sim_object.hh"
+
+namespace ArmISA
+{
+
+class Interrupts : public SimObject
+{
+ private:
+ BaseCPU * cpu;
+
+ uint64_t intStatus;
+
+ public:
+
+ void
+ setCPU(BaseCPU * _cpu)
+ {
+ cpu = _cpu;
+ }
+
+ typedef ArmInterruptsParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ Interrupts(Params * p) : SimObject(p), cpu(NULL)
+ {
+ clearAll();
+ }
+
+
+ void
+ post(int int_num, int index)
+ {
+ }
+
+ void
+ clear(int int_num, int index)
+ {
+ }
+
+ void
+ clearAll()
+ {
+ intStatus = 0;
+ }
+
+ bool
+ checkInterrupts(ThreadContext *tc) const
+ {
+ return intStatus;
+ }
+
+ Fault
+ getInterrupt(ThreadContext *tc)
+ {
+ warn_once("ARM Interrupts not handled\n");
+ return NoFault;
+ }
+
+ void
+ updateIntrInfo(ThreadContext *tc)
+ {
+
+ }
+
+ void
+ serialize(std::ostream &os)
+ {
+ }
+
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
+ {
+ }
+};
+} // namespace ARM_ISA
+
+#endif // __ARCH_ARM_INTERRUPT_HH__
diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh
new file mode 100644
index 000000000..15499601a
--- /dev/null
+++ b/src/arch/arm/intregs.hh
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2009 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include <assert.h>
+
+#ifndef __ARCH_ARM_INTREGS_HH__
+#define __ARCH_ARM_INTREGS_HH__
+
+namespace ArmISA
+{
+
+enum IntRegIndex
+{
+ /* All the unique register indices. */
+ INTREG_R0,
+ INTREG_R1,
+ INTREG_R2,
+ INTREG_R3,
+ INTREG_R4,
+ INTREG_R5,
+ INTREG_R6,
+ INTREG_R7,
+ INTREG_R8,
+ INTREG_R9,
+ INTREG_R10,
+ INTREG_R11,
+ INTREG_R12,
+ INTREG_R13,
+ INTREG_SP = INTREG_R13,
+ INTREG_R14,
+ INTREG_LR = INTREG_R14,
+ INTREG_R15,
+ INTREG_PC = INTREG_R15,
+
+ INTREG_R13_SVC,
+ INTREG_SP_SVC = INTREG_R13_SVC,
+ INTREG_R14_SVC,
+ INTREG_LR_SVC = INTREG_R14_SVC,
+
+ INTREG_R13_MON,
+ INTREG_SP_MON = INTREG_R13_MON,
+ INTREG_R14_MON,
+ INTREG_LR_MON = INTREG_R14_MON,
+
+ INTREG_R13_ABT,
+ INTREG_SP_ABT = INTREG_R13_ABT,
+ INTREG_R14_ABT,
+ INTREG_LR_ABT = INTREG_R14_ABT,
+
+ INTREG_R13_UND,
+ INTREG_SP_UND = INTREG_R13_UND,
+ INTREG_R14_UND,
+ INTREG_LR_UND = INTREG_R14_UND,
+
+ INTREG_R13_IRQ,
+ INTREG_SP_IRQ = INTREG_R13_IRQ,
+ INTREG_R14_IRQ,
+ INTREG_LR_IRQ = INTREG_R14_IRQ,
+
+ INTREG_R8_FIQ,
+ INTREG_R9_FIQ,
+ INTREG_R10_FIQ,
+ INTREG_R11_FIQ,
+ INTREG_R12_FIQ,
+ INTREG_R13_FIQ,
+ INTREG_SP_FIQ = INTREG_R13_FIQ,
+ INTREG_R14_FIQ,
+ INTREG_LR_FIQ = INTREG_R14_FIQ,
+
+ INTREG_ZERO, // Dummy zero reg since there has to be one.
+ INTREG_UREG0,
+ INTREG_RHI,
+ INTREG_RLO,
+ INTREG_CONDCODES,
+
+ NUM_INTREGS,
+ NUM_ARCH_INTREGS = INTREG_PC + 1,
+
+ /* All the aliased indexes. */
+
+ /* USR mode */
+ INTREG_R0_USR = INTREG_R0,
+ INTREG_R1_USR = INTREG_R1,
+ INTREG_R2_USR = INTREG_R2,
+ INTREG_R3_USR = INTREG_R3,
+ INTREG_R4_USR = INTREG_R4,
+ INTREG_R5_USR = INTREG_R5,
+ INTREG_R6_USR = INTREG_R6,
+ INTREG_R7_USR = INTREG_R7,
+ INTREG_R8_USR = INTREG_R8,
+ INTREG_R9_USR = INTREG_R9,
+ INTREG_R10_USR = INTREG_R10,
+ INTREG_R11_USR = INTREG_R11,
+ INTREG_R12_USR = INTREG_R12,
+ INTREG_R13_USR = INTREG_R13,
+ INTREG_SP_USR = INTREG_SP,
+ INTREG_R14_USR = INTREG_R14,
+ INTREG_LR_USR = INTREG_LR,
+ INTREG_R15_USR = INTREG_R15,
+ INTREG_PC_USR = INTREG_PC,
+
+ /* SVC mode */
+ INTREG_R0_SVC = INTREG_R0,
+ INTREG_R1_SVC = INTREG_R1,
+ INTREG_R2_SVC = INTREG_R2,
+ INTREG_R3_SVC = INTREG_R3,
+ INTREG_R4_SVC = INTREG_R4,
+ INTREG_R5_SVC = INTREG_R5,
+ INTREG_R6_SVC = INTREG_R6,
+ INTREG_R7_SVC = INTREG_R7,
+ INTREG_R8_SVC = INTREG_R8,
+ INTREG_R9_SVC = INTREG_R9,
+ INTREG_R10_SVC = INTREG_R10,
+ INTREG_R11_SVC = INTREG_R11,
+ INTREG_R12_SVC = INTREG_R12,
+ INTREG_PC_SVC = INTREG_PC,
+ INTREG_R15_SVC = INTREG_R15,
+
+ /* MON mode */
+ INTREG_R0_MON = INTREG_R0,
+ INTREG_R1_MON = INTREG_R1,
+ INTREG_R2_MON = INTREG_R2,
+ INTREG_R3_MON = INTREG_R3,
+ INTREG_R4_MON = INTREG_R4,
+ INTREG_R5_MON = INTREG_R5,
+ INTREG_R6_MON = INTREG_R6,
+ INTREG_R7_MON = INTREG_R7,
+ INTREG_R8_MON = INTREG_R8,
+ INTREG_R9_MON = INTREG_R9,
+ INTREG_R10_MON = INTREG_R10,
+ INTREG_R11_MON = INTREG_R11,
+ INTREG_R12_MON = INTREG_R12,
+ INTREG_PC_MON = INTREG_PC,
+ INTREG_R15_MON = INTREG_R15,
+
+ /* ABT mode */
+ INTREG_R0_ABT = INTREG_R0,
+ INTREG_R1_ABT = INTREG_R1,
+ INTREG_R2_ABT = INTREG_R2,
+ INTREG_R3_ABT = INTREG_R3,
+ INTREG_R4_ABT = INTREG_R4,
+ INTREG_R5_ABT = INTREG_R5,
+ INTREG_R6_ABT = INTREG_R6,
+ INTREG_R7_ABT = INTREG_R7,
+ INTREG_R8_ABT = INTREG_R8,
+ INTREG_R9_ABT = INTREG_R9,
+ INTREG_R10_ABT = INTREG_R10,
+ INTREG_R11_ABT = INTREG_R11,
+ INTREG_R12_ABT = INTREG_R12,
+ INTREG_PC_ABT = INTREG_PC,
+ INTREG_R15_ABT = INTREG_R15,
+
+ /* UND mode */
+ INTREG_R0_UND = INTREG_R0,
+ INTREG_R1_UND = INTREG_R1,
+ INTREG_R2_UND = INTREG_R2,
+ INTREG_R3_UND = INTREG_R3,
+ INTREG_R4_UND = INTREG_R4,
+ INTREG_R5_UND = INTREG_R5,
+ INTREG_R6_UND = INTREG_R6,
+ INTREG_R7_UND = INTREG_R7,
+ INTREG_R8_UND = INTREG_R8,
+ INTREG_R9_UND = INTREG_R9,
+ INTREG_R10_UND = INTREG_R10,
+ INTREG_R11_UND = INTREG_R11,
+ INTREG_R12_UND = INTREG_R12,
+ INTREG_PC_UND = INTREG_PC,
+ INTREG_R15_UND = INTREG_R15,
+
+ /* IRQ mode */
+ INTREG_R0_IRQ = INTREG_R0,
+ INTREG_R1_IRQ = INTREG_R1,
+ INTREG_R2_IRQ = INTREG_R2,
+ INTREG_R3_IRQ = INTREG_R3,
+ INTREG_R4_IRQ = INTREG_R4,
+ INTREG_R5_IRQ = INTREG_R5,
+ INTREG_R6_IRQ = INTREG_R6,
+ INTREG_R7_IRQ = INTREG_R7,
+ INTREG_R8_IRQ = INTREG_R8,
+ INTREG_R9_IRQ = INTREG_R9,
+ INTREG_R10_IRQ = INTREG_R10,
+ INTREG_R11_IRQ = INTREG_R11,
+ INTREG_R12_IRQ = INTREG_R12,
+ INTREG_PC_IRQ = INTREG_PC,
+ INTREG_R15_IRQ = INTREG_R15,
+
+ /* FIQ mode */
+ INTREG_R0_FIQ = INTREG_R0,
+ INTREG_R1_FIQ = INTREG_R1,
+ INTREG_R2_FIQ = INTREG_R2,
+ INTREG_R3_FIQ = INTREG_R3,
+ INTREG_R4_FIQ = INTREG_R4,
+ INTREG_R5_FIQ = INTREG_R5,
+ INTREG_R6_FIQ = INTREG_R6,
+ INTREG_R7_FIQ = INTREG_R7,
+ INTREG_PC_FIQ = INTREG_PC,
+ INTREG_R15_FIQ = INTREG_R15,
+};
+
+typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS];
+
+const IntRegMap IntRegUsrMap = {
+ INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR,
+ INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR,
+ INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR,
+ INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR
+};
+
+static inline IntRegIndex
+INTREG_USR(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegUsrMap[index];
+}
+
+const IntRegMap IntRegSvcMap = {
+ INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC,
+ INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC,
+ INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC,
+ INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC
+};
+
+static inline IntRegIndex
+INTREG_SVC(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegSvcMap[index];
+}
+
+const IntRegMap IntRegMonMap = {
+ INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON,
+ INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON,
+ INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON,
+ INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON
+};
+
+static inline IntRegIndex
+INTREG_MON(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegMonMap[index];
+}
+
+const IntRegMap IntRegAbtMap = {
+ INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT,
+ INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT,
+ INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT,
+ INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT
+};
+
+static inline IntRegIndex
+INTREG_ABT(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegAbtMap[index];
+}
+
+const IntRegMap IntRegUndMap = {
+ INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND,
+ INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND,
+ INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND,
+ INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND
+};
+
+static inline IntRegIndex
+INTREG_UND(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegUndMap[index];
+}
+
+const IntRegMap IntRegIrqMap = {
+ INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ,
+ INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ,
+ INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ,
+ INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ
+};
+
+static inline IntRegIndex
+INTREG_IRQ(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegIrqMap[index];
+}
+
+const IntRegMap IntRegFiqMap = {
+ INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ,
+ INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ,
+ INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ,
+ INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ
+};
+
+static inline IntRegIndex
+INTREG_FIQ(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegFiqMap[index];
+}
+
+static inline IntRegIndex
+intRegForceUser(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+
+ return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS);
+}
+
+}
+
+#endif
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 2315afa9e..905eb0183 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -44,6 +44,38 @@ namespace ArmISA
{
protected:
MiscReg miscRegs[NumMiscRegs];
+ const IntRegIndex *intRegMap;
+
+ void
+ updateRegMap(CPSR cpsr)
+ {
+ switch (cpsr.mode) {
+ case MODE_USER:
+ case MODE_SYSTEM:
+ intRegMap = IntRegUsrMap;
+ break;
+ case MODE_FIQ:
+ intRegMap = IntRegFiqMap;
+ break;
+ case MODE_IRQ:
+ intRegMap = IntRegIrqMap;
+ break;
+ case MODE_SVC:
+ intRegMap = IntRegSvcMap;
+ break;
+ case MODE_MON:
+ intRegMap = IntRegMonMap;
+ break;
+ case MODE_ABORT:
+ intRegMap = IntRegAbtMap;
+ break;
+ case MODE_UNDEFINED:
+ intRegMap = IntRegUndMap;
+ break;
+ default:
+ panic("Unrecognized mode setting in CPSR.\n");
+ }
+ }
public:
void clear()
@@ -52,6 +84,15 @@ namespace ArmISA
CPSR cpsr = 0;
cpsr.mode = MODE_USER;
miscRegs[MISCREG_CPSR] = cpsr;
+ updateRegMap(cpsr);
+
+ SCTLR sctlr = 0;
+ sctlr.nmfi = 1;
+ sctlr.rao1 = 1;
+ sctlr.rao2 = 1;
+ sctlr.rao3 = 1;
+ sctlr.rao4 = 1;
+
//XXX We need to initialize the rest of the state.
}
@@ -59,34 +100,94 @@ namespace ArmISA
readMiscRegNoEffect(int misc_reg)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ return miscRegs[MISCREG_SPSR];
+ case MODE_FIQ:
+ return miscRegs[MISCREG_SPSR_FIQ];
+ case MODE_IRQ:
+ return miscRegs[MISCREG_SPSR_IRQ];
+ case MODE_SVC:
+ return miscRegs[MISCREG_SPSR_SVC];
+ case MODE_MON:
+ return miscRegs[MISCREG_SPSR_MON];
+ case MODE_ABORT:
+ return miscRegs[MISCREG_SPSR_ABT];
+ case MODE_UNDEFINED:
+ return miscRegs[MISCREG_SPSR_UND];
+ default:
+ return miscRegs[MISCREG_SPSR];
+ }
+ }
return miscRegs[misc_reg];
}
MiscReg
readMiscReg(int misc_reg, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- return miscRegs[misc_reg];
+ return readMiscRegNoEffect(misc_reg);
}
void
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ case MODE_FIQ:
+ miscRegs[MISCREG_SPSR_FIQ] = val;
+ return;
+ case MODE_IRQ:
+ miscRegs[MISCREG_SPSR_IRQ] = val;
+ return;
+ case MODE_SVC:
+ miscRegs[MISCREG_SPSR_SVC] = val;
+ return;
+ case MODE_MON:
+ miscRegs[MISCREG_SPSR_MON] = val;
+ return;
+ case MODE_ABORT:
+ miscRegs[MISCREG_SPSR_ABT] = val;
+ return;
+ case MODE_UNDEFINED:
+ miscRegs[MISCREG_SPSR_UND] = val;
+ return;
+ default:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ }
+ }
miscRegs[misc_reg] = val;
}
void
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- miscRegs[misc_reg] = val;
+ if (misc_reg == MISCREG_CPSR) {
+ updateRegMap(val);
+ }
+ return setMiscRegNoEffect(misc_reg, val);
}
int
flattenIntIndex(int reg)
{
- return reg;
+ assert(reg >= 0);
+ if (reg < NUM_ARCH_INTREGS) {
+ return intRegMap[reg];
+ } else if (reg < NUM_INTREGS) {
+ return reg;
+ } else {
+ reg -= NUM_INTREGS;
+ assert(reg < NUM_ARCH_INTREGS);
+ return reg;
+ }
}
int
@@ -95,9 +196,10 @@ namespace ArmISA
return reg;
}
- void serialize(std::ostream &os)
+ void serialize(EventManager *em, std::ostream &os)
{}
- void unserialize(Checkpoint *cp, const std::string &section)
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section)
{}
ISA()
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
index 5785939cc..8ff819983 100644
--- a/src/arch/arm/isa/bitfields.isa
+++ b/src/arch/arm/isa/bitfields.isa
@@ -38,14 +38,18 @@ def bitfield ENCODING encoding;
def bitfield OPCODE opcode;
def bitfield MEDIA_OPCODE mediaOpcode;
def bitfield MEDIA_OPCODE2 mediaOpcode2;
+def bitfield USEIMM useImm;
def bitfield OPCODE_24 opcode24;
def bitfield OPCODE_23_20 opcode23_20;
def bitfield OPCODE_23_21 opcode23_21;
def bitfield OPCODE_22 opcode22;
+def bitfield OPCODE_20 opcode20;
def bitfield OPCODE_19 opcode19;
+def bitfield OPCODE_18 opcode18;
def bitfield OPCODE_15_12 opcode15_12;
def bitfield OPCODE_15 opcode15;
def bitfield MISC_OPCODE miscOpcode;
+def bitfield OPC2 opc2;
def bitfield OPCODE_7 opcode7;
def bitfield OPCODE_4 opcode4;
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index a999b52e9..ff20c6107 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -51,20 +51,25 @@ format DataOp {
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
Rd = (uint32_t)(resTemp & 0xffffffff);
Rn = (uint32_t)(resTemp >> 32);
- }});
- 0x5: WarnUnimpl::smlal();
+ }}, llbit);
+ 0x5: smlal({{
+ resTemp = ((int64_t)Rm) * ((int64_t)Rs);
+ resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd);
+ Rd = (uint32_t)(resTemp & 0xffffffff);
+ Rn = (uint32_t)(resTemp >> 32);
+ }}, llbit);
0x6: smull({{
resTemp = ((int64_t)(int32_t)Rm)*
((int64_t)(int32_t)Rs);
Rd = (int32_t)(resTemp & 0xffffffff);
Rn = (int32_t)(resTemp >> 32);
- }});
+ }}, llbit);
0x7: umlal({{
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
Rd = (uint32_t)(resTemp & 0xffffffff);
Rn = (uint32_t)(resTemp >> 32);
- }});
+ }}, llbit);
}
1: decode PUBWL {
0x10: WarnUnimpl::swp();
@@ -91,9 +96,9 @@ format DataOp {
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
- 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
- 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
- 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
+ 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add);
+ 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub);
+ 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb);
0x8: tst({{ resTemp = Rn & op2; }});
0x9: teq({{ resTemp = Rn ^ op2; }});
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
@@ -105,10 +110,37 @@ format DataOp {
}
1: decode MISC_OPCODE {
0x0: decode OPCODE {
- 0x8: WarnUnimpl::mrs_cpsr();
- 0x9: WarnUnimpl::msr_cpsr();
- 0xa: WarnUnimpl::mrs_spsr();
- 0xb: WarnUnimpl::msr_spsr();
+ 0x8: PredOp::mrs_cpsr({{
+ Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
+ }});
+ 0x9: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_cpsr_reg({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ Rm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ 1: PredImmOp::msr_cpsr_imm({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
+ 0xb: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_spsr_reg({{
+ Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
+ }});
+ 1: PredImmOp::msr_spsr_imm({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm,
+ RN, false);
+ }});
+ }
}
0x1: decode OPCODE {
0x9: BranchExchange::bx({{ }});
@@ -129,28 +161,32 @@ format DataOp {
0xb: WarnUnimpl::qdsub();
}
0x8: decode OPCODE {
- 0x8: WarnUnimpl::smlabb();
+ 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
0x9: WarnUnimpl::smlalbb();
0xa: WarnUnimpl::smlawb();
- 0xb: WarnUnimpl::smulbb();
+ 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
}
0xa: decode OPCODE {
- 0x8: WarnUnimpl::smlatb();
- 0x9: WarnUnimpl::smulwb();
+ 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
+ 0x9: smulwb({{
+ Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16);
+ }}, none);
0xa: WarnUnimpl::smlaltb();
- 0xb: WarnUnimpl::smultb();
+ 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
}
0xc: decode OPCODE {
- 0x8: WarnUnimpl::smlabt();
+ 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
0x9: WarnUnimpl::smlawt();
0xa: WarnUnimpl::smlalbt();
- 0xb: WarnUnimpl::smulbt();
+ 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
}
0xe: decode OPCODE {
- 0x8: WarnUnimpl::smlatt();
- 0x9: WarnUnimpl::smulwt();
+ 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
+ 0x9: smulwt({{
+ Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16);
+ }}, none);
0xa: WarnUnimpl::smlaltt();
- 0xb: WarnUnimpl::smultt();
+ 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
}
}
}
@@ -163,9 +199,15 @@ format DataOp {
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
- 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
- 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
- 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
+ 0x5: adci({{
+ Rd = resTemp = Rn + rotated_imm + CondCodes<29:>;
+ }}, add);
+ 0x6: sbci({{
+ Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>;
+ }}, sub);
+ 0x7: rsci({{
+ Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>;
+ }}, rsb);
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
@@ -178,11 +220,27 @@ format DataOp {
}
1: decode OPCODE {
// The following two instructions aren't supposed to be defined
- 0x8: WarnUnimpl::undefined_instruction();
- 0x9: WarnUnimpl::undefined_instruction();
-
- 0xa: WarnUnimpl::mrs_i_cpsr();
- 0xb: WarnUnimpl::mrs_i_spsr();
+ 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
+ 0x9: decode RN {
+ 0: decode IMM {
+ 0: PredImmOp::nop({{ ; }});
+ 1: WarnUnimpl::yield();
+ 2: WarnUnimpl::wfe();
+ 3: WarnUnimpl::wfi();
+ 4: WarnUnimpl::sev();
+ }
+ default: PredImmOp::msr_i_cpsr({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
+ 0xb: PredImmOp::msr_i_spsr({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
+ }});
}
}
0x2: AddrMode2::addrMode2(Disp, disp);
@@ -324,77 +382,79 @@ format DataOp {
}
}
0x7: decode OPCODE_24 {
- 0: decode CPNUM {
- // Coprocessor Instructions
- 0x1: decode OPCODE_4 {
+ 0: decode OPCODE_4 {
+ 0: decode CPNUM {
format FloatOp {
- // Basic FPA Instructions
- 0: decode OPCODE_23_20 {
- 0x0: decode OPCODE_15 {
- 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
- 1: mvf({{ Fd.sf = Fm.sf; }});
- }
- 0x1: decode OPCODE_15 {
- 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: mnf({{ Fd.sf = -Fm.sf; }});
- }
- 0x2: decode OPCODE_15 {
- 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
- 1: abs({{ Fd.sf = fabs(Fm.sf); }});
- }
- 0x3: decode OPCODE_15 {
- 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
- 1: rnd({{ Fd.sf = rint(Fm.sf); }});
- }
- 0x4: decode OPCODE_15 {
- 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
- }
- 0x5: decode OPCODE_15 {
- 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: log({{ Fd.sf = log10(Fm.sf); }});
- }
- 0x6: decode OPCODE_15 {
- 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
- 1: lgn({{ Fd.sf = log(Fm.sf); }});
- }
- 0x7: decode OPCODE_15 {
- 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
- 1: exp({{ Fd.sf = exp(Fm.sf); }});
- }
- 0x8: decode OPCODE_15 {
- 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
- 1: sin({{ Fd.sf = sin(Fm.sf); }});
- }
- 0x9: decode OPCODE_15 {
- 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: cos({{ Fd.sf = cos(Fm.sf); }});
- }
- 0xa: decode OPCODE_15 {
- 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: tan({{ Fd.sf = tan(Fm.sf); }});
- }
- 0xb: decode OPCODE_15 {
- 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: asn({{ Fd.sf = asin(Fm.sf); }});
- }
- 0xc: decode OPCODE_15 {
- 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
- 1: acs({{ Fd.sf = acos(Fm.sf); }});
- }
- 0xd: decode OPCODE_15 {
- 1: atn({{ Fd.sf = atan(Fm.sf); }});
- }
- 0xe: decode OPCODE_15 {
- // Unnormalised Round
- 1: FailUnimpl::urd();
- }
- 0xf: decode OPCODE_15 {
- // Normalise
- 1: FailUnimpl::nrm();
- }
- }
- 1: decode OPCODE_15_12 {
+ 0x1: decode OPCODE_23_20 {
+ 0x0: decode OPCODE_15 {
+ 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
+ 1: mvf({{ Fd.sf = Fm.sf; }});
+ }
+ 0x1: decode OPCODE_15 {
+ 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: mnf({{ Fd.sf = -Fm.sf; }});
+ }
+ 0x2: decode OPCODE_15 {
+ 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
+ 1: abs({{ Fd.sf = fabs(Fm.sf); }});
+ }
+ 0x3: decode OPCODE_15 {
+ 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
+ 1: rnd({{ Fd.sf = rint(Fm.sf); }});
+ }
+ 0x4: decode OPCODE_15 {
+ 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
+ }
+ 0x5: decode OPCODE_15 {
+ 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: log({{ Fd.sf = log10(Fm.sf); }});
+ }
+ 0x6: decode OPCODE_15 {
+ 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
+ 1: lgn({{ Fd.sf = log(Fm.sf); }});
+ }
+ 0x7: decode OPCODE_15 {
+ 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
+ 1: exp({{ Fd.sf = exp(Fm.sf); }});
+ }
+ 0x8: decode OPCODE_15 {
+ 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
+ 1: sin({{ Fd.sf = sin(Fm.sf); }});
+ }
+ 0x9: decode OPCODE_15 {
+ 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: cos({{ Fd.sf = cos(Fm.sf); }});
+ }
+ 0xa: decode OPCODE_15 {
+ 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: tan({{ Fd.sf = tan(Fm.sf); }});
+ }
+ 0xb: decode OPCODE_15 {
+ 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: asn({{ Fd.sf = asin(Fm.sf); }});
+ }
+ 0xc: decode OPCODE_15 {
+ 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
+ 1: acs({{ Fd.sf = acos(Fm.sf); }});
+ }
+ 0xd: decode OPCODE_15 {
+ 1: atn({{ Fd.sf = atan(Fm.sf); }});
+ }
+ 0xe: decode OPCODE_15 {
+ // Unnormalised Round
+ 1: FailUnimpl::urd();
+ }
+ 0xf: decode OPCODE_15 {
+ // Normalise
+ 1: FailUnimpl::nrm();
+ }
+ } // OPCODE_23_20
+ } // format FloatOp
+ } // CPNUM
+ 1: decode CPNUM { // 27-24=1110,4 ==1
+ 1: decode OPCODE_15_12 {
+ format FloatOp {
0xf: decode OPCODE_23_21 {
format FloatCmp {
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
@@ -417,36 +477,86 @@ format DataOp {
0x4: FailUnimpl::wfc();
0x5: FailUnimpl::rfc();
}
- }
+ } // format FloatOp
}
- }
- 0xa: decode MISC_OPCODE {
- 0x1: decode MEDIA_OPCODE {
- 0xf: decode RN {
- 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
- 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
- 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
- }
- 0xe: decode RN {
- 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
- 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
- 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ 0xa: decode MISC_OPCODE {
+ 0x1: decode MEDIA_OPCODE {
+ 0xf: decode RN {
+ 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
+ 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
+ 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
+ }
+ 0xe: decode RN {
+ 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
+ 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
+ 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ }
+ } // MEDIA_OPCODE (MISC_OPCODE 0x1)
+ } // MISC_OPCODE (CPNUM 0xA)
+ 0xf: decode RN {
+ // Barrriers, Cache Maintence, NOPS
+ 7: decode OPCODE_23_21 {
+ 0: decode RM {
+ 0: decode OPC2 {
+ 4: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi
+ }
+ }
+ 1: WarnUnimpl::cp15_cache_maint();
+ 4: WarnUnimpl::cp15_par();
+ 5: decode OPC2 {
+ 0,1: WarnUnimpl::cp15_cache_maint2();
+ 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 6,7: WarnUnimpl::cp15_bp_maint();
+ }
+ 6: WarnUnimpl::cp15_cache_maint3();
+ 8: WarnUnimpl::cp15_va_to_pa();
+ 10: decode OPC2 {
+ 1,2: WarnUnimpl::cp15_cache_maint3();
+ 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ }
+ 11: WarnUnimpl::cp15_cache_maint4();
+ 13: decode OPC2 {
+ 1: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch
+ }
+ }
+ 14: WarnUnimpl::cp15_cache_maint5();
+ } // RM
+ } // OPCODE_23_21 CR
+
+ // Thread ID and context ID registers
+ // Thread ID register needs cheaper access than miscreg
+ 13: WarnUnimpl::mcr_mrc_cp15_c7();
+
+ // All the rest
+ default: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15({{
+ fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
+ 1: PredOp::mrc_cp15({{
+ fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
}
- }
+ } // RN
+ } // CPNUM (OP4 == 1)
+ } //OPCODE_4
+
+#if FULL_SYSTEM
+ 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
+#else
+ 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode))
+ {
+ if (IMMED_23_0)
+ xc->syscall(IMMED_23_0);
+ else
+ xc->syscall(R7);
}
- }
- format PredOp {
- // ARM System Call (SoftWare Interrupt)
- 1: swi({{ if (testPredicate(Cpsr, condCode))
- {
- if (IMMED_23_0)
- xc->syscall(IMMED_23_0);
- else
- xc->syscall(R7);
- }
- }});
- }
- }
+ }});
+#endif // FULL_SYSTEM
+ } // OPCODE_24
+
}
}
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index 95f4f14e1..5f1b541ff 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{
else:
inst_flags += ('IsCondControl', )
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = NPC + 4 + disp;\n'
icode += '} else {\n'
@@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{
#Condition code
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
icode += '} else {\n'
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index e88531580..e79529615 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -119,8 +119,8 @@ let {{
_ic = %(fReg1)s >= %(fReg2)s;
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
'''
}};
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 355a67ea9..c834c22cb 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -72,6 +72,18 @@ let {{
'predicate_test': predicateTest},
['IsMicroop'])
+ microLdrRetUopCode = '''
+ Ra = Mem;
+ Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
+ '''
+ microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
+ 'MicroMemOp',
+ {'memacc_code': microLdrRetUopCode,
+ 'ea_code':
+ 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
'MicroMemOp',
{'memacc_code': 'Mem = Ra;',
@@ -80,14 +92,19 @@ let {{
['IsMicroop'])
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+ MicroMemDeclare.subst(microLdrRetUopIop) + \
MicroMemDeclare.subst(microStrUopIop)
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+ MicroConstructor.subst(microLdrRetUopIop) + \
MicroConstructor.subst(microStrUopIop)
exec_output = LoadExecute.subst(microLdrUopIop) + \
+ LoadExecute.subst(microLdrRetUopIop) + \
StoreExecute.subst(microStrUopIop) + \
LoadInitiateAcc.subst(microLdrUopIop) + \
+ LoadInitiateAcc.subst(microLdrRetUopIop) + \
StoreInitiateAcc.subst(microStrUopIop) + \
LoadCompleteAcc.subst(microLdrUopIop) + \
+ LoadCompleteAcc.subst(microLdrRetUopIop) + \
StoreCompleteAcc.subst(microStrUopIop)
}};
@@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
- uint32_t regs_to_handle = reglist;
- uint32_t start_addr = 0;
+ uint32_t regs = reglist;
+ uint32_t addr = 0;
+ bool up = machInst.puswl.up;
- switch (puswl)
- {
- case 0x00: // stmda
- case 0x01: // L ldmda_l
- case 0x02: // W stmda_w
- case 0x03: // WL ldmda_wl
- start_addr = (ones << 2) - 4;
- break;
- case 0x08: // U stmia_u
- case 0x09: // U L ldmia_ul
- case 0x0a: // U W stmia
- case 0x0b: // U WL ldmia
- start_addr = 0;
- break;
- case 0x10: // P stmdb
- case 0x11: // P L ldmdb
- case 0x12: // P W stmdb
- case 0x13: // P WL ldmdb
- start_addr = (ones << 2); // U-bit is already 0 for subtract
- break;
- case 0x18: // PU stmib
- case 0x19: // PU L ldmib
- case 0x1a: // PU W stmib
- case 0x1b: // PU WL ldmib
- start_addr = 4;
- break;
- default:
- panic("Unhandled Load/Store Multiple Instruction, "
- "puswl = 0x%x", (unsigned) puswl);
- break;
- }
+ if (!up)
+ addr = (ones << 2) - 4;
+
+ if (machInst.puswl.prepost)
+ addr += 4;
- // Add 0 to Rn and stick it in Raddr (register 17).
+ // Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
- microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
+ microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
- unsigned j = 0;
- for (int i = 1; i < ones+1; i++) {
- // Get next available bit for transfer
- while (! ( regs_to_handle & (1<<j)))
- j++;
- regs_to_handle &= ~(1<<j);
+ unsigned reg = 0;
+ bool force_user = machInst.puswl.psruser & !OPCODE_15;
+ bool exception_ret = machInst.puswl.psruser & OPCODE_15;
- if (loadop)
- microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
- else
- microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
+ for (int i = 1; i < ones + 1; i++) {
+ // Find the next register.
+ while (!bits(regs, reg))
+ reg++;
+ replaceBits(regs, reg, 0);
+
+ unsigned regIdx = reg;
+ if (force_user) {
+ regIdx = intRegForceUser(regIdx);
+ }
+
+ if (machInst.puswl.loadOp) {
+ if (reg == INTREG_PC && exception_ret) {
+ // This must be the exception return form of ldm.
+ microOps[i] =
+ new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
+ } else {
+ microOps[i] =
+ new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
+ } else {
+ microOps[i] =
+ new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
if (up)
- start_addr += 4;
+ addr += 4;
else
- start_addr -= 4;
+ addr -= 4;
}
- if (writeback) {
+ StaticInstPtr &lastUop = microOps[numMicroops - 1];
+ if (machInst.puswl.writeback) {
if (up) {
- microOps[numMicroops-1] =
- new MicroAddiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else {
- microOps[numMicroops-1] =
- new MicroSubiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ lastUop->setLastMicroop();
}
}};
@@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback)
{
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
@@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback) {
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index e90788c91..0d6ee32f7 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -34,7 +34,7 @@
//
let {{
- predicateTest = 'testPredicate(Cpsr, condCode)'
+ predicateTest = 'testPredicate(CondCodes, condCode)'
}};
def template PredOpExecute {{
@@ -81,32 +81,45 @@ def template DataImmDecode {{
}};
let {{
+
+ calcCcCode = '''
+ if (%(canOverflow)s){
+ cprintf("canOverflow: %%d\\n", Rd < resTemp);
+ replaceBits(CondCodes, 27, Rd < resTemp);
+ } else {
+ uint16_t _ic, _iv, _iz, _in;
+ _in = (resTemp >> %(negBit)d) & 1;
+ _iz = (resTemp == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
- calcCcCode = '''
- uint16_t _ic, _iv, _iz, _in;
-
- _in = (resTemp >> 31) & 1;
- _iz = (resTemp == 0);
- _iv = %(ivValue)s & 1;
- _ic = %(icValue)s & 1;
-
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
-
- DPRINTF(Arm, "in = %%d\\n", _in);
- DPRINTF(Arm, "iz = %%d\\n", _iz);
- DPRINTF(Arm, "ic = %%d\\n", _ic);
- DPRINTF(Arm, "iv = %%d\\n", _iv);
+ DPRINTF(Arm, "in = %%d\\n", _in);
+ DPRINTF(Arm, "iz = %%d\\n", _iz);
+ DPRINTF(Arm, "ic = %%d\\n", _ic);
+ DPRINTF(Arm, "iv = %%d\\n", _iv);
+ }
'''
-
}};
let {{
def getCcCode(flagtype):
icReg = icImm = iv = ''
+ negBit = 31
+ canOverflow = 'false'
+
if flagtype == "none":
- icReg = icImm = 'Cpsr<29:>'
- iv = 'Cpsr<28:>'
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ canOverflow = "true"
+ icReg = icImm = iv = '0'
elif flagtype == "add":
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -117,17 +130,32 @@ let {{
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
else:
- icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
- icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
- iv = 'Cpsr<28:>'
- return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
- calcCcCode % {"icValue" : icImm, "ivValue" : iv})
+ icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
+ icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
+ iv = 'CondCodes<28:>'
+ return (calcCcCode % {"icValue" : icReg,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow },
+ calcCcCode % {"icValue" : icImm,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow })
def getImmCcCode(flagtype):
ivValue = icValue = ''
+ negBit = 31
+ canOverflow = 'false'
if flagtype == "none":
- icValue = 'Cpsr<29:>'
- ivValue = 'Cpsr<28:>'
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ icVaule = ivValue = '0'
+ canOverflow = "true"
elif flagtype == "add":
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
@@ -138,18 +166,18 @@ let {{
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
else:
- icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
- ivValue = 'Cpsr<28:>'
+ icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
+ ivValue = 'CondCodes<28:>'
return calcCcCode % vars()
}};
def format DataOp(code, flagtype = logic) {{
(regCcCode, immCcCode) = getCcCode(flagtype)
- regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
- shift, Cpsr<29:0>);
+ regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
+ shift, CondCodes<29:>);
op2 = op2;''' + code
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
- shift, Cpsr<29:0>);
+ shift, CondCodes<29:>);
op2 = op2;''' + code
regIop = InstObjParams(name, Name, 'PredIntOp',
{"code": regCode,
diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa
index c82bb41c6..6909c3f85 100644
--- a/src/arch/arm/isa/formats/unimp.isa
+++ b/src/arch/arm/isa/formats/unimp.isa
@@ -115,7 +115,7 @@ output exec {{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
Fault
diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa
index 2ad7a2506..97a0caa6b 100644
--- a/src/arch/arm/isa/formats/unknown.isa
+++ b/src/arch/arm/isa/formats/unknown.isa
@@ -74,7 +74,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
}};
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
index b5efec568..d42ffb147 100644
--- a/src/arch/arm/isa/formats/util.isa
+++ b/src/arch/arm/isa/formats/util.isa
@@ -33,8 +33,10 @@ let {{
# Generic substitutions for Arm instructions
def ArmGenericCodeSubs(code):
# Substitute in the shifted portion of operations
- new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
- new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
+ new_code = re.sub(r'Rm_Imm',
+ 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code)
+ new_code = re.sub(r'Rm_Rs',
+ 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code)
return new_code
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index ac7427dad..aadefc79c 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -58,15 +58,16 @@ def operands {{
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
+ 'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
#Destination register for load/store double instructions
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
- 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
- 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
- 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
- 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
+ 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7),
+ 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8),
+ 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
+ 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10),
#Register fields for microops
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
@@ -80,12 +81,13 @@ def operands {{
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
- 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
- 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
- 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
- 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
+ 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40),
+ 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41),
+ 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51)
}};
diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh
index 542174b6b..91c51c46b 100644
--- a/src/arch/arm/isa_traits.hh
+++ b/src/arch/arm/isa_traits.hh
@@ -104,6 +104,8 @@ namespace ArmISA
const int WordBytes = 4;
const int HalfwordBytes = 2;
const int ByteBytes = 1;
+
+ const uint32_t HighVecs = 0xFFFF0000;
};
using namespace ArmISA;
diff --git a/src/arch/arm/kernel_stats.hh b/src/arch/arm/kernel_stats.hh
new file mode 100644
index 000000000..18bdc500d
--- /dev/null
+++ b/src/arch/arm/kernel_stats.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_ARM_KERNEL_STATS_HH__
+#define __ARCH_ARM_KERNEL_STATS_HH__
+
+#include <map>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "kern/kernel_stats.hh"
+
+namespace ArmISA {
+namespace Kernel {
+
+enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num };
+extern const char *modestr[];
+
+class Statistics : public ::Kernel::Statistics
+{
+ public:
+ Statistics(System *system) : ::Kernel::Statistics(system)
+ {}
+};
+
+} /* end namespace ArmISA::Kernel */
+} /* end namespace ArmISA */
+
+#endif // __ARCH_ARM_KERNEL_STATS_HH__
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh
index d99fa8e49..f829dd7c6 100644
--- a/src/arch/arm/linux/linux.hh
+++ b/src/arch/arm/linux/linux.hh
@@ -86,6 +86,7 @@ class ArmLinux : public Linux
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
+ static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel
//@}
/// For table().
@@ -147,6 +148,21 @@ class ArmLinux : public Linux
uint64_t st_ino;
} tgt_stat64;
+ typedef struct {
+ int32_t uptime; /* Seconds since boot */
+ uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint32_t totalram; /* Total usable main memory size */
+ uint32_t freeram; /* Available memory size */
+ uint32_t sharedram; /* Amount of shared memory */
+ uint32_t bufferram; /* Memory used by buffers */
+ uint32_t totalswap; /* Total swap space size */
+ uint32_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint32_t totalhigh; /* Total high memory size */
+ uint32_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 56e3588a7..f909d871a 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -50,7 +50,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -179,7 +180,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<ArmLinux>),
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
@@ -417,7 +418,8 @@ static SyscallReturn
setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- uint32_t tlsPtr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ uint32_t tlsPtr = process->getSyscallArg(tc, index);
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
@@ -511,12 +513,12 @@ ArmLinuxProcess::startup()
}
ArmISA::IntReg
-ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i)
+ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
{
// Linux apparently allows more parameter than the ABI says it should.
// This limit may need to be increased even further.
assert(i < 6);
- return tc->readIntReg(ArgumentReg0 + i);
+ return tc->readIntReg(ArgumentReg0 + i++);
}
void
diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh
index 53b3781d2..ab836fab2 100644
--- a/src/arch/arm/linux/process.hh
+++ b/src/arch/arm/linux/process.hh
@@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess
void startup();
- ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
/// The target system's hostname.
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index 3180669de..d100efb8e 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -55,23 +55,24 @@ namespace ArmISA
enum MiscRegIndex {
MISCREG_CPSR = 0,
- MISCREG_SPSR,
+ MISCREG_SPSR,
MISCREG_SPSR_FIQ,
MISCREG_SPSR_IRQ,
MISCREG_SPSR_SVC,
+ MISCREG_SPSR_MON,
MISCREG_SPSR_UND,
MISCREG_SPSR_ABT,
MISCREG_FPSR,
MISCREG_FPSID,
MISCREG_FPSCR,
MISCREG_FPEXC,
- NUM_MISCREGS
+ MISCREG_SCTLR,
+ NUM_MISCREGS
};
const char * const miscRegName[NUM_MISCREGS] = {
- "cpsr",
- "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt",
- "fpsr"
+ "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und",
+ "spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr"
};
BitUnion32(CPSR)
@@ -80,8 +81,10 @@ namespace ArmISA
Bitfield<29> c;
Bitfield<28> v;
Bitfield<27> q;
+ Bitfield<26,25> it1;
Bitfield<24> j;
Bitfield<19, 16> ge;
+ Bitfield<15,10> it2;
Bitfield<9> e;
Bitfield<8> a;
Bitfield<7> i;
@@ -89,6 +92,35 @@ namespace ArmISA
Bitfield<5> t;
Bitfield<4, 0> mode;
EndBitUnion(CPSR)
+
+ // This mask selects bits of the CPSR that actually go in the CondCodes
+ // integer register to allow renaming.
+ static const uint32_t CondCodesMask = 0xF80F0000;
+
+ BitUnion32(SCTLR)
+ Bitfield<30> te; // Thumb Exception Enable
+ Bitfield<29> afe; // Access flag enable
+ Bitfield<28> tre; // TEX Remap bit
+ Bitfield<27> nmfi;// Non-maskable fast interrupts enable
+ Bitfield<25> ee; // Exception Endianness bit
+ Bitfield<24> ve; // Interrupt vectors enable
+ Bitfield<23> rao1;// Read as one
+ Bitfield<22> u; // Alignment (now unused)
+ Bitfield<21> fi; // Fast interrupts configuration enable
+ Bitfield<18> rao2;// Read as one
+ Bitfield<17> ha; // Hardware access flag enable
+ Bitfield<16> rao3;// Read as one
+ Bitfield<14> rr; // Round robin cache replacement
+ Bitfield<13> v; // Base address for exception vectors
+ Bitfield<12> i; // instruction cache enable
+ Bitfield<11> z; // branch prediction enable bit
+ Bitfield<10> sw; // Enable swp/swpb
+ Bitfield<6,3> rao4;// Read as one
+ Bitfield<7> b; // Endianness support (unused)
+ Bitfield<2> c; // Cache enable bit
+ Bitfield<1> a; // Alignment fault checking
+ Bitfield<0> m; // MMU enable bit
+ EndBitUnion(SCTLR)
};
#endif // __ARCH_ARM_MISCREGS_HH__
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 1ad9e1a19..01f3205eb 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
//CPSR
- newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
+ newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
+ tc->readIntReg(INTREG_CONDCODES);
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
}
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index cd7cc9736..702922a43 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
}
ArmISA::IntReg
-ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 4);
- return tc->readIntReg(ArgumentReg0 + i);
+ return tc->readIntReg(ArgumentReg0 + i++);
}
void
diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh
index 8954d3719..f793892d0 100644
--- a/src/arch/arm/process.hh
+++ b/src/arch/arm/process.hh
@@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess
public:
void argsInit(int intSize, int pageSize);
- ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 7f9b6b828..41bbf4e7f 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -32,6 +32,7 @@
#define __ARCH_ARM_REGISTERS_HH__
#include "arch/arm/max_inst_regs.hh"
+#include "arch/arm/intregs.hh"
#include "arch/arm/miscregs.hh"
namespace ArmISA {
@@ -51,13 +52,11 @@ typedef float FloatReg;
typedef uint64_t MiscReg;
// Constants Related to the number of registers
-const int NumIntArchRegs = 16;
-const int NumIntSpecialRegs = 19;
+const int NumIntArchRegs = NUM_ARCH_INTREGS;
const int NumFloatArchRegs = 16;
const int NumFloatSpecialRegs = 5;
-const int NumInternalProcRegs = 0;
-const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
+const int NumIntRegs = NUM_INTREGS;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
const int NumMiscRegs = NUM_MISCREGS;
@@ -72,12 +71,11 @@ const int ArgumentReg1 = 1;
const int ArgumentReg2 = 2;
const int ArgumentReg3 = 3;
const int FramePointerReg = 11;
-const int StackPointerReg = 13;
-const int ReturnAddressReg = 14;
-const int PCReg = 15;
+const int StackPointerReg = INTREG_SP;
+const int ReturnAddressReg = INTREG_LR;
+const int PCReg = INTREG_PC;
-const int ZeroReg = NumIntArchRegs;
-const int AddrReg = ZeroReg + 1; // Used to generate address for uops
+const int ZeroReg = INTREG_ZERO;
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ReturnValueReg;
@@ -116,35 +114,6 @@ enum FCSRFields {
Cause_Field = 11
};
-enum MiscIntRegNums {
- zero_reg = NumIntArchRegs,
- addr_reg,
-
- rhi,
- rlo,
-
- r8_fiq, /* FIQ mode register bank */
- r9_fiq,
- r10_fiq,
- r11_fiq,
- r12_fiq,
-
- r13_fiq, /* FIQ mode SP and LR */
- r14_fiq,
-
- r13_irq, /* IRQ mode SP and LR */
- r14_irq,
-
- r13_svc, /* SVC mode SP and LR */
- r14_svc,
-
- r13_undef, /* UNDEF mode SP and LR */
- r14_undef,
-
- r13_abt, /* ABT mode SP and LR */
- r14_abt
-};
-
} // namespace ArmISA
#endif
diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc
new file mode 100644
index 000000000..6b346b0ab
--- /dev/null
+++ b/src/arch/arm/stacktrace.cc
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#include <string>
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/stacktrace.hh"
+#include "arch/arm/vtophys.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+#include "sim/system.hh"
+
+using namespace std;
+namespace ArmISA
+{
+ ProcessInfo::ProcessInfo(ThreadContext *_tc)
+ : tc(_tc)
+ {
+ Addr addr = 0;
+
+ VirtualPort *vp;
+
+ vp = tc->getVirtPort();
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = vp->readGtoH<int32_t>(addr);
+ }
+
+ Addr
+ ProcessInfo::task(Addr ksp) const
+ {
+ return 0;
+ }
+
+ int
+ ProcessInfo::pid(Addr ksp) const
+ {
+ return -1;
+ }
+
+ string
+ ProcessInfo::name(Addr ksp) const
+ {
+ return "Implement me";
+ }
+
+ StackTrace::StackTrace()
+ : tc(0), stack(64)
+ {
+ }
+
+ StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
+ : tc(0), stack(64)
+ {
+ trace(_tc, inst);
+ }
+
+ StackTrace::~StackTrace()
+ {
+ }
+
+ void
+ StackTrace::trace(ThreadContext *_tc, bool is_call)
+ {
+ }
+
+ bool
+ StackTrace::isEntry(Addr addr)
+ {
+ return false;
+ }
+
+ bool
+ StackTrace::decodeStack(MachInst inst, int &disp)
+ {
+ return false;
+ }
+
+ bool
+ StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+ {
+ return false;
+ }
+
+ /*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+ bool
+ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+ int &size, Addr &ra)
+ {
+ return false;
+ }
+
+#if TRACING_ON
+ void
+ StackTrace::dump()
+ {
+ DPRINTFN("------ Stack ------\n");
+
+ DPRINTFN(" Not implemented\n");
+ }
+#endif
+}
diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh
index 3f9c91096..05fdb9e78 100644
--- a/src/arch/arm/stacktrace.hh
+++ b/src/arch/arm/stacktrace.hh
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Ali Saidi
- * Stephen Hines
+ * Authors: Nathan Binkert
*/
#ifndef __ARCH_ARM_STACKTRACE_HH__
@@ -37,11 +35,11 @@
#include "cpu/static_inst.hh"
class ThreadContext;
-class StackTrace;
-
namespace ArmISA
{
+class StackTrace;
+
class ProcessInfo
{
private:
@@ -64,7 +62,7 @@ class ProcessInfo
class StackTrace
{
protected:
- typedef TheISA::MachInst MachInst;
+ typedef ArmISA::MachInst MachInst;
private:
ThreadContext *tc;
std::vector<Addr> stack;
@@ -94,10 +92,6 @@ class StackTrace
public:
const std::vector<Addr> &getstack() const { return stack; }
- static const int user = 1;
- static const int console = 2;
- static const int unknown = 3;
-
#if TRACING_ON
private:
void dump();
@@ -123,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
return true;
}
-}
+} // Namespace ArmISA
#endif // __ARCH_ARM_STACKTRACE_HH__
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
new file mode 100644
index 000000000..e7470f89a
--- /dev/null
+++ b/src/arch/arm/system.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#include "arch/arm/system.hh"
+
+
+using namespace LittleEndianGuest;
+
+ArmSystem::ArmSystem(Params *p)
+ : System(p)
+{
+
+}
+
+ArmSystem::~ArmSystem()
+{
+}
+
+
+ArmSystem *
+ArmSystemParams::create()
+{
+ return new ArmSystem(this);
+}
diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
new file mode 100644
index 000000000..9dfb66fb7
--- /dev/null
+++ b/src/arch/arm/system.hh
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#ifndef __ARCH_ARM_SYSTEM_HH__
+#define __ARCH_ARM_SYSTEM_HH__
+
+#include <string>
+#include <vector>
+
+#include "params/ArmSystem.hh"
+#include "sim/sim_object.hh"
+#include "sim/system.hh"
+
+class ArmSystem : public System
+{
+ public:
+ typedef ArmSystemParams Params;
+ ArmSystem(Params *p);
+ ~ArmSystem();
+
+ virtual Addr fixFuncEventAddr(Addr addr)
+ {
+ //XXX This may eventually have to do something useful.
+ return addr;
+ }
+};
+
+#endif
+
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index febc6d081..864c061a2 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
return NoFault;
#else
- fatal("translate atomic not yet implemented\n");
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+ if (!sctlr.m) {
+ req->setPaddr(req->getVaddr());
+ return NoFault;
+ }
+ panic("MMU translation not implemented\n");
+ return NoFault;
+
+
#endif
}
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
index 2c4e1291c..e0b3951b9 100644
--- a/src/arch/arm/types.hh
+++ b/src/arch/arm/types.hh
@@ -45,16 +45,20 @@ namespace ArmISA
// All the different types of opcode fields.
Bitfield<27, 25> encoding;
+ Bitfield<25> useImm;
Bitfield<24, 21> opcode;
Bitfield<24, 20> mediaOpcode;
Bitfield<24> opcode24;
Bitfield<23, 20> opcode23_20;
Bitfield<23, 21> opcode23_21;
+ Bitfield<20> opcode20;
Bitfield<22> opcode22;
Bitfield<19> opcode19;
+ Bitfield<18> opcode18;
Bitfield<15, 12> opcode15_12;
Bitfield<15> opcode15;
Bitfield<7, 4> miscOpcode;
+ Bitfield<7,5> opc2;
Bitfield<7> opcode7;
Bitfield<4> opcode4;
@@ -156,6 +160,7 @@ namespace ArmISA
MODE_FIQ = 17,
MODE_IRQ = 18,
MODE_SVC = 19,
+ MODE_MON = 22,
MODE_ABORT = 23,
MODE_UNDEFINED = 27,
MODE_SYSTEM = 31
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
new file mode 100644
index 000000000..5ce32542b
--- /dev/null
+++ b/src/arch/arm/utility.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/utility.hh"
+#include "cpu/thread_context.hh"
+
+
+namespace ArmISA {
+
+void
+initCPU(ThreadContext *tc, int cpuId)
+{
+ // Reset CP15?? What does that mean -- ali
+
+ // FPEXC.EN = 0
+
+ static Fault reset = new Reset;
+ if (cpuId == 0)
+ reset->invoke(tc);
+}
+
+uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
+#if FULL_SYSTEM
+ panic("getArgument() not implemented for ARM!\n");
+#else
+ panic("getArgument() only implemented for FULL_SYSTEM\n");
+ M5_DUMMY_RETURN
+#endif
+}
+
+Fault
+setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
+{
+ return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
+ CRn, opc1, CRm, opc2));
+}
+
+Fault
+readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
+{
+ return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
+ CRn, opc1, CRm, opc2));
+
+}
+
+
+}
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index a2f0ef170..3ddfd12dd 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -125,6 +125,20 @@ namespace ArmISA {
{
panic("Copy Misc. Regs Not Implemented Yet\n");
}
+
+ void initCPU(ThreadContext *tc, int cpuId);
+
+ static inline bool
+ inUserMode(ThreadContext *tc)
+ {
+ return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER;
+ }
+
+uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+
+Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
+Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
+
};