arm: add ARM support to M5

This commit is contained in:
Stephen Hines 2009-04-05 18:53:15 -07:00
parent 65332ef3a9
commit 7a7c4c5fca
51 changed files with 8822 additions and 0 deletions

58
src/arch/arm/ArmTLB.py Normal file
View file

@ -0,0 +1,58 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
# 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: Stephen Hines
from m5.SimObject import SimObject
from m5.params import *
class ArmTLB(SimObject):
abstract = True
type = 'ArmTLB'
cxx_namespace = 'ArmISA'
cxx_class = 'TLB'
size = Param.Int("TLB size")
class ArmDTB(ArmTLB):
type = 'ArmDTB'
cxx_namespace = 'ArmISA'
cxx_class = 'DTB'
size = 64
class ArmITB(ArmTLB):
type = 'ArmITB'
cxx_namespace = 'ArmISA'
cxx_class = 'ITB'
size = 64
class ArmUTB(ArmTLB):
type = 'ArmUTB'
cxx_namespace = 'ArmISA'
cxx_class = 'UTB'
size = 64

61
src/arch/arm/SConscript Normal file
View file

@ -0,0 +1,61 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
# 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: Stephen Hines
Import('*')
if env['TARGET_ISA'] == 'arm':
# Workaround for bug in SCons version > 0.97d20071212
# Scons bug id: 2006 M5 Bug id: 308
Dir('isa/formats')
Source('faults.cc')
Source('pagetable.cc')
Source('regfile/regfile.cc')
Source('tlb.cc')
Source('utility.cc')
Source('vtophys.cc')
SimObject('ArmTLB.py')
TraceFlag('Arm')
if env['FULL_SYSTEM']:
#Insert Full-System Files Here
pass
else:
Source('process.cc')
Source('linux/linux.cc')
Source('linux/process.cc')
# Add in files generated by the ISA description.
isa_desc_files = env.ISADesc('isa/main.isa')
# Only non-header files need to be compiled.
for f in isa_desc_files:
if not f.path.endswith('.hh'):
Source(f)

33
src/arch/arm/SConsopts Normal file
View file

@ -0,0 +1,33 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
# 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: Stephen Hines
Import('*')
all_isa_list.append('arm')

515
src/arch/arm/faults.cc Normal file
View file

@ -0,0 +1,515 @@
/*
* Copyright (c) 2003-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
* 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
* Stephen Hines
*/
#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;
FaultName AlignmentFault::_name = "Alignment";
FaultVect AlignmentFault::_vect = 0x0301;
FaultStat AlignmentFault::_count;
FaultName ResetFault::_name = "Reset Fault";
#if FULL_SYSTEM
FaultVect ResetFault::_vect = 0xBFC00000;
#else
FaultVect ResetFault::_vect = 0x001;
#endif
FaultStat ResetFault::_count;
FaultName AddressErrorFault::_name = "Address Error";
FaultVect AddressErrorFault::_vect = 0x0180;
FaultStat AddressErrorFault::_count;
FaultName StoreAddressErrorFault::_name = "Store Address Error";
FaultVect StoreAddressErrorFault::_vect = 0x0180;
FaultStat StoreAddressErrorFault::_count;
FaultName SystemCallFault::_name = "Syscall";
FaultVect SystemCallFault::_vect = 0x0180;
FaultStat SystemCallFault::_count;
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)
{
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);
// 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());
//RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
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());
//RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil
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 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);
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

574
src/arch/arm/faults.hh Normal file
View file

@ -0,0 +1,574 @@
/*
* Copyright (c) 2003-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
* 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
* Stephen Hines
*/
#ifndef __ARM_FAULTS_HH__
#define __ARM_FAULTS_HH__
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace ArmISA
{
typedef const Addr FaultVect;
class ArmFault : 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;}
};
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);
};
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);
#endif
};
class InterruptFault : public ArmFault
{
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
};
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
};
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 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
#endif // __ARM_FAULTS_HH__

87
src/arch/arm/isa/base.isa Normal file
View file

@ -0,0 +1,87 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Base class for ARM instructions, and some support functions
//
//Outputs to decoder.hh
output header {{
using namespace ArmISA;
/**
* Base class for all MIPS static instructions.
*/
class ArmStaticInst : public StaticInst
{
protected:
// Constructor
ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
{
}
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
void printReg(std::ostream &os, int reg) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
//Ouputs to decoder.cc
output decoder {{
void ArmStaticInst::printReg(std::ostream &os, int reg) const
{
if (reg < FP_Base_DepTag) {
ccprintf(os, "r%d", reg);
}
else {
ccprintf(os, "f%d", reg - FP_Base_DepTag);
}
}
std::string ArmStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
return ss.str();
}
}};

View file

@ -0,0 +1,170 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//
// Opcode fields
def bitfield OPCODE <27:25>;
def bitfield OPCODE_27_25 <27:25>;
def bitfield OPCODE_24_21 <24:21>;
def bitfield OPCODE_24_23 <24:23>;
def bitfield OPCODE_24 <24:24>;
def bitfield OPCODE_23_20 <23:20>;
def bitfield OPCODE_23_21 <23:21>;
def bitfield OPCODE_23 <23:23>;
def bitfield OPCODE_22_8 <22: 8>;
def bitfield OPCODE_22_21 <22:21>;
def bitfield OPCODE_22 <22:22>;
def bitfield OPCODE_21_20 <21:20>;
def bitfield OPCODE_20 <20:20>;
def bitfield OPCODE_19_18 <19:18>;
def bitfield OPCODE_19 <19:19>;
def bitfield OPCODE_15_12 <15:12>;
def bitfield OPCODE_15 <15:15>;
def bitfield OPCODE_9 < 9: 9>;
def bitfield OPCODE_7_4 < 7: 4>;
def bitfield OPCODE_7_5 < 7: 5>;
def bitfield OPCODE_7_6 < 7: 6>;
def bitfield OPCODE_7 < 7: 7>;
def bitfield OPCODE_6_5 < 6: 5>;
def bitfield OPCODE_6 < 6: 6>;
def bitfield OPCODE_5 < 5: 5>;
def bitfield OPCODE_4 < 4: 4>;
// Other
def bitfield COND_CODE <31:28>;
def bitfield S_FIELD <20:20>;
def bitfield RN <19:16>;
def bitfield RD <15:12>;
def bitfield SHIFT_SIZE <11: 7>;
def bitfield SHIFT < 6: 5>;
def bitfield RM < 3: 0>;
def bitfield RE <20:16>;
def bitfield RS <11: 8>;
def bitfield RDUP <19:16>;
def bitfield RNDN <15:12>;
def bitfield RDHI <15:12>;
def bitfield RDLO <11: 8>;
def bitfield U_FIELD <23:23>;
def bitfield PUSWL <24:20>;
def bitfield PREPOST <24:24>;
def bitfield UP <23:23>;
def bitfield PSRUSER <22:22>;
def bitfield WRITEBACK <21:21>;
def bitfield LOADOP <20:20>;
def bitfield PUBWL <24:20>;
def bitfield PUIWL <24:20>;
def bitfield BYTEACCESS <22:22>;
def bitfield LUAS <23:20>;
def bitfield IMM < 7: 0>;
def bitfield IMMED_7_4 < 7: 4>;
def bitfield IMMED_3_0 < 3: 0>;
def bitfield F_MSR <19:19>;
def bitfield S_MSR <18:18>;
def bitfield X_MSR <17:17>;
def bitfield C_MSR <16:16>;
def bitfield Y_6 < 6: 6>;
def bitfield X_5 < 5: 5>;
def bitfield IMMED_15_4 <15: 4>;
def bitfield W_FIELD <21:21>;
def bitfield ROTATE <11: 8>;
def bitfield IMMED_7_0 < 7: 0>;
def bitfield T_FIELD <21:21>;
def bitfield IMMED_11_0 <11: 0>;
def bitfield IMMED_20_16 <20:16>;
def bitfield IMMED_19_16 <19:16>;
def bitfield IMMED_HI_11_8 <11: 8>;
def bitfield IMMED_LO_3_0 < 3: 0>;
def bitfield ROT <11:10>;
def bitfield R_FIELD < 5: 5>;
def bitfield CARET <22:22>;
def bitfield REGLIST <15: 0>;
def bitfield OFFSET <23: 0>;
def bitfield COPRO <11: 8>;
def bitfield OP1_7_4 < 7: 4>;
def bitfield CM < 3: 0>;
def bitfield L_FIELD <22:22>;
def bitfield CD <15:12>;
def bitfield OPTION < 7: 0>;
def bitfield OP1_23_20 <23:20>;
def bitfield CN <19:16>;
def bitfield OP2_7_5 < 7: 5>;
def bitfield OP1_23_21 <23:21>;
def bitfield IMMED_23_0 <23: 0>;
def bitfield M_FIELD <17:17>;
def bitfield A_FIELD < 8: 8>;
def bitfield I_FIELD < 7: 7>;
def bitfield F_FIELD < 6: 6>;
def bitfield MODE < 4: 0>;
def bitfield A_BLX <24:24>;
def bitfield CPNUM <11: 8>;
// Note that FP Regs are only 3 bits
def bitfield FN <18:16>;
def bitfield FD <14:12>;
def bitfield FPREGIMM < 3: 3>;
// We can just use 3:0 for FM since the hard-wired FP regs are handled in
// float_regfile.hh
def bitfield FM < 3: 0>;
def bitfield FPIMM < 2: 0>;
def bitfield PUNWL <24:20>;
// M5 instructions
def bitfield M5FUNC <7:0>;

View file

@ -0,0 +1,28 @@
// Copyright (c) 2007, 2008
// The Florida State University
// All Rights Reserved
//
// This code is part of the M5 simulator.
//
// Permission is granted to use, copy, create derivative works and
// redistribute this software and such derivative works for any
// purpose, so long as the copyright notice above, this grant of
// permission, and the disclaimer below appear in all copies made; and
// so long as the name of The Florida State University is not used in
// any advertising or publicity pertaining to the use or distribution
// of this software without specific, written prior authorization.
//
// THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
// FLORIDA STATE UNIVERSITY AS TO ITS FITNESS FOR ANY PURPOSE, AND
// WITHOUT WARRANTY BY THE FLORIDA STATE UNIVERSITY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE. THE REGENTS OF THE FLORIDA STATE UNIVERSITY SHALL NOT BE
// LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
// INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
// ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
// IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGES.
//
// Authors: Stephen R. Hines - modified for use in ARM version

View file

@ -0,0 +1,845 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// The actual ARM ISA decoder
// --------------------------
// The following instructions are specified in the ARM ISA
// Specification. Decoding closely follows the style specified
// in the ARM ISA specification document starting with Table B.1 or 3-1
//
//
decode COND_CODE default Unknown::unknown() {
0xf: decode COND_CODE {
0x0: decode OPCODE_27_25 {
// Just a simple trick to allow us to specify our new uops here
0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
'IsMicroop');
0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
'IsMicroop');
0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
{{ EA = Raddr + disp; }},
inst_flags = [IsMicroop]);
0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
{{ EA = Raddr + disp; }},
inst_flags = [IsMicroop]);
0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
'IsMicroop');
0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
'IsMicroop');
}
0x1: decode OPCODE_27_25 {
0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
'IsMicroop');
0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff;
Rlo = Fd.ud & 0xffffffff; }},
'IsMicroop');
0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }},
{{ EA = Rn + disp; }},
inst_flags = [IsMicroop]);
0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }},
{{ EA = Rn + disp; }},
inst_flags = [IsMicroop]);
0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }},
{{ EA = Rn + disp; }},
inst_flags = [IsMicroop]);
0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }},
{{ EA = Rn + disp; }},
inst_flags = [IsMicroop]);
}
default: Unknown::unknown(); // TODO: Ignore other NV space for now
}
format BasicOp{
default: decode OPCODE_27_25 {
0x0: decode OPCODE_4 {
0: decode S_FIELD {
0: decode OPCODE_24_21 {
format PredIntOp {
0x0: and({{ Rd = Rn & Rm_Imm; }});
0x1: eor({{ Rd = Rn ^ Rm_Imm; }});
0x2: sub({{ Rd = Rn - Rm_Imm; }});
0x3: rsb({{ Rd = Rm_Imm - Rn; }});
0x4: add({{ Rd = Rn + Rm_Imm; }});
0x5: adc({{ Rd = Rn + Rm_Imm + Cpsr<29:>; }});
0x6: sbc({{ Rd = Rn - Rm_Imm + Cpsr<29:> - 1; }});
0x7: rsc({{ Rd = Rm_Imm - Rn + Cpsr<29:> - 1; }});
//0x8:mrs_cpsr -- TODO
//0x9:msr_cpsr -- TODO
//0xa:mrs_spsr -- TODO
//0xb:msr_spsr -- TODO
0xc: orr({{ Rd = Rn | Rm_Imm; }});
0xd: mov({{ Rd = Rm_Imm; }});
0xe: bic({{ Rd = Rn & ~Rm_Imm; }});
0xf: mvn({{ Rd = ~Rm_Imm; }});
}
}
1: decode OPCODE_24_21 {
format PredIntOpCc {
0x0: ands({{
uint32_t resTemp;
Rd = resTemp = Rn & Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x1: eors({{
uint32_t resTemp;
Rd = resTemp = Rn ^ Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x2: subs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = Rn - val2;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0x3: rsbs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = val2 - Rn;
}},
{{ arm_sub_carry(resTemp, val2, Rn) }},
{{ arm_sub_overflow(resTemp, val2, Rn) }});
0x4: adds({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = Rn + val2;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0x5: adcs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = Rn + val2 + Cpsr<29:>;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0x6: sbcs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0x7: rscs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, val2, Rn) }},
{{ arm_sub_overflow(resTemp, val2, Rn) }});
0x8: tst({{
uint32_t resTemp;
resTemp = Rn & Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x9: teq({{
uint32_t resTemp;
resTemp = Rn ^ Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xa: cmp({{
uint32_t resTemp,
val2 = Rm_Imm;
resTemp = Rn - val2;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0xb: cmn({{
uint32_t resTemp,
val2 = Rm_Imm;
resTemp = Rn + val2;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0xc: orrs({{
uint32_t resTemp,
val2 = Rm_Imm;
Rd = resTemp = Rn | val2;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xd: movs({{
uint32_t resTemp;
Rd = resTemp = Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xe: bics({{
uint32_t resTemp;
Rd = resTemp = Rn & ~Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xf: mvns({{
uint32_t resTemp;
Rd = resTemp = ~Rm_Imm;
}},
{{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
}
}
}
1: decode OPCODE_7 {
0: decode S_FIELD {
0: decode OPCODE_24_21 {
format PredIntOp {
0x0: and_rs({{ Rd = Rn & Rm_Rs; }});
0x1: eor_rs({{ Rd = Rn ^ Rm_Rs; }});
0x2: sub_rs({{ Rd = Rn - Rm_Rs; }});
0x3: rsb_rs({{ Rd = Rm_Rs - Rn; }});
0x4: add_rs({{ Rd = Rn + Rm_Rs; }});
0x5: adc_rs({{ Rd = Rn + Rm_Rs + Cpsr<29:>; }});
0x6: sbc_rs({{ Rd = Rn - Rm_Rs + Cpsr<29:> - 1; }});
0x7: rsc_rs({{ Rd = Rm_Rs - Rn + Cpsr<29:> - 1; }});
0xc: orr_rs({{ Rd = Rn | Rm_Rs; }});
0xd: mov_rs({{ Rd = Rm_Rs; }});
0xe: bic_rs({{ Rd = Rn & ~Rm_Rs; }});
0xf: mvn_rs({{ Rd = ~Rm_Rs; }});
default: decode OPCODE_7_4 {
0x1: decode OPCODE_24_21 {
0x9: BranchExchange::bx({{ }});
0xb: PredOp::clz({{
if (Rm == 0)
Rd = 32;
else
{
int i;
for (i = 0; i < 32; i++)
{
if (Rm & (1<<(31-i)))
break;
}
Rd = i;
}
}});
}
0x3: decode OPCODE_24_21 {
0x9: BranchExchange::blx({{ LR = NPC; }});
}
}
}
}
1: decode OPCODE_24_21 {
format PredIntOpCc {
0x0: ands_rs({{
uint32_t resTemp;
Rd = resTemp = Rn & Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x1: eors_rs({{
uint32_t resTemp;
Rd = resTemp = Rn ^ Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x2: subs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = Rn - val2;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0x3: rsbs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = val2 - Rn;
}},
{{ arm_sub_carry(resTemp, val2, Rn) }},
{{ arm_sub_overflow(resTemp, val2, Rn) }});
0x4: adds_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = Rn + val2;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0x5: adcs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = Rn + val2 + Cpsr<29:>;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0x6: sbcs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0x7: rscs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, val2, Rn) }},
{{ arm_sub_overflow(resTemp, val2, Rn) }});
0x8: tst_rs({{
uint32_t resTemp;
resTemp = Rn & Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x9: teq_rs({{
uint32_t resTemp;
resTemp = Rn ^ Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xa: cmp_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
resTemp = Rn - val2;
}},
{{ arm_sub_carry(resTemp, Rn, val2) }},
{{ arm_sub_overflow(resTemp, Rn, val2) }});
0xb: cmn_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
resTemp = Rn + val2;
}},
{{ arm_add_carry(resTemp, Rn, val2) }},
{{ arm_add_overflow(resTemp, Rn, val2) }});
0xc: orrs_rs({{
uint32_t resTemp,
val2 = Rm_Rs;
Rd = resTemp = Rn | val2;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xd: movs_rs({{
uint32_t resTemp;
Rd = resTemp = Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xe: bics_rs({{
uint32_t resTemp;
Rd = resTemp = Rn & ~Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xf: mvns_rs({{
uint32_t resTemp;
Rd = resTemp = ~Rm_Rs;
}},
{{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
{{ Cpsr<28:> }});
}
}
}
1: decode OPCODE_6_5 {
0x0: decode OPCODE_24 {
0: decode LUAS {
format PredIntOp {
0x0: mul({{ Rn = Rm * Rs; }});
0x1: PredIntOpCc::muls({{
uint32_t resTemp;
Rn = resTemp = Rm * Rs;
}},
{{ Cpsr<29:> }},
{{ Cpsr<28:> }});
0x2: mla_a({{ Rn = Rm * Rs + Rd; }});
0x8: umull_l({{
uint64_t resTemp;
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
Rd = (uint32_t)(resTemp & 0xffffffff);
Rn = (uint32_t)(resTemp >> 32);
}});
0xa: umlal_lu({{
uint64_t resTemp;
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);
}});
0xc: smull_lu({{
int64_t resTemp;
resTemp = ((int64_t)Rm)*((int64_t)Rs);
Rd = (int32_t)(resTemp & 0xffffffff);
Rn = (int32_t)(resTemp >> 32);
}});
}
}
}
0x1: decode PUIWL {
0x04,0x0c: ArmStoreMemory::strh_i({{ Mem.uh = Rd.uh;
Rn = Rn + hilo; }},
{{ EA = Rn; }});
0x05,0x0d: ArmLoadMemory::ldrh_il({{ Rd.uh = Mem.uh;
Rn = Rn + hilo; }},
{{ EA = Rn; }});
0x10,0x18: ArmStoreMemory::strh_p({{ Mem.uh = Rd.uh; }},
{{ EA = Rn + Rm; }});
0x11,0x19: ArmLoadMemory::ldrh_pl({{ Rd.uh = Mem.uh; }},
{{ EA = Rn + Rm; }});
0x12,0x1a: ArmStoreMemory::strh_pw({{ Mem.uh = Rd.uh;
Rn = Rn + Rm; }},
{{ EA = Rn + Rm; }});
0x13,0x1b: ArmLoadMemory::ldrh_pwl({{ Rd.uh = Mem.uh;
Rn = Rn + Rm; }},
{{ EA = Rn + Rm; }});
0x14,0x1c: ArmStoreMemory::strh_pi({{ Mem.uh = Rd.uh; }},
{{ EA = Rn + hilo; }});
0x15,0x1d: ArmLoadMemory::ldrh_pil({{ Rd.uh = Mem.uh; }},
{{ EA = Rn + hilo; }});
0x16,0x1e: ArmStoreMemory::strh_piw({{ Mem.uh = Rd.uh;
Rn = Rn + hilo; }},
{{ EA = Rn + hilo; }});
0x17,0x1f: ArmLoadMemory::ldrh_piwl({{ Rd.uh = Mem.uh;
Rn = Rn + hilo; }},
{{ EA = Rn + hilo; }});
}
0x2: decode PUIWL {
format ArmLoadMemory {
0x11,0x19: ldrsb_pl({{ Rd.sb = Mem.sb; }},
{{ EA = Rn + Rm; }});
0x13,0x1b: ldrsb_pwl({{ Rd.sb = Mem.sb;
Rn = Rn + Rm; }},
{{ EA = Rn + Rm; }});
0x15,0x1d: ldrsb_pil({{ Rd.sb = Mem.sb; }},
{{ EA = Rn + hilo; }});
0x17,0x1f: ldrsb_piwl({{ Rd.sb = Mem.sb;
Rn = Rn + hilo; }},
{{ EA = Rn + hilo; }});
}
}
0x3: decode PUIWL {
format ArmLoadMemory {
0x11,0x19: ldrsh_pl({{ Rd.sh = Mem.sh; }},
{{ EA = Rn + Rm; }});
0x13,0x1b: ldrsh_pwl({{ Rd.sh = Mem.sh;
Rn = Rn + Rm; }},
{{ EA = Rn + Rm; }});
0x15,0x1d: ldrsh_pil({{ Rd.sh = Mem.sh; }},
{{ EA = Rn + hilo; }});
0x17,0x1f: ldrsh_piwl({{ Rd.sh = Mem.sh;
Rn = Rn + hilo; }},
{{ EA = Rn + hilo; }});
}
}
}
}
}
0x1: decode S_FIELD {
0: decode OPCODE_24_21 {
format PredImmOp {
0x0: andi({{ Rd = Rn & rotated_imm; }});
0x1: eori({{ Rd = Rn ^ rotated_imm; }});
0x2: subi({{ Rd = Rn - rotated_imm; }});
0x3: rsbi({{ Rd = rotated_imm - Rn; }});
0x4: addi({{ Rd = Rn + rotated_imm; }});
0x5: adci({{ Rd = Rn + rotated_imm + Cpsr<29:>; }});
0x6: sbci({{ Rd = Rn - rotated_imm + Cpsr<29:> - 1; }});
0x7: rsci({{ Rd = rotated_imm - Rn + Cpsr<29:> - 1; }});
0xc: orri({{ Rd = Rn | rotated_imm; }});
0xd: decode RN {
0: movi({{ Rd = rotated_imm; }});
}
0xe: bici({{ Rd = Rn & ~rotated_imm; }});
0xf: decode RN {
0: mvni({{ Rd = ~rotated_imm; }});
}
}
}
1: decode OPCODE_24_21 {
format PredImmOpCc {
0x0: andsi({{
uint32_t resTemp;
Rd = resTemp = Rn & rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x1: eorsi({{
uint32_t resTemp;
Rd = resTemp = Rn ^ rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x2: subsi({{
uint32_t resTemp;
Rd = resTemp = Rn - rotated_imm;
}},
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
0x3: rsbsi({{
uint32_t resTemp;
Rd = resTemp = rotated_imm - Rn;
}},
{{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
{{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
0x4: addsi({{
uint32_t resTemp;
Rd = resTemp = Rn + rotated_imm;
}},
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
0x5: adcsi({{
uint32_t resTemp;
Rd = resTemp = Rn + rotated_imm + Cpsr<29:>;
}},
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
0x6: sbcsi({{
uint32_t resTemp;
Rd = resTemp = Rn -rotated_imm + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
0x7: rscsi({{
uint32_t resTemp;
Rd = resTemp = rotated_imm - Rn + Cpsr<29:> - 1;
}},
{{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
{{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
0x8: tsti({{
uint32_t resTemp;
resTemp = Rn & rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0x9: teqi({{
uint32_t resTemp;
resTemp = Rn ^ rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xa: cmpi({{
uint32_t resTemp;
resTemp = Rn - rotated_imm;
}},
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
0xb: cmni({{
uint32_t resTemp;
resTemp = Rn + rotated_imm;
}},
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
0xc: orrsi({{
uint32_t resTemp;
Rd = resTemp = Rn | rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xd: movsi({{
uint32_t resTemp;
Rd = resTemp = rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xe: bicsi({{
uint32_t resTemp;
Rd = resTemp = Rn & ~rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
0xf: mvnsi({{
uint32_t resTemp;
Rd = resTemp = ~rotated_imm;
}},
{{ (rotate ? rotated_carry:Cpsr<29:>) }},
{{ Cpsr<28:> }});
}
}
}
0x2: decode PUBWL {
// CAREFUL:
// Can always do EA + disp, since we negate disp using the UP flag
// Post-indexed variants
0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd;
Rn = Rn + disp; }},
{{ EA = Rn; }});
0x01,0x09: ArmLoadMemory::ldr_l({{ Rd = Mem;
Rn = Rn + disp; }},
{{ EA = Rn; }});
0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub;
Rn = Rn + disp; }},
{{ EA = Rn; }});
0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rd.ub = Mem.ub;
Rn = Rn + disp; }},
{{ EA = Rn; }});
// Pre-indexed variants
0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }});
0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }});
0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd;
Rn = Rn + disp; }});
0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rd = Mem;
Rn = Rn + disp; }});
0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }});
0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }});
0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub;
Rn = Rn + disp; }});
0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rd.ub = Mem.ub;
Rn = Rn + disp; }});
}
0x3: decode OPCODE_4 {
0: decode PUBWL {
0x00,0x08: ArmStoreMemory::strr_({{
Mem = Rd;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn; }});
0x01,0x09: ArmLoadMemory::ldrr_l({{
Rd = Mem;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn; }});
0x04,0x0c: ArmStoreMemory::strr_b({{
Mem.ub = Rd.ub;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn; }});
0x05,0x0d: ArmLoadMemory::ldrr_bl({{
Rd.ub = Mem.ub;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn; }});
0x10,0x18: ArmStoreMemory::strr_p({{
Mem = Rd; }},
{{ EA = Rn + Rm_Imm; }});
0x11,0x19: ArmLoadMemory::ldrr_pl({{
Rd = Mem; }},
{{ EA = Rn + Rm_Imm; }});
0x12,0x1a: ArmStoreMemory::strr_pw({{
Mem = Rd;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn + Rm_Imm; }});
0x13,0x1b: ArmLoadMemory::ldrr_pwl({{
Rd = Mem;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn + Rm_Imm; }});
0x14,0x1c: ArmStoreMemory::strr_pb({{
Mem.ub = Rd.ub; }},
{{ EA = Rn + Rm_Imm; }});
0x15,0x1d: ArmLoadMemory::ldrr_pbl({{
Rd.ub = Mem.ub; }},
{{ EA = Rn + Rm_Imm; }});
0x16,0x1e: ArmStoreMemory::strr_pbw({{
Mem.ub = Rd.ub;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn + Rm_Imm; }});
0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{
Rd.ub = Mem.ub;
Rn = Rn + Rm_Imm; }},
{{ EA = Rn + Rm_Imm; }});
}
}
0x4: decode PUSWL {
// Right now we only handle cases when S (PSRUSER) is not set
default: ArmMacroStore::ldmstm({{ }});
}
0x5: decode OPCODE_24 {
// Branch (and Link) Instructions
0: Branch::b({{ }});
1: Branch::bl({{ LR = NPC; }});
}
0x6: decode CPNUM {
0x1: decode PUNWL {
0x02,0x0a: decode OPCODE_15 {
0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf;
Rn = Rn + disp8; }},
{{ EA = Rn; }});
1: ArmMacroFPAOp::stfd_({{ }});
}
0x03,0x0b: decode OPCODE_15 {
0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf;
Rn = Rn + disp8; }},
{{ EA = Rn; }});
1: ArmMacroFPAOp::ldfd_({{ }});
}
0x06,0x0e: decode OPCODE_15 {
0: ArmMacroFPAOp::stfe_nw({{ }});
}
0x07,0x0f: decode OPCODE_15 {
0: ArmMacroFPAOp::ldfe_nw({{ }});
}
0x10,0x18: decode OPCODE_15 {
0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }},
{{ EA = Rn + disp8; }});
1: ArmMacroFPAOp::stfd_p({{ }});
}
0x11,0x19: decode OPCODE_15 {
0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }},
{{ EA = Rn + disp8; }});
1: ArmMacroFPAOp::ldfd_p({{ }});
}
0x12,0x1a: decode OPCODE_15 {
0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf;
Rn = Rn + disp8; }},
{{ EA = Rn + disp8; }});
1: ArmMacroFPAOp::stfd_pw({{ }});
}
0x13,0x1b: decode OPCODE_15 {
0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf;
Rn = Rn + disp8; }},
{{ EA = Rn + disp8; }});
1: ArmMacroFPAOp::ldfd_pw({{ }});
}
0x14,0x1c: decode OPCODE_15 {
0: ArmMacroFPAOp::stfe_pn({{ }});
}
0x15,0x1d: decode OPCODE_15 {
0: ArmMacroFPAOp::ldfe_pn({{ }});
}
0x16,0x1e: decode OPCODE_15 {
0: ArmMacroFPAOp::stfe_pnw({{ }});
}
0x17,0x1f: decode OPCODE_15 {
0: ArmMacroFPAOp::ldfe_pnw({{ }});
}
}
0x2: decode PUNWL {
// could really just decode as a single instruction
0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }});
0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }});
0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }});
0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }});
0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }});
0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }});
0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
}
}
0x7: decode OPCODE_24 {
0: decode CPNUM {
// Coprocessor Instructions
0x1: decode OPCODE_4 {
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 {
0xf: decode OPCODE_23_21 {
format FloatCmp {
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
0x5: cnf({{ Fn.df }}, {{ -Fm.df }});
0x6: cmfe({{ Fn.df }}, {{ Fm.df}});
0x7: cnfe({{ Fn.df }}, {{ -Fm.df}});
}
}
default: decode OPCODE_23_20 {
0x0: decode OPCODE_7 {
0: flts({{ Fn.sf = (float) Rd.sw; }});
1: fltd({{ Fn.df = (double) Rd.sw; }});
}
0x1: decode OPCODE_7 {
0: fixs({{ Rd = (uint32_t) Fm.sf; }});
1: fixd({{ Rd = (uint32_t) Fm.df; }});
}
0x2: wfs({{ Fpsr = Rd; }});
0x3: rfs({{ Rd = Fpsr; }});
0x4: FailUnimpl::wfc();
0x5: FailUnimpl::rfc();
}
}
}
}
}
format PredOp {
// ARM System Call (SoftWare Interrupt)
1: swi({{ if (arm_predicate(xc->readMiscReg(ArmISA::CPSR),
condCode))
{
//xc->syscall(R7);
xc->syscall(IMMED_23_0);
}
}});
}
}
}
}
}

View file

@ -0,0 +1,103 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
// Declarations for execute() methods.
def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// Basic instruction class declaration template.
def template BasicDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
}
}};
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
// Basic decode template.
def template BasicDecode {{
return new %(class_name)s(machInst);
}};
// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
// Definitions of execute methods that panic.
def template BasicExecPanic {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Execute method called when it shouldn't!");
}
}};
// The most basic instruction format...
def format BasicOp(code, *flags) {{
iop = InstObjParams(name, Name, 'ArmStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -0,0 +1,307 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
//
output header {{
#include <iostream>
/**
* Base class for instructions whose disassembly is not purely a
* function of the machine instruction (i.e., it depends on the
* PC). This class overrides the disassemble() method to check
* the PC and symbol table values before re-using a cached
* disassembly string. This is necessary for branches and jumps,
* where the disassembly string includes the target address (which
* may depend on the PC and/or symbol table).
*/
class PCDependentDisassembly : public PredOp
{
protected:
/// Cached program counter from last disassembly
mutable Addr cachedPC;
/// Cached symbol table pointer from last disassembly
mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, MachInst _machInst,
OpClass __opClass)
: PredOp(mnem, _machInst, __opClass),
cachedPC(0), cachedSymtab(0)
{
}
const std::string &
disassemble(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for branches (PC-relative control transfers),
* conditional or unconditional.
*/
class Branch : public PCDependentDisassembly
{
protected:
/// target address (signed) Displacement .
int32_t disp;
/// Constructor.
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(OFFSET << 2)
{
//If Bit 26 is 1 then Sign Extend
if ( (disp & 0x02000000) > 0 ) {
disp |= 0xFC000000;
}
}
Addr branchTarget(Addr branchPC) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for branch and exchange instructions on the ARM
*/
class BranchExchange : public PredOp
{
protected:
/// Constructor
BranchExchange(const char *mnem, MachInst _machInst,
OpClass __opClass)
: PredOp(mnem, _machInst, __opClass)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for jumps (register-indirect control transfers). In
* the Arm ISA, these are always unconditional.
*/
class Jump : public PCDependentDisassembly
{
protected:
/// Displacement to target address (signed).
int32_t disp;
uint32_t target;
public:
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(OFFSET << 2)
{
}
Addr branchTarget(ThreadContext *tc) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
Addr
Branch::branchTarget(Addr branchPC) const
{
return branchPC + 8 + disp;
}
Addr
Jump::branchTarget(ThreadContext *tc) const
{
Addr NPC = tc->readPC() + 8;
uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
return (Rb & ~3) | (NPC & 1);
}
const std::string &
PCDependentDisassembly::disassemble(Addr pc,
const SymbolTable *symtab) const
{
if (!cachedDisassembly ||
pc != cachedPC || symtab != cachedSymtab)
{
if (cachedDisassembly)
delete cachedDisassembly;
cachedDisassembly =
new std::string(generateDisassembly(pc, symtab));
cachedPC = pc;
cachedSymtab = symtab;
}
return *cachedDisassembly;
}
std::string
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
Addr target = pc + 8 + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
else
ccprintf(ss, "0x%x", target);
return ss.str();
}
std::string
BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
return ss.str();
}
std::string
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
return ss.str();
}
}};
def format Branch(code,*opt_flags) {{
#Build Instruction Flags
#Use Link & Likely Flags to Add Link/Condition Code
inst_flags = ('IsDirectControl', )
for x in opt_flags:
if x == 'Link':
code += 'LR = NPC;\n'
else:
inst_flags += (x, )
#Take into account uncond. branch instruction
if 'cond == 1' in code:
inst_flags += ('IsUnCondControl', )
else:
inst_flags += ('IsCondControl', )
icode = 'if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode)) {\n'
icode += code
icode += ' NPC = NPC + 4 + disp;\n'
icode += '} else {\n'
icode += ' NPC = NPC;\n'
icode += '};\n'
code = icode
iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format BranchExchange(code,*opt_flags) {{
#Build Instruction Flags
#Use Link & Likely Flags to Add Link/Condition Code
inst_flags = ('IsIndirectControl', )
for x in opt_flags:
if x == 'Link':
code += 'LR = NPC;\n'
else:
inst_flags += (x, )
#Take into account uncond. branch instruction
if 'cond == 1' in code:
inst_flags += ('IsUnCondControl', )
else:
inst_flags += ('IsCondControl', )
#Condition code
icode = 'if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode)) {\n'
icode += code
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
icode += '} else {\n'
icode += ' NPC = NPC;\n'
icode += '};\n'
code = icode
iop = InstObjParams(name, Name, 'BranchExchange', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format Jump(code, *opt_flags) {{
#Build Instruction Flags
#Use Link Flag to Add Link Code
inst_flags = ('IsIndirectControl', 'IsUncondControl')
for x in opt_flags:
if x == 'Link':
code = 'LR = NPC;\n' + code
elif x == 'ClearHazards':
code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
else:
inst_flags += (x, )
iop = InstObjParams(name, Name, 'Jump', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
#exec_output = PredOpExecute.subst(iop)
}};

View file

@ -0,0 +1,57 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
//Templates from this format are used later
//Include the basic format
##include "basic.isa"
//Include support for predicated instructions
##include "pred.isa"
//Include utility functions
##include "util.isa"
//Include the float formats
##include "fp.isa"
//Include the mem format
##include "mem.isa"
//Include the macro-mem format
##include "macromem.isa"
//Include the branch format
##include "branch.isa"
//Include the unimplemented format
##include "unimp.isa"
//Include the unknown format
##include "unknown.isa"

View file

@ -0,0 +1,150 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Floating Point operate instructions
//
output header {{
/**
* Base class for FP operations.
*/
class FPAOp : public PredOp
{
protected:
/// Constructor
FPAOp(const char *mnem, MachInst _machInst, OpClass __opClass) : PredOp(mnem, _machInst, __opClass)
{
}
//std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output exec {{
}};
def template FPAExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode) &&
fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
def template FloatDoubleDecode {{
{
ArmStaticInst *i = NULL;
switch (OPCODE_19 << 1 | OPCODE_7)
{
case 0:
i = (ArmStaticInst *)new %(class_name)sS(machInst);
break;
case 1:
i = (ArmStaticInst *)new %(class_name)sD(machInst);
break;
case 2:
case 3:
default:
panic("Cannot decode float/double nature of the instruction");
}
return i;
}
}};
// Primary format for float point operate instructions:
def format FloatOp(code, *flags) {{
orig_code = code
cblk = code
iop = InstObjParams(name, Name, 'FPAOp', cblk, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = FPAExecute.subst(iop)
sng_cblk = code
sng_iop = InstObjParams(name, Name+'S', 'FPAOp', sng_cblk, flags)
header_output += BasicDeclare.subst(sng_iop)
decoder_output += BasicConstructor.subst(sng_iop)
exec_output += FPAExecute.subst(sng_iop)
dbl_code = re.sub(r'\.sf', '.df', orig_code)
dbl_cblk = dbl_code
dbl_iop = InstObjParams(name, Name+'D', 'FPAOp', dbl_cblk, flags)
header_output += BasicDeclare.subst(dbl_iop)
decoder_output += BasicConstructor.subst(dbl_iop)
exec_output += FPAExecute.subst(dbl_iop)
decode_block = FloatDoubleDecode.subst(iop)
}};
let {{
calcFPCcCode = '''
uint16_t _in, _iz, _ic, _iv;
_in = %(fReg1)s < %(fReg2)s;
_iz = %(fReg1)s == %(fReg2)s;
_ic = %(fReg1)s >= %(fReg2)s;
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
(Cpsr & 0x0FFFFFFF);
'''
}};
def format FloatCmp(fReg1, fReg2, *flags) {{
code = calcFPCcCode % vars()
iop = InstObjParams(name, Name, 'FPAOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = FPAExecute.subst(iop)
}};

View file

@ -0,0 +1,389 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Macro Memory-format instructions
//
output header {{
/**
* Arm Macro Memory operations like LDM/STM
*/
class ArmMacroMemoryOp : public PredMacroOp
{
protected:
/// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags;
/// Pointer to EAComp object.
const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
const StaticInstPtr memAccPtr;
uint32_t reglist;
uint32_t ones;
uint32_t puswl,
prepost,
up,
psruser,
writeback,
loadop;
ArmMacroMemoryOp(const char *mnem, MachInst _machInst, OpClass __opClass,
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: PredMacroOp(mnem, _machInst, __opClass),
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
reglist(REGLIST), ones(0), puswl(PUSWL), prepost(PREPOST), up(UP),
psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP)
{
ones = number_of_ones(reglist);
numMicroops = ones + writeback + 1;
// Remember that writeback adds a uop
microOps = new StaticInstPtr[numMicroops];
}
};
/**
* Arm Macro FPA operations to fix ldfd and stfd instructions
*/
class ArmMacroFPAOp : public PredMacroOp
{
protected:
uint32_t puswl,
prepost,
up,
psruser,
writeback,
loadop;
int32_t disp8;
ArmMacroFPAOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: PredMacroOp(mnem, _machInst, __opClass),
puswl(PUSWL), prepost(PREPOST), up(UP),
psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP),
disp8(IMMED_7_0 << 2)
{
numMicroops = 3 + writeback;
microOps = new StaticInstPtr[numMicroops];
}
};
/**
* Arm Macro FM operations to fix lfm and sfm
*/
class ArmMacroFMOp : public PredMacroOp
{
protected:
uint32_t punwl,
prepost,
up,
n1bit,
writeback,
loadop,
n0bit,
count;
int32_t disp8;
ArmMacroFMOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: PredMacroOp(mnem, _machInst, __opClass),
punwl(PUNWL), prepost(PREPOST), up(UP),
n1bit(OPCODE_22), writeback(WRITEBACK), loadop(LOADOP),
n0bit(OPCODE_15), disp8(IMMED_7_0 << 2)
{
// Transfer 1-4 registers based on n1 and n0 bits (with 00 repr. 4)
count = (n1bit << 1) | n0bit;
if (count == 0)
count = 4;
numMicroops = (3*count) + writeback;
microOps = new StaticInstPtr[numMicroops];
}
};
}};
output decoder {{
}};
def template MacroStoreDeclare {{
/**
* Static instructions class for a store multiple instruction
*/
class %(class_name)s : public %(base_class)s
{
public:
// Constructor
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
};
}};
def template MacroStoreConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
uint32_t regs_to_handle = reglist;
uint32_t j = 0,
start_addr = 0,
end_addr = 0;
switch (puswl)
{
case 0x01: // L ldmda_l
start_addr = (ones << 2) - 4;
end_addr = 0;
break;
case 0x03: // WL ldmda_wl
start_addr = (ones << 2) - 4;
end_addr = 0;
break;
case 0x08: // U stmia_u
start_addr = 0;
end_addr = (ones << 2) - 4;
break;
case 0x09: // U L ldmia_ul
start_addr = 0;
end_addr = (ones << 2) - 4;
break;
case 0x0b: // U WL ldmia
start_addr = 0;
end_addr = (ones << 2) - 4;
break;
case 0x11: // P L ldmdb
start_addr = (ones << 2); // U-bit is already 0 for subtract
end_addr = 4; // negative 4
break;
case 0x12: // P W stmdb
start_addr = (ones << 2); // U-bit is already 0 for subtract
end_addr = 4; // negative 4
break;
case 0x18: // PU stmib
start_addr = 4;
end_addr = (ones << 2) + 4;
break;
case 0x19: // PU L ldmib
start_addr = 4;
end_addr = (ones << 2) + 4;
break;
default:
panic("Unhandled Load/Store Multiple Instruction");
break;
}
//TODO - Add addi_uop/subi_uop here to create starting addresses
//Just using addi with 0 offset makes a "copy" of Rn for our use
uint32_t newMachInst = 0;
newMachInst = machInst & 0xffff0000;
microOps[0] = new Addi_uop(newMachInst);
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);
microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
if (up)
start_addr += 4;
else
start_addr -= 4;
}
/* TODO: Take a look at how these 2 values should meet together
if (start_addr != (end_addr - 4))
{
fprintf(stderr, "start_addr: %d\n", start_addr);
fprintf(stderr, "end_addr: %d\n", end_addr);
panic("start_addr does not meet end_addr");
}
*/
if (writeback)
{
uint32_t newMachInst = machInst & 0xf0000000;
uint32_t rn = (machInst >> 16) & 0x0f;
// 3322 2222 2222 1111 1111 11
// 1098 7654 3210 9876 5432 1098 7654 3210
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
// sub rn, rn, imm
newMachInst |= 0x02400000;
newMachInst |= ((rn << 16) | (rn << 12));
newMachInst |= (ones << 2);
if (up)
{
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
}
else
{
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
}
}
microOps[numMicroops-1]->setLastMicroop();
}
}};
def template MacroStoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
def template MacroFPAConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
uint32_t start_addr = 0;
if (prepost)
start_addr = disp8;
else
start_addr = 0;
emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
if (writeback)
{
uint32_t newMachInst = machInst & 0xf0000000;
uint32_t rn = (machInst >> 16) & 0x0f;
// 3322 2222 2222 1111 1111 11
// 1098 7654 3210 9876 5432 1098 7654 3210
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
// sub rn, rn, imm
newMachInst |= 0x02400000;
newMachInst |= ((rn << 16) | (rn << 12));
if (up)
{
newMachInst |= disp8;
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
}
else
{
newMachInst |= disp8;
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
}
}
microOps[numMicroops-1]->setLastMicroop();
}
}};
def template MacroFMConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
uint32_t start_addr = 0;
if (prepost)
start_addr = disp8;
else
start_addr = 0;
for (int i = 0; i < count; i++)
{
emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
}
if (writeback)
{
uint32_t newMachInst = machInst & 0xf0000000;
uint32_t rn = (machInst >> 16) & 0x0f;
// 3322 2222 2222 1111 1111 11
// 1098 7654 3210 9876 5432 1098 7654 3210
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
// sub rn, rn, imm
newMachInst |= 0x02400000;
newMachInst |= ((rn << 16) | (rn << 12));
if (up)
{
newMachInst |= disp8;
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
}
else
{
newMachInst |= disp8;
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
}
}
microOps[numMicroops-1]->setLastMicroop();
}
}};
def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
header_output = MacroStoreDeclare.subst(iop)
decoder_output = MacroStoreConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = MacroStoreExecute.subst(iop)
}};
def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
iop = InstObjParams(name, Name, 'ArmMacroFPAOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = MacroFPAConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
iop = InstObjParams(name, Name, 'ArmMacroFMOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = MacroFMConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};

View file

@ -0,0 +1,593 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Memory-format instructions
//
output header {{
/**
* Base class for general Arm memory-format instructions.
*/
class Memory : public PredOp
{
protected:
/// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags;
/// Pointer to EAComp object.
const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
const StaticInstPtr memAccPtr;
/// Displacement for EA calculation (signed).
int32_t disp;
int32_t disp8;
int32_t up;
int32_t hilo,
shift_size,
shift;
/// Constructor
Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: PredOp(mnem, _machInst, __opClass),
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
disp(IMMED_11_0), disp8(IMMED_7_0 << 2), up(UP),
hilo((IMMED_HI_11_8 << 4) | IMMED_LO_3_0),
shift_size(SHIFT_SIZE), shift(SHIFT)
{
// When Up is not set, then we must subtract by the displacement
if (!up)
{
disp = -disp;
disp8 = -disp8;
hilo = -hilo;
}
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
public:
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
const StaticInstPtr &memAccInst() const { return memAccPtr; }
};
/**
* Base class for a few miscellaneous memory-format insts
* that don't interpret the disp field
*/
class MemoryNoDisp : public Memory
{
protected:
/// Constructor
MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s", mnemonic);
}
std::string
MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s", mnemonic);
}
}};
def template LoadStoreDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
protected:
/**
* "Fake" effective address computation class for "%(mnemonic)s".
*/
class EAComp : public %(base_class)s
{
public:
/// Constructor
EAComp(MachInst machInst);
%(BasicExecDeclare)s
};
/**
* "Fake" memory access instruction class for "%(mnemonic)s".
*/
class MemAcc : public %(base_class)s
{
public:
/// Constructor
MemAcc(MachInst machInst);
%(BasicExecDeclare)s
};
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template InitiateAccDeclare {{
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template CompleteAccDeclare {{
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template EACompConstructor {{
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
{
%(constructor)s;
}
}};
def template MemAccConstructor {{
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
{
%(constructor)s;
}
}};
def template LoadStoreConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
new EAComp(machInst), new MemAcc(machInst))
{
%(constructor)s;
}
}};
def template EACompExecute {{
Fault
%(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(op_wb)s;
xc->setEA(EA);
}
}
return fault;
}
}};
def template LoadMemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
EA = xc->getEA();
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template LoadExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
}
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
// ARM instructions will not have a pkt if the predicate is false
Mem = pkt->get<typeof(Mem)>();
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreMemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
EA = xc->getEA();
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
// Need to write back any potential address register update
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_dest_decl)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreCondCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_dest_decl)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template MiscMemAccExecute {{
Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
EA = xc->getEA();
if (fault == NoFault) {
%(memacc_code)s;
}
}
return NoFault;
}
}};
def template MiscExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault) {
%(memacc_code)s;
}
}
return NoFault;
}
}};
def template MiscInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
return NoFault;
}
}};
def template MiscCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
return NoFault;
}
}};
def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
mem_flags = [], inst_flags = []) {{
ea_code = ArmGenericCodeSubs(ea_code)
memacc_code = ArmGenericCodeSubs(memacc_code)
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = BasicDecode,
exec_template_base = 'Load')
}};
def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
mem_flags = [], inst_flags = []) {{
ea_code = ArmGenericCodeSubs(ea_code)
memacc_code = ArmGenericCodeSubs(memacc_code)
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
exec_template_base = 'Store')
}};

View file

@ -0,0 +1,402 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Predicated Instruction Execution
//
output header {{
#include <iostream>
enum ArmPredicateBits {
COND_EQ = 0,
COND_NE, // 1
COND_CS, // 2
COND_CC, // 3
COND_MI, // 4
COND_PL, // 5
COND_VS, // 6
COND_VC, // 7
COND_HI, // 8
COND_LS, // 9
COND_GE, // 10
COND_LT, // 11
COND_GT, // 12
COND_LE, // 13
COND_AL, // 14
COND_NV // 15
};
inline uint32_t
rotate_imm(uint32_t immValue, uint32_t rotateValue)
{
return ((immValue >> (int)(rotateValue & 31)) |
(immValue << (32 - (int)(rotateValue & 31))));
}
inline uint32_t nSet(uint32_t cpsr) { return cpsr & (1<<31); }
inline uint32_t zSet(uint32_t cpsr) { return cpsr & (1<<30); }
inline uint32_t cSet(uint32_t cpsr) { return cpsr & (1<<29); }
inline uint32_t vSet(uint32_t cpsr) { return cpsr & (1<<28); }
inline bool arm_predicate(uint32_t cpsr, uint32_t predBits)
{
enum ArmPredicateBits armPredBits = (enum ArmPredicateBits) predBits;
uint32_t result = 0;
switch (armPredBits)
{
case COND_EQ:
result = zSet(cpsr); break;
case COND_NE:
result = !zSet(cpsr); break;
case COND_CS:
result = cSet(cpsr); break;
case COND_CC:
result = !cSet(cpsr); break;
case COND_MI:
result = nSet(cpsr); break;
case COND_PL:
result = !nSet(cpsr); break;
case COND_VS:
result = vSet(cpsr); break;
case COND_VC:
result = !vSet(cpsr); break;
case COND_HI:
result = cSet(cpsr) && !zSet(cpsr); break;
case COND_LS:
result = !cSet(cpsr) || zSet(cpsr); break;
case COND_GE:
result = (!nSet(cpsr) && !vSet(cpsr)) || (nSet(cpsr) && vSet(cpsr)); break;
case COND_LT:
result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)); break;
case COND_GT:
result = (!nSet(cpsr) && !vSet(cpsr) && !zSet(cpsr)) || (nSet(cpsr) && vSet(cpsr) && !zSet(cpsr)); break;
case COND_LE:
result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)) || zSet(cpsr); break;
case COND_AL: result = 1; break;
case COND_NV: result = 0; break;
default:
fprintf(stderr, "Unhandled predicate condition: %d\n", armPredBits);
exit(1);
}
if (result)
return true;
else
return false;
}
/**
* Base class for predicated integer operations.
*/
class PredOp : public ArmStaticInst
{
protected:
uint32_t condCode;
/// Constructor
PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
ArmStaticInst(mnem, _machInst, __opClass),
condCode(COND_CODE)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated immediate operations.
*/
class PredImmOp : public PredOp
{
protected:
uint32_t imm;
uint32_t rotate;
uint32_t rotated_imm;
uint32_t rotated_carry;
/// Constructor
PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
imm(IMM), rotate(ROTATE << 1), rotated_imm(0),
rotated_carry(0)
{
rotated_imm = rotate_imm(imm, rotate);
if (rotate != 0)
rotated_carry = (rotated_imm >> 31) & 1;
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated integer operations.
*/
class PredIntOp : public PredOp
{
protected:
uint32_t shift_size;
uint32_t shift;
/// Constructor
PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
shift_size(SHIFT_SIZE), shift(SHIFT)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated macro-operations.
*/
class PredMacroOp : public PredOp
{
protected:
uint32_t numMicroops;
StaticInstPtr * microOps;
/// Constructor
PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
numMicroops(0)
{
// We rely on the subclasses of this object to handle the
// initialization of the micro-operations, since they are
// all of variable length
flags[IsMacroop] = true;
}
~PredMacroOp()
{
if (numMicroops)
delete [] microOps;
}
StaticInstPtr fetchMicroop(MicroPC microPC)
{
assert(microPC < numMicroops);
return microOps[microPC];
}
%(BasicExecPanic)s
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated micro-operations.
*/
class PredMicroop : public PredOp
{
/// Constructor
PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass)
{
flags[IsMicroop] = true;
}
};
}};
def template PredOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
{
if (fault == NoFault)
{
%(op_wb)s;
}
}
else
return NoFault;
// Predicated false instructions should not return faults
return fault;
}
}};
//Outputs to decoder.cc
output decoder {{
std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
}
ss << ", ";
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ", ";
}
return ss.str();
}
std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
}
ss << ", ";
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ", ";
}
return ss.str();
}
std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
}
ss << ", ";
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ", ";
}
return ss.str();
}
std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
return ss.str();
}
}};
let {{
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);
'''
}};
def format PredOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'PredOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
def format PredImmOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
ccCode = calcCcCode % vars()
code += ccCode;
iop = InstObjParams(name, Name, 'PredImmOp',
{"code": code, "cc_code": ccCode}, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
def format PredIntOp(code, *opt_flags) {{
new_code = ArmGenericCodeSubs(code)
iop = InstObjParams(name, Name, 'PredIntOp', new_code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
ccCode = calcCcCode % vars()
code += ccCode;
new_code = ArmGenericCodeSubs(code)
iop = InstObjParams(name, Name, 'PredIntOp',
{"code": new_code, "cc_code": ccCode }, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};

View file

@ -0,0 +1,144 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Unimplemented instructions
//
output header {{
/**
* Static instruction class for unimplemented instructions that
* cause simulator termination. Note that these are recognized
* (legal) instructions that the simulator does not support; the
* 'Unknown' class is used for unrecognized/illegal instructions.
* This is a leaf class.
*/
class FailUnimplemented : public ArmStaticInst
{
public:
/// Constructor
FailUnimplemented(const char *_mnemonic, MachInst _machInst)
: ArmStaticInst(_mnemonic, _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for unimplemented instructions that cause a warning
* to be printed (but do not terminate simulation). This
* implementation is a little screwy in that it will print a
* warning for each instance of a particular unimplemented machine
* instruction, not just for each unimplemented opcode. Should
* probably make the 'warned' flag a static member of the derived
* class.
*/
class WarnUnimplemented : public ArmStaticInst
{
private:
/// Have we warned on this instruction yet?
mutable bool warned;
public:
/// Constructor
WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
: ArmStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
FailUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
return csprintf("%-10s (unimplemented)", mnemonic);
}
std::string
WarnUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
return csprintf("%-10s (unimplemented)", mnemonic);
}
}};
output exec {{
Fault
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
inst2string(machInst));
return new UnimplementedOpcodeFault;
}
Fault
WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (!warned) {
warn("\tinstruction '%s' unimplemented\n", mnemonic);
warned = true;
}
return NoFault;
}
}};
def format FailUnimpl() {{
iop = InstObjParams(name, 'FailUnimplemented')
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};
def format WarnUnimpl() {{
iop = InstObjParams(name, 'WarnUnimplemented')
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};

View file

@ -0,0 +1,84 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output header {{
/**
* Static instruction class for unknown (illegal) instructions.
* These cause simulator termination if they are executed in a
* non-speculative mode. This is a leaf class.
*/
class Unknown : public ArmStaticInst
{
public:
/// Constructor
Unknown(MachInst _machInst)
: ArmStaticInst("unknown", _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)",
"unknown", machInst, OPCODE, inst2string(machInst));
}
}};
output exec {{
Fault
Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
return new UnimplementedOpcodeFault;
}
}};
def format Unknown() {{
decode_block = 'return new Unknown(machInst);\n'
}};

View file

@ -0,0 +1,217 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
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'^', 'Cpsr = Cpsr;', new_code)
return new_code
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
decode_template = BasicDecode, exec_template_base = ''):
# Make sure flags are in lists (convert to lists if not).
mem_flags = makeList(mem_flags)
inst_flags = makeList(inst_flags)
# add hook to get effective addresses into execution trace output.
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
# Some CPU models execute the memory operation as an atomic unit,
# while others want to separate them into an effective address
# computation and a memory access operation. As a result, we need
# to generate three StaticInst objects. Note that the latter two
# are nested inside the larger "atomic" one.
# Generate InstObjParams for each of the three objects. Note that
# they differ only in the set of code objects contained (which in
# turn affects the object's overall operand list).
iop = InstObjParams(name, Name, base_class,
{ 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
inst_flags)
ea_iop = InstObjParams(name, Name, base_class,
{ 'ea_code':ea_code },
inst_flags)
memacc_iop = InstObjParams(name, Name, base_class,
{ 'memacc_code':memacc_code, 'postacc_code':postacc_code },
inst_flags)
if mem_flags:
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
iop.constructor += s
memacc_iop.constructor += s
# select templates
# The InitiateAcc template is the same for StoreCond templates as the
# corresponding Store template..
StoreCondInitiateAcc = StoreInitiateAcc
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
fullExecTemplate = eval(exec_template_base + 'Execute')
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
# (header_output, decoder_output, decode_block, exec_output)
return (LoadStoreDeclare.subst(iop),
EACompConstructor.subst(ea_iop)
+ MemAccConstructor.subst(memacc_iop)
+ LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
EACompExecute.subst(ea_iop)
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop)
+ initiateAccTemplate.subst(iop)
+ completeAccTemplate.subst(iop))
}};
output header {{
std::string inst2string(MachInst machInst);
StaticInstPtr gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp);
int emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp);
}};
output decoder {{
std::string inst2string(MachInst machInst)
{
std::string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
if ((machInst & mask) == 0) {
str += "0";
} else {
str += "1";
}
mask = mask >> 1;
}
return str;
}
// Generate the bit pattern for an Ldr_uop or Str_uop;
StaticInstPtr
gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp)
{
StaticInstPtr newInst;
uint32_t newMachInst = baseinst & 0xffff0000;
newMachInst |= (rd << 12);
newMachInst |= disp;
if (loadop)
newInst = new Ldr_uop(newMachInst);
else
newInst = new Str_uop(newMachInst);
return newInst;
}
// Emits uops for a double fp move
int
emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp)
{
StaticInstPtr newInst;
uint32_t newMachInst;
if (loadop)
{
newMachInst = baseinst & 0xfffff000;
newMachInst |= (disp & 0x0fff);
newInst = new Ldlo_uop(newMachInst);
microOps[index++] = newInst;
newMachInst = baseinst & 0xfffff000;
if (up)
newMachInst |= ((disp + 4) & 0x0fff);
else
newMachInst |= ((disp - 4) & 0x0fff);
newInst = new Ldhi_uop(newMachInst);
microOps[index++] = newInst;
newMachInst = baseinst & 0xf000f000;
newInst = new Mvtd_uop(newMachInst);
microOps[index++] = newInst;
}
else
{
newMachInst = baseinst & 0xf000f000;
newInst = new Mvfd_uop(newMachInst);
microOps[index++] = newInst;
newMachInst = baseinst & 0xfffff000;
newMachInst |= (disp & 0x0fff);
newInst = new Stlo_uop(newMachInst);
microOps[index++] = newInst;
newMachInst = baseinst & 0xfffff000;
if (up)
newMachInst |= ((disp + 4) & 0x0fff);
else
newMachInst |= ((disp - 4) & 0x0fff);
newInst = new Sthi_uop(newMachInst);
microOps[index++] = newInst;
}
return 3;
}
}};
output exec {{
using namespace ArmISA;
/// CLEAR ALL CPU INST/EXE HAZARDS
inline void
clear_exe_inst_hazards()
{
//CODE HERE
}
#if FULL_SYSTEM
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
return NoFault;
}
#else
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
return NoFault;
}
#endif
}};

View file

@ -0,0 +1,82 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//
output header {{
#include <sstream>
#include <iostream>
#include <iomanip>
#include "arch/arm/isa_traits.hh"
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
}};
output decoder {{
#include <cmath>
#if defined(linux)
#include <fenv.h>
#endif
#include "arch/arm/faults.hh"
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
using namespace ArmISA;
using std::isnan;
}};
output exec {{
#include "arch/arm/faults.hh"
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include <cmath>
#if defined(linux)
#include <fenv.h>
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/sim_exit.hh"
using namespace ArmISA;
using std::isnan;
}};

63
src/arch/arm/isa/main.isa Normal file
View file

@ -0,0 +1,63 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// ARM ISA description file.
//
////////////////////////////////////////////////////////////////////
//Include the C++ include directives
##include "includes.isa"
////////////////////////////////////////////////////////////////////
//
// Namespace statement. Everything below this line will be in the
// ArmISAInst namespace.
//
namespace ArmISA;
//Include the utility functions
##include "util.isa"
//Include the bitfield definitions
##include "bitfields.isa"
//Include the operand_types and operand definitions
##include "operands.isa"
//Include the base class for Arm instructions, and some support code
##include "base.isa"
//Include the definitions for the instruction formats
##include "formats/formats.isa"
//Include the decoder definition
##include "decoder.isa"

View file

@ -0,0 +1,72 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
def operand_types {{
'sb' : ('signed int', 8),
'ub' : ('unsigned int', 8),
'sh' : ('signed int', 16),
'uh' : ('unsigned int', 16),
'sw' : ('signed int', 32),
'uw' : ('unsigned int', 32),
'ud' : ('unsigned int', 64),
'sf' : ('float', 32),
'df' : ('float', 64)
}};
def operands {{
#General Purpose Integer Reg Operands
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3),
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4),
'Re': ('IntReg', 'uw', 'RE', 'IsInteger', 5),
'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 5),
'R0': ('IntReg', 'uw', '0', 'IsInteger', 5),
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 5),
'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 6),
'LR': ('IntReg', 'uw', '14', 'IsInteger', 6),
'Ignore': ('IntReg', 'uw', '16', 'IsInteger', 99),
#General Purpose Floating Point Reg Operands
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 1),
'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 2),
'Fm': ('FloatReg', 'df', 'FM', 'IsFloating', 3),
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8),
'Cpsr': ('ControlReg', 'uw', 'CPSR', 'IsInteger', 7),
'Fpsr': ('ControlReg', 'uw', 'FPSR', 'IsInteger', 7),
'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9),
'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 9),
}};

282
src/arch/arm/isa/util.isa Normal file
View file

@ -0,0 +1,282 @@
// -*- mode:c++ -*-
// Copyright (c) 2007-2008 The Florida State University
// 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: Stephen Hines
////////////////////////////////////////////////////////////////////
//
// Utility functions for execute methods
//
//
output header {{
// Shift types for ARM instructions
enum ArmShiftType {
LSL = 0,
LSR,
ASR,
ROR
};
enum ArmShiftMode {
};
inline uint32_t number_of_ones(int32_t val)
{
uint32_t ones = 0;
for (int i = 0; i < 32; i++ )
{
if ( val & (1<<i) )
ones++;
}
return ones;
}
}};
output exec {{
static int32_t arm_NEG(int32_t val) { return (val >> 31); }
static int32_t arm_POS(int32_t val) { return ((~val) >> 31); }
// Shift Rm by an immediate value
inline int32_t
shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
{
enum ArmShiftType shiftType;
shiftType = (enum ArmShiftType) type;
switch (shiftType)
{
case LSL:
return (base << shamt);
case LSR:
if (shamt == 0)
return (0);
else
return (base >> shamt);
case ASR:
if (shamt == 0)
return ((uint32_t) ((int32_t) base >> 31L));
else
return ((uint32_t) (((int32_t) base) >> shamt));
case ROR:
//shamt = shamt & 0x1f;
if (shamt == 0)
return (cfval << 31) | (base >> 1); // RRX
else
return (base << (32 - shamt)) | (base >> shamt);
default:
fprintf(stderr, "Unhandled shift type\n");
exit(1);
break;
}
return 0;
}
// Shift Rm by Rs
inline int32_t
shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
{
enum ArmShiftType shiftType;
shiftType = (enum ArmShiftType) type;
switch (shiftType)
{
case LSL:
if (shamt == 0)
return (base);
else if (shamt >= 32)
return (0);
else
return (base << shamt);
case LSR:
if (shamt == 0)
return (base);
else if (shamt >= 32)
return (0);
else
return (base >> shamt);
case ASR:
if (shamt == 0)
return base;
else if (shamt >= 32)
return ((uint32_t) ((int32_t) base >> 31L));
else
return ((uint32_t) (((int32_t) base) >> (int) shamt));
case ROR:
shamt = shamt & 0x1f;
if (shamt == 0)
return (base);
else
return ((base << (32 - shamt)) | (base >> shamt));
default:
fprintf(stderr, "Unhandled shift type\n");
exit(1);
break;
}
return 0;
}
// Generate C for a shift by immediate
inline int32_t
shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type,
uint32_t cfval)
{
enum ArmShiftType shiftType;
shiftType = (enum ArmShiftType) type;
switch (shiftType)
{
case LSL:
return (base >> (32 - shamt)) & 1;
case LSR:
if (shamt == 0)
return (base >> 31) & 1;
else
return (base >> (shamt - 1)) & 1;
case ASR:
if (shamt == 0)
return (base >> 31L);
else
return ((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1;
case ROR:
shamt = shamt & 0x1f;
if (shamt == 0)
return (base & 1); // RRX
else
return (base >> (shamt - 1)) & 1;
default:
fprintf(stderr, "Unhandled shift type\n");
exit(1);
break;
}
return 0;
}
// Generate C for a shift by Rs
inline int32_t
shift_carry_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval)
{
enum ArmShiftType shiftType;
shiftType = (enum ArmShiftType) type;
switch (shiftType)
{
case LSL:
if (shamt == 0)
return (!!cfval);
else if (shamt == 32)
return (base & 1);
else if (shamt > 32)
return (0);
else
return ((base >> (32 - shamt)) & 1);
case LSR:
if (shamt == 0)
return (!!cfval);
else if (shamt == 32)
return (base >> 31);
else if (shamt > 32)
return (0);
else
return ((base >> (shamt - 1)) & 1);
case ASR:
if (shamt == 0)
return (!!cfval);
else if (shamt >= 32)
return (base >> 31L);
else
return (((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1);
case ROR:
if (shamt == 0)
return (!!cfval);
shamt = shamt & 0x1f;
if (shamt == 0)
return (base >> 31); // RRX
else
return ((base >> (shamt - 1)) & 1);
default:
fprintf(stderr, "Unhandled shift type\n");
exit(1);
break;
}
return 0;
}
// Generate the appropriate carry bit for an addition operation
inline int32_t
arm_add_carry(int32_t result, int32_t lhs, int32_t rhs)
{
if ((lhs | rhs) >> 30)
return ((arm_NEG(lhs) && arm_NEG(rhs)) ||
(arm_NEG(lhs) && arm_POS(result)) ||
(arm_NEG(rhs) && arm_POS(result)));
else
return 0;
}
// Generate the appropriate carry bit for a subtraction operation
inline int32_t
arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs)
{
if ((lhs >= rhs) || ((rhs | lhs) >> 31))
return ((arm_NEG(lhs) && arm_POS(rhs)) ||
(arm_NEG(lhs) && arm_POS(result)) ||
(arm_POS(rhs) && arm_POS(result)));
else
return 0;
}
inline int32_t
arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs)
{
if ((lhs | rhs) >> 30)
return ((arm_NEG(lhs) && arm_NEG(rhs) && arm_POS(result)) ||
(arm_POS(lhs) && arm_POS(rhs) && arm_NEG(result)));
else
return 0;
}
inline int32_t
arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs)
{
if ((lhs >= rhs) || ((rhs | lhs) >> 31))
return ((arm_NEG(lhs) && arm_POS(rhs) && arm_POS(result)) ||
(arm_POS(lhs) && arm_NEG(rhs) && arm_NEG(result)));
else
return 0;
}
}};

158
src/arch/arm/isa_traits.hh Normal file
View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2003-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
* 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
* Stephen Hines
*/
#ifndef __ARCH_ARM_ISA_TRAITS_HH__
#define __ARCH_ARM_ISA_TRAITS_HH__
#include "arch/arm/types.hh"
#include "sim/host.hh"
namespace LittleEndianGuest {};
#define TARGET_ARM
class StaticInstPtr;
namespace ArmISA
{
using namespace LittleEndianGuest;
StaticInstPtr decodeInst(ExtMachInst);
// ARM DOES NOT have a delay slot
#define ISA_HAS_DELAY_SLOT 0
const Addr PageShift = 12;
const Addr PageBytes = ULL(1) << PageShift;
const Addr Page_Mask = ~(PageBytes - 1);
const Addr PageOffset = PageBytes - 1;
////////////////////////////////////////////////////////////////////////
//
// Translation stuff
//
const Addr PteShift = 3;
const Addr NPtePageShift = PageShift - PteShift;
const Addr NPtePage = ULL(1) << NPtePageShift;
const Addr PteMask = NPtePage - 1;
//// All 'Mapped' segments go through the TLB
//// All other segments are translated by dropping the MSB, to give
//// the corresponding physical address
// User Segment - Mapped
const Addr USegBase = ULL(0x0);
const Addr USegEnd = ULL(0x7FFFFFFF);
// Kernel Segment 0 - Unmapped
const Addr KSeg0End = ULL(0x9FFFFFFF);
const Addr KSeg0Base = ULL(0x80000000);
const Addr KSeg0Mask = ULL(0x1FFFFFFF);
// For loading... XXX This maybe could be USegEnd?? --ali
const Addr LoadAddrMask = ULL(0xffffffffff);
const unsigned VABits = 32;
const unsigned PABits = 32; // Is this correct?
const Addr VAddrImplMask = (ULL(1) << VABits) - 1;
const Addr VAddrUnImplMask = ~VAddrImplMask;
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
inline Addr VAddrVPN(Addr a) { return a >> ArmISA::PageShift; }
inline Addr VAddrOffset(Addr a) { return a & ArmISA::PageOffset; }
const Addr PAddrImplMask = (ULL(1) << PABits) - 1;
// return a no-op instruction... used for instruction fetch faults
const ExtMachInst NoopMachInst = 0x00000000;
// Constants Related to the number of registers
const int NumIntArchRegs = 16;
const int NumIntSpecialRegs = 19;
const int NumFloatArchRegs = 16;
const int NumFloatSpecialRegs = 5;
const int NumControlRegs = 7;
const int NumInternalProcRegs = 0;
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
const int NumMiscRegs = NumControlRegs;
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
// Static instruction parameters
const int MaxInstSrcRegs = 5;
const int MaxInstDestRegs = 3;
// semantically meaningful register indices
const int ReturnValueReg = 0;
const int ReturnValueReg1 = 1;
const int ReturnValueReg2 = 2;
const int ArgumentReg0 = 0;
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 ZeroReg = NumIntArchRegs;
const int AddrReg = ZeroReg + 1; // Used to generate address for uops
const int ArgumentReg[] = {0, 1, 2, 3};
const int NumArgumentRegs = sizeof(ArgumentReg)/ sizeof(const int);
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ReturnValueReg;
const int SyscallSuccessReg = ReturnValueReg;
const int LogVMPageSize = 12; // 4K bytes
const int VMPageSize = (1 << LogVMPageSize);
const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
const int MachineBytes = 4;
const int WordBytes = 4;
const int HalfwordBytes = 2;
const int ByteBytes = 1;
// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = NumIntRegs;
const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
};
using namespace ArmISA;
#endif // __ARCH_ARM_ISA_TRAITS_HH__

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2003-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
* 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: Stephen Hines
*/
#include "arch/arm/linux/linux.hh"
#include <fcntl.h>
// open(2) flags translation table
OpenFlagTransTable ArmLinux::openFlagTable[] = {
#ifdef _MSC_VER
{ ArmLinux::TGT_O_RDONLY, _O_RDONLY },
{ ArmLinux::TGT_O_WRONLY, _O_WRONLY },
{ ArmLinux::TGT_O_RDWR, _O_RDWR },
{ ArmLinux::TGT_O_APPEND, _O_APPEND },
{ ArmLinux::TGT_O_CREAT, _O_CREAT },
{ ArmLinux::TGT_O_TRUNC, _O_TRUNC },
{ ArmLinux::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
{ ArmLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
{ ArmLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
{ ArmLinux::TGT_O_SYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
{ ArmLinux::TGT_O_RDONLY, O_RDONLY },
{ ArmLinux::TGT_O_WRONLY, O_WRONLY },
{ ArmLinux::TGT_O_RDWR, O_RDWR },
{ ArmLinux::TGT_O_APPEND, O_APPEND },
{ ArmLinux::TGT_O_CREAT, O_CREAT },
{ ArmLinux::TGT_O_TRUNC, O_TRUNC },
{ ArmLinux::TGT_O_EXCL, O_EXCL },
{ ArmLinux::TGT_O_NONBLOCK, O_NONBLOCK },
{ ArmLinux::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
{ ArmLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int ArmLinux::NUM_OPEN_FLAGS =
(sizeof(ArmLinux::openFlagTable)/sizeof(ArmLinux::openFlagTable[0]));

128
src/arch/arm/linux/linux.hh Normal file
View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2003-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
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_LINUX_LINUX_HH__
#define __ARCH_ARM_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
class ArmLinux : public Linux
{
public:
/// This table maps the target open() flags to the corresponding
/// host open() flags.
static OpenFlagTransTable openFlagTable[];
/// Number of entries in openFlagTable[].
static const int NUM_OPEN_FLAGS;
//@{
/// open(2) flag values.
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT
static const int TGT_O_EXCL = 0x00000200; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00000400; //!< O_NOCTTY
static const int TGT_O_TRUNC = 0x00001000; //!< O_TRUNC
static const int TGT_O_APPEND = 0x00002000; //!< O_APPEND
static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
static const int TGT_O_SYNC = 0x00010000; //!< O_SYNC
static const int TGT_FASYNC = 0x00020000; //!< FASYNC
static const int TGT_O_DIRECT = 0x00040000; //!< O_DIRECT
static const int TGT_O_LARGEFILE = 0x00100000; //!< O_LARGEFILE
static const int TGT_O_DIRECTORY = 0x00200000; //!< O_DIRECTORY
static const int TGT_O_NOFOLLOW = 0x00400000; //!< O_NOFOLLOW
static const int TGT_O_NOATIME = 0x01000000; //!< O_NOATIME
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x800;
//@{
/// For getsysinfo().
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
//@}
//@{
/// For getrusage().
static const int TGT_RUSAGE_SELF = 0;
static const int TGT_RUSAGE_CHILDREN = -1;
static const int TGT_RUSAGE_BOTH = -2;
//@}
//@{
/// For setsysinfo().
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
//@}
//@{
/// ioctl() command codes.
static const unsigned TIOCGETP_ = 0x40067408;
static const unsigned TIOCSETP_ = 0x80067409;
static const unsigned TIOCSETN_ = 0x8006740a;
static const unsigned TIOCSETC_ = 0x80067411;
static const unsigned TIOCGETC_ = 0x40067412;
static const unsigned FIONREAD_ = 0x4004667f;
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
//@}
/// For table().
static const int TBL_SYSINFO = 12;
/// Resource enumeration for getrlimit().
enum rlimit_resources {
TGT_RLIMIT_CPU = 0,
TGT_RLIMIT_FSIZE = 1,
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
TGT_RLIMIT_NOFILE = 5,
TGT_RLIMIT_AS = 6,
TGT_RLIMIT_RSS = 7,
TGT_RLIMIT_VMEM = 7,
TGT_RLIMIT_NPROC = 8,
TGT_RLIMIT_MEMLOCK = 9,
TGT_RLIMIT_LOCKS = 10
};
};
#endif

View file

@ -0,0 +1,434 @@
/*
* Copyright (c) 2003-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
* 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: Korey Sewell
* Stephen Hines
*/
#include "arch/arm/linux/linux.hh"
#include "arch/arm/linux/process.hh"
#include "arch/arm/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
using namespace std;
using namespace ArmISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
strcpy(name->release, "2.4.20");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "arm");
name.copyOut(tc->getMemPort());
return 0;
}
SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("open", openFunc<ArmLinux>),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("waitpid", unimplementedFunc), //???
/* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("execve", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("time", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<ArmLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc),
/* 17 */ SyscallDesc("break", obreakFunc), //???
/* 18 */ SyscallDesc("unused#18", unimplementedFunc), //???
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
/* 21 */ SyscallDesc("mount", unimplementedFunc),
/* 22 */ SyscallDesc("umount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
/* 24 */ SyscallDesc("getuid", getuidFunc),
/* 25 */ SyscallDesc("stime", unimplementedFunc),
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
/* 28 */ SyscallDesc("unused#28", unimplementedFunc),
/* 29 */ SyscallDesc("pause", unimplementedFunc),
/* 30 */ SyscallDesc("utime", unimplementedFunc),
/* 31 */ SyscallDesc("stty", unimplementedFunc),
/* 32 */ SyscallDesc("gtty", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
/* 34 */ SyscallDesc("nice", unimplementedFunc),
/* 35 */ SyscallDesc("ftime", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", ignoreFunc),
/* 38 */ SyscallDesc("rename", unimplementedFunc),
/* 39 */ SyscallDesc("mkdir", unimplementedFunc),
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", obreakFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc),
/* 49 */ SyscallDesc("geteuid", geteuidFunc),
/* 50 */ SyscallDesc("getegid", getegidFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<ArmLinux>),
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
/* 58 */ SyscallDesc("ulimit", unimplementedFunc),
/* 59 */ SyscallDesc("unused#59", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("ustat", unimplementedFunc),
/* 63 */ SyscallDesc("dup2", unimplementedFunc),
/* 64 */ SyscallDesc("getppid", getpagesizeFunc),
/* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
/* 66 */ SyscallDesc("setsid", unimplementedFunc),
/* 67 */ SyscallDesc("sigaction",unimplementedFunc),
/* 68 */ SyscallDesc("sgetmask", unimplementedFunc),
/* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
/* 70 */ SyscallDesc("setreuid", unimplementedFunc),
/* 71 */ SyscallDesc("setregid", unimplementedFunc),
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 77 */ SyscallDesc("getrusage", unimplementedFunc),
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 80 */ SyscallDesc("getgroups", unimplementedFunc),
/* 81 */ SyscallDesc("setgroups", unimplementedFunc),
/* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
/* 83 */ SyscallDesc("symlink", unimplementedFunc),
/* 84 */ SyscallDesc("unused#84", unimplementedFunc),
/* 85 */ SyscallDesc("readlink", unimplementedFunc),
/* 86 */ SyscallDesc("uselib", unimplementedFunc),
/* 87 */ SyscallDesc("swapon", gethostnameFunc),
/* 88 */ SyscallDesc("reboot", unimplementedFunc),
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
/* 90 */ SyscallDesc("mmap", mmapFunc<ArmLinux>),
/* 91 */ SyscallDesc("munmap",munmapFunc),
/* 92 */ SyscallDesc("truncate", truncateFunc),
/* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
/* 97 */ SyscallDesc("setpriority", unimplementedFunc),
/* 98 */ SyscallDesc("profil", unimplementedFunc),
/* 99 */ SyscallDesc("statfs", unimplementedFunc),
/* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
/* 101 */ SyscallDesc("ioperm", unimplementedFunc),
/* 102 */ SyscallDesc("socketcall", unimplementedFunc),
/* 103 */ SyscallDesc("syslog", unimplementedFunc),
/* 104 */ SyscallDesc("setitimer", unimplementedFunc),
/* 105 */ SyscallDesc("getitimer", unimplementedFunc),
/* 106 */ SyscallDesc("stat", statFunc<ArmLinux>),
/* 107 */ SyscallDesc("lstat", unimplementedFunc),
/* 108 */ SyscallDesc("fstat", fstatFunc<ArmLinux>),
/* 109 */ SyscallDesc("unused#109", unimplementedFunc),
/* 110 */ SyscallDesc("iopl", unimplementedFunc),
/* 111 */ SyscallDesc("vhangup", unimplementedFunc),
/* 112 */ SyscallDesc("idle", ignoreFunc),
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
/* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
/* 120 */ SyscallDesc("clone", unimplementedFunc),
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 122 */ SyscallDesc("uname", unameFunc),
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
/* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
/* 125 */ SyscallDesc("mprotect", ignoreFunc),
/* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
/* 127 */ SyscallDesc("create_module", unimplementedFunc),
/* 128 */ SyscallDesc("init_module", unimplementedFunc),
/* 129 */ SyscallDesc("delete_module", unimplementedFunc),
/* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
/* 131 */ SyscallDesc("quotactl", unimplementedFunc),
/* 132 */ SyscallDesc("getpgid", unimplementedFunc),
/* 133 */ SyscallDesc("fchdir", unimplementedFunc),
/* 134 */ SyscallDesc("bdflush", unimplementedFunc),
/* 135 */ SyscallDesc("sysfs", unimplementedFunc),
/* 136 */ SyscallDesc("personality", unimplementedFunc),
/* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
/* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
/* 140 */ SyscallDesc("llseek", unimplementedFunc),
/* 141 */ SyscallDesc("getdents", unimplementedFunc),
/* 142 */ SyscallDesc("newselect", unimplementedFunc),
/* 143 */ SyscallDesc("flock", unimplementedFunc),
/* 144 */ SyscallDesc("msync", unimplementedFunc),
/* 145 */ SyscallDesc("readv", unimplementedFunc),
/* 146 */ SyscallDesc("writev", writevFunc<ArmLinux>),
/* 147 */ SyscallDesc("getsid", unimplementedFunc),
/* 148 */ SyscallDesc("fdatasync", unimplementedFunc),
/* 149 */ SyscallDesc("sysctl", unimplementedFunc),
/* 150 */ SyscallDesc("mlock", unimplementedFunc),
/* 151 */ SyscallDesc("munlock", unimplementedFunc),
/* 152 */ SyscallDesc("mlockall", unimplementedFunc),
/* 153 */ SyscallDesc("munlockall", unimplementedFunc),
/* 154 */ SyscallDesc("sched_setparam", unimplementedFunc),
/* 155 */ SyscallDesc("sched_getparam", unimplementedFunc),
/* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
/* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
/* 158 */ SyscallDesc("sched_yield", unimplementedFunc),
/* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
/* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
/* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
/* 162 */ SyscallDesc("nanosleep", unimplementedFunc),
/* 163 */ SyscallDesc("mremap", unimplementedFunc), // ARM-specific
/* 164 */ SyscallDesc("setresuid", unimplementedFunc),
/* 165 */ SyscallDesc("getresuid", unimplementedFunc),
/* 166 */ SyscallDesc("vm862", unimplementedFunc),
/* 167 */ SyscallDesc("query_module", unimplementedFunc),
/* 168 */ SyscallDesc("poll", unimplementedFunc),
/* 169 */ SyscallDesc("nfsservctl", unimplementedFunc),
/* 170 */ SyscallDesc("setresgid", unimplementedFunc),
/* 171 */ SyscallDesc("getresgid", unimplementedFunc),
/* 172 */ SyscallDesc("prctl", unimplementedFunc),
/* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
/* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc),
/* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
/* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 180 */ SyscallDesc("pread64", unimplementedFunc),
/* 181 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 182 */ SyscallDesc("chown", unimplementedFunc),
/* 183 */ SyscallDesc("getcwd", unimplementedFunc),
/* 184 */ SyscallDesc("capget", unimplementedFunc),
/* 185 */ SyscallDesc("capset", unimplementedFunc),
/* 186 */ SyscallDesc("sigaltstack", unimplementedFunc),
/* 187 */ SyscallDesc("sendfile", unimplementedFunc),
/* 188 */ SyscallDesc("getpmsg", unimplementedFunc),
/* 189 */ SyscallDesc("putpmsg", unimplementedFunc),
/* 190 */ SyscallDesc("vfork", unimplementedFunc),
/* 191 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 192 */ SyscallDesc("mmap2", unimplementedFunc),
/* 193 */ SyscallDesc("truncate64", unimplementedFunc),
/* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
/* 195 */ SyscallDesc("stat64", unimplementedFunc),
/* 196 */ SyscallDesc("lstat64", lstat64Func<ArmLinux>),
/* 197 */ SyscallDesc("fstat64", fstatFunc<ArmLinux>),
/* 198 */ SyscallDesc("lchown", unimplementedFunc),
/* 199 */ SyscallDesc("getuid", getuidFunc),
/* 200 */ SyscallDesc("getgid", getgidFunc),
/* 201 */ SyscallDesc("geteuid", geteuidFunc),
/* 202 */ SyscallDesc("getegid", getegidFunc),
/* 203 */ SyscallDesc("setreuid", unimplementedFunc),
/* 204 */ SyscallDesc("setregid", unimplementedFunc),
/* 205 */ SyscallDesc("getgroups", unimplementedFunc),
/* 206 */ SyscallDesc("setgroups", unimplementedFunc),
/* 207 */ SyscallDesc("fchown", unimplementedFunc),
/* 208 */ SyscallDesc("setresuid", unimplementedFunc),
/* 209 */ SyscallDesc("getresuid", unimplementedFunc),
/* 210 */ SyscallDesc("setresgid", unimplementedFunc),
/* 211 */ SyscallDesc("getresgid", unimplementedFunc),
/* 212 */ SyscallDesc("chown", unimplementedFunc),
/* 213 */ SyscallDesc("setuid", unimplementedFunc),
/* 214 */ SyscallDesc("setgid", unimplementedFunc),
/* 215 */ SyscallDesc("setfsuid", unimplementedFunc),
/* 216 */ SyscallDesc("setfsgid", unimplementedFunc),
/* 217 */ SyscallDesc("getdents64", unimplementedFunc),
/* 218 */ SyscallDesc("pivot_root", unimplementedFunc),
/* 219 */ SyscallDesc("mincore", unimplementedFunc),
/* 220 */ SyscallDesc("madvise", unimplementedFunc),
/* 221 */ SyscallDesc("fcntl64", fcntl64Func),
/* 222 */ SyscallDesc("tux", unimplementedFunc),
/* 223 */ SyscallDesc("unknown#223", unimplementedFunc),
/* 224 */ SyscallDesc("gettid", unimplementedFunc),
/* 225 */ SyscallDesc("readahead", unimplementedFunc),
/* 226 */ SyscallDesc("setxattr", unimplementedFunc),
/* 227 */ SyscallDesc("lsetxattr", unimplementedFunc),
/* 228 */ SyscallDesc("fsetxattr", unimplementedFunc),
/* 229 */ SyscallDesc("getxattr", unimplementedFunc),
/* 230 */ SyscallDesc("lgetxattr", unimplementedFunc),
/* 231 */ SyscallDesc("fgetxattr", unimplementedFunc),
/* 232 */ SyscallDesc("listxattr", unimplementedFunc),
/* 233 */ SyscallDesc("llistxattr", unimplementedFunc),
/* 234 */ SyscallDesc("flistxattr", unimplementedFunc),
/* 235 */ SyscallDesc("removexattr", unimplementedFunc),
/* 236 */ SyscallDesc("lremovexattr", unimplementedFunc),
/* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 238 */ SyscallDesc("tkill", unimplementedFunc),
/* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
/* 240 */ SyscallDesc("futex", unimplementedFunc),
/* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
/* 243 */ SyscallDesc("io_setup", unimplementedFunc),
/* 244 */ SyscallDesc("io_destory", unimplementedFunc),
/* 245 */ SyscallDesc("io_getevents", unimplementedFunc),
/* 246 */ SyscallDesc("io_submit", unimplementedFunc),
/* 247 */ SyscallDesc("io_cancel", unimplementedFunc),
/* 248 */ SyscallDesc("exit_group", exitFunc),
/* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
/* 250 */ SyscallDesc("epoll_create", unimplementedFunc),
/* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc),
/* 252 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc),
/* 254 */ SyscallDesc("set_thread_area", unimplementedFunc),
/* 255 */ SyscallDesc("get_thread_area", unimplementedFunc),
/* 256 */ SyscallDesc("set_tid_address", unimplementedFunc),
/* 257 */ SyscallDesc("timer_create", unimplementedFunc),
/* 258 */ SyscallDesc("timer_settime", unimplementedFunc),
/* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
/* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
/* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
/* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
/* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
/* 266 */ SyscallDesc("statfs64", unimplementedFunc),
/* 267 */ SyscallDesc("fstatfs64", unimplementedFunc),
/* 268 */ SyscallDesc("tgkill", unimplementedFunc),
/* 269 */ SyscallDesc("utimes", unimplementedFunc),
/* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc),
/* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
/* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc),
/* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc),
/* 274 */ SyscallDesc("mq_open", unimplementedFunc),
/* 275 */ SyscallDesc("mq_unlink", unimplementedFunc),
/* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc),
/* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
/* 278 */ SyscallDesc("mq_notify", unimplementedFunc),
/* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
/* 280 */ SyscallDesc("waitid", unimplementedFunc),
/* 281 */ SyscallDesc("socket", unimplementedFunc),
/* 282 */ SyscallDesc("bind", unimplementedFunc),
/* 283 */ SyscallDesc("connect", unimplementedFunc),
/* 284 */ SyscallDesc("listen", unimplementedFunc),
/* 285 */ SyscallDesc("accept", unimplementedFunc),
/* 286 */ SyscallDesc("getsockname", unimplementedFunc),
/* 287 */ SyscallDesc("getpeername", unimplementedFunc),
/* 288 */ SyscallDesc("socketpair", unimplementedFunc),
/* 289 */ SyscallDesc("send", unimplementedFunc),
/* 290 */ SyscallDesc("sendto", unimplementedFunc),
/* 291 */ SyscallDesc("recv", unimplementedFunc),
/* 292 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 293 */ SyscallDesc("shutdown", unimplementedFunc),
/* 294 */ SyscallDesc("setsockopt", unimplementedFunc),
/* 295 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 296 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 297 */ SyscallDesc("rcvmsg", unimplementedFunc),
/* 298 */ SyscallDesc("semop", unimplementedFunc),
/* 299 */ SyscallDesc("semget", unimplementedFunc),
/* 300 */ SyscallDesc("semctl", unimplementedFunc),
/* 301 */ SyscallDesc("msgsend", unimplementedFunc),
/* 302 */ SyscallDesc("msgrcv", unimplementedFunc),
/* 303 */ SyscallDesc("msgget", unimplementedFunc),
/* 304 */ SyscallDesc("msgctl", unimplementedFunc),
/* 305 */ SyscallDesc("shmat", unimplementedFunc),
/* 306 */ SyscallDesc("shmdt", unimplementedFunc),
/* 307 */ SyscallDesc("shmget", unimplementedFunc),
/* 308 */ SyscallDesc("shmctl", unimplementedFunc),
/* 309 */ SyscallDesc("add_key", unimplementedFunc),
/* 310 */ SyscallDesc("request_key", unimplementedFunc),
/* 311 */ SyscallDesc("keyctl", unimplementedFunc),
/* 312 */ SyscallDesc("semtimedop", unimplementedFunc),
/* 313 */ SyscallDesc("vserver", unimplementedFunc),
/* 314 */ SyscallDesc("ioprio_set", unimplementedFunc),
/* 315 */ SyscallDesc("ioprio_get", unimplementedFunc),
/* 316 */ SyscallDesc("inotify_init", unimplementedFunc),
/* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
/* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
/* 319 */ SyscallDesc("mbind", unimplementedFunc),
/* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc),
/* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc),
/* 322 */ SyscallDesc("openat", unimplementedFunc),
/* 323 */ SyscallDesc("mkdirat", unimplementedFunc),
/* 324 */ SyscallDesc("mknodat", unimplementedFunc),
/* 325 */ SyscallDesc("fchownat", unimplementedFunc),
/* 326 */ SyscallDesc("futimesat", unimplementedFunc),
/* 327 */ SyscallDesc("fstatat64", unimplementedFunc),
/* 328 */ SyscallDesc("unlinkat", unimplementedFunc),
/* 329 */ SyscallDesc("renameat", unimplementedFunc),
/* 330 */ SyscallDesc("linkat", unimplementedFunc),
/* 331 */ SyscallDesc("symlinkat", unimplementedFunc),
/* 332 */ SyscallDesc("readlinkat", unimplementedFunc),
/* 333 */ SyscallDesc("fchmodat", unimplementedFunc),
/* 334 */ SyscallDesc("faccessat", unimplementedFunc),
/* 335 */ SyscallDesc("pselect6", unimplementedFunc),
/* 336 */ SyscallDesc("ppoll", unimplementedFunc),
/* 337 */ SyscallDesc("unshare", unimplementedFunc),
/* 338 */ SyscallDesc("set_robust_list", unimplementedFunc),
/* 339 */ SyscallDesc("get_robust_list", unimplementedFunc),
/* 340 */ SyscallDesc("splice", unimplementedFunc),
/* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc),
/* 342 */ SyscallDesc("tee", unimplementedFunc),
/* 343 */ SyscallDesc("vmsplice", unimplementedFunc),
/* 344 */ SyscallDesc("move_pages", unimplementedFunc),
/* 345 */ SyscallDesc("getcpu", unimplementedFunc),
/* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc),
};
ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
: ArmLiveProcess(params, objFile),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{ }
SyscallDesc*
ArmLinuxProcess::getDesc(int callnum)
{
// Angel SWI syscalls are unsupported in this release
if (callnum == 0x123456)
panic("Attempt to execute an ANGEL_SWI system call (newlib-related)");
else if ((callnum & 0x00f00000) == 0x00900000)
callnum &= 0x000fffff;
// Linux syscalls have to strip off the 0x00900000
if (callnum < 0 || callnum > Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARM_LINUX_PROCESS_HH__
#define __ARM_LINUX_PROCESS_HH__
#include "arch/arm/process.hh"
/// A process with emulated Arm/Linux syscalls.
class ArmLinuxProcess : public ArmLiveProcess
{
public:
ArmLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
virtual SyscallDesc* getDesc(int callnum);
/// The target system's hostname.
static const char *hostname;
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
const int Num_Syscall_Descs;
};
#endif // __ARM_LINUX_PROCESS_HH__

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006 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
* 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: Steve Reinhardt
* Stephen Hines
*/
#ifndef __ARCH_ARM_LOCKED_MEM_HH__
#define __ARCH_ARM_LOCKED_MEM_HH__
/**
* @file
*
* ISA-specific helper functions for locked memory accesses.
*/
#include "mem/request.hh"
namespace ArmISA
{
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
}
template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
return true;
}
} // namespace ArmISA
#endif

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006 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
* 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
* Stephen Hines
*/
#ifndef __ARCH_ARM_MMAPED_IPR_HH__
#define __ARCH_ARM_MMAPED_IPR_HH__
/**
* @file
*
* ISA-specific helper functions for memory mapped IPR accesses.
*/
#include "base/misc.hh"
#include "mem/packet.hh"
class ThreadContext;
namespace ArmISA
{
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
panic("No implementation for handleIprRead in ARM\n");
}
inline Tick
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
panic("No implementation for handleIprWrite in ARM\n");
}
} // namespace ArmISA
#endif

78
src/arch/arm/pagetable.cc Normal file
View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2007 MIPS Technologies, Inc.
* Copyright (c) 2007-2008 The Florida State University
* 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
* Steve Reinhardt
* Jaidev Patwardhan
* Stephen Hines
*/
#include "arch/arm/pagetable.hh"
#include "sim/serialize.hh"
namespace ArmISA
{
void
PTE::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(Mask);
SERIALIZE_SCALAR(VPN);
SERIALIZE_SCALAR(asid);
SERIALIZE_SCALAR(G);
SERIALIZE_SCALAR(PFN0);
SERIALIZE_SCALAR(D0);
SERIALIZE_SCALAR(V0);
SERIALIZE_SCALAR(C0);
SERIALIZE_SCALAR(PFN1);
SERIALIZE_SCALAR(D1);
SERIALIZE_SCALAR(V1);
SERIALIZE_SCALAR(C1);
SERIALIZE_SCALAR(AddrShiftAmount);
SERIALIZE_SCALAR(OffsetMask);
}
void
PTE::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(Mask);
UNSERIALIZE_SCALAR(VPN);
UNSERIALIZE_SCALAR(asid);
UNSERIALIZE_SCALAR(G);
UNSERIALIZE_SCALAR(PFN0);
UNSERIALIZE_SCALAR(D0);
UNSERIALIZE_SCALAR(V0);
UNSERIALIZE_SCALAR(C0);
UNSERIALIZE_SCALAR(PFN1);
UNSERIALIZE_SCALAR(D1);
UNSERIALIZE_SCALAR(V1);
UNSERIALIZE_SCALAR(C1);
UNSERIALIZE_SCALAR(AddrShiftAmount);
UNSERIALIZE_SCALAR(OffsetMask);
}
}

102
src/arch/arm/pagetable.hh Normal file
View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2007 MIPS Technologies, Inc.
* Copyright (c) 2007-2008 The Florida State University
* 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
* Steve Reinhardt
* Jaidev Patwardhan
* Stephen Hines
*/
#ifndef __ARCH_ARM_PAGETABLE_H__
#define __ARCH_ARM_PAGETABLE_H__
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include "arch/arm/vtophys.hh"
#include "config/full_system.hh"
namespace ArmISA {
struct VAddr
{
static const int ImplBits = 43;
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
static const Addr UnImplMask = ~ImplMask;
VAddr(Addr a) : addr(a) {}
Addr addr;
operator Addr() const { return addr; }
const VAddr &operator=(Addr a) { addr = a; return *this; }
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
Addr page() const { return addr & Page_Mask; }
Addr offset() const { return addr & PageOffset; }
Addr level3() const
{ return ArmISA::PteAddr(addr >> PageShift); }
Addr level2() const
{ return ArmISA::PteAddr(addr >> (NPtePageShift + PageShift)); }
Addr level1() const
{ return ArmISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
};
// ITB/DTB page table entry
struct PTE
{
Addr Mask; // What parts of the VAddr (from bits 28..11) should be used in translation (includes Mask and MaskX from PageMask)
Addr VPN; // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11 from EntryHi)
uint8_t asid; // Address Space ID (8 bits) // Lower 8 bits of EntryHi
bool G; // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit
/* Contents of Entry Lo0 */
Addr PFN0; // Physical Frame Number - Even
bool D0; // Even entry Dirty Bit
bool V0; // Even entry Valid Bit
uint8_t C0; // Cache Coherency Bits - Even
/* Contents of Entry Lo1 */
Addr PFN1; // Physical Frame Number - Odd
bool D1; // Odd entry Dirty Bit
bool V1; // Odd entry Valid Bit
uint8_t C1; // Cache Coherency Bits (3 bits)
/* The next few variables are put in as optimizations to reduce TLB lookup overheads */
/* For a given Mask, what is the address shift amount, and what is the OffsetMask */
int AddrShiftAmount;
int OffsetMask;
bool Valid() { return (V0 | V1);};
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
};
#endif // __ARCH_ARM_PAGETABLE_H__

103
src/arch/arm/predecoder.hh Normal file
View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2006 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
* 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
* Stephen Hines
*/
#ifndef __ARCH_ARM_PREDECODER_HH__
#define __ARCH_ARM_PREDECODER_HH__
#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "sim/host.hh"
class ThreadContext;
namespace ArmISA
{
class Predecoder
{
protected:
ThreadContext * tc;
//The extended machine instruction being generated
ExtMachInst emi;
public:
Predecoder(ThreadContext * _tc) : tc(_tc)
{}
ThreadContext * getTC()
{
return tc;
}
void setTC(ThreadContext * _tc)
{
tc = _tc;
}
void process()
{}
void reset()
{}
//Use this to give data to the predecoder. This should be used
//when there is control flow.
void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
{
emi = inst;
}
//Use this to give data to the predecoder. This should be used
//when instructions are executed in order.
void moreBytes(MachInst machInst)
{
moreBytes(0, 0, machInst);
}
bool needMoreBytes()
{
return true;
}
bool extMachInstReady()
{
return true;
}
//This returns a constant reference to the ExtMachInst to avoid a copy
const ExtMachInst & getExtMachInst()
{
return emi;
}
};
};
#endif // __ARCH_ARM_PREDECODER_HH__

158
src/arch/arm/process.cc Normal file
View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#include "arch/arm/isa_traits.hh"
#include "arch/arm/process.hh"
#include "arch/arm/types.hh"
#include "base/loader/elf_object.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
using namespace std;
using namespace ArmISA;
ArmLiveProcess::ArmLiveProcess(LiveProcessParams * params,
ObjectFile *objFile)
: LiveProcess(params, objFile)
{
stack_base = 0xc0000000L;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
// Set up break point (Top of Heap)
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
// Set up region for mmaps. For now, start at bottom of kuseg space.
mmap_start = mmap_end = 0x70000000L;
}
void
ArmLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
}
void
ArmLiveProcess::copyStringArray32(std::vector<std::string> &strings,
Addr array_ptr, Addr data_ptr,
TranslatingPort* memPort)
{
Addr data_ptr_swap;
for (int i = 0; i < strings.size(); ++i) {
data_ptr_swap = htog(data_ptr);
memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
sizeof(uint32_t));
memPort->writeString(data_ptr, strings[i].c_str());
array_ptr += sizeof(uint32_t);
data_ptr += strings[i].size() + 1;
}
// add NULL terminator
data_ptr = 0;
memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(uint32_t));
}
void
ArmLiveProcess::argsInit(int intSize, int pageSize)
{
// Overloaded argsInit so that we can fine-tune for ARM architecture
Process::startup();
// load object file into target memory
objFile->loadSections(initVirtMem);
// Calculate how much space we need for arg & env arrays.
int argv_array_size = intSize * (argv.size() + 1);
int envp_array_size = intSize * (envp.size() + 1);
int arg_data_size = 0;
for (int i = 0; i < argv.size(); ++i) {
arg_data_size += argv[i].size() + 1;
}
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
}
int space_needed =
argv_array_size + envp_array_size + arg_data_size + env_data_size;
if (space_needed < 16*1024)
space_needed = 16*1024;
// set bottom of stack
stack_min = stack_base - space_needed;
// align it
stack_min = roundDown(stack_min, pageSize);
stack_size = stack_base - stack_min;
// map memory
pTable->allocate(stack_min, roundUp(stack_size, pageSize));
// map out initial stack contents
Addr argv_array_base = stack_min + intSize; // room for argc
Addr envp_array_base = argv_array_base + argv_array_size;
Addr arg_data_base = envp_array_base + envp_array_size;
Addr env_data_base = arg_data_base + arg_data_size;
// write contents to stack
uint64_t argc = argv.size();
if (intSize == 8)
argc = htog((uint64_t)argc);
else if (intSize == 4)
argc = htog((uint32_t)argc);
else
panic("Unknown int size");
initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
copyStringArray32(argv, argv_array_base, arg_data_base, initVirtMem);
copyStringArray32(envp, envp_array_base, env_data_base, initVirtMem);
/*
//uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e};
uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1};
initVirtMem->writeBlob(0xffff0fe0, insns, 8);
*/
threadContexts[0]->setIntReg(ArgumentReg1, argc);
threadContexts[0]->setIntReg(ArgumentReg2, argv_array_base);
threadContexts[0]->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
threadContexts[0]->setPC(prog_entry);
threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
}

59
src/arch/arm/process.hh Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARM_PROCESS_HH__
#define __ARM_PROCESS_HH__
#include <string>
#include <vector>
#include "sim/process.hh"
class LiveProcess;
class ObjectFile;
class System;
class ArmLiveProcess : public LiveProcess
{
protected:
ArmLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
void startup();
void copyStringArray32(std::vector<std::string> &strings,
Addr array_ptr, Addr data_ptr,
TranslatingPort* memPort);
public:
void argsInit(int intSize, int pageSize);
};
#endif // __ARM_PROCESS_HH__

36
src/arch/arm/regfile.hh Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_REGFILE_HH__
#define __ARCH_ARM_REGFILE_HH__
#include "arch/arm/regfile/regfile.hh"
#endif

View file

@ -0,0 +1,181 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__
#define __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__
#include "arch/arm/types.hh"
#include "arch/arm/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
#include "sim/faults.hh"
#include "sim/serialize.hh"
#include <string>
class Checkpoint;
namespace ArmISA
{
static inline std::string getFloatRegName(RegIndex)
{
return "";
}
const uint32_t ARM32_QNAN = 0x7fbfffff;
const uint64_t ARM64_QNAN = ULL(0x7fbfffffffffffff);
enum FPControlRegNums {
FIR = NumFloatArchRegs,
FCCR,
FEXR,
FENR,
FCSR
};
enum FCSRBits {
Inexact = 1,
Underflow,
Overflow,
DivideByZero,
Invalid,
Unimplemented
};
enum FCSRFields {
Flag_Field = 1,
Enable_Field = 6,
Cause_Field = 11
};
const int SingleWidth = 32;
const int SingleBytes = SingleWidth / 4;
const int DoubleWidth = 64;
const int DoubleBytes = DoubleWidth / 4;
const int QuadWidth = 128;
const int QuadBytes = QuadWidth / 4;
class FloatRegFile
{
protected:
union {
FloatRegBits qregs[NumFloatRegs];
FloatRegVal regs[NumFloatRegs];
};
public:
void clear()
{
bzero(regs, sizeof(regs));
regs[8] = 0.0;
regs[9] = 1.0;
regs[10] = 2.0;
regs[11] = 3.0;
regs[12] = 4.0;
regs[13] = 5.0;
regs[14] = 0.5;
regs[15] = 10.0;
}
FloatRegVal readReg(int floatReg, int width)
{
return regs[floatReg];
}
FloatRegBits readRegBits(int floatReg, int width)
{
//return qregs[floatReg];
switch(width)
{
case SingleWidth:
{
union {
float f;
uint32_t i;
} s;
s.f = (float) regs[floatReg];
return s.i;
}
case DoubleWidth:
{
uint64_t tmp = (qregs[floatReg]<<32|qregs[floatReg]>>32);
return tmp;
}
default:
panic("Attempted to read a %d bit floating point "
"register!", width);
}
}
Fault setReg(int floatReg, const FloatRegVal &val, int width)
{
if (floatReg > 7)
panic("Writing to a hard-wired FP register");
regs[floatReg] = val;
return NoFault;
}
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
{
if (floatReg > 7)
panic("Writing to a hard-wired FP register");
switch(width)
{
case DoubleWidth:
{
uint64_t tmp = (val << 32 | val >> 32);
qregs[floatReg] = tmp;
return NoFault;
}
case SingleWidth:
default:
panic("Attempted to write a %d bit floating point "
"register!", width);
}
}
void serialize(std::ostream &os)
{
SERIALIZE_ARRAY(regs, NumFloatRegs);
}
void unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(regs, NumFloatRegs);
}
};
} // namespace ArmISA
#endif

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_REGFILE_INT_REGFILE_HH__
#define __ARCH_ARM_REGFILE_INT_REGFILE_HH__
#include "arch/arm/isa_traits.hh"
#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
#include "sim/serialize.hh"
class Checkpoint;
class ThreadContext;
namespace ArmISA
{
static inline std::string getIntRegName(RegIndex)
{
return "";
}
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
};
class IntRegFile
{
protected:
IntReg regs[NumIntRegs];
public:
IntReg readReg(int intReg)
{
return regs[intReg];
}
void clear()
{
bzero(regs, sizeof(regs));
}
Fault setReg(int intReg, const IntReg &val)
{
regs[intReg] = val;
return NoFault;
}
void serialize(std::ostream &os)
{
SERIALIZE_ARRAY(regs, NumIntRegs);
}
void unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(regs, NumIntRegs);
}
};
} // namespace ArmISA
#endif

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_REGFILE_MISC_REGFILE_HH__
#define __ARCH_ARM_REGFILE_MISC_REGFILE_HH__
#include "arch/arm/types.hh"
#include "sim/faults.hh"
class ThreadContext;
namespace ArmISA
{
static inline std::string getMiscRegName(RegIndex)
{
return "";
}
//Coprocessor 0 Register Names
enum MiscRegTags {
// Status Registers for the ARM
//
// CPSR Layout
// 31302928 ... 7 6 5 4 3 2 1 0
// N Z C V ... I F T { MODE }
CPSR = 0,
SPSR_FIQ,
SPSR_IRQ,
SPSR_SVC,
SPSR_UND,
SPSR_ABT,
FPSR
};
class MiscRegFile {
protected:
MiscReg miscRegFile[NumMiscRegs];
public:
void clear()
{
// Unknown startup state in misc register file currently
}
void copyMiscRegs(ThreadContext *tc);
MiscReg readRegNoEffect(int misc_reg)
{
return miscRegFile[misc_reg];
}
MiscReg readReg(int misc_reg, ThreadContext *tc)
{
return miscRegFile[misc_reg];
}
void setRegNoEffect(int misc_reg, const MiscReg &val)
{
miscRegFile[misc_reg] = val;
}
void setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc)
{
miscRegFile[misc_reg] = val;
}
friend class RegFile;
};
} // namespace ArmISA
#endif

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#include "arch/arm/regfile/regfile.hh"
#include "sim/serialize.hh"
using namespace std;
namespace ArmISA
{
void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
panic("Copy Regs Not Implemented Yet\n");
}
void
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
panic("Copy Misc. Regs Not Implemented Yet\n");
}
void
MiscRegFile::copyMiscRegs(ThreadContext *tc)
{
panic("Copy Misc. Regs Not Implemented Yet\n");
}
void
RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
//SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
//SERIALZE_ARRAY(miscRegFile);
//SERIALIZE_SCALAR(miscRegs.fpcr);
//SERIALIZE_SCALAR(miscRegs.lock_flag);
//SERIALIZE_SCALAR(miscRegs.lock_addr);
//SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
SERIALIZE_SCALAR(nnpc);
}
void
RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
intRegFile.unserialize(cp, section);
//UNSERIALIZE_ARRAY(floatRegFile);
//UNSERIALZE_ARRAY(miscRegFile);
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
//UNSERIALIZE_SCALAR(miscRegs.lock_addr);
//UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
UNSERIALIZE_SCALAR(nnpc);
}
} // namespace ArmISA

View file

@ -0,0 +1,203 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_REGFILE_REGFILE_HH__
#define __ARCH_ARM_REGFILE_REGFILE_HH__
#include "arch/arm/types.hh"
#include "arch/arm/regfile/int_regfile.hh"
#include "arch/arm/regfile/float_regfile.hh"
#include "arch/arm/regfile/misc_regfile.hh"
#include "sim/faults.hh"
class Checkpoint;
class ThreadContext;
namespace ArmISA
{
class RegFile {
protected:
IntRegFile intRegFile; // (signed) integer register file
FloatRegFile floatRegFile; // floating point register file
MiscRegFile miscRegFile; // control register file
public:
void clear()
{
intRegFile.clear();
floatRegFile.clear();
miscRegFile.clear();
}
MiscReg readMiscRegNoEffect(int miscReg)
{
return miscRegFile.readRegNoEffect(miscReg);
}
MiscReg readMiscReg(int miscReg, ThreadContext *tc)
{
return miscRegFile.readReg(miscReg, tc);
}
void setMiscRegNoEffect(int miscReg, const MiscReg &val)
{
miscRegFile.setRegNoEffect(miscReg, val);
}
void setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
miscRegFile.setReg(miscReg, val, tc);
}
FloatRegVal readFloatReg(int floatReg)
{
return floatRegFile.readReg(floatReg,SingleWidth);
}
FloatRegVal readFloatReg(int floatReg, int width)
{
return floatRegFile.readReg(floatReg,width);
}
FloatRegBits readFloatRegBits(int floatReg)
{
return floatRegFile.readRegBits(floatReg,SingleWidth);
}
FloatRegBits readFloatRegBits(int floatReg, int width)
{
return floatRegFile.readRegBits(floatReg,width);
}
void setFloatReg(int floatReg, const FloatRegVal &val)
{
floatRegFile.setReg(floatReg, val, SingleWidth);
}
void setFloatReg(int floatReg, const FloatRegVal &val, int width)
{
floatRegFile.setReg(floatReg, val, width);
}
void setFloatRegBits(int floatReg, const FloatRegBits &val)
{
floatRegFile.setRegBits(floatReg, val, SingleWidth);
}
void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
floatRegFile.setRegBits(floatReg, val, width);
}
IntReg readIntReg(int intReg)
{
// In the Arm, reading from the PC for a generic instruction yields
// the current PC + 8, due to previous pipeline implementations
if (intReg == PCReg)
return intRegFile.readReg(intReg) + 8;
//return pc + 8;
else
return intRegFile.readReg(intReg);
}
void setIntReg(int intReg, const IntReg &val)
{
// Have to trap writes to PC so that they update NPC instead
if (intReg == PCReg)
setNextPC(val);
else
intRegFile.setReg(intReg, val);
}
protected:
Addr pc; // program counter
Addr npc; // next-cycle program counter
Addr nnpc; // next-next-cycle program counter
public:
Addr readPC()
{
return intRegFile.readReg(PCReg);
//return pc;
}
void setPC(Addr val)
{
intRegFile.setReg(PCReg, val);
//pc = val;
}
Addr readNextPC()
{
return npc;
}
void setNextPC(Addr val)
{
npc = val;
}
Addr readNextNPC()
{
return npc + sizeof(MachInst);
}
void setNextNPC(Addr val)
{
//nnpc = val;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
void changeContext(RegContextParam param, RegContextVal val)
{
}
};
static inline int flattenIntIndex(ThreadContext * tc, int reg)
{
return reg;
}
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
{
return reg;
}
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
} // namespace ArmISA
#endif

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2002-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
* 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
* Stephen Hines
*/
#ifndef __ARCH_ARM_REMOTE_GDB_HH__
#define __ARCH_ARM_REMOTE_GDB_HH__
#include "base/remote_gdb.hh"
namespace ArmISA
{
class RemoteGDB : public BaseRemoteGDB
{
public:
//These needs to be written to suit ARM
RemoteGDB(System *system, ThreadContext *context)
: BaseRemoteGDB(system, context, 1)
{}
bool acc(Addr, size_t)
{ panic("acc not implemented for ARM!"); }
void getregs()
{ panic("getregs not implemented for ARM!"); }
void setregs()
{ panic("setregs not implemented for ARM!"); }
void clearSingleStep()
{ panic("clearSingleStep not implemented for ARM!"); }
void setSingleStep()
{ panic("setSingleStep not implemented for ARM!"); }
};
}
#endif /* __ARCH_ARM_REMOTE_GDB_H__ */

128
src/arch/arm/stacktrace.hh Normal file
View file

@ -0,0 +1,128 @@
/*
* 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
* 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
* Stephen Hines
*/
#ifndef __ARCH_ARM_STACKTRACE_HH__
#define __ARCH_ARM_STACKTRACE_HH__
#include "base/trace.hh"
#include "cpu/static_inst.hh"
class ThreadContext;
class StackTrace;
namespace ArmISA
{
class ProcessInfo
{
private:
ThreadContext *tc;
int thread_info_size;
int task_struct_size;
int task_off;
int pid_off;
int name_off;
public:
ProcessInfo(ThreadContext *_tc);
Addr task(Addr ksp) const;
int pid(Addr ksp) const;
std::string name(Addr ksp) const;
};
class StackTrace
{
protected:
typedef TheISA::MachInst MachInst;
private:
ThreadContext *tc;
std::vector<Addr> stack;
private:
bool isEntry(Addr addr);
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
bool decodeSave(MachInst inst, int &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void clear()
{
tc = 0;
stack.clear();
}
bool valid() const { return tc != NULL; }
bool trace(ThreadContext *tc, StaticInstPtr inst);
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();
public:
void dprintf() { if (DTRACE(Stack)) dump(); }
#else
public:
void dprintf() {}
#endif
};
inline bool
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
{
if (!inst->isCall() && !inst->isReturn())
return false;
if (valid())
clear();
trace(tc, !inst->isReturn());
return true;
}
}
#endif // __ARCH_ARM_STACKTRACE_HH__

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2003-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
* 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
* Korey Sewell
* Stephen Hines
*/
#ifndef __ARCH_ARM_SYSCALLRETURN_HH__
#define __ARCH_ARM_SYSCALLRETURN_HH__
#include "sim/syscallreturn.hh"
#include "cpu/thread_context.hh"
namespace ArmISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
ThreadContext *tc)
{
if (return_value.successful()) {
// no error
//regs->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
//regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
tc->setIntReg(ReturnValueReg, return_value.value());
}
}
}
#endif

364
src/arch/arm/tlb.cc Normal file
View file

@ -0,0 +1,364 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* Copyright (c) 2007 MIPS Technologies, Inc.
* Copyright (c) 2007-2008 The Florida State University
* 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
* Steve Reinhardt
* Stephen Hines
*/
#include <string>
#include <vector>
#include "arch/arm/pagetable.hh"
#include "arch/arm/tlb.hh"
#include "arch/arm/faults.hh"
#include "arch/arm/utility.hh"
#include "base/inifile.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "sim/process.hh"
#include "mem/page_table.hh"
#include "params/ArmDTB.hh"
#include "params/ArmITB.hh"
#include "params/ArmTLB.hh"
#include "params/ArmUTB.hh"
using namespace std;
using namespace ArmISA;
///////////////////////////////////////////////////////////////////////
//
// ARM TLB
//
#define MODE2MASK(X) (1 << (X))
TLB::TLB(const Params *p)
: BaseTLB(p), size(p->size), nlu(0)
{
table = new ArmISA::PTE[size];
memset(table, 0, sizeof(ArmISA::PTE[size]));
smallPages=0;
}
TLB::~TLB()
{
if (table)
delete [] table;
}
// look up an entry in the TLB
ArmISA::PTE *
TLB::lookup(Addr vpn, uint8_t asn) const
{
// assume not found...
ArmISA::PTE *retval = NULL;
PageTable::const_iterator i = lookupTable.find(vpn);
if (i != lookupTable.end()) {
while (i->first == vpn) {
int index = i->second;
ArmISA::PTE *pte = &table[index];
/* 1KB TLB Lookup code - from ARM ARM Volume III - Rev. 2.50 */
Addr Mask = pte->Mask;
Addr InvMask = ~Mask;
Addr VPN = pte->VPN;
// warn("Valid: %d - %d\n",pte->V0,pte->V1);
if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid)))
{ // We have a VPN + ASID Match
retval = pte;
break;
}
++i;
}
}
DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
return retval;
}
ArmISA::PTE* TLB::getEntry(unsigned Index) const
{
// Make sure that Index is valid
assert(Index<size);
return &table[Index];
}
int TLB::probeEntry(Addr vpn,uint8_t asn) const
{
// assume not found...
ArmISA::PTE *retval = NULL;
int Ind=-1;
PageTable::const_iterator i = lookupTable.find(vpn);
if (i != lookupTable.end()) {
while (i->first == vpn) {
int index = i->second;
ArmISA::PTE *pte = &table[index];
/* 1KB TLB Lookup code - from ARM ARM Volume III - Rev. 2.50 */
Addr Mask = pte->Mask;
Addr InvMask = ~Mask;
Addr VPN = pte->VPN;
if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid)))
{ // We have a VPN + ASID Match
retval = pte;
Ind = index;
break;
}
++i;
}
}
DPRINTF(Arm,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
return Ind;
}
Fault inline
TLB::checkCacheability(RequestPtr &req)
{
Addr VAddrUncacheable = 0xA0000000;
// In ARM, cacheability is controlled by certain bits of the virtual address
// or by the TLB entry
if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
// mark request as uncacheable
req->setFlags(req->getFlags() | UNCACHEABLE);
}
return NoFault;
}
void TLB::insertAt(ArmISA::PTE &pte, unsigned Index, int _smallPages)
{
smallPages=_smallPages;
if(Index > size){
warn("Attempted to write at index (%d) beyond TLB size (%d)",Index,size);
} else {
// Update TLB
DPRINTF(TLB,"TLB[%d]: %x %x %x %x\n",Index,pte.Mask<<11,((pte.VPN << 11) | pte.asid),((pte.PFN0 <<6) | (pte.C0 << 3) | (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
((pte.PFN1 <<6) | (pte.C1 << 3) | (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
if(table[Index].V0 == true || table[Index].V1 == true){ // Previous entry is valid
PageTable::iterator i = lookupTable.find(table[Index].VPN);
lookupTable.erase(i);
}
table[Index]=pte;
// Update fast lookup table
lookupTable.insert(make_pair(table[Index].VPN, Index));
// int TestIndex=probeEntry(pte.VPN,pte.asid);
// warn("Inserted at: %d, Found at: %d (%x)\n",Index,TestIndex,pte.Mask);
}
}
// insert a new TLB entry
void
TLB::insert(Addr addr, ArmISA::PTE &pte)
{
fatal("TLB Insert not yet implemented\n");
}
void
TLB::flushAll()
{
DPRINTF(TLB, "flushAll\n");
memset(table, 0, sizeof(ArmISA::PTE[size]));
lookupTable.clear();
nlu = 0;
}
void
TLB::serialize(ostream &os)
{
SERIALIZE_SCALAR(size);
SERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
nameOut(os, csprintf("%s.PTE%d", name(), i));
table[i].serialize(os);
}
}
void
TLB::unserialize(Checkpoint *cp, const string &section)
{
UNSERIALIZE_SCALAR(size);
UNSERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
if (table[i].V0 || table[i].V1) {
lookupTable.insert(make_pair(table[i].VPN, i));
}
}
}
void
TLB::regStats()
{
read_hits
.name(name() + ".read_hits")
.desc("DTB read hits")
;
read_misses
.name(name() + ".read_misses")
.desc("DTB read misses")
;
read_accesses
.name(name() + ".read_accesses")
.desc("DTB read accesses")
;
write_hits
.name(name() + ".write_hits")
.desc("DTB write hits")
;
write_misses
.name(name() + ".write_misses")
.desc("DTB write misses")
;
write_accesses
.name(name() + ".write_accesses")
.desc("DTB write accesses")
;
hits
.name(name() + ".hits")
.desc("DTB hits")
;
misses
.name(name() + ".misses")
.desc("DTB misses")
;
invalids
.name(name() + ".invalids")
.desc("DTB access violations")
;
accesses
.name(name() + ".accesses")
.desc("DTB accesses")
;
hits = read_hits + write_hits;
misses = read_misses + write_misses;
accesses = read_accesses + write_accesses;
}
Fault
ITB::translate(RequestPtr &req, ThreadContext *tc)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
Fault fault = p->pTable->translate(req);
if(fault != NoFault)
return fault;
return NoFault;
#else
fatal("ITB translate not yet implemented\n");
#endif
}
Fault
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
Fault fault = p->pTable->translate(req);
if(fault != NoFault)
return fault;
return NoFault;
#else
fatal("DTB translate not yet implemented\n");
#endif
}
///////////////////////////////////////////////////////////////////////
//
// Arm ITB
//
ITB::ITB(const Params *p)
: TLB(p)
{}
///////////////////////////////////////////////////////////////////////
//
// Arm DTB
//
DTB::DTB(const Params *p)
: TLB(p)
{}
///////////////////////////////////////////////////////////////////////
//
// Arm UTB
//
UTB::UTB(const Params *p)
: ITB(p), DTB(p)
{}
ArmISA::PTE &
TLB::index(bool advance)
{
ArmISA::PTE *pte = &table[nlu];
if (advance)
nextnlu();
return *pte;
}
ArmISA::ITB *
ArmITBParams::create()
{
return new ArmISA::ITB(this);
}
ArmISA::DTB *
ArmDTBParams::create()
{
return new ArmISA::DTB(this);
}
ArmISA::UTB *
ArmUTBParams::create()
{
return new ArmISA::UTB(this);
}

164
src/arch/arm/tlb.hh Normal file
View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* Copyright (c) 2007 MIPS Technologies, Inc.
* Copyright (c) 2007-2008 The Florida State University
* 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
* Steve Reinhardt
* Stephen Hines
*/
#ifndef __ARCH_ARM_TLB_HH__
#define __ARCH_ARM_TLB_HH__
#include <map>
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include "arch/arm/vtophys.hh"
#include "arch/arm/pagetable.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
#include "params/ArmDTB.hh"
#include "params/ArmITB.hh"
#include "sim/faults.hh"
#include "sim/tlb.hh"
class ThreadContext;
/* ARM does not distinguish between a DTLB and an ITLB -> unified TLB
However, to maintain compatibility with other architectures, we'll
simply create an ITLB and DTLB that will point to the real TLB */
namespace ArmISA {
// WARN: This particular TLB entry is not necessarily conformed to ARM ISA
struct TlbEntry
{
Addr _pageStart;
TlbEntry() {}
TlbEntry(Addr asn, Addr vaddr, Addr paddr) : _pageStart(paddr) {}
Addr pageStart()
{
return _pageStart;
}
void serialize(std::ostream &os)
{
SERIALIZE_SCALAR(_pageStart);
}
void unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(_pageStart);
}
};
class TLB : public BaseTLB
{
protected:
typedef std::multimap<Addr, int> PageTable;
PageTable lookupTable; // Quick lookup into page table
ArmISA::PTE *table; // the Page Table
int size; // TLB Size
int nlu; // not last used entry (for replacement)
void nextnlu() { if (++nlu >= size) nlu = 0; }
ArmISA::PTE *lookup(Addr vpn, uint8_t asn) const;
mutable Stats::Scalar<> read_hits;
mutable Stats::Scalar<> read_misses;
mutable Stats::Scalar<> read_acv;
mutable Stats::Scalar<> read_accesses;
mutable Stats::Scalar<> write_hits;
mutable Stats::Scalar<> write_misses;
mutable Stats::Scalar<> write_acv;
mutable Stats::Scalar<> write_accesses;
Stats::Formula hits;
Stats::Formula misses;
Stats::Formula invalids;
Stats::Formula accesses;
public:
typedef ArmTLBParams Params;
TLB(const Params *p);
int probeEntry(Addr vpn,uint8_t) const;
ArmISA::PTE *getEntry(unsigned) const;
virtual ~TLB();
int smallPages;
int getsize() const { return size; }
ArmISA::PTE &index(bool advance = true);
void insert(Addr vaddr, ArmISA::PTE &pte);
void insertAt(ArmISA::PTE &pte, unsigned Index, int _smallPages);
void flushAll();
void demapPage(Addr vaddr, uint64_t asn)
{
panic("demapPage unimplemented.\n");
}
// static helper functions... really
static bool validVirtualAddress(Addr vaddr);
static Fault checkCacheability(RequestPtr &req);
// Checkpointing
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
void regStats();
};
class ITB : public TLB {
public:
typedef ArmTLBParams Params;
ITB(const Params *p);
Fault translate(RequestPtr &req, ThreadContext *tc);
};
class DTB : public TLB {
public:
typedef ArmTLBParams Params;
DTB(const Params *p);
Fault translate(RequestPtr &req, ThreadContext *tc, bool write = false);
};
class UTB : public ITB, public DTB {
public:
typedef ArmTLBParams Params;
UTB(const Params *p);
};
}
#endif // __ARCH_ARM_TLB_HH__

114
src/arch/arm/types.hh Normal file
View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_TYPES_HH__
#define __ARCH_ARM_TYPES_HH__
#include "sim/host.hh"
namespace ArmISA
{
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
typedef uint8_t RegIndex;
typedef uint64_t IntReg;
typedef uint64_t LargestRead;
// Need to use 64 bits to make sure that read requests get handled properly
// floating point register file entry type
typedef uint32_t FloatReg32;
typedef uint64_t FloatReg64;
typedef uint64_t FloatRegBits;
typedef double FloatRegVal;
typedef double FloatReg;
// cop-0/cop-1 system control register
typedef uint64_t MiscReg;
typedef union {
IntReg intreg;
FloatReg fpreg;
MiscReg ctrlreg;
} AnyReg;
typedef int RegContextParam;
typedef int RegContextVal;
//used in FP convert & round function
enum ConvertType{
SINGLE_TO_DOUBLE,
SINGLE_TO_WORD,
SINGLE_TO_LONG,
DOUBLE_TO_SINGLE,
DOUBLE_TO_WORD,
DOUBLE_TO_LONG,
LONG_TO_SINGLE,
LONG_TO_DOUBLE,
LONG_TO_WORD,
LONG_TO_PS,
WORD_TO_SINGLE,
WORD_TO_DOUBLE,
WORD_TO_LONG,
WORD_TO_PS,
PL_TO_SINGLE,
PU_TO_SINGLE
};
//used in FP convert & round function
enum RoundMode{
RND_ZERO,
RND_DOWN,
RND_UP,
RND_NEAREST
};
enum OperatingMode {
MODE_USER = 16,
MODE_FIQ = 17,
MODE_IRQ = 18,
MODE_SVC = 19,
MODE_ABORT = 23,
MODE_UNDEFINED = 27,
MODE_SYSTEM = 31
};
struct CoreSpecific {
// Empty for now on the ARM
};
} // namespace ArmISA
#endif

201
src/arch/arm/utility.cc Normal file
View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 2003-2006 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
* 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: Korey Sewell
* Stephen Hines
*/
#include "arch/arm/regfile.hh"
#include "arch/arm/utility.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
using namespace ArmISA;
uint64_t
ArmISA::fpConvert(ConvertType cvt_type, double fp_val)
{
switch (cvt_type)
{
case SINGLE_TO_DOUBLE:
{
double sdouble_val = fp_val;
void *sdouble_ptr = &sdouble_val;
uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
return sdp_bits;
}
case SINGLE_TO_WORD:
{
int32_t sword_val = (int32_t) fp_val;
void *sword_ptr = &sword_val;
uint64_t sword_bits= *(uint32_t *) sword_ptr;
return sword_bits;
}
case WORD_TO_SINGLE:
{
float wfloat_val = fp_val;
void *wfloat_ptr = &wfloat_val;
uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
return wfloat_bits;
}
case WORD_TO_DOUBLE:
{
double wdouble_val = fp_val;
void *wdouble_ptr = &wdouble_val;
uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
return wdp_bits;
}
default:
panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
return 0;
}
}
double
ArmISA::roundFP(double val, int digits)
{
double digit_offset = pow(10.0,digits);
val = val * digit_offset;
val = val + 0.5;
val = floor(val);
val = val / digit_offset;
return val;
}
double
ArmISA::truncFP(double val)
{
int trunc_val = (int) val;
return (double) trunc_val;
}
bool
ArmISA::getCondCode(uint32_t fcsr, int cc_idx)
{
int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
bool cc_val = (fcsr >> shift) & 0x00000001;
return cc_val;
}
uint32_t
ArmISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
{
int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) |
cc_val << cc_idx |
bits(fcsr, cc_idx - 1, 0);
return fcsr;
}
uint32_t
ArmISA::genInvalidVector(uint32_t fcsr_bits)
{
//Set FCSR invalid in "flag" field
int invalid_offset = Invalid + Flag_Field;
fcsr_bits = fcsr_bits | (1 << invalid_offset);
//Set FCSR invalid in "cause" flag
int cause_offset = Invalid + Cause_Field;
fcsr_bits = fcsr_bits | (1 << cause_offset);
return fcsr_bits;
}
bool
ArmISA::isNan(void *val_ptr, int size)
{
switch (size)
{
case 32:
{
uint32_t val_bits = *(uint32_t *) val_ptr;
return (bits(val_bits, 30, 23) == 0xFF);
}
case 64:
{
uint64_t val_bits = *(uint64_t *) val_ptr;
return (bits(val_bits, 62, 52) == 0x7FF);
}
default:
panic("Type unsupported. Size mismatch\n");
}
}
bool
ArmISA::isQnan(void *val_ptr, int size)
{
switch (size)
{
case 32:
{
uint32_t val_bits = *(uint32_t *) val_ptr;
return (bits(val_bits, 30, 22) == 0x1FE);
}
case 64:
{
uint64_t val_bits = *(uint64_t *) val_ptr;
return (bits(val_bits, 62, 51) == 0xFFE);
}
default:
panic("Type unsupported. Size mismatch\n");
}
}
bool
ArmISA::isSnan(void *val_ptr, int size)
{
switch (size)
{
case 32:
{
uint32_t val_bits = *(uint32_t *) val_ptr;
return (bits(val_bits, 30, 22) == 0x1FF);
}
case 64:
{
uint64_t val_bits = *(uint64_t *) val_ptr;
return (bits(val_bits, 62, 51) == 0xFFF);
}
default:
panic("Type unsupported. Size mismatch\n");
}
}

92
src/arch/arm/utility.hh Normal file
View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2003-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
* 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: Korey Sewell
* Stephen Hines
*/
#ifndef __ARCH_ARM_UTILITY_HH__
#define __ARCH_ARM_UTILITY_HH__
#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "sim/host.hh"
class ThreadContext;
namespace ArmISA {
//Floating Point Utility Functions
uint64_t fpConvert(ConvertType cvt_type, double fp_val);
double roundFP(double val, int digits);
double truncFP(double val);
bool getCondCode(uint32_t fcsr, int cc);
uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val);
uint32_t genInvalidVector(uint32_t fcsr);
bool isNan(void *val_ptr, int size);
bool isQnan(void *val_ptr, int size);
bool isSnan(void *val_ptr, int size);
/**
* Function to insure ISA semantics about 0 registers.
* @param tc The thread context.
*/
template <class TC>
void zeroRegisters(TC *tc);
// Instruction address compression hooks
static inline Addr realPCToFetchPC(const Addr &addr) {
return addr;
}
static inline Addr fetchPCToRealPC(const Addr &addr) {
return addr;
}
// the size of "fetched" instructions
static inline size_t fetchInstSize() {
return sizeof(MachInst);
}
static inline MachInst makeRegisterCopy(int dest, int src) {
panic("makeRegisterCopy not implemented");
return 0;
}
inline void startupCPU(ThreadContext *tc, int cpuId)
{
tc->activate(0);
}
};
#endif

66
src/arch/arm/vtophys.cc Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2002-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
* 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
* Nathan Binkert
* Stephen Hines
*/
#include <string>
#include "arch/arm/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
using namespace std;
using namespace ArmISA;
Addr
ArmISA::vtophys(Addr vaddr)
{
Addr paddr = 0;
if (ArmISA::IsUSeg(vaddr))
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
else if (ArmISA::IsKSeg0(vaddr))
paddr = ArmISA::KSeg02Phys(vaddr);
else
panic("vtophys: ptbr is not set on virtual lookup for vaddr %#x", vaddr);
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
return paddr;
}
Addr
ArmISA::vtophys(ThreadContext *tc, Addr addr)
{
fatal("VTOPHYS: Unimplemented on ARM\n");
}

59
src/arch/arm/vtophys.hh Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2002-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
* 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
* Nathan Binkert
* Stephen Hines
*/
#ifndef __ARCH_ARM_VTOPHYS_H__
#define __ARCH_ARM_VTOPHYS_H__
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
class ThreadContext;
class FunctionalPort;
namespace ArmISA {
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
// User Virtual
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
inline bool IsKSeg0(Addr a) { return KSeg0Base <= a && a <= KSeg0End; }
inline Addr KSeg02Phys(Addr addr) { return addr & KSeg0Mask; }
Addr vtophys(Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
};
#endif // __ARCH_ARM_VTOPHYS_H__