summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/arch/isa_parser.py26
-rwxr-xr-xsrc/arch/mips/bare_iron/system.cc12
-rwxr-xr-xsrc/arch/mips/bare_iron/system.hh11
-rwxr-xr-xsrc/arch/mips/dt_constants.hh269
-rw-r--r--src/arch/mips/faults.cc546
-rw-r--r--src/arch/mips/faults.hh34
-rw-r--r--src/arch/mips/idle_event.cc5
-rwxr-xr-xsrc/arch/mips/interrupts.cc229
-rwxr-xr-xsrc/arch/mips/interrupts.hh114
-rw-r--r--src/arch/mips/isa.cc341
-rw-r--r--src/arch/mips/isa/decoder.isa528
-rw-r--r--src/arch/mips/isa/formats/mt.isa27
-rw-r--r--src/arch/mips/isa/operands.isa39
-rw-r--r--src/arch/mips/isa_traits.hh242
-rw-r--r--src/arch/mips/kernel_stats.hh5
-rw-r--r--src/arch/mips/linux/linux.cc4
-rw-r--r--src/arch/mips/linux/linux.hh14
-rw-r--r--src/arch/mips/linux/process.cc48
-rw-r--r--src/arch/mips/linux/system.cc7
-rw-r--r--src/arch/mips/locked_mem.hh15
-rwxr-xr-xsrc/arch/mips/mips_core_specific.cc65
-rw-r--r--src/arch/mips/mmaped_ipr.hh2
-rwxr-xr-xsrc/arch/mips/mt.hh185
-rwxr-xr-xsrc/arch/mips/mt_constants.hh140
-rw-r--r--src/arch/mips/pagetable.cc72
-rwxr-xr-xsrc/arch/mips/pagetable.hh91
-rwxr-xr-xsrc/arch/mips/pra_constants.hh741
-rw-r--r--src/arch/mips/predecoder.hh109
-rw-r--r--src/arch/mips/stacktrace.cc120
-rwxr-xr-xsrc/arch/mips/system.cc87
-rwxr-xr-xsrc/arch/mips/system.hh9
-rw-r--r--src/arch/mips/tlb.cc507
-rw-r--r--src/arch/mips/types.hh79
-rw-r--r--src/arch/mips/utility.cc9
-rw-r--r--src/arch/mips/utility.hh159
-rwxr-xr-xsrc/arch/mips/vtophys.cc4
-rwxr-xr-xsrc/dev/mips/Malta.py6
-rwxr-xr-xsrc/dev/mips/SConscript1
-rwxr-xr-xsrc/dev/mips/backdoor.cc2
-rwxr-xr-xsrc/dev/mips/malta.cc25
-rwxr-xr-xsrc/dev/mips/malta.hh24
-rwxr-xr-xsrc/dev/mips/malta_io.cc564
-rwxr-xr-xsrc/dev/mips/malta_io.hh248
43 files changed, 2124 insertions, 3641 deletions
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 6f002c05b..d5b5bbe4f 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -1431,32 +1431,6 @@ class ControlRegOperand(Operand):
self.base_name
return wb
-class ControlBitfieldOperand(ControlRegOperand):
- def makeRead(self):
- bit_select = 0
- if (self.ctype == 'float' or self.ctype == 'double'):
- error(0, 'Attempt to read control register as FP')
- if self.read_code != None:
- return self.buildReadCode('readMiscReg')
- base = 'xc->readMiscReg(%s)' % self.reg_spec
- name = self.base_name
- return '%s = bits(%s, %s_HI, %s_LO);' % \
- (name, base, name, name)
-
- def makeWrite(self):
- if (self.ctype == 'float' or self.ctype == 'double'):
- error(0, 'Attempt to write control register as FP')
- if self.write_code != None:
- return self.buildWriteCode('setMiscReg')
- base = 'xc->readMiscReg(%s)' % self.reg_spec
- name = self.base_name
- wb_val = 'insertBits(%s, %s_HI, %s_LO, %s)' % \
- (base, name, name, self.base_name)
- wb = 'xc->setMiscRegOperand(this, %s, %s );\n' % (self.dest_reg_idx, wb_val)
- wb += 'if (traceData) { traceData->setData(%s); }' % \
- self.base_name
- return wb
-
class MemOperand(Operand):
def isMem(self):
return 1
diff --git a/src/arch/mips/bare_iron/system.cc b/src/arch/mips/bare_iron/system.cc
index 765dec4b0..ff928acfc 100755
--- a/src/arch/mips/bare_iron/system.cc
+++ b/src/arch/mips/bare_iron/system.cc
@@ -28,20 +28,8 @@
* Authors: Jaidev Patwardhan
*/
-#include "arch/vtophys.hh"
#include "arch/mips/bare_iron/system.hh"
-#include "arch/mips/system.hh"
-#include "cpu/thread_context.hh"
-#include "cpu/base.hh"
-#include "dev/platform.hh"
-#include "mem/physical.hh"
-#include "mem/port.hh"
#include "params/BareIronMipsSystem.hh"
-#include "sim/byteswap.hh"
-
-using namespace std;
-using namespace MipsISA;
-
BareIronMipsSystem::BareIronMipsSystem(Params *p)
: MipsSystem(p)
diff --git a/src/arch/mips/bare_iron/system.hh b/src/arch/mips/bare_iron/system.hh
index e593f832c..e7a498012 100755
--- a/src/arch/mips/bare_iron/system.hh
+++ b/src/arch/mips/bare_iron/system.hh
@@ -31,11 +31,6 @@
#ifndef __ARCH_MIPS_BARE_IRON_SYSTEM_HH__
#define __ARCH_MIPS_BARE_IRON_SYSTEM_HH__
-class ThreadContext;
-
-class BreakPCEvent;
-class IdleStartEvent;
-
#include "arch/mips/system.hh"
#include "params/BareIronMipsSystem.hh"
@@ -46,15 +41,9 @@ class IdleStartEvent;
*/
class BareIronMipsSystem : public MipsSystem
{
- private:
-
-
public:
static const int CommandLineSize = 256;
- private:
-
- public:
BareIronMipsSystem(Params *p);
~BareIronMipsSystem();
};
diff --git a/src/arch/mips/dt_constants.hh b/src/arch/mips/dt_constants.hh
index a836c86da..64b1cf232 100755
--- a/src/arch/mips/dt_constants.hh
+++ b/src/arch/mips/dt_constants.hh
@@ -32,184 +32,105 @@
#define __ARCH_MIPS_DT_CONSTANTS_HH__
#include "arch/mips/types.hh"
+#include "base/bitunion.hh"
namespace MipsISA
{
- // See the EJTAG Specification - Revision 4.10
- // Also see PDTrace Specification - Revision 4.30
-
- // Debug Register - CP0 Reg 23, Sel 0
- const unsigned Debug_DBD = 31;
- const unsigned Debug_DM_HI = 30;
- const unsigned Debug_DM_LO = 30;
- const unsigned Debug_NODCR = 29;
- const unsigned Debug_LSNM = 28;
- const unsigned Debug_DOZE = 27;
- const unsigned Debug_HALT = 26;
- const unsigned Debug_COUNTDM = 25;
- const unsigned Debug_IBUSEP = 24;
- const unsigned Debug_MCHECKEP = 23;
- const unsigned Debug_CACHEEP = 22;
- const unsigned Debug_DBUSEP = 21;
- const unsigned Debug_IEXI_HI = 20;
- const unsigned Debug_IEXI_LO = 20;
- const unsigned Debug_DDBS_IMPR = 19;
- const unsigned Debug_DDBL_IMPR = 18;
- const unsigned Debug_EJTAGVER_2 =17;
- const unsigned Debug_EJTAGVER_1 =16;
- const unsigned Debug_EJTAGVER_0 =15;
- const unsigned Debug_EJTAGVER_HI = 17;
- const unsigned Debug_EJTAGVER_LO = 15;
- const unsigned Debug_DEXC_CODE_HI = 14;
- const unsigned Debug_DEXC_CODE_LO = 10;
- const unsigned Debug_NOSST = 9;
- const unsigned Debug_SST = 8;
- const unsigned Debug_OFFLINE = 7;
- const unsigned Debug_DIBIMPR = 6;
- const unsigned Debug_DINT = 5;
- const unsigned Debug_DIB = 4;
- const unsigned Debug_DDBS = 3;
- const unsigned Debug_DDBL = 2;
- const unsigned Debug_DBp = 1;
- const unsigned Debug_DSS = 0;
-
-
- // TraceControl Register - CP0 Reg 23, Sel 1
- const unsigned TraceControl_TS = 31;
- const unsigned TraceControl_UT = 30;
- const unsigned TraceControl_TB = 27;
- const unsigned TraceControl_IO = 26;
- const unsigned TraceControl_D = 25;
- const unsigned TraceControl_E = 24;
- const unsigned TraceControl_K = 23;
- const unsigned TraceControl_S = 22;
- const unsigned TraceControl_U = 21;
- const unsigned TraceControl_ASID_M_HI = 20;
- const unsigned TraceControl_ASID_M_LO = 13;
- const unsigned TraceControl_ASID_HI = 12;
- const unsigned TraceControl_ASID_LO = 5;
- const unsigned TraceControl_G = 4;
- const unsigned TraceControl_TFCR = 3;
- const unsigned TraceControl_TLSM = 2;
- const unsigned TraceControl_TIM = 1;
- const unsigned TraceControl_ON = 0;
-
- // TraceControl2 Register - CP0 Reg 23, Sel 2
- const unsigned TraceControl2_CPUIDV = 29;
- const unsigned TraceControl2_CPUID_HI = 28;
- const unsigned TraceControl2_CPUID_LO = 21;
- const unsigned TraceControl2_TCV = 20;
- const unsigned TraceControl2_TCNUM_HI = 19;
- const unsigned TraceControl2_TCNUM_LO = 12;
- const unsigned TraceControl2_MODE_HI = 11;
- const unsigned TraceControl2_MODE_LO = 7;
- const unsigned TraceControl2_VALIDMODES_HI = 6;
- const unsigned TraceControl2_VALIDMODES_LO = 5;
- const unsigned TraceControl2_TBI = 4;
- const unsigned TraceControl2_TBU = 3;
- const unsigned TraceControl2_SYP_HI = 2;
- const unsigned TraceControl2_SYP_LO = 0;
-
- // UserTraceData Register - CP0 Reg 23, Sel 3
- // Just holds 32-bits (or 64-bits) of data
-
- // TraceIBPC Register - CP0 Reg 23, Sel 4
- const unsigned TraceIBPC_MB = 31;
- const unsigned TraceIBPC_IE = 28;
- const unsigned TraceIBPC_ATE = 27;
- const unsigned TraceIBPC_IBPC8_HI = 26;
- const unsigned TraceIBPC_IBPC8_LO = 24;
- const unsigned TraceIBPC_IBPC7_HI = 23;
- const unsigned TraceIBPC_IBPC7_LO = 21;
- const unsigned TraceIBPC_IBPC6_HI = 20;
- const unsigned TraceIBPC_IBPC6_LO = 18;
- const unsigned TraceIBPC_IBPC5_HI = 17;
- const unsigned TraceIBPC_IBPC5_LO = 15;
- const unsigned TraceIBPC_IBPC4_HI = 14;
- const unsigned TraceIBPC_IBPC4_LO = 12;
- const unsigned TraceIBPC_IBPC3_HI = 11;
- const unsigned TraceIBPC_IBPC3_LO = 9;
- const unsigned TraceIBPC_IBPC2_HI = 8;
- const unsigned TraceIBPC_IBPC2_LO = 6;
- const unsigned TraceIBPC_IBPC1_HI = 5;
- const unsigned TraceIBPC_IBPC1_LO = 3;
- const unsigned TraceIBPC_IBPC0_HI = 2;
- const unsigned TraceIBPC_IBPC0_LO = 0;
-
-
- // TraceDBPC Register - CP0 Reg 23, Sel 5
- const unsigned TRACEDBPC_MB = 31;
- const unsigned TRACEDBPC_DE = 28;
- const unsigned TRACEDBPC_ATE = 27;
- const unsigned TRACEDBPC_DBPC8_HI = 26;
- const unsigned TRACEDBPC_DBPC8_LO = 24;
- const unsigned TRACEDBPC_DBPC7_HI = 23;
- const unsigned TRACEDBPC_DBPC7_LO = 21;
- const unsigned TRACEDBPC_DBPC6_HI = 20;
- const unsigned TRACEDBPC_DBPC6_LO = 18;
- const unsigned TRACEDBPC_DBPC5_HI = 17;
- const unsigned TRACEDBPC_DBPC5_LO = 15;
- const unsigned TRACEDBPC_DBPC4_HI = 14;
- const unsigned TRACEDBPC_DBPC4_LO = 12;
- const unsigned TRACEDBPC_DBPC3_HI = 11;
- const unsigned TRACEDBPC_DBPC3_LO = 9;
- const unsigned TRACEDBPC_DBPC2_HI = 8;
- const unsigned TRACEDBPC_DBPC2_LO = 6;
- const unsigned TRACEDBPC_DBPC1_HI = 5;
- const unsigned TRACEDBPC_DBPC1_LO = 3;
- const unsigned TRACEDBPC_DBPC0_HI = 2;
- const unsigned TRACEDBPC_DBPC0_LO = 0;
-
- // TraceIBPC2 - Not part of CP0, but part of TRACE
- const unsigned TraceIBPC_IBPC14_HI = 17;
- const unsigned TraceIBPC_IBPC14_LO = 15;
- const unsigned TraceIBPC_IBPC13_HI = 14;
- const unsigned TraceIBPC_IBPC13_LO = 12;
- const unsigned TraceIBPC_IBPC12_HI = 11;
- const unsigned TraceIBPC_IBPC12_LO = 9;
- const unsigned TraceIBPC_IBPC11_HI = 8;
- const unsigned TraceIBPC_IBPC11_LO = 6;
- const unsigned TraceIBPC_IBPC10_HI = 5;
- const unsigned TraceIBPC_IBPC10_LO = 3;
- const unsigned TraceIBPC_IBPC9_HI = 2;
- const unsigned TraceIBPC_IBPC9_LO = 0;
-
-
- // TraceDBPC2 - Not part of CP0, but part of TRACE
- const unsigned TRACEDBPC_DBPC14_HI = 17;
- const unsigned TRACEDBPC_DBPC14_LO = 15;
- const unsigned TRACEDBPC_DBPC13_HI = 14;
- const unsigned TRACEDBPC_DBPC13_LO = 12;
- const unsigned TRACEDBPC_DBPC12_HI = 11;
- const unsigned TRACEDBPC_DBPC12_LO = 9;
- const unsigned TRACEDBPC_DBPC11_HI = 8;
- const unsigned TRACEDBPC_DBPC11_LO = 6;
- const unsigned TRACEDBPC_DBPC10_HI = 5;
- const unsigned TRACEDBPC_DBPC10_LO = 3;
- const unsigned TRACEDBPC_DBPC9_HI = 2;
- const unsigned TRACEDBPC_DBPC9_LO = 0;
-
-
- // Debug Register 2 - CP0 Reg 23, Sel 6
- const unsigned DEBUG2_PRM = 3;
- const unsigned DEBUG2_DQ = 2;
- const unsigned DEBUG2_TUP = 1;
- const unsigned DEBUG2_PACO = 0;
-
- // DEPC Register - CP0 Reg 24, Sel 0
- // Debug Exception Program Counter
- const unsigned DEPC_HI = 31;
- const unsigned DEPC_LO = 0;
-
-
-
- // DESAVE - CP0 Reg 31, Sel 0
- // Debug Exception Save Register
- const unsigned DESAVE_HI = 31;
- const unsigned DESAVE_LO = 0;
-
-
+BitUnion32(DebugReg)
+ Bitfield<31> dbd;
+ Bitfield<30> dm;
+ Bitfield<29> nodcr;
+ Bitfield<28> lsnm;
+ Bitfield<27> doze;
+ Bitfield<26> halt;
+ Bitfield<25> conutdm;
+ Bitfield<24> ibusep;
+ Bitfield<23> mcheckep;
+ Bitfield<22> cacheep;
+ Bitfield<21> dbusep;
+ Bitfield<20, 19> iexi;
+ Bitfield<19> ddbsImpr;
+ Bitfield<18> ddblImpr;
+ SubBitUnion(ejtagVer, 17, 15)
+ Bitfield<17> ejtagVer2;
+ Bitfield<16> ejtagVer1;
+ Bitfield<15> ejtagVer0;
+ EndSubBitUnion(ejtagVer)
+ Bitfield<14, 10> dexcCode;
+ Bitfield<9> nosst;
+ Bitfield<8> sst;
+ Bitfield<7> offline;
+ Bitfield<6> dibimpr;
+ Bitfield<5> dint;
+ Bitfield<4> dib;
+ Bitfield<3> ddbs;
+ Bitfield<2> ddbl;
+ Bitfield<1> dbp;
+ Bitfield<0> dss;
+EndBitUnion(DebugReg)
+
+BitUnion32(TraceControlReg)
+ Bitfield<31> ts;
+ Bitfield<30> ut;
+ Bitfield<27> tb;
+ Bitfield<26> io;
+ Bitfield<25> d;
+ Bitfield<24> e;
+ Bitfield<23> k;
+ Bitfield<22> s;
+ Bitfield<21> u;
+ Bitfield<20, 13> asidM;
+ Bitfield<12, 5> asid;
+ Bitfield<4> g;
+ Bitfield<3> tfcr;
+ Bitfield<2> tlsm;
+ Bitfield<1> tim;
+ Bitfield<0> on;
+EndBitUnion(TraceControlReg)
+
+BitUnion32(TraceControl2Reg)
+ Bitfield<29> cpuidv;
+ Bitfield<28, 21> cpuid;
+ Bitfield<20> tcv;
+ Bitfield<19, 12> tcnum;
+ Bitfield<11, 7> mode;
+ Bitfield<6, 5> validModes;
+ Bitfield<4> tbi;
+ Bitfield<3> tbu;
+ Bitfield<2, 0> syp;
+EndBitUnion(TraceControl2Reg)
+
+BitUnion32(TraceBPCReg)
+ Bitfield<31> mb;
+ Bitfield<28> e;
+ Bitfield<27> ate;
+ Bitfield<26, 24> bpc8;
+ Bitfield<23, 21> bpc7;
+ Bitfield<20, 18> bpc6;
+ Bitfield<17, 15> bpc5;
+ Bitfield<14, 12> bpc4;
+ Bitfield<11, 9> bpc3;
+ Bitfield<8, 6> bpc2;
+ Bitfield<5, 3> bpc1;
+ Bitfield<2, 0> bpc0;
+EndBitUnion(TraceBPCReg)
+
+BitUnion32(TraceBPC2Reg)
+ Bitfield<17, 15> bpc14;
+ Bitfield<14, 12> bpc13;
+ Bitfield<11, 9> bpc12;
+ Bitfield<8, 6> bpc11;
+ Bitfield<5, 3> bpc10;
+ Bitfield<2, 0> bpc9;
+EndBitUnion(TraceBPC2Reg)
+
+BitUnion32(Debug2Reg)
+ Bitfield<3> prm;
+ Bitfield<2> dq;
+ Bitfield<1> tup;
+ Bitfield<0> paco;
+EndBitUnion(Debug2Reg)
} // namespace MipsISA
#endif
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index 347d041a3..6faab054f 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -85,7 +85,6 @@ 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;
@@ -106,7 +105,6 @@ 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;
@@ -168,344 +166,366 @@ FaultVect DspStateDisabledFault::_vect = 0x001a;
FaultStat DspStateDisabledFault::_count;
#if FULL_SYSTEM
-void MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
+void
+MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
{
- tc->setPC(HandlerBase);
- tc->setNextPC(HandlerBase+sizeof(MachInst));
- tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
+ tc->setPC(HandlerBase);
+ tc->setNextPC(HandlerBase + sizeof(MachInst));
+ tc->setNextNPC(HandlerBase + 2 * sizeof(MachInst));
}
-void MipsFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
+void
+MipsFault::setExceptionState(ThreadContext *tc, uint8_t excCode)
{
- // modify SRS Ctl - Save CSS, put ESS into CSS
- MiscReg stat = tc->readMiscReg(MipsISA::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(MipsISA::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(MipsISA::SRSCtl,srs);
- //tc->setShadowSet(ESS);
+ // modify SRS Ctl - Save CSS, put ESS into CSS
+ StatusReg status = tc->readMiscReg(Status);
+ if (status.exl != 1 && status.bev != 1) {
+ // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
+ SRSCtlReg srsCtl = tc->readMiscReg(SRSCtl);
+ srsCtl.pss = srsCtl.css;
+ srsCtl.css = srsCtl.ess;
+ tc->setMiscRegNoEffect(SRSCtl, srsCtl);
}
- // set EXL bit (don't care if it is already set!)
- replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
- tc->setMiscRegNoEffect(MipsISA::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(MipsPRA,"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(MipsISA::EPC,tc->readPC()-sizeof(MachInst));
- // In the branch delay slot? set CAUSE_31
- C_BD = 1;
- } else {
- tc->setMiscRegNoEffect(MipsISA::EPC,tc->readPC());
- // In the branch delay slot? reset CAUSE_31
- C_BD = 0;
- }
-
- // Set Cause_EXCCODE field
- MiscReg cause = tc->readMiscReg(MipsISA::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(MipsISA::Cause,cause);
+ // set EXL bit (don't care if it is already set!)
+ status.exl = 1;
+ tc->setMiscRegNoEffect(Status, status);
+
+ // write EPC
+ // CHECK ME or FIXME or FIX ME or POSSIBLE HACK
+ // Check to see if the exception occurred in the branch delay slot
+ DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n",
+ tc->readPC(), tc->readNextPC(), tc->readNextNPC());
+ int bd = 0;
+ if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) {
+ tc->setMiscRegNoEffect(EPC, tc->readPC() - sizeof(MachInst));
+ // In the branch delay slot? set CAUSE_31
+ bd = 1;
+ } else {
+ tc->setMiscRegNoEffect(EPC, tc->readPC());
+ // In the branch delay slot? reset CAUSE_31
+ bd = 0;
+ }
+ // Set Cause_EXCCODE field
+ CauseReg cause = tc->readMiscReg(Cause);
+ cause.excCode = excCode;
+ cause.bd = bd;
+ cause.ce = 0;
+ tc->setMiscRegNoEffect(Cause, cause);
}
-void ArithmeticFault::invoke(ThreadContext *tc)
+void
+ArithmeticFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0xC);
-
- // Set new PC
- Addr HandlerBase;
- MiscReg stat = tc->readMiscReg(MipsISA::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(MipsISA::EBase);
- }else{
- HandlerBase = 0xBFC00200;
- }
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0xC);
+
+ // Set new PC
+ Addr HandlerBase;
+ StatusReg status = tc->readMiscReg(Status);
+ // Here, the handler is dependent on BEV, which is not modified by
+ // setExceptionState()
+ if (!status.bev) {
+ // See MIPS ARM Vol 3, Revision 2, Page 38
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ } else {
+ HandlerBase = 0xBFC00200;
+ }
+ setHandlerPC(HandlerBase, tc);
}
-void StoreAddressErrorFault::invoke(ThreadContext *tc)
+void
+StoreAddressErrorFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x5);
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::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(MipsISA::EPC));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x5);
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void TrapFault::invoke(ThreadContext *tc)
+void
+TrapFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- setExceptionState(tc,0xD);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::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(MipsISA::EPC));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0xD);
+
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void BreakpointFault::invoke(ThreadContext *tc)
+void
+BreakpointFault::invoke(ThreadContext *tc)
{
- setExceptionState(tc,0x9);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::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(MipsISA::EPC));
+ setExceptionState(tc, 0x9);
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void DtbInvalidFault::invoke(ThreadContext *tc)
+void
+DtbInvalidFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(MipsISA::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(MipsISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
- setExceptionState(tc,0x3);
-
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ EntryHiReg entryHi = tc->readMiscReg(EntryHi);
+ entryHi.asid = entryHiAsid;
+ entryHi.vpn2 = entryHiVPN2;
+ entryHi.vpn2x = entryHiVPN2X;
+ tc->setMiscRegNoEffect(EntryHi, entryHi);
+
+ ContextReg context = tc->readMiscReg(Context);
+ context.badVPN2 = contextBadVPN2;
+ tc->setMiscRegNoEffect(Context, context);
+ setExceptionState(tc, 0x3);
+
+
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void AddressErrorFault::invoke(ThreadContext *tc)
+void
+AddressErrorFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x4);
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x4);
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void ItbInvalidFault::invoke(ThreadContext *tc)
+void
+ItbInvalidFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x2);
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(MipsISA::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(MipsISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
-
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(MipsISA::EPC));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x2);
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ EntryHiReg entryHi = tc->readMiscReg(EntryHi);
+ entryHi.asid = entryHiAsid;
+ entryHi.vpn2 = entryHiVPN2;
+ entryHi.vpn2x = entryHiVPN2X;
+ tc->setMiscRegNoEffect(EntryHi, entryHi);
+
+ ContextReg context = tc->readMiscReg(Context);
+ context.badVPN2 = contextBadVPN2;
+ tc->setMiscRegNoEffect(Context, context);
+
+
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase,tc);
+ DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n",
+ HandlerBase, tc->readMiscReg(EPC));
}
-void ItbRefillFault::invoke(ThreadContext *tc)
+void
+ItbRefillFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered (%x).\n", name(),BadVAddr);
- Addr HandlerBase;
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(MipsISA::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(MipsISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(MipsISA::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(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
- }
-
- setExceptionState(tc,0x2);
- setHandlerPC(HandlerBase,tc);
+ DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), badVAddr);
+ Addr HandlerBase;
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ EntryHiReg entryHi = tc->readMiscReg(EntryHi);
+ entryHi.asid = entryHiAsid;
+ entryHi.vpn2 = entryHiVPN2;
+ entryHi.vpn2x = entryHiVPN2X;
+ tc->setMiscRegNoEffect(EntryHi, entryHi);
+ ContextReg context = tc->readMiscReg(Context);
+ context.badVPN2 = contextBadVPN2;
+ tc->setMiscRegNoEffect(Context, context);
+
+ StatusReg status = tc->readMiscReg(Status);
+ // Since handler depends on EXL bit, must check EXL bit before setting it!!
+ // See MIPS ARM Vol 3, Revision 2, Page 38
+ if (status.exl == 1) {
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ } else {
+ // Offset 0x000
+ HandlerBase = tc->readMiscReg(EBase);
+ }
+
+ setExceptionState(tc, 0x2);
+ setHandlerPC(HandlerBase, tc);
}
-void DtbRefillFault::invoke(ThreadContext *tc)
+void
+DtbRefillFault::invoke(ThreadContext *tc)
{
- // Set new PC
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- Addr HandlerBase;
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(MipsISA::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(MipsISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(MipsISA::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(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(MipsISA::EBase); // Offset 0x000
- }
-
-
- setExceptionState(tc,0x3);
-
- setHandlerPC(HandlerBase,tc);
+ // Set new PC
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ Addr HandlerBase;
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ EntryHiReg entryHi = tc->readMiscReg(EntryHi);
+ entryHi.asid = entryHiAsid;
+ entryHi.vpn2 = entryHiVPN2;
+ entryHi.vpn2x = entryHiVPN2X;
+ tc->setMiscRegNoEffect(EntryHi, entryHi);
+
+ ContextReg context = tc->readMiscReg(Context);
+ context.badVPN2 = contextBadVPN2;
+ tc->setMiscRegNoEffect(Context, context);
+
+ StatusReg status = tc->readMiscReg(Status);
+ // Since handler depends on EXL bit, must check EXL bit before setting it!!
+ // See MIPS ARM Vol 3, Revision 2, Page 38
+ if (status.exl) {
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ } else {
+ // Offset 0x000
+ HandlerBase = tc->readMiscReg(EBase);
+ }
+
+ setExceptionState(tc, 0x3);
+
+ setHandlerPC(HandlerBase, tc);
}
-void TLBModifiedFault::invoke(ThreadContext *tc)
+void
+TLBModifiedFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- tc->setMiscRegNoEffect(MipsISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(MipsISA::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(MipsISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(MipsISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(MipsISA::Context,ctxt);
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ tc->setMiscRegNoEffect(BadVAddr, badVAddr);
+ EntryHiReg entryHi = tc->readMiscReg(EntryHi);
+ entryHi.asid = entryHiAsid;
+ entryHi.vpn2 = entryHiVPN2;
+ entryHi.vpn2x = entryHiVPN2X;
+ tc->setMiscRegNoEffect(EntryHi, entryHi);
+
+ ContextReg context = tc->readMiscReg(Context);
+ context.badVPN2 = contextBadVPN2;
+ tc->setMiscRegNoEffect(Context, context);
// Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::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(MipsISA::EPC));
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setExceptionState(tc, 0x1);
+ setHandlerPC(HandlerBase, tc);
}
-void SystemCallFault::invoke(ThreadContext *tc)
+void
+SystemCallFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x8);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::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(MipsISA::EPC));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x8);
+ // Set new PC
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
}
-void InterruptFault::invoke(ThreadContext *tc)
+void
+InterruptFault::invoke(ThreadContext *tc)
{
#if FULL_SYSTEM
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
-
-
- uint8_t IV = bits(tc->readMiscRegNoEffect(MipsISA::Cause),Cause_IV);
- if (IV)// Offset 200 for release 2
- HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
- else//Ofset at 180 for release 1
- HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase);
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x0A);
+ Addr HandlerBase;
+
+ CauseReg cause = tc->readMiscRegNoEffect(Cause);
+ if (cause.iv) {
+ // Offset 200 for release 2
+ HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(EBase);
+ } else {
+ //Ofset at 180 for release 1
+ HandlerBase = vect() + tc->readMiscRegNoEffect(EBase);
+ }
- setHandlerPC(HandlerBase,tc);
+ setHandlerPC(HandlerBase, tc);
#endif
}
#endif // FULL_SYSTEM
-void ResetFault::invoke(ThreadContext *tc)
+void
+ResetFault::invoke(ThreadContext *tc)
{
#if FULL_SYSTEM
- DPRINTF(MipsPRA,"%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(MipsPRA,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
+ DPRINTF(MipsPRA, "%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(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC());
#endif
- // Set Coprocessor 1 (Floating Point) To Usable
- tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000);
+ // Set Coprocessor 1 (Floating Point) To Usable
+ StatusReg status = tc->readMiscRegNoEffect(Status);
+ status.cu.cu1 = 1;
+ tc->setMiscReg(Status, status);
}
-void ReservedInstructionFault::invoke(ThreadContext *tc)
+void
+ReservedInstructionFault::invoke(ThreadContext *tc)
{
#if FULL_SYSTEM
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscRegNoEffect(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0x0A);
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscRegNoEffect(EBase);
+ setHandlerPC(HandlerBase, tc);
#else
panic("%s encountered.\n", name());
#endif
}
-void ThreadFault::invoke(ThreadContext *tc)
+void
+ThreadFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ panic("%s encountered.\n", name());
}
-void DspStateDisabledFault::invoke(ThreadContext *tc)
+void
+DspStateDisabledFault::invoke(ThreadContext *tc)
{
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ panic("%s encountered.\n", name());
}
-void CoprocessorUnusableFault::invoke(ThreadContext *tc)
+void
+CoprocessorUnusableFault::invoke(ThreadContext *tc)
{
#if FULL_SYSTEM
- DPRINTF(MipsPRA,"%s encountered.\n", name());
- setExceptionState(tc,0xb);
- /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
- MiscReg cause = tc->readMiscReg(MipsISA::Cause);
- replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
- tc->setMiscRegNoEffect(MipsISA::Cause,cause);
-
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
-
- // warn("Status: %x, Cause: %x\n",tc->readMiscReg(MipsISA::Status),tc->readMiscReg(MipsISA::Cause));
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ setExceptionState(tc, 0xb);
+ // The ID of the coprocessor causing the exception is stored in
+ // CoprocessorUnusableFault::coProcID
+ CauseReg cause = tc->readMiscReg(Cause);
+ cause.ce = coProcID;
+ tc->setMiscRegNoEffect(Cause, cause);
+
+ Addr HandlerBase;
+ // Offset 0x180 - General Exception Vector
+ HandlerBase = vect() + tc->readMiscReg(EBase);
+ setHandlerPC(HandlerBase, tc);
+
#else
warn("%s (CP%d) encountered.\n", name(), coProcID);
#endif
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index 2d98b5f71..7a001d390 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -36,10 +36,9 @@
#include "sim/faults.hh"
-// The design of the "name" and "vect" functions is in sim/faults.hh
-
namespace MipsISA
{
+
typedef const Addr FaultVect;
class MipsFault : public FaultBase
@@ -48,15 +47,15 @@ class MipsFault : public FaultBase
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;
+ Addr badVAddr;
+ Addr entryHiAsid;
+ Addr entryHiVPN2;
+ Addr entryHiVPN2X;
+ Addr contextBadVPN2;
#if FULL_SYSTEM
- void invoke(ThreadContext * tc) {};
- void setExceptionState(ThreadContext *,uint8_t);
- void setHandlerPC(Addr,ThreadContext *);
+ void invoke(ThreadContext * tc) {};
+ void setExceptionState(ThreadContext *, uint8_t);
+ void setHandlerPC(Addr, ThreadContext *);
#endif
virtual FaultVect vect() = 0;
virtual FaultStat & countStat() = 0;
@@ -116,6 +115,7 @@ class AddressErrorFault : public MipsFault
#endif
};
+
class StoreAddressErrorFault : public MipsFault
{
private:
@@ -129,8 +129,8 @@ class StoreAddressErrorFault : public MipsFault
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
-
};
+
class UnimplementedOpcodeFault : public MipsFault
{
private:
@@ -157,6 +157,7 @@ class TLBRefillIFetchFault : public MipsFault
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
+
class TLBInvalidIFetchFault : public MipsFault
{
private:
@@ -259,6 +260,7 @@ class ResetFault : public MipsFault
void invoke(ThreadContext * tc);
};
+
class SystemCallFault : public MipsFault
{
private:
@@ -284,6 +286,7 @@ class SoftResetFault : public MipsFault
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
+
class DebugSingleStep : public MipsFault
{
private:
@@ -296,6 +299,7 @@ class DebugSingleStep : public MipsFault
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
+
class DebugInterrupt : public MipsFault
{
private:
@@ -350,7 +354,6 @@ class ThreadFault : public MipsFault
void invoke(ThreadContext * tc);
};
-
class ArithmeticFault : public MipsFault
{
protected:
@@ -384,8 +387,6 @@ class InterruptFault : public MipsFault
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
-
- //void invoke(ThreadContext * tc);
};
class TrapFault : public MipsFault
@@ -432,6 +433,7 @@ class ItbRefillFault : public MipsFault
void invoke(ThreadContext * tc);
#endif
};
+
class DtbRefillFault : public MipsFault
{
private:
@@ -475,8 +477,8 @@ class ItbInvalidFault : public MipsFault
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
-
};
+
class TLBModifiedFault : public MipsFault
{
private:
@@ -490,7 +492,6 @@ class TLBModifiedFault : public MipsFault
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
-
};
class DtbInvalidFault : public MipsFault
@@ -506,7 +507,6 @@ class DtbInvalidFault : public MipsFault
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
-
};
class FloatEnableFault : public MipsFault
diff --git a/src/arch/mips/idle_event.cc b/src/arch/mips/idle_event.cc
index 0aea08834..8c98c5078 100644
--- a/src/arch/mips/idle_event.cc
+++ b/src/arch/mips/idle_event.cc
@@ -40,9 +40,4 @@ void
IdleStartEvent::process(ThreadContext *tc)
{
fatal("Idle Start Event Not Defined for MIPS ISA ");
-
- // if (tc->getKernelStats())
- // tc->getKernelStats()->setIdleProcess(
- // tc->readMiscRegNoEffect(MipsISA::IPR_PALtemp23), tc);
- //remove();
}
diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc
index 99f96fafc..4b1f37856 100755
--- a/src/arch/mips/interrupts.cc
+++ b/src/arch/mips/interrupts.cc
@@ -31,243 +31,142 @@
* Korey Sewell
*/
-#include "arch/mips/pra_constants.hh"
+#include "arch/mips/interrupts.hh"
#include "arch/mips/isa_traits.hh"
+#include "arch/mips/pra_constants.hh"
+#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "arch/mips/interrupts.hh"
namespace MipsISA
{
-static inline uint8_t getCauseIP_(ThreadContext *tc) {
- MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause);
- uint8_t IP_ = bits(cause,Cause_IP7, Cause_IP0);
- return IP_;
-}
-static inline void setCauseIP_(ThreadContext *tc, uint8_t val) {
- MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause);
- replaceBits(cause,Cause_IP7,Cause_IP0,val);
- tc->setMiscRegNoEffect(MipsISA::Cause,cause);
+static inline uint8_t
+getCauseIP(ThreadContext *tc) {
+ CauseReg cause = tc->readMiscRegNoEffect(Cause);
+ return cause.ip;
}
-/*
- void Interrupts::post(int int_num, int index)
- {
- DPRINTF(Interrupt, "Interrupt %d posted\n", int_num);
-
- //index should not be used
- assert(index == 0);
-
- if (int_num < 0 || int_num >= NumInterruptLevels)
- panic("int_num out of bounds\n");
- intstatus |= 1 << int_num;
- }
-
- void Interrupts::clear(int int_num, int index)
- {
- DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num);
-
- //index should not be used
- assert(index == 0);
-
- if (int_num < 0 || int_num >= NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- intstatus &= ~(1 << int_num);
- }
-
- void Interrupts::clearAll()
- {
- DPRINTF(Interrupt, "Interrupts all cleared\n");
- intstatus = 0;
- }
-
-
-
- Fault Interrupts::getInterrupt(ThreadContext * tc)
- {
- DPRINTF(Interrupt, "Interrupts getInterrupt\n");
- // If a timer interrupt has occured, check to see if a
- // mtc0 to Compare register caused this interrupt to
- // be cleared. If this is the case, clear intstatus
- // bit for timer interrupt
- if (oncputimerintr){
- DPRINTF(Interrupt, "Interrupts oncputimerintr==true\n");
- MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause);
- uint8_t IP_ = bits(cause,Cause_IP7, Cause_IP0);
- MiscReg intctl = tc->readMiscRegNoEffect(MipsISA::IntCtl);
- uint8_t IPTI = bits(intctl, IntCtl_IPTI_HI, IntCtl_IPTI_LO);
- //mtc0 to compare must have cleared bit in IP
- if ( ((1 << IPTI) & IP_) == 0){
- clear(IPTI, 0);
- oncputimerintr=false;
- }
- }
- //if there is a on cpu timer interrupt (i.e. Compare == Count)
- //update intstatus before proceeding to interrupt
- if (onCpuTimerInterrupt(tc)){
- DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc)==true\n");
- //determine timer interrupt IP #
- MiscReg intctl = tc->readMiscRegNoEffect(MipsISA::IntCtl);
- uint8_t IPTI = bits(intctl, IntCtl_IPTI_HI, IntCtl_IPTI_LO);
- //set intstatus to correspond
- post(IPTI, 0);
- oncputimerintr=true;
- }
-
- //Check if there are any outstanding interrupts
- MiscReg status = tc->readMiscRegNoEffect(MipsISA::Status);
- if (bits(status, Status_IE_LO) == 1 && //interrupts must be enabled
- bits(status, Status_ERL) == 0 && //error level must be 0 or interrupts inhibited
- bits(status, Status_EXL) == 0 ) //exception level must be 0 or interrupts inhibited
- {
- // Software interrupts & hardware interrupts are handled in software.
- // So if any interrupt that isn't masked is detected, jump to interrupt
- // handler
- uint8_t IM, IP; //IM=interrupt mask, IP=interrupt pending
- IM = bits(status,Status_IM7,Status_IM0);
- IP = intstatus;
- //IM and IP are already correctly aligned
- if (IM & IP){
- DPRINTF(Flow, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n",
- IM, IP);
- return new InterruptFault;
- }
- }
-
- return NoFault;
-
- }
-
- void Interrupts::updateIntrInfo(ThreadContext *tc) const
- {
- //Merge Interrupts.intstatus with mips MipISA::Status
- MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause);
- replaceBits(cause,Cause_IP7,Cause_IP0,intstatus);
- tc->setMiscRegNoEffect(MipsISA::Cause,cause);
- }
-
- bool Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
- {
- MiscReg compare = tc->readMiscRegNoEffect(MipsISA::Compare);
- MiscReg count = tc->readMiscRegNoEffect(MipsISA::Count);
- if (compare == count)
- return true;
- return false;
- }
+static inline void
+setCauseIP(ThreadContext *tc, uint8_t val) {
+ CauseReg cause = tc->readMiscRegNoEffect(Cause);
+ cause.ip = val;
+ tc->setMiscRegNoEffect(Cause, cause);
+}
-*/
-void Interrupts::post(int int_num, ThreadContext* tc)
+void
+Interrupts::post(int int_num, ThreadContext* tc)
{
DPRINTF(Interrupt, "Interrupt %d posted\n", int_num);
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
- uint8_t intstatus= getCauseIP_(tc);
+ uint8_t intstatus = getCauseIP(tc);
intstatus |= 1 << int_num;
- setCauseIP_(tc, intstatus);
+ setCauseIP(tc, intstatus);
}
-void Interrupts::post(int int_num, int index)
+void
+Interrupts::post(int int_num, int index)
{
- fatal("Must use Thread COntext when posting MIPS Interrupts in M5");
+ fatal("Must use Thread Context when posting MIPS Interrupts in M5");
}
-void Interrupts::clear(int int_num, ThreadContext* tc)
+void
+Interrupts::clear(int int_num, ThreadContext* tc)
{
DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num);
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
- uint8_t intstatus = getCauseIP_(tc);
+ uint8_t intstatus = getCauseIP(tc);
intstatus &= ~(1 << int_num);
- setCauseIP_(tc, intstatus);
+ setCauseIP(tc, intstatus);
}
-void Interrupts::clear(int int_num, int index)
+void
+Interrupts::clear(int int_num, int index)
{
- fatal("Must use Thread COntext when clearing MIPS Interrupts in M5");
+ fatal("Must use Thread Context when clearing MIPS Interrupts in M5");
}
-void Interrupts::clearAll(ThreadContext *tc)
+void
+Interrupts::clearAll(ThreadContext *tc)
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
uint8_t intstatus = 0;
- setCauseIP_(tc, intstatus);
+ setCauseIP(tc, intstatus);
}
-void Interrupts::clearAll()
+void
+Interrupts::clearAll()
{
- fatal("Must use Thread COntext when clearing MIPS Interrupts in M5");
+ fatal("Must use Thread Context when clearing MIPS Interrupts in M5");
}
-Fault Interrupts::getInterrupt(ThreadContext * tc)
+Fault
+Interrupts::getInterrupt(ThreadContext * tc)
{
DPRINTF(Interrupt, "Interrupts getInterrupt\n");
-
-
//Check if there are any outstanding interrupts
- MiscReg status = tc->readMiscRegNoEffect(MipsISA::Status);
- if (bits(status, Status_IE_LO) == 1 && //interrupts must be enabled
- bits(status, Status_ERL_HI,Status_ERL_LO) == 0 && //error level must be 0 or interrupts inhibited
- bits(status, Status_EXL_HI,Status_EXL_LO) == 0 ) //exception level must be 0 or interrupts inhibited
- {
+ StatusReg status = tc->readMiscRegNoEffect(Status);
+ // Interrupts must be enabled, error level must be 0 or interrupts
+ // inhibited, and exception level must be 0 or interrupts inhibited
+ if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) {
// Software interrupts & hardware interrupts are handled in software.
// So if any interrupt that isn't masked is detected, jump to interrupt
// handler
- uint8_t IM, IP; //IM=interrupt mask, IP=interrupt pending
- IM = bits(status,Status_IM7,Status_IM0);
- IP = getCauseIP_(tc);
- //IM and IP are already correctly aligned
- if (IM & IP){
+ CauseReg cause = tc->readMiscRegNoEffect(Cause);
+ if (status.im && cause.ip) {
DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n",
- IM, IP);
+ (unsigned)status.im, (unsigned)cause.ip);
return new InterruptFault;
}
}
return NoFault;
-
}
-bool Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
+
+bool
+Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
{
- MiscReg compare = tc->readMiscRegNoEffect(MipsISA::Compare);
- MiscReg count = tc->readMiscRegNoEffect(MipsISA::Count);
+ MiscReg compare = tc->readMiscRegNoEffect(Compare);
+ MiscReg count = tc->readMiscRegNoEffect(Count);
if (compare == count && count != 0)
return true;
return false;
}
-void Interrupts::updateIntrInfo(ThreadContext *tc) const
+
+void
+Interrupts::updateIntrInfo(ThreadContext *tc) const
{
//Nothing needs to be done.
- ;
}
-bool Interrupts::interruptsPending(ThreadContext *tc) const
+bool
+Interrupts::interruptsPending(ThreadContext *tc) const
{
//if there is a on cpu timer interrupt (i.e. Compare == Count)
//update CauseIP before proceeding to interrupt
- if (onCpuTimerInterrupt(tc)){
- DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc)==true\n");
+ if (onCpuTimerInterrupt(tc)) {
+ DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n");
//determine timer interrupt IP #
- MiscReg intctl = tc->readMiscRegNoEffect(MipsISA::IntCtl);
- uint8_t IPTI = bits(intctl, IntCtl_IPTI_HI, IntCtl_IPTI_LO);
- //set intstatus to correspond
- //post(IPTI, tc);
- uint8_t intstatus= getCauseIP_(tc);
- intstatus |= 1 << IPTI;
- setCauseIP_(tc, intstatus);
+ IntCtlReg intCtl = tc->readMiscRegNoEffect(IntCtl);
+ uint8_t intStatus = getCauseIP(tc);
+ intStatus |= 1 << intCtl.ipti;
+ setCauseIP(tc, intStatus);
}
- return (getCauseIP_(tc) != 0);
+ return (getCauseIP(tc) != 0);
}
+}
-
-
-
+MipsISA::Interrupts *
+MipsInterruptsParams::create()
+{
+ return new MipsISA::Interrupts(this);
}
diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh
index af71e4636..c852bc9d0 100755
--- a/src/arch/mips/interrupts.hh
+++ b/src/arch/mips/interrupts.hh
@@ -31,97 +31,48 @@
#ifndef __ARCH_MIPS_INTERRUPT_HH__
#define __ARCH_MIPS_INTERRUPT_HH__
+#include <string>
#include "arch/mips/faults.hh"
#include "base/compiler.hh"
+#include "base/misc.hh"
+#include "params/MipsInterrupts.hh"
+#include "sim/serialize.hh"
+#include "sim/sim_object.hh"
-
+class BaseCPU;
+class Checkpoint;
namespace MipsISA
{
-class Interrupts
+
+class Interrupts : public SimObject
{
- /*
- protected:
- uint8_t intstatus;
- bool oncputimerintr;
- public:
- Interrupts()
- {
- intstatus = 0;
- newInfoSet = false;
- oncputimerintr = false;
-
- }
- // post(int int_num, int index) is responsible
- // for posting an interrupt. It sets a bit
- // in intstatus corresponding to Cause IP*. The
- // MIPS register Cause is updated by updateIntrInfo
- // which is called by checkInterrupts
- //
- void post(int int_num, int index);
- // clear(int int_num, int index) is responsible
- // for clearing an interrupt. It clear a bit
- // in intstatus corresponding to Cause IP*. The
- // MIPS register Cause is updated by updateIntrInfo
- // which is called by checkInterrupts
- //
- void clear(int int_num, int index);
- // clearAll() is responsible
- // for clearing all interrupts. It clears all bits
- // in intstatus corresponding to Cause IP*. The
- // MIPS register Cause is updated by updateIntrInfo
- // which is called by checkInterrupts
- //
- void clearAll();
-
- // getInterrupt(ThreadContext * tc) checks if an interrupt
- // should be returned. It ands the interrupt mask and
- // and interrupt pending bits to see if one exists. It
- // also makes sure interrupts are enabled (IE) and
- // that ERL and ERX are not set
- //
- Fault getInterrupt(ThreadContext * tc);
-
- // updateIntrInfo(ThreadContext *tc) const syncs the
- // MIPS cause register with the instatus variable. instatus
- // is essentially a copy of the MIPS cause[IP7:IP0]
- //
- void updateIntrInfo(ThreadContext *tc) const;
- void updateIntrInfoCpuTimerIntr(ThreadContext *tc) const;
- bool onCpuTimerInterrupt(ThreadContext *tc) const;
-
- bool checkInterrupts(ThreadContext *tc) const {
- //return (intstatus != 0) && !(tc->readPC() & 0x3);
- if (oncputimerintr == false){
- updateIntrInfo(tc);
- return ((intstatus != 0) || onCpuTimerInterrupt(tc));
- }
- else
- return true;
-
- }
- */
-
-
- protected:
- //uint8_t intstatus;
- //bool oncputimerintr;
public:
- Interrupts()
+ typedef MipsInterruptsParams Params;
+
+ const Params *
+ params() const
{
- //intstatus = 0;
- newInfoSet = false;
- //oncputimerintr = false;
+ return dynamic_cast<const Params *>(_params);
+ }
+ Interrupts(Params * p) : SimObject(p)
+ {
+ newInfoSet = false;
}
+
+ void
+ setCPU(BaseCPU *_cpu)
+ {}
+
// post(int int_num, int index) is responsible
// for posting an interrupt. It sets a bit
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
// which is called by checkInterrupts
//
- void post(int int_num, ThreadContext* tc);
+ void post(int int_num, ThreadContext *tc);
void post(int int_num, int index);
// clear(int int_num, int index) is responsible
@@ -139,7 +90,7 @@ class Interrupts
// MIPS register Cause is updated by updateIntrInfo
// which is called by checkInterrupts
//
- void clearAll(ThreadContext* tc);
+ void clearAll(ThreadContext *tc);
void clearAll();
// getInterrupt(ThreadContext * tc) checks if an interrupt
@@ -148,7 +99,7 @@ class Interrupts
// also makes sure interrupts are enabled (IE) and
// that ERL and ERX are not set
//
- Fault getInterrupt(ThreadContext * tc);
+ Fault getInterrupt(ThreadContext *tc);
// updateIntrInfo(ThreadContext *tc) const syncs the
// MIPS cause register with the instatus variable. instatus
@@ -165,27 +116,22 @@ class Interrupts
}
- void serialize(std::ostream &os)
+ void
+ serialize(std::ostream &os)
{
fatal("Serialization of Interrupts Unimplemented for MIPS");
- //SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
- //SERIALIZE_SCALAR(intstatus);
}
- void unserialize(Checkpoint *cp, const std::string &section)
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
{
fatal("Unserialization of Interrupts Unimplemented for MIPS");
- //UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
- //UNSERIALIZE_SCALAR(intstatus);
}
-
-
private:
bool newInfoSet;
int newIpl;
int newSummary;
-
};
}
diff --git a/src/arch/mips/isa.cc b/src/arch/mips/isa.cc
index f03a72e98..6ef6f9f41 100644
--- a/src/arch/mips/isa.cc
+++ b/src/arch/mips/isa.cc
@@ -110,8 +110,8 @@ ISA::init()
miscRegFile_WriteMask.resize(NumMiscRegs);
- for (int i=0; i < NumMiscRegs; i++) {
- miscRegFile_WriteMask[i].push_back(0);
+ for (int i = 0; i < NumMiscRegs; i++) {
+ miscRegFile_WriteMask[i].push_back(0);
}
clear(0);
}
@@ -181,253 +181,244 @@ ISA::reset(std::string core_name, ThreadID num_threads,
// ===================================================
DPRINTF(MipsPRA, "Initializing CP0 State.... ");
- MiscReg ProcID = readMiscRegNoEffect(PRId);
- replaceBits(ProcID,PRIdCoOp_HI,PRIdCoOp_LO,cp.CP0_PRId_CompanyOptions);
- replaceBits(ProcID,PRIdCoID_HI,PRIdCoID_LO,cp.CP0_PRId_CompanyID);
- replaceBits(ProcID,PRIdProc_ID_HI,PRIdProc_ID_LO,cp.CP0_PRId_ProcessorID);
- replaceBits(ProcID,PRIdRev_HI,PRIdRev_LO,cp.CP0_PRId_Revision);
- setMiscRegNoEffect(PRId,ProcID);
+ PRIdReg procId = readMiscRegNoEffect(PRId);
+ procId.coOp = cp.CP0_PRId_CompanyOptions;
+ procId.coId = cp.CP0_PRId_CompanyID;
+ procId.procId = cp.CP0_PRId_ProcessorID;
+ procId.rev = cp.CP0_PRId_Revision;
+ setMiscRegNoEffect(PRId, procId);
+
// Now, create Write Mask for ProcID register
MiscReg ProcID_Mask = 0; // Read-Only register
- replaceBits(ProcID_Mask,0,32,0);
- setRegMask(PRId,ProcID_Mask);
+ replaceBits(ProcID_Mask, 0, 32, 0);
+ setRegMask(PRId, ProcID_Mask);
// Config
- MiscReg cfg = readMiscRegNoEffect(Config);
- replaceBits(cfg, Config_BE_HI, Config_BE_LO, cp.CP0_Config_BE);
- replaceBits(cfg, Config_AT_HI, Config_AT_LO, cp.CP0_Config_AT);
- replaceBits(cfg, Config_AR_HI, Config_AR_LO, cp.CP0_Config_AR);
- replaceBits(cfg, Config_MT_HI, Config_MT_LO, cp.CP0_Config_MT);
- replaceBits(cfg, Config_VI_HI, Config_VI_LO, cp.CP0_Config_VI);
- replaceBits(cfg, Config_M, 1);
+ ConfigReg cfg = readMiscRegNoEffect(Config);
+ cfg.be = cp.CP0_Config_BE;
+ cfg.at = cp.CP0_Config_AT;
+ cfg.ar = cp.CP0_Config_AR;
+ cfg.mt = cp.CP0_Config_MT;
+ cfg.vi = cp.CP0_Config_VI;
+ cfg.m = 1;
setMiscRegNoEffect(Config, cfg);
// Now, create Write Mask for Config register
MiscReg cfg_Mask = 0x7FFF0007;
- replaceBits(cfg_Mask,0,32,0);
- setRegMask(Config,cfg_Mask);
+ replaceBits(cfg_Mask, 0, 32, 0);
+ setRegMask(Config, cfg_Mask);
// Config1
- MiscReg cfg1 = readMiscRegNoEffect(Config1);
- replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO,
- cp.CP0_Config1_MMU);
- replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, cp.CP0_Config1_IS);
- replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, cp.CP0_Config1_IL);
- replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, cp.CP0_Config1_IA);
- replaceBits(cfg1, Config1_DS_HI, Config1_DS_LO, cp.CP0_Config1_DS);
- replaceBits(cfg1, Config1_DL_HI, Config1_DL_LO, cp.CP0_Config1_DL);
- replaceBits(cfg1, Config1_DA_HI, Config1_DA_LO, cp.CP0_Config1_DA);
- replaceBits(cfg1, Config1_FP_HI, Config1_FP_LO, cp.CP0_Config1_FP);
- replaceBits(cfg1, Config1_EP_HI, Config1_EP_LO, cp.CP0_Config1_EP);
- replaceBits(cfg1, Config1_WR_HI, Config1_WR_LO, cp.CP0_Config1_WR);
- replaceBits(cfg1, Config1_MD_HI, Config1_MD_LO, cp.CP0_Config1_MD);
- replaceBits(cfg1, Config1_C2_HI, Config1_C2_LO, cp.CP0_Config1_C2);
- replaceBits(cfg1, Config1_PC_HI, Config1_PC_LO, cp.CP0_Config1_PC);
- replaceBits(cfg1, Config1_M, cp.CP0_Config1_M);
+ Config1Reg cfg1 = readMiscRegNoEffect(Config1);
+ cfg1.mmuSize = cp.CP0_Config1_MMU;
+ cfg1.is = cp.CP0_Config1_IS;
+ cfg1.il = cp.CP0_Config1_IL;
+ cfg1.ia = cp.CP0_Config1_IA;
+ cfg1.ds = cp.CP0_Config1_DS;
+ cfg1.dl = cp.CP0_Config1_DL;
+ cfg1.da = cp.CP0_Config1_DA;
+ cfg1.fp = cp.CP0_Config1_FP;
+ cfg1.ep = cp.CP0_Config1_EP;
+ cfg1.wr = cp.CP0_Config1_WR;
+ cfg1.md = cp.CP0_Config1_MD;
+ cfg1.c2 = cp.CP0_Config1_C2;
+ cfg1.pc = cp.CP0_Config1_PC;
+ cfg1.m = cp.CP0_Config1_M;
setMiscRegNoEffect(Config1, cfg1);
// Now, create Write Mask for Config register
MiscReg cfg1_Mask = 0; // Read Only Register
- replaceBits(cfg1_Mask,0,32,0);
- setRegMask(Config1,cfg1_Mask);
+ replaceBits(cfg1_Mask, 0, 32, 0);
+ setRegMask(Config1, cfg1_Mask);
// Config2
- MiscReg cfg2 = readMiscRegNoEffect(Config2);
- replaceBits(cfg2, Config2_TU_HI, Config2_TU_LO, cp.CP0_Config2_TU);
- replaceBits(cfg2, Config2_TS_HI, Config2_TS_LO, cp.CP0_Config2_TS);
- replaceBits(cfg2, Config2_TL_HI, Config2_TL_LO, cp.CP0_Config2_TL);
- replaceBits(cfg2, Config2_TA_HI, Config2_TA_LO, cp.CP0_Config2_TA);
- replaceBits(cfg2, Config2_SU_HI, Config2_SU_LO, cp.CP0_Config2_SU);
- replaceBits(cfg2, Config2_SS_HI, Config2_SS_LO, cp.CP0_Config2_SS);
- replaceBits(cfg2, Config2_SL_HI, Config2_SL_LO, cp.CP0_Config2_SL);
- replaceBits(cfg2, Config2_SA_HI, Config2_SA_LO, cp.CP0_Config2_SA);
- replaceBits(cfg2, Config2_M, cp.CP0_Config2_M);
+ Config2Reg cfg2 = readMiscRegNoEffect(Config2);
+ cfg2.tu = cp.CP0_Config2_TU;
+ cfg2.ts = cp.CP0_Config2_TS;
+ cfg2.tl = cp.CP0_Config2_TL;
+ cfg2.ta = cp.CP0_Config2_TA;
+ cfg2.su = cp.CP0_Config2_SU;
+ cfg2.ss = cp.CP0_Config2_SS;
+ cfg2.sl = cp.CP0_Config2_SL;
+ cfg2.sa = cp.CP0_Config2_SA;
+ cfg2.m = cp.CP0_Config2_M;
setMiscRegNoEffect(Config2, cfg2);
// Now, create Write Mask for Config register
MiscReg cfg2_Mask = 0x7000F000; // Read Only Register
- replaceBits(cfg2_Mask,0,32,0);
- setRegMask(Config2,cfg2_Mask);
+ replaceBits(cfg2_Mask, 0, 32, 0);
+ setRegMask(Config2, cfg2_Mask);
// Config3
- MiscReg cfg3 = readMiscRegNoEffect(Config3);
- replaceBits(cfg3, Config3_DSPP_HI, Config3_DSPP_LO, cp.CP0_Config3_DSPP);
- replaceBits(cfg3, Config3_LPA_HI, Config3_LPA_LO, cp.CP0_Config3_LPA);
- replaceBits(cfg3, Config3_VEIC_HI, Config3_VEIC_LO, cp.CP0_Config3_VEIC);
- replaceBits(cfg3, Config3_VINT_HI, Config3_VINT_LO, cp.CP0_Config3_VInt);
- replaceBits(cfg3, Config3_SP_HI, Config3_SP_LO, cp.CP0_Config3_SP);
- replaceBits(cfg3, Config3_MT_HI, Config3_MT_LO, cp.CP0_Config3_MT);
- replaceBits(cfg3, Config3_SM_HI, Config3_SM_LO, cp.CP0_Config3_SM);
- replaceBits(cfg3, Config3_TL_HI, Config3_TL_LO, cp.CP0_Config3_TL);
+ Config3Reg cfg3 = readMiscRegNoEffect(Config3);
+ cfg3.dspp = cp.CP0_Config3_DSPP;
+ cfg3.lpa = cp.CP0_Config3_LPA;
+ cfg3.veic = cp.CP0_Config3_VEIC;
+ cfg3.vint = cp.CP0_Config3_VInt;
+ cfg3.sp = cp.CP0_Config3_SP;
+ cfg3.mt = cp.CP0_Config3_MT;
+ cfg3.sm = cp.CP0_Config3_SM;
+ cfg3.tl = cp.CP0_Config3_TL;
setMiscRegNoEffect(Config3, cfg3);
// Now, create Write Mask for Config register
MiscReg cfg3_Mask = 0; // Read Only Register
- replaceBits(cfg3_Mask,0,32,0);
- setRegMask(Config3,cfg3_Mask);
+ replaceBits(cfg3_Mask, 0, 32, 0);
+ setRegMask(Config3, cfg3_Mask);
// EBase - CPUNum
- MiscReg EB = readMiscRegNoEffect(EBase);
- replaceBits(EB, EBase_CPUNum_HI, EBase_CPUNum_LO, cp.CP0_EBase_CPUNum);
- replaceBits(EB, 31, 31, 1);
- setMiscRegNoEffect(EBase, EB);
+ EBaseReg eBase = readMiscRegNoEffect(EBase);
+ eBase.cpuNum = cp.CP0_EBase_CPUNum;
+ replaceBits(eBase, 31, 31, 1);
+ setMiscRegNoEffect(EBase, eBase);
// Now, create Write Mask for Config register
MiscReg EB_Mask = 0x3FFFF000;// Except Exception Base, the
// entire register is read only
- replaceBits(EB_Mask,0,32,0);
- setRegMask(EBase,EB_Mask);
+ replaceBits(EB_Mask, 0, 32, 0);
+ setRegMask(EBase, EB_Mask);
// SRS Control - HSS (Highest Shadow Set)
- MiscReg SC = readMiscRegNoEffect(SRSCtl);
- replaceBits(SC, SRSCtl_HSS_HI,SRSCtl_HSS_LO,cp.CP0_SrsCtl_HSS);
- setMiscRegNoEffect(SRSCtl, SC);
+ SRSCtlReg scsCtl = readMiscRegNoEffect(SRSCtl);
+ scsCtl.hss = cp.CP0_SrsCtl_HSS;
+ setMiscRegNoEffect(SRSCtl, scsCtl);
// Now, create Write Mask for the SRS Ctl register
MiscReg SC_Mask = 0x0000F3C0;
- replaceBits(SC_Mask,0,32,0);
- setRegMask(SRSCtl,SC_Mask);
+ replaceBits(SC_Mask, 0, 32, 0);
+ setRegMask(SRSCtl, SC_Mask);
// IntCtl - IPTI, IPPCI
- MiscReg IC = readMiscRegNoEffect(IntCtl);
- replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,cp.CP0_IntCtl_IPTI);
- replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,cp.CP0_IntCtl_IPPCI);
- setMiscRegNoEffect(IntCtl, IC);
+ IntCtlReg intCtl = readMiscRegNoEffect(IntCtl);
+ intCtl.ipti = cp.CP0_IntCtl_IPTI;
+ intCtl.ippci = cp.CP0_IntCtl_IPPCI;
+ setMiscRegNoEffect(IntCtl, intCtl);
// Now, create Write Mask for the IntCtl register
MiscReg IC_Mask = 0x000003E0;
- replaceBits(IC_Mask,0,32,0);
- setRegMask(IntCtl,IC_Mask);
+ replaceBits(IC_Mask, 0, 32, 0);
+ setRegMask(IntCtl, IC_Mask);
// Watch Hi - M - FIXME (More than 1 Watch register)
- MiscReg WHi = readMiscRegNoEffect(WatchHi0);
- replaceBits(WHi, WatchHi_M, cp.CP0_WatchHi_M);
- setMiscRegNoEffect(WatchHi0, WHi);
+ WatchHiReg watchHi = readMiscRegNoEffect(WatchHi0);
+ watchHi.m = cp.CP0_WatchHi_M;
+ setMiscRegNoEffect(WatchHi0, watchHi);
// Now, create Write Mask for the IntCtl register
MiscReg wh_Mask = 0x7FFF0FFF;
- replaceBits(wh_Mask,0,32,0);
- setRegMask(WatchHi0,wh_Mask);
+ replaceBits(wh_Mask, 0, 32, 0);
+ setRegMask(WatchHi0, wh_Mask);
// Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
- MiscReg PCtr = readMiscRegNoEffect(PerfCnt0);
- replaceBits(PCtr, PerfCntCtl_M, cp.CP0_PerfCtr_M);
- replaceBits(PCtr, PerfCntCtl_W, cp.CP0_PerfCtr_W);
- setMiscRegNoEffect(PerfCnt0, PCtr);
+ PerfCntCtlReg perfCntCtl = readMiscRegNoEffect(PerfCnt0);
+ perfCntCtl.m = cp.CP0_PerfCtr_M;
+ perfCntCtl.w = cp.CP0_PerfCtr_W;
+ setMiscRegNoEffect(PerfCnt0, perfCntCtl);
// Now, create Write Mask for the IntCtl register
MiscReg pc_Mask = 0x00007FF;
- replaceBits(pc_Mask,0,32,0);
- setRegMask(PerfCnt0,pc_Mask);
+ replaceBits(pc_Mask, 0, 32, 0);
+ setRegMask(PerfCnt0, pc_Mask);
// Random
- MiscReg random = readMiscRegNoEffect(CP0_Random);
- random = 63;
- setMiscRegNoEffect(CP0_Random, random);
+ setMiscRegNoEffect(CP0_Random, 63);
// Now, create Write Mask for the IntCtl register
MiscReg random_Mask = 0;
- replaceBits(random_Mask,0,32,0);
- setRegMask(CP0_Random,random_Mask);
+ replaceBits(random_Mask, 0, 32, 0);
+ setRegMask(CP0_Random, random_Mask);
// PageGrain
- MiscReg pagegrain = readMiscRegNoEffect(PageGrain);
- replaceBits(pagegrain,PageGrain_ESP,cp.CP0_Config3_SP);
- setMiscRegNoEffect(PageGrain, pagegrain);
+ PageGrainReg pageGrain = readMiscRegNoEffect(PageGrain);
+ pageGrain.esp = cp.CP0_Config3_SP;
+ setMiscRegNoEffect(PageGrain, pageGrain);
// Now, create Write Mask for the IntCtl register
MiscReg pg_Mask = 0x10000000;
- replaceBits(pg_Mask,0,32,0);
- setRegMask(PageGrain,pg_Mask);
+ replaceBits(pg_Mask, 0, 32, 0);
+ setRegMask(PageGrain, pg_Mask);
// Status
- MiscReg stat = readMiscRegNoEffect(Status);
+ StatusReg status = readMiscRegNoEffect(Status);
// Only CU0 and IE are modified on a reset - everything else needs
// to be controlled on a per CPU model basis
// Enable CP0 on reset
- // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1);
+ // status.cu0 = 1;
// Enable ERL bit on a reset
- replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1);
-
+ status.erl = 1;
// Enable BEV bit on a reset
- replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1);
+ status.bev = 1;
- setMiscRegNoEffect(Status, stat);
+ setMiscRegNoEffect(Status, status);
// Now, create Write Mask for the Status register
MiscReg stat_Mask = 0xFF78FF17;
- replaceBits(stat_Mask,0,32,0);
- setRegMask(Status,stat_Mask);
+ replaceBits(stat_Mask, 0, 32, 0);
+ setRegMask(Status, stat_Mask);
// MVPConf0
- MiscReg mvp_conf0 = readMiscRegNoEffect(MVPConf0);
- replaceBits(mvp_conf0, MVPC0_TCA, 1);
- replaceBits(mvp_conf0, MVPC0_PVPE_HI, MVPC0_PVPE_LO, num_vpes - 1);
- replaceBits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO, num_threads - 1);
- setMiscRegNoEffect(MVPConf0, mvp_conf0);
+ MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MVPConf0);
+ mvpConf0.tca = 1;
+ mvpConf0.pvpe = num_vpes - 1;
+ mvpConf0.ptc = num_threads - 1;
+ setMiscRegNoEffect(MVPConf0, mvpConf0);
// VPEConf0
- MiscReg vpe_conf0 = readMiscRegNoEffect(VPEConf0);
- replaceBits(vpe_conf0, VPEC0_MVP, 1);
- setMiscRegNoEffect(VPEConf0, vpe_conf0);
+ VPEConf0Reg vpeConf0 = readMiscRegNoEffect(VPEConf0);
+ vpeConf0.mvp = 1;
+ setMiscRegNoEffect(VPEConf0, vpeConf0);
// TCBind
for (ThreadID tid = 0; tid < num_threads; tid++) {
- MiscReg tc_bind = readMiscRegNoEffect(TCBind, tid);
- replaceBits(tc_bind, TCB_CUR_TC_HI, TCB_CUR_TC_LO, tid);
- setMiscRegNoEffect(TCBind, tc_bind, tid);
+ TCBindReg tcBind = readMiscRegNoEffect(TCBind, tid);
+ tcBind.curTC = tid;
+ setMiscRegNoEffect(TCBind, tcBind, tid);
}
// TCHalt
- MiscReg tc_halt = readMiscRegNoEffect(TCHalt);
- replaceBits(tc_halt, TCH_H, 0);
- setMiscRegNoEffect(TCHalt, tc_halt);
- /*for (ThreadID tid = 1; tid < num_threads; tid++) {
- // Set TCHalt Halt bit to 1 for all other threads
- tc_halt = readMiscRegNoEffect(TCHalt, tid);
- replaceBits(tc_halt, TCH_H, 1);
- setReg(TCHalt, tc_halt, tid);
- }*/
+ TCHaltReg tcHalt = readMiscRegNoEffect(TCHalt);
+ tcHalt.h = 0;
+ setMiscRegNoEffect(TCHalt, tcHalt);
// TCStatus
// Set TCStatus Activated to 1 for the initial thread that is running
- MiscReg tc_status = readMiscRegNoEffect(TCStatus);
- replaceBits(tc_status, TCS_A, 1);
- setMiscRegNoEffect(TCStatus, tc_status);
+ TCStatusReg tcStatus = readMiscRegNoEffect(TCStatus);
+ tcStatus.a = 1;
+ setMiscRegNoEffect(TCStatus, tcStatus);
// Set Dynamically Allocatable bit to 1 for all other threads
for (ThreadID tid = 1; tid < num_threads; tid++) {
- tc_status = readMiscRegNoEffect(TCStatus, tid);
- replaceBits(tc_status, TCSTATUS_DA, 1);
- setMiscRegNoEffect(TCStatus, tc_status, tid);
+ tcStatus = readMiscRegNoEffect(TCStatus, tid);
+ tcStatus.da = 1;
+ setMiscRegNoEffect(TCStatus, tcStatus, tid);
}
MiscReg Mask = 0x7FFFFFFF;
// Now, create Write Mask for the Index register
- replaceBits(Mask,0,32,0);
- setRegMask(Index,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(Index, Mask);
Mask = 0x3FFFFFFF;
- replaceBits(Mask,0,32,0);
- setRegMask(EntryLo0,Mask);
- setRegMask(EntryLo1,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(EntryLo0, Mask);
+ setRegMask(EntryLo1, Mask);
Mask = 0xFF800000;
- replaceBits(Mask,0,32,0);
- setRegMask(Context,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(Context, Mask);
Mask = 0x1FFFF800;
- replaceBits(Mask,0,32,0);
- setRegMask(PageMask,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(PageMask, Mask);
Mask = 0x0;
- replaceBits(Mask,0,32,0);
- setRegMask(BadVAddr,Mask);
- setRegMask(LLAddr,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(BadVAddr, Mask);
+ setRegMask(LLAddr, Mask);
Mask = 0x08C00300;
- replaceBits(Mask,0,32,0);
- setRegMask(Cause,Mask);
+ replaceBits(Mask, 0, 32, 0);
+ setRegMask(Cause, Mask);
}
inline unsigned
ISA::getVPENum(ThreadID tid)
{
- unsigned tc_bind = miscRegFile[TCBind - Ctrl_Base_DepTag][tid];
- return bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+ TCBindReg tcBind = miscRegFile[TCBind - Ctrl_Base_DepTag][tid];
+ return tcBind.curVPE;
}
MiscReg
@@ -456,12 +447,7 @@ ISA::readMiscReg(int reg_idx, ThreadContext *tc, ThreadID tid)
misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
miscRegFile[misc_reg][reg_sel]);
-
- switch (misc_reg)
- {
- default:
- return miscRegFile[misc_reg][reg_sel];
- }
+ return miscRegFile[misc_reg][reg_sel];
}
void
@@ -495,7 +481,6 @@ ISA::setRegMask(int reg_idx, const MiscReg &val, ThreadID tid)
// (1) Some CP0 Registers have fields that cannot
// be overwritten. Make sure to handle those particular registers
// with care!
-//template <class TC>
void
ISA::setMiscReg(int reg_idx, const MiscReg &val,
ThreadContext *tc, ThreadID tid)
@@ -524,21 +509,21 @@ ISA::setMiscReg(int reg_idx, const MiscReg &val,
MiscReg
ISA::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val)
{
- MiscReg retVal = val;
-
- // Mask off read-only regions
- retVal &= miscRegFile_WriteMask[misc_reg][reg_sel];
- MiscReg curVal = miscRegFile[misc_reg][reg_sel];
- // Mask off current alue with inverse mask (clear writeable bits)
- curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]);
- retVal |= curVal; // Combine the two
- DPRINTF(MipsPRA,
- "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
- "current val: %lx, written val: %x\n",
- miscRegFile_WriteMask[misc_reg][reg_sel],
- ~miscRegFile_WriteMask[misc_reg][reg_sel],
- val, miscRegFile[misc_reg][reg_sel], retVal);
- return retVal;
+ MiscReg retVal = val;
+
+ // Mask off read-only regions
+ retVal &= miscRegFile_WriteMask[misc_reg][reg_sel];
+ MiscReg curVal = miscRegFile[misc_reg][reg_sel];
+ // Mask off current alue with inverse mask (clear writeable bits)
+ curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]);
+ retVal |= curVal; // Combine the two
+ DPRINTF(MipsPRA,
+ "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
+ "current val: %lx, written val: %x\n",
+ miscRegFile_WriteMask[misc_reg][reg_sel],
+ ~miscRegFile_WriteMask[misc_reg][reg_sel],
+ val, miscRegFile[misc_reg][reg_sel], retVal);
+ return retVal;
}
void
@@ -561,22 +546,22 @@ ISA::updateCPU()
// EVALUATE CP0 STATE FOR MIPS MT
//
///////////////////////////////////////////////////////////////////
- unsigned mvp_conf0 = readMiscRegNoEffect(MVPConf0);
- ThreadID num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MVPConf0);
+ ThreadID num_threads = mvpConf0.ptc + 1;
for (ThreadID tid = 0; tid < num_threads; tid++) {
- MiscReg tc_status = readMiscRegNoEffect(TCStatus, tid);
- MiscReg tc_halt = readMiscRegNoEffect(TCHalt, tid);
+ TCStatusReg tcStatus = readMiscRegNoEffect(TCStatus, tid);
+ TCHaltReg tcHalt = readMiscRegNoEffect(TCHalt, tid);
//@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
- if (bits(tc_halt, TCH_H) == 1 || bits(tc_status, TCS_A) == 0) {
+ if (tcHalt.h == 1 || tcStatus.a == 0) {
haltThread(cpu->getContext(tid));
- } else if (bits(tc_halt, TCH_H) == 0 && bits(tc_status, TCS_A) == 1) {
+ } else if (tcHalt.h == 0 && tcStatus.a == 1) {
restoreThread(cpu->getContext(tid));
}
}
- num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ num_threads = mvpConf0.ptc + 1;
// Toggle update flag after we finished updating
cp0Updated = false;
@@ -595,8 +580,6 @@ ISA::CP0Event::process()
cp0->updateCPU();
break;
}
-
- //cp0EventRemoveList.push(this);
}
const char *
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index a463093ec..60bc15513 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -120,8 +120,22 @@ decode OPCODE_HI default Unknown::unknown() {
//used to distinguish JR from JR.HB and JALR from JALR.HB"
format Jump {
0x0: decode HINT {
- 0x1: jr_hb({{ if(Config1_CA == 0){NNPC = Rs;}else{panic("MIPS16e not supported\n");}; }}, IsReturn, ClearHazards);
- default: jr({{ if(Config1_CA == 0){NNPC = Rs;}else{panic("MIPS16e not supported\n");};}}, IsReturn);
+ 0x1: jr_hb({{
+ Config1Reg config1 = Config1;
+ if (config1.ca == 0) {
+ NNPC = Rs;
+ } else {
+ panic("MIPS16e not supported\n");
+ }
+ }}, IsReturn, ClearHazards);
+ default: jr({{
+ Config1Reg config1 = Config1;
+ if (config1.ca == 0) {
+ NNPC = Rs;
+ } else {
+ panic("MIPS16e not supported\n");
+ }
+ }}, IsReturn);
}
0x1: decode HINT {
@@ -351,25 +365,32 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode RS_MSB {
0x0: decode RS {
format CP0Control {
- 0x0: mfc0({{ Rt = CP0_RD_SEL;
- /* Hack for PageMask */
- if(RD == 5) // PageMask
- if(Config3_SP == 0 || PageGrain_ESP == 0)
- Rt &= 0xFFFFE7FF;
- }});
- 0x4: mtc0({{ CP0_RD_SEL = Rt;
-
- if(RD == 11) // Compare{
- if(Cause_TI == 1){
- Cause_TI = 0;
- MiscReg cause = xc->readMiscRegNoEffect(MipsISA::Cause);
- int Offset = 10; // corresponding to Cause_IP0
- Offset += ((IntCtl_IPTI) - 2);
- replaceBits(cause,Offset,Offset,0);
- xc->setMiscRegNoEffect(MipsISA::Cause,cause);
- }
-
- }});
+ 0x0: mfc0({{
+ Config3Reg config3 = Config3;
+ PageGrainReg pageGrain = PageGrain;
+ Rt = CP0_RD_SEL;
+ /* Hack for PageMask */
+ if (RD == 5) {
+ // PageMask
+ if(config3.sp == 0 || pageGrain.esp == 0)
+ Rt &= 0xFFFFE7FF;
+ }
+ }});
+ 0x4: mtc0({{
+ CP0_RD_SEL = Rt;
+ CauseReg cause = Cause;
+ IntCtlReg intCtl = IntCtl;
+ if (RD == 11) {
+ // Compare
+ if (cause.ti == 1) {
+ cause.ti = 0;
+ int offset = 10; // corresponding to cause.ip0
+ offset += intCtl.ipti - 2;
+ replaceBits(cause, offset, offset, 0);
+ }
+ }
+ Cause = cause;
+ }});
}
format CP0Unimpl {
0x1: dmfc0();
@@ -378,9 +399,10 @@ decode OPCODE_HI default Unknown::unknown() {
}
format MT_MFTR { // Decode MIPS MT MFTR instruction into sub-instructions
0x8: decode MT_U {
- 0x0: mftc0({{ data = xc->readRegOtherThread((RT << 3 | SEL) +
- Ctrl_Base_DepTag);
- }});
+ 0x0: mftc0({{
+ data = xc->readRegOtherThread((RT << 3 | SEL) +
+ Ctrl_Base_DepTag);
+ }});
0x1: decode SEL {
0x0: mftgpr({{ data = xc->readRegOtherThread(RT); }});
0x1: decode RT {
@@ -537,16 +559,22 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode POS {
0x0: decode SEL {
0x1: decode SC {
- 0x0: dvpe({{ Rt = MVPControl;
- if (VPEConf0<VPEC0_MVP:> == 1) {
- MVPControl = insertBits(MVPControl, MVPC_EVP, 0);
- }
- }});
- 0x1: evpe({{ Rt = MVPControl;
- if (VPEConf0<VPEC0_MVP:> == 1) {
- MVPControl = insertBits(MVPControl, MVPC_EVP, 1);
- }
- }});
+ 0x0: dvpe({{
+ MVPControlReg mvpControl = MVPControl;
+ VPEConf0Reg vpeConf0 = VPEConf0;
+ Rt = MVPControl;
+ if (vpeConf0.mvp == 1)
+ mvpControl.evp = 0;
+ MVPControl = mvpControl;
+ }});
+ 0x1: evpe({{
+ MVPControlReg mvpControl = MVPControl;
+ VPEConf0Reg vpeConf0 = VPEConf0;
+ Rt = MVPControl;
+ if (vpeConf0.mvp == 1)
+ mvpControl.evp = 1;
+ MVPControl = mvpControl;
+ }});
default:CP0Unimpl::unknown();
}
default:CP0Unimpl::unknown();
@@ -557,12 +585,18 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode POS {
0xF: decode SEL {
0x1: decode SC {
- 0x0: dmt({{ Rt = VPEControl;
- VPEControl = insertBits(VPEControl, VPEC_TE, 0);
- }});
- 0x1: emt({{ Rt = VPEControl;
- VPEControl = insertBits(VPEControl, VPEC_TE, 1);
- }});
+ 0x0: dmt({{
+ VPEControlReg vpeControl = VPEControl;
+ Rt = vpeControl;
+ vpeControl.te = 0;
+ VPEControl = vpeControl;
+ }});
+ 0x1: emt({{
+ VPEControlReg vpeControl = VPEControl;
+ Rt = vpeControl;
+ vpeControl.te = 1;
+ VPEControl = vpeControl;
+ }});
default:CP0Unimpl::unknown();
}
default:CP0Unimpl::unknown();
@@ -573,27 +607,29 @@ decode OPCODE_HI default Unknown::unknown() {
0xC: decode POS {
0x0: decode SC {
0x0: CP0Control::di({{
- if(Config_AR >= 1) // Rev 2.0 or beyond?
- {
- Rt = Status;
- Status_IE = 0;
- }
- else // Enable this else branch once we actually set values for Config on init
- {
+ StatusReg status = Status;
+ ConfigReg config = Config;
+ // Rev 2.0 or beyond?
+ if (config.ar >= 1) {
+ Rt = status;
+ status.ie = 0;
+ } else {
+ // Enable this else branch once we
+ // actually set values for Config on init
fault = new ReservedInstructionFault();
- }
- }});
+ }
+ Status = status;
+ }});
0x1: CP0Control::ei({{
- if(Config_AR >= 1)
- {
- Rt = Status;
- Status_IE = 1;
- }
- else
- {
+ StatusReg status = Status;
+ ConfigReg config = Config;
+ if (config.ar >= 1) {
+ Rt = status;
+ status.ie = 1;
+ } else {
fault = new ReservedInstructionFault();
- }
- }});
+ }
+ }});
default:CP0Unimpl::unknown();
}
}
@@ -601,29 +637,23 @@ decode OPCODE_HI default Unknown::unknown() {
}
format CP0Control {
0xA: rdpgpr({{
- if(Config_AR >= 1)
- { // Rev 2 of the architecture
- panic("Shadow Sets Not Fully Implemented.\n");
- //Rd = xc->tcBase()->readIntReg(RT + NumIntRegs * SRSCtl_PSS);
- }
- else
- {
+ ConfigReg config = Config;
+ if (config.ar >= 1) {
+ // Rev 2 of the architecture
+ panic("Shadow Sets Not Fully Implemented.\n");
+ } else {
fault = new ReservedInstructionFault();
}
- }});
+ }});
0xE: wrpgpr({{
- if(Config_AR >= 1)
- { // Rev 2 of the architecture
- panic("Shadow Sets Not Fully Implemented.\n");
- //xc->tcBase()->setIntReg(RD + NumIntRegs * SRSCtl_PSS,Rt);
- // warn("Writing %d to %d, PSS: %d, SRS: %x\n",Rt,RD + NumIntRegs * SRSCtl_PSS, SRSCtl_PSS,SRSCtl);
+ ConfigReg config = Config;
+ if (config.ar >= 1) {
+ // Rev 2 of the architecture
+ panic("Shadow Sets Not Fully Implemented.\n");
+ } else {
+ fault = new ReservedInstructionFault();
}
- else
- {
- fault = new ReservedInstructionFault();
- }
-
- }});
+ }});
}
}
@@ -632,44 +662,43 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode FUNCTION {
format CP0Control {
0x18: eret({{
- DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC);
- // Ugly hack to get the value of Status_EXL
- if(Status_EXL == 1){
- DPRINTF(MipsPRA,"ERET EXL Hack\n");
- }
- if(Status_ERL == 1){
- Status_ERL = 0;
- NPC = ErrorEPC;
- NNPC = ErrorEPC + sizeof(MachInst); // Need to adjust NNPC, otherwise things break
- }
- else {
- NPC = EPC;
- NNPC = EPC + sizeof(MachInst); // Need to adjust NNPC, otherwise things break
- Status_EXL = 0;
- if(Config_AR >=1 && SRSCtl_HSS > 0 && Status_BEV == 0){
- SRSCtl_CSS = SRSCtl_PSS;
- //xc->setShadowSet(SRSCtl_PSS);
+ StatusReg status = Status;
+ ConfigReg config = Config;
+ SRSCtlReg srsCtl = SRSCtl;
+ DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC);
+ if (status.erl == 1) {
+ status.erl = 0;
+ NPC = ErrorEPC;
+ // Need to adjust NNPC, otherwise things break
+ NNPC = ErrorEPC + sizeof(MachInst);
+ } else {
+ NPC = EPC;
+ // Need to adjust NNPC, otherwise things break
+ NNPC = EPC + sizeof(MachInst);
+ status.exl = 0;
+ if (config.ar >=1 &&
+ srsCtl.hss > 0 &&
+ status.bev == 0) {
+ srsCtl.css = srsCtl.pss;
+ //xc->setShadowSet(srsCtl.pss);
+ }
}
- }
- LLFlag = 0;
- }},IsReturn,IsSerializing,IsERET);
+ LLFlag = 0;
+ Status = status;
+ SRSCtl = srsCtl;
+ }},IsReturn,IsSerializing,IsERET);
0x1F: deret({{
- // if(EJTagImplemented()) {
- if(Debug_DM == 1){
- Debug_DM = 1;
- Debug_IEXI = 0;
- NPC = DEPC;
- }
- else
- {
- // Undefined;
- }
- //} // EJTag Implemented
- //else {
- // Reserved Instruction Exception
- //}
- }},IsReturn,IsSerializing,IsERET);
+ DebugReg debug = Debug;
+ if (debug.dm == 1) {
+ debug.dm = 1;
+ debug.iexi = 0;
+ NPC = DEPC;
+ } else {
+ // Undefined;
+ }
+ Debug = debug;
+ }}, IsReturn, IsSerializing, IsERET);
}
format CP0TLB {
0x01: tlbr({{
@@ -689,140 +718,157 @@ decode OPCODE_HI default Unknown::unknown() {
}}); // Need to hook up to TLB
0x02: tlbwi({{
- //Create PTE
- MipsISA::PTE NewEntry;
- //Write PTE
- NewEntry.Mask = (Addr)(PageMask >> 11);
- NewEntry.VPN = (Addr)(EntryHi >> 11);
- /* PageGrain _ ESP Config3 _ SP */
- if(((PageGrain>>28) & 1) == 0 || ((Config3>>4)&1) ==0) {
- NewEntry.Mask |= 0x3; // If 1KB pages are *NOT* enabled, lowest bits of the mask are 0b11 for TLB writes
- NewEntry.VPN &= 0xFFFFFFFC; // Reset bits 0 and 1 if 1KB pages are not enabled
- }
- NewEntry.asid = (uint8_t)(EntryHi & 0xFF);
-
- NewEntry.PFN0 = (Addr)(EntryLo0 >> 6);
- NewEntry.PFN1 = (Addr)(EntryLo1 >> 6);
- NewEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
- NewEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
- NewEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
- NewEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
- NewEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
- NewEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
- NewEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
- /* Now, compute the AddrShiftAmount and OffsetMask - TLB optimizations */
- /* Addr Shift Amount for 1KB or larger pages */
- // warn("PTE->Mask: %x\n",pte->Mask);
- if((NewEntry.Mask & 0xFFFF) == 3){
- NewEntry.AddrShiftAmount = 12;
- } else if((NewEntry.Mask & 0xFFFF) == 0x0000){
- NewEntry.AddrShiftAmount = 10;
- } else if((NewEntry.Mask & 0xFFFC) == 0x000C){
- NewEntry.AddrShiftAmount = 14;
- } else if((NewEntry.Mask & 0xFFF0) == 0x0030){
- NewEntry.AddrShiftAmount = 16;
- } else if((NewEntry.Mask & 0xFFC0) == 0x00C0){
- NewEntry.AddrShiftAmount = 18;
- } else if((NewEntry.Mask & 0xFF00) == 0x0300){
- NewEntry.AddrShiftAmount = 20;
- } else if((NewEntry.Mask & 0xFC00) == 0x0C00){
- NewEntry.AddrShiftAmount = 22;
- } else if((NewEntry.Mask & 0xF000) == 0x3000){
- NewEntry.AddrShiftAmount = 24;
- } else if((NewEntry.Mask & 0xC000) == 0xC000){
- NewEntry.AddrShiftAmount = 26;
- } else if((NewEntry.Mask & 0x30000) == 0x30000){
- NewEntry.AddrShiftAmount = 28;
- } else {
- fatal("Invalid Mask Pattern Detected!\n");
- }
- NewEntry.OffsetMask = ((1<<NewEntry.AddrShiftAmount)-1);
-
- MipsISA::TLB *Ptr=xc->tcBase()->getITBPtr();
- MiscReg c3=xc->readMiscReg(MipsISA::Config3);
- MiscReg pg=xc->readMiscReg(MipsISA::PageGrain);
- int SP=0;
- if(bits(c3,Config3_SP)==1 && bits(pg,PageGrain_ESP)==1){
- SP=1;
- }
- Ptr->insertAt(NewEntry,Index & 0x7FFFFFFF,SP);
+ //Create PTE
+ MipsISA::PTE NewEntry;
+ //Write PTE
+ NewEntry.Mask = (Addr)(PageMask >> 11);
+ NewEntry.VPN = (Addr)(EntryHi >> 11);
+ /* PageGrain _ ESP Config3 _ SP */
+ if(((PageGrain>>28) & 1) == 0 || ((Config3>>4)&1) ==0) {
+ // If 1KB pages are *NOT* enabled, lowest bits of the
+ // mask are 0b11 for TLB writes
+ NewEntry.Mask |= 0x3;
+ // Reset bits 0 and 1 if 1KB pages are not enabled
+ NewEntry.VPN &= 0xFFFFFFFC;
+ }
+ NewEntry.asid = (uint8_t)(EntryHi & 0xFF);
+
+ NewEntry.PFN0 = (Addr)(EntryLo0 >> 6);
+ NewEntry.PFN1 = (Addr)(EntryLo1 >> 6);
+ NewEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
+ NewEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
+ NewEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
+ NewEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
+ NewEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
+ NewEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
+ NewEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
+ /* Now, compute the AddrShiftAmount and OffsetMask - TLB
+ optimizations */
+ /* Addr Shift Amount for 1KB or larger pages */
+ if ((NewEntry.Mask & 0xFFFF) == 3) {
+ NewEntry.AddrShiftAmount = 12;
+ } else if ((NewEntry.Mask & 0xFFFF) == 0x0000) {
+ NewEntry.AddrShiftAmount = 10;
+ } else if ((NewEntry.Mask & 0xFFFC) == 0x000C) {
+ NewEntry.AddrShiftAmount = 14;
+ } else if ((NewEntry.Mask & 0xFFF0) == 0x0030) {
+ NewEntry.AddrShiftAmount = 16;
+ } else if ((NewEntry.Mask & 0xFFC0) == 0x00C0) {
+ NewEntry.AddrShiftAmount = 18;
+ } else if ((NewEntry.Mask & 0xFF00) == 0x0300) {
+ NewEntry.AddrShiftAmount = 20;
+ } else if ((NewEntry.Mask & 0xFC00) == 0x0C00) {
+ NewEntry.AddrShiftAmount = 22;
+ } else if ((NewEntry.Mask & 0xF000) == 0x3000) {
+ NewEntry.AddrShiftAmount = 24;
+ } else if ((NewEntry.Mask & 0xC000) == 0xC000) {
+ NewEntry.AddrShiftAmount = 26;
+ } else if ((NewEntry.Mask & 0x30000) == 0x30000) {
+ NewEntry.AddrShiftAmount = 28;
+ } else {
+ fatal("Invalid Mask Pattern Detected!\n");
+ }
+ NewEntry.OffsetMask = ((1<<NewEntry.AddrShiftAmount)-1);
+
+ MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
+ Config3Reg config3 = Config3;
+ PageGrainReg pageGrain = PageGrain;
+ int SP = 0;
+ if (bits(config3, config3.sp) == 1 &&
+ bits(pageGrain, pageGrain.esp) == 1) {
+ SP = 1;
+ }
+ IndexReg index = Index;
+ Ptr->insertAt(NewEntry, Index & 0x7FFFFFFF, SP);
}});
0x06: tlbwr({{
- //Create PTE
- MipsISA::PTE NewEntry;
- //Write PTE
- NewEntry.Mask = (Addr)(PageMask >> 11);
- NewEntry.VPN = (Addr)(EntryHi >> 11);
- /* PageGrain _ ESP Config3 _ SP */
- if(((PageGrain>>28) & 1) == 0 || ((Config3>>4)&1) ==0) {
- NewEntry.Mask |= 0x3; // If 1KB pages are *NOT* enabled, lowest bits of the mask are 0b11 for TLB writes
- NewEntry.VPN &= 0xFFFFFFFC; // Reset bits 0 and 1 if 1KB pages are not enabled
- }
- NewEntry.asid = (uint8_t)(EntryHi & 0xFF);
-
- NewEntry.PFN0 = (Addr)(EntryLo0 >> 6);
- NewEntry.PFN1 = (Addr)(EntryLo1 >> 6);
- NewEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
- NewEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
- NewEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
- NewEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
- NewEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
- NewEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
- NewEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
- /* Now, compute the AddrShiftAmount and OffsetMask - TLB optimizations */
- /* Addr Shift Amount for 1KB or larger pages */
- // warn("PTE->Mask: %x\n",pte->Mask);
- if((NewEntry.Mask & 0xFFFF) == 3){
- NewEntry.AddrShiftAmount = 12;
- } else if((NewEntry.Mask & 0xFFFF) == 0x0000){
- NewEntry.AddrShiftAmount = 10;
- } else if((NewEntry.Mask & 0xFFFC) == 0x000C){
- NewEntry.AddrShiftAmount = 14;
- } else if((NewEntry.Mask & 0xFFF0) == 0x0030){
- NewEntry.AddrShiftAmount = 16;
- } else if((NewEntry.Mask & 0xFFC0) == 0x00C0){
- NewEntry.AddrShiftAmount = 18;
- } else if((NewEntry.Mask & 0xFF00) == 0x0300){
- NewEntry.AddrShiftAmount = 20;
- } else if((NewEntry.Mask & 0xFC00) == 0x0C00){
- NewEntry.AddrShiftAmount = 22;
- } else if((NewEntry.Mask & 0xF000) == 0x3000){
- NewEntry.AddrShiftAmount = 24;
- } else if((NewEntry.Mask & 0xC000) == 0xC000){
- NewEntry.AddrShiftAmount = 26;
- } else if((NewEntry.Mask & 0x30000) == 0x30000){
- NewEntry.AddrShiftAmount = 28;
- } else {
- fatal("Invalid Mask Pattern Detected!\n");
- }
- NewEntry.OffsetMask = ((1<<NewEntry.AddrShiftAmount)-1);
-
- MipsISA::TLB *Ptr=xc->tcBase()->getITBPtr();
- MiscReg c3=xc->readMiscReg(MipsISA::Config3);
- MiscReg pg=xc->readMiscReg(MipsISA::PageGrain);
- int SP=0;
- if(bits(c3,Config3_SP)==1 && bits(pg,PageGrain_ESP)==1){
- SP=1;
- }
- Ptr->insertAt(NewEntry,Random,SP);
+ //Create PTE
+ MipsISA::PTE NewEntry;
+ //Write PTE
+ NewEntry.Mask = (Addr)(PageMask >> 11);
+ NewEntry.VPN = (Addr)(EntryHi >> 11);
+ /* PageGrain _ ESP Config3 _ SP */
+ if (((PageGrain >> 28) & 1) == 0 ||
+ (( Config3 >> 4) & 1) ==0) {
+ // If 1KB pages are *NOT* enabled, lowest bits of
+ // the mask are 0b11 for TLB writes
+ NewEntry.Mask |= 0x3;
+ // Reset bits 0 and 1 if 1KB pages are not enabled
+ NewEntry.VPN &= 0xFFFFFFFC;
+ }
+ NewEntry.asid = (uint8_t)(EntryHi & 0xFF);
+
+ NewEntry.PFN0 = (Addr)(EntryLo0 >> 6);
+ NewEntry.PFN1 = (Addr)(EntryLo1 >> 6);
+ NewEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
+ NewEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
+ NewEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
+ NewEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
+ NewEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
+ NewEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
+ NewEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
+ /* Now, compute the AddrShiftAmount and OffsetMask -
+ TLB optimizations */
+ /* Addr Shift Amount for 1KB or larger pages */
+ if ((NewEntry.Mask & 0xFFFF) == 3){
+ NewEntry.AddrShiftAmount = 12;
+ } else if ((NewEntry.Mask & 0xFFFF) == 0x0000) {
+ NewEntry.AddrShiftAmount = 10;
+ } else if ((NewEntry.Mask & 0xFFFC) == 0x000C) {
+ NewEntry.AddrShiftAmount = 14;
+ } else if ((NewEntry.Mask & 0xFFF0) == 0x0030) {
+ NewEntry.AddrShiftAmount = 16;
+ } else if ((NewEntry.Mask & 0xFFC0) == 0x00C0) {
+ NewEntry.AddrShiftAmount = 18;
+ } else if ((NewEntry.Mask & 0xFF00) == 0x0300) {
+ NewEntry.AddrShiftAmount = 20;
+ } else if ((NewEntry.Mask & 0xFC00) == 0x0C00) {
+ NewEntry.AddrShiftAmount = 22;
+ } else if ((NewEntry.Mask & 0xF000) == 0x3000) {
+ NewEntry.AddrShiftAmount = 24;
+ } else if ((NewEntry.Mask & 0xC000) == 0xC000) {
+ NewEntry.AddrShiftAmount = 26;
+ } else if ((NewEntry.Mask & 0x30000) == 0x30000) {
+ NewEntry.AddrShiftAmount = 28;
+ } else {
+ fatal("Invalid Mask Pattern Detected!\n");
+ }
+ NewEntry.OffsetMask = ((1 << NewEntry.AddrShiftAmount) - 1);
+
+ MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
+ Config3Reg config3 = Config3;
+ PageGrainReg pageGrain = PageGrain;
+ int SP = 0;
+ if (bits(config3, config3.sp) == 1 &&
+ bits(pageGrain, pageGrain.esp) == 1) {
+ SP = 1;
+ }
+ IndexReg index = Index;
+ Ptr->insertAt(NewEntry, Random, SP);
}});
0x08: tlbp({{
- int TLB_Index;
- Addr VPN;
- if(PageGrain_ESP == 1 && Config3_SP ==1){
- VPN = EntryHi >> 11;
- } else {
- VPN = ((EntryHi >> 11) & 0xFFFFFFFC); // Mask off lower 2 bits
- }
- TLB_Index = xc->tcBase()->getITBPtr()->probeEntry(VPN,EntryHi_ASID);
- if(TLB_Index != -1){ // Check TLB for entry matching EntryHi
- Index=TLB_Index;
- // warn("\ntlbp: Match Found!\n");
- } else {// else, set Index = 1<<31
- Index = (1<<31);
- }
- }});
+ Config3Reg config3 = Config3;
+ PageGrainReg pageGrain = PageGrain;
+ EntryHiReg entryHi = EntryHi;
+ int TLB_Index;
+ Addr VPN;
+ if (pageGrain.esp == 1 && config3.sp ==1) {
+ VPN = EntryHi >> 11;
+ } else {
+ // Mask off lower 2 bits
+ VPN = ((EntryHi >> 11) & 0xFFFFFFFC);
+ }
+ TLB_Index = xc->tcBase()->getITBPtr()->
+ probeEntry(VPN, entryHi.asid);
+ // Check TLB for entry matching EntryHi
+ if (TLB_Index != -1) {
+ Index = TLB_Index;
+ } else {
+ // else, set Index = 1 << 31
+ Index = (1 << 31);
+ }
+ }});
}
format CP0Unimpl {
0x20: wait();
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
index 1928ee903..4f2d33709 100644
--- a/src/arch/mips/isa/formats/mt.isa
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -85,7 +85,10 @@ output decoder {{
}};
output exec {{
- void getThrRegExValues(%(CPU_exec_context)s *xc, unsigned &vpe_conf0, unsigned &tc_bind_mt, unsigned &tc_bind, unsigned &vpe_control, unsigned &mvp_conf0)
+ void getThrRegExValues(%(CPU_exec_context)s *xc,
+ VPEConf0Reg &vpe_conf0, TCBindReg &tc_bind_mt,
+ TCBindReg &tc_bind, VPEControlReg &vpe_control,
+ MVPConf0Reg &mvp_conf0)
{
vpe_conf0 = xc->readMiscReg(VPEConf0);
tc_bind_mt = xc->readRegOtherThread(TCBind + Ctrl_Base_DepTag);
@@ -94,7 +97,7 @@ output exec {{
mvp_conf0 = xc->readMiscReg(MVPConf0);
}
- void getMTExValues(%(CPU_exec_context)s *xc, unsigned &config3)
+ void getMTExValues(%(CPU_exec_context)s *xc, Config3Reg &config3)
{
config3 = xc->readMiscReg(Config3);
}
@@ -108,17 +111,19 @@ def template ThreadRegisterExecute {{
%(op_decl)s;
%(op_rd)s;
- unsigned vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0;
+ VPEConf0Reg vpeConf0;
+ TCBindReg tcBindMT;
+ TCBindReg tcBind;
+ VPEControlReg vpeControl;
+ MVPConf0Reg mvpConf0;
- getThrRegExValues(xc, vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0);
+ getThrRegExValues(xc, vpeConf0, tcBindMT,
+ tcBind, vpeControl, mvpConf0);
if (isCoprocessorEnabled(xc, 0)) {
- if (bits(vpe_conf0, VPEC0_MVP) == 0 &&
- bits(tc_bind_mt, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) !=
- bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
+ if (vpeConf0.mvp == 0 && tcBindMT.curVPE != tcBind.curVPE) {
data = -1;
- } else if (bits(vpe_control, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO) >
- bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO)) {
+ } else if (vpeControl.targTC > mvpConf0.ptc) {
data = -1;
} else {
int top_bit = 0;
@@ -154,12 +159,12 @@ def template MTExecute{{
%(op_decl)s;
%(op_rd)s;
- unsigned config3;
+ Config3Reg config3;
getMTExValues(xc, config3);
if (isCoprocessorEnabled(xc, 0)) {
- if (bits(config3, CFG3_MT) == 1) {
+ if (config3.mt == 1) {
%(code)s;
} else {
fault = new ReservedInstructionFault();
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
index c2733be9d..1af8857cc 100644
--- a/src/arch/mips/isa/operands.isa
+++ b/src/arch/mips/isa/operands.isa
@@ -140,43 +140,8 @@ def operands {{
'Config1': ('ControlReg','uw', 'MipsISA::Config1',None,1),
'Config2': ('ControlReg','uw', 'MipsISA::Config2',None,1),
'PageGrain': ('ControlReg','uw', 'MipsISA::PageGrain',None,1),
-
-
- # named bitfields of Control Regs
- 'Status_IE': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_ERL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_EXL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_BEV': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_CU3': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_CU2': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_CU1': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'Status_CU0': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
- 'SRSCtl_HSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
- 'SRSCtl_PSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
- 'SRSCtl_CSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
- 'Config_AR': ('ControlBitfield', 'uw', 'MipsISA::Config', None, 3),
- 'Config_MT': ('ControlBitfield', 'uw', 'MipsISA::Config', None, 1),
- 'Config1_CA': ('ControlBitfield', 'uw', 'MipsISA::Config1', None, 1),
- 'Config3_SP': ('ControlBitfield', 'uw', 'MipsISA::Config3', None, 1),
- 'PageGrain_ESP': ('ControlBitfield', 'uw', 'MipsISA::PageGrain', None, 1),
- 'Cause_EXCCODE': ('ControlBitfield', 'uw', 'MipsISA::Cause', None, 4),
- 'Cause_TI': ('ControlBitfield', 'uw', 'MipsISA::Cause', None, 4),
- 'IntCtl_IPTI': ('ControlBitfield', 'uw', 'MipsISA::IntCtl', None, 4),
- 'EntryHi_ASID': ('ControlBitfield', 'uw', 'MipsISA::EntryHi', None, 1),
- 'EntryLo0_PFN': ('ControlBitfield', 'uw', 'MipsISA::EntryLo0', None, 1),
- 'EntryLo0_C': ('ControlBitfield', 'uw', 'MipsISA::EntryLo0', None, 3),
- 'EntryLo0_D': ('ControlBitfield', 'uw', 'MipsISA::EntryLo0', None, 1),
- 'EntryLo0_V': ('ControlBitfield', 'uw', 'MipsISA::EntryLo0', None, 1),
- 'EntryLo0_G': ('ControlBitfield', 'uw', 'MipsISA::EntryLo0', None, 1),
- 'EntryLo1_PFN': ('ControlBitfield', 'uw', 'MipsISA::EntryLo1', None, 1),
- 'EntryLo1_C': ('ControlBitfield', 'uw', 'MipsISA::EntryLo1', None, 3),
- 'EntryLo1_D': ('ControlBitfield', 'uw', 'MipsISA::EntryLo1', None, 1),
- 'EntryLo1_V': ('ControlBitfield', 'uw', 'MipsISA::EntryLo1', None, 1),
- 'EntryLo1_G': ('ControlBitfield', 'uw', 'MipsISA::EntryLo1', None, 1),
-
- # named bitfields of Debug Regs
- 'Debug_DM': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
- 'Debug_IEXI': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
+ 'Debug': ('ControlReg','uw', 'MipsISA::Debug',None,1),
+ 'Cause': ('ControlReg','uw', 'MipsISA::Cause',None,1),
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh
index a8d5b07b6..38b43af9d 100644
--- a/src/arch/mips/isa_traits.hh
+++ b/src/arch/mips/isa_traits.hh
@@ -41,133 +41,129 @@
namespace LittleEndianGuest {};
-#define TARGET_MIPS
-
class StaticInstPtr;
namespace MipsISA
{
- using namespace LittleEndianGuest;
-
- StaticInstPtr decodeInst(ExtMachInst);
-
- // MIPS DOES have a delay slot
- #define ISA_HAS_DELAY_SLOT 1
-
- const Addr PageShift = 13;
- 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);
-
- // Kernel Segment 1 - Unmapped, Uncached
- const Addr KSeg1End = ULL(0xBFFFFFFF);
- const Addr KSeg1Base = ULL(0xA0000000);
- const Addr KSeg1Mask = ULL(0x1FFFFFFF);
-
- // Kernel/Supervisor Segment - Mapped
- const Addr KSSegEnd = ULL(0xDFFFFFFF);
- const Addr KSSegBase = ULL(0xC0000000);
-
- // Kernel Segment 3 - Mapped
- const Addr KSeg3End = ULL(0xFFFFFFFF);
- const Addr KSeg3Base = ULL(0xE0000000);
-
-
- // For loading... XXX This maybe could be USegEnd?? --ali
- const Addr LoadAddrMask = ULL(0xffffffffff);
-
- inline Addr Phys2K0Seg(Addr addr)
- {
- // if (addr & PAddrUncachedBit43) {
-// addr &= PAddrUncachedMask;
-// addr |= PAddrUncachedBit40;
-// }
- return addr | KSeg0Base;
- }
-
-
- 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 >> MipsISA::PageShift; }
- inline Addr VAddrOffset(Addr a) { return a & MipsISA::PageOffset; }
-
- const Addr PAddrImplMask = (ULL(1) << PABits) - 1;
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Interrupt levels
- //
- enum InterruptLevels
- {
- INTLEVEL_SOFTWARE_MIN = 4,
- INTLEVEL_SOFTWARE_MAX = 19,
-
- INTLEVEL_EXTERNAL_MIN = 20,
- INTLEVEL_EXTERNAL_MAX = 34,
-
- INTLEVEL_IRQ0 = 20,
- INTLEVEL_IRQ1 = 21,
- INTINDEX_ETHERNET = 0,
- INTINDEX_SCSI = 1,
- INTLEVEL_IRQ2 = 22,
- INTLEVEL_IRQ3 = 23,
-
- INTLEVEL_SERIAL = 33,
-
- NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
- };
-
- // MIPS modes
- enum mode_type
- {
- mode_kernel = 0, // kernel
- mode_supervisor = 1, // supervisor
- mode_user = 2, // user mode
- mode_debug = 3, // debug mode
- mode_number // number of modes
- };
-
- // return a no-op instruction... used for instruction fetch faults
- const ExtMachInst NoopMachInst = 0x00000000;
-
- const int LogVMPageSize = 13; // 8K 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;
-
- const int ANNOTE_NONE = 0;
- const uint32_t ITOUCH_ANNOTE = 0xffffffff;
+
+using namespace LittleEndianGuest;
+
+StaticInstPtr decodeInst(ExtMachInst);
+
+// MIPS DOES have a delay slot
+#define ISA_HAS_DELAY_SLOT 1
+
+const Addr PageShift = 13;
+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);
+
+// Kernel Segment 1 - Unmapped, Uncached
+const Addr KSeg1End = ULL(0xBFFFFFFF);
+const Addr KSeg1Base = ULL(0xA0000000);
+const Addr KSeg1Mask = ULL(0x1FFFFFFF);
+
+// Kernel/Supervisor Segment - Mapped
+const Addr KSSegEnd = ULL(0xDFFFFFFF);
+const Addr KSSegBase = ULL(0xC0000000);
+
+// Kernel Segment 3 - Mapped
+const Addr KSeg3End = ULL(0xFFFFFFFF);
+const Addr KSeg3Base = ULL(0xE0000000);
+
+
+// For loading... XXX This maybe could be USegEnd?? --ali
+const Addr LoadAddrMask = ULL(0xffffffffff);
+
+inline Addr Phys2K0Seg(Addr addr)
+{
+ return addr | KSeg0Base;
+}
+
+
+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 >> MipsISA::PageShift; }
+inline Addr VAddrOffset(Addr a) { return a & MipsISA::PageOffset; }
+
+const Addr PAddrImplMask = (ULL(1) << PABits) - 1;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Interrupt levels
+//
+enum InterruptLevels
+{
+ INTLEVEL_SOFTWARE_MIN = 4,
+ INTLEVEL_SOFTWARE_MAX = 19,
+
+ INTLEVEL_EXTERNAL_MIN = 20,
+ INTLEVEL_EXTERNAL_MAX = 34,
+
+ INTLEVEL_IRQ0 = 20,
+ INTLEVEL_IRQ1 = 21,
+ INTINDEX_ETHERNET = 0,
+ INTINDEX_SCSI = 1,
+ INTLEVEL_IRQ2 = 22,
+ INTLEVEL_IRQ3 = 23,
+
+ INTLEVEL_SERIAL = 33,
+
+ NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
+};
+
+// MIPS modes
+enum mode_type
+{
+ mode_kernel = 0, // kernel
+ mode_supervisor = 1, // supervisor
+ mode_user = 2, // user mode
+ mode_debug = 3, // debug mode
+ mode_number // number of modes
+};
+
+// return a no-op instruction... used for instruction fetch faults
+const ExtMachInst NoopMachInst = 0x00000000;
+
+const int LogVMPageSize = 13; // 8K 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;
+
+const int ANNOTE_NONE = 0;
+const uint32_t ITOUCH_ANNOTE = 0xffffffff;
+
};
#endif // __ARCH_MIPS_ISA_TRAITS_HH__
diff --git a/src/arch/mips/kernel_stats.hh b/src/arch/mips/kernel_stats.hh
index 82d576891..f14c6f851 100644
--- a/src/arch/mips/kernel_stats.hh
+++ b/src/arch/mips/kernel_stats.hh
@@ -32,11 +32,6 @@
#ifndef __ARCH_MIPS_KERNEL_STATS_HH__
#define __ARCH_MIPS_KERNEL_STATS_HH__
-#include <map>
-#include <stack>
-#include <string>
-#include <vector>
-
#include "kern/kernel_stats.hh"
namespace MipsISA {
diff --git a/src/arch/mips/linux/linux.cc b/src/arch/mips/linux/linux.cc
index 8745731dc..6cfc93585 100644
--- a/src/arch/mips/linux/linux.cc
+++ b/src/arch/mips/linux/linux.cc
@@ -69,7 +69,3 @@ OpenFlagTransTable MipsLinux::openFlagTable[] = {
const int MipsLinux::NUM_OPEN_FLAGS =
(sizeof(MipsLinux::openFlagTable)/sizeof(MipsLinux::openFlagTable[0]));
-
-
-
-
diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh
index aaeba0a42..ee81fa18f 100644
--- a/src/arch/mips/linux/linux.hh
+++ b/src/arch/mips/linux/linux.hh
@@ -68,13 +68,13 @@ class MipsLinux : public Linux
//@{
/// 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
+ 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
//@}
//@{
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 24e71305a..53a24487f 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -74,15 +74,15 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
-
- case 45: { // GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
- // I don't think this exactly matches the HW FPCR
- *fpcr = 0;
- fpcr.copyOut(tc->getMemPort());
- return 0;
- }
-
+ case 45:
+ {
+ // GSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ // I don't think this exactly matches the HW FPCR
+ *fpcr = 0;
+ fpcr.copyOut(tc->getMemPort());
+ return 0;
+ }
default:
cerr << "sys_getsysinfo: unknown op " << op << endl;
abort();
@@ -102,15 +102,16 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
switch (op) {
- case 14: { // SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
- // I don't think this exactly matches the HW FPCR
- fpcr.copyIn(tc->getMemPort());
- DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
+ case 14:
+ {
+ // SSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ // I don't think this exactly matches the HW FPCR
+ fpcr.copyIn(tc->getMemPort());
+ DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
- return 0;
- }
-
+ return 0;
+ }
default:
cerr << "sys_setsysinfo: unknown op " << op << endl;
abort();
@@ -196,8 +197,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
- /* 75 */ SyscallDesc("setrlimit", unimplementedFunc/*setrlimitFunc<MipsLinux>*/),
- /* 76 */ SyscallDesc("getrlimit", unimplementedFunc/*getrlimitFunc<MipsLinux>*/),
+ /* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 77 */ SyscallDesc("getrusage", getrusageFunc<MipsLinux>),
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
@@ -241,7 +242,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
- /* 120 */ SyscallDesc("clone", unimplementedFunc/*cloneFunc<MipsLinux>*/),
+ /* 120 */ SyscallDesc("clone", unimplementedFunc),
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 122 */ SyscallDesc("uname", unameFunc),
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
@@ -315,12 +316,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 191 */ SyscallDesc("getresgid", unimplementedFunc),
/* 192 */ SyscallDesc("prctl", unimplementedFunc),
/* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 194 */ SyscallDesc("rt_sigaction", unimplementedFunc/*rt_sigactionFunc<MipsLinux>*/),
- /* 195 */ SyscallDesc("rt_sigprocmask", unimplementedFunc/*rt_sigprocmaskFunc<MipsLinux>*/),
+ /* 194 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 195 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
- /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc/*rt_sigsuspendFunc<MipsLinux>*/),
+ /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 202 */ SyscallDesc("chown", unimplementedFunc),
@@ -406,7 +407,6 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 282 */ SyscallDesc("keyctl", unimplementedFunc)
};
-
MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
: MipsLiveProcess(params, objFile),
diff --git a/src/arch/mips/linux/system.cc b/src/arch/mips/linux/system.cc
index 23062c96b..295e22a61 100644
--- a/src/arch/mips/linux/system.cc
+++ b/src/arch/mips/linux/system.cc
@@ -88,7 +88,6 @@ LinuxMipsSystem::LinuxMipsSystem(Params *p)
virtPort.write(addr, (uint64_t)(Clock::Frequency /
p->boot_cpu_frequency));
-
/**
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
* paritiuclar EV6 we have only supports 127 asns.
@@ -105,12 +104,6 @@ LinuxMipsSystem::LinuxMipsSystem(Params *p)
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
-#if 0
- kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
- if (!kernelDieEvent)
- panic("could not find kernel symbol \'die_if_kernel\'");
-#endif
-
#endif
/**
diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh
index e202a11aa..3c81bc249 100644
--- a/src/arch/mips/locked_mem.hh
+++ b/src/arch/mips/locked_mem.hh
@@ -45,17 +45,18 @@
namespace MipsISA
{
+
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf);
xc->setMiscRegNoEffect(LLFlag, true);
- DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
+ DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link"
+ " Address set to %x.\n",
req->threadId(), req->getPaddr() & ~0xf);
}
-
template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
@@ -89,14 +90,17 @@ handleLockedWrite(XC *xc, Request *req)
}
if (stCondFailures == 5000) {
- panic("Max (5000) Store Conditional Fails Reached. Check Code For Deadlock.\n");
+ panic("Max (5000) Store Conditional Fails Reached. "
+ "Check Code For Deadlock.\n");
}
if (!lock_flag){
- DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
+ DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, "
+ "Store Conditional Failed.\n",
req->threadId());
} else if ((req->getPaddr() & ~0xf) != lock_addr) {
- DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
+ DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, "
+ "Store Conditional Failed.\n",
req->threadId());
}
// store conditional failed already, so don't issue it to mem
@@ -107,7 +111,6 @@ handleLockedWrite(XC *xc, Request *req)
return true;
}
-
} // namespace MipsISA
#endif
diff --git a/src/arch/mips/mips_core_specific.cc b/src/arch/mips/mips_core_specific.cc
index 21847378f..14f4186e3 100755
--- a/src/arch/mips/mips_core_specific.cc
+++ b/src/arch/mips/mips_core_specific.cc
@@ -29,20 +29,9 @@
* Steve Reinhardt
*/
-#include "arch/mips/faults.hh"
-#include "arch/mips/isa_traits.hh"
-#include "arch/mips/tlb.hh"
-//#include "base/kgdb.h"
-#include "base/remote_gdb.hh"
-#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
-#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
-#include "sim/debug.hh"
-#include "sim/sim_exit.hh"
-#include "arch/mips/mips_core_specific.hh"
#if FULL_SYSTEM
@@ -52,61 +41,11 @@
//
void
MipsISA::initCPU(ThreadContext *tc, int cpuId)
-{
-
- // MipsFault *reset = new ResetFault;
-// tc->setPC(reset->vect());
-// tc->setNextPC(tc->readPC() + sizeof(MachInst));
-
-// delete reset;
-}
+{}
template <class CPU>
void
MipsISA::processInterrupts(CPU *cpu)
-{
- //Check if there are any outstanding interrupts
- //Handle the interrupts
- /* int ipl = 0;
- int summary = 0;
-
- cpu->checkInterrupts = false;
-
- if (cpu->readMiscReg(IPR_ASTRR))
- panic("asynchronous traps not implemented\n");
-
- if (cpu->readMiscReg(IPR_SIRR)) {
- for (int i = INTLEVEL_SOFTWARE_MIN;
- i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
- // See table 4-19 of the 21164 hardware reference
- ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
- summary |= (ULL(1) << i);
- }
- }
- }
-
- uint64_t interrupts = cpu->intr_status();
-
- if (interrupts) {
- for (int i = INTLEVEL_EXTERNAL_MIN;
- i < INTLEVEL_EXTERNAL_MAX; i++) {
- if (interrupts & (ULL(1) << i)) {
- // See table 4-19 of the 21164 hardware reference
- ipl = i;
- summary |= (ULL(1) << i);
- }
- }
- }
-
- if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) {
- cpu->setMiscReg(IPR_ISR, summary);
- cpu->setMiscReg(IPR_INTID, ipl);
- cpu->trap(new InterruptFault);
- DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- cpu->readMiscReg(IPR_IPLR), ipl, summary);
- }
- */
-}
+{}
#endif // FULL_SYSTEM || BARE_IRON
diff --git a/src/arch/mips/mmaped_ipr.hh b/src/arch/mips/mmaped_ipr.hh
index fa82a645c..99c2e7fc7 100644
--- a/src/arch/mips/mmaped_ipr.hh
+++ b/src/arch/mips/mmaped_ipr.hh
@@ -44,6 +44,7 @@ class ThreadContext;
namespace MipsISA
{
+
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
@@ -56,7 +57,6 @@ handleIprWrite(ThreadContext *xc, Packet *pkt)
panic("No implementation for handleIprWrite in MIPS\n");
}
-
} // namespace MipsISA
#endif
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index b581d5cf0..a6363e191 100755
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -40,6 +40,7 @@
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/mt_constants.hh"
+#include "arch/mips/pra_constants.hh"
#include "arch/mips/registers.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
@@ -50,21 +51,20 @@
namespace MipsISA
{
-
template <class TC>
inline unsigned
getVirtProcNum(TC *tc)
{
- MiscReg tcbind = tc->readMiscRegNoEffect(TCBind);
- return bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+ TCBindReg tcbind = tc->readMiscRegNoEffect(TCBind);
+ return tcbind.curVPE;
}
template <class TC>
inline unsigned
getTargetThread(TC *tc)
{
- MiscReg vpec_ctrl = tc->readMiscRegNoEffect(VPEControl);
- return bits(vpec_ctrl, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO);
+ VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(VPEControl);
+ return vpeCtrl.targTC;
}
template <class TC>
@@ -75,11 +75,13 @@ haltThread(TC *tc)
tc->halt();
// Save last known PC in TCRestart
- // @TODO: Needs to check if this is a branch and if so, take previous instruction
+ // @TODO: Needs to check if this is a branch and if so,
+ // take previous instruction
tc->setMiscReg(TCRestart, tc->readNextPC());
- warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->threadId(), tc->getCpuPtr()->name(),
- tc->readPC(), tc->readNextPC());
+ warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x",
+ curTick, tc->threadId(), tc->getCpuPtr()->name(),
+ tc->readPC(), tc->readNextPC());
}
}
@@ -92,14 +94,14 @@ restoreThread(TC *tc)
IntReg pc = tc->readMiscRegNoEffect(TCRestart);
// TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
- // tc->setPCEvent(pc, pc + 4, pc + 8);
tc->setPC(pc);
tc->setNextPC(pc + 4);
tc->setNextNPC(pc + 8);
tc->activate(0);
- warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->threadId(), tc->getCpuPtr()->name(),
- tc->readPC());
+ warn("%i: Restoring thread %i in %s @ PC %x",
+ curTick, tc->threadId(), tc->getCpuPtr()->name(),
+ tc->readPC());
}
}
@@ -107,58 +109,48 @@ template <class TC>
void
forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
{
- int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(MVPConf0);
+ int num_threads = mvpConf.ptc + 1;
int success = 0;
for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
- unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
- tid);
- unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind);
-
- if (bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) ==
- bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
+ TCBindReg tidTCBind =
+ tc->readRegOtherThread(TCBind + Ctrl_Base_DepTag, tid);
+ TCBindReg tcBind = tc->readMiscRegNoEffect(TCBind);
- unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
- tid);
+ if (tidTCBind.curVPE = tcBind.curVPE) {
- unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
- tid);
+ TCStatusReg tidTCStatus =
+ tc->readRegOtherThread(TCStatus + Ctrl_Base_DepTag,tid);
- if (bits(tid_TCStatus, TCS_DA) == 1 &&
- bits(tid_TCHalt, TCH_H) == 0 &&
- bits(tid_TCStatus, TCS_A) == 0 &&
- success == 0) {
+ TCHaltReg tidTCHalt =
+ tc->readRegOtherThread(TCHalt + Ctrl_Base_DepTag,tid);
- tc->setRegOtherThread(MipsISA::TCRestart + Ctrl_Base_DepTag, Rs, tid);
+ if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
+ tidTCStatus.a == 0 && success == 0) {
+ tc->setRegOtherThread(TCRestart + Ctrl_Base_DepTag, Rs, tid);
tc->setRegOtherThread(Rd_bits, Rt, tid);
- unsigned status_ksu = bits(tc->readMiscReg(MipsISA::Status),
- S_KSU_HI, S_KSU_LO);
- unsigned tc_status_asid = bits(tc->readMiscReg(MipsISA::TCStatus),
- TCS_ASID_HI, TCS_ASID_LO);
+ StatusReg status = tc->readMiscReg(Status);
+ TCStatusReg tcStatus = tc->readMiscReg(TCStatus);
// Set Run-State to Running
- replaceBits(tid_TCStatus, TCSTATUS_RNST_HI, TCSTATUS_RNST_LO, 0);
-
+ tidTCStatus.rnst = 0;
// Set Delay-Slot to 0
- replaceBits(tid_TCStatus, TCSTATUS_TDS, 0);
-
+ tidTCStatus.tds = 0;
// Set Dirty TC to 1
- replaceBits(tid_TCStatus, TCSTATUS_DT, 1);
-
+ tidTCStatus.dt = 1;
// Set Activated to 1
- replaceBits(tid_TCStatus, TCSTATUS_A, 1);
-
+ tidTCStatus.a = 1;
// Set status to previous thread's status
- replaceBits(tid_TCStatus, TCSTATUS_TKSU_HI, TCSTATUS_TKSU_LO, status_ksu);
-
+ tidTCStatus.tksu = status.ksu;
// Set ASID to previous thread's state
- replaceBits(tid_TCStatus, TCSTATUS_ASID_HI, TCSTATUS_ASID_LO, tc_status_asid);
+ tidTCStatus.asid = tcStatus.asid;
// Write Status Register
- tc->setRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
- tid_TCStatus, tid);
+ tc->setRegOtherThread(TCStatus + Ctrl_Base_DepTag,
+ tidTCStatus, tid);
// Mark As Successful Fork
success = 1;
@@ -169,8 +161,9 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
}
if (success == 0) {
- unsigned vpe_control = tc->readMiscRegNoEffect(MipsISA::VPEControl);
- tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 1));
+ VPEControlReg vpeControl = tc->readMiscRegNoEffect(VPEControl);
+ vpeControl.excpt = 1;
+ tc->setMiscReg(VPEControl, vpeControl);
fault = new ThreadFault();
}
}
@@ -181,68 +174,54 @@ int
yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
{
if (src_reg == 0) {
- unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0);
- ThreadID num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(MVPConf0);
+ ThreadID num_threads = mvpConf0.ptc + 1;
int ok = 0;
// Get Current VPE & TC numbers from calling thread
- unsigned tcbind = tc->readMiscRegNoEffect(TCBind);
- unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
- unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
+ TCBindReg tcBind = tc->readMiscRegNoEffect(TCBind);
for (ThreadID tid = 0; tid < num_threads; tid++) {
- unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
- tid);
- unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
- tid);
- unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
- tid);
-
- unsigned tid_vpe = bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
- unsigned tid_tc = bits(tid_TCBind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
- unsigned tid_tcstatus_da = bits(tid_TCStatus, TCS_DA);
- unsigned tid_tcstatus_a = bits(tid_TCStatus, TCS_A);
- unsigned tid_tchalt_h = bits(tid_TCHalt, TCH_H);
-
- if (tid_vpe == cur_vpe &&
- tid_tc == cur_tc &&
- tid_tcstatus_da == 1 &&
- tid_tchalt_h == 0 &&
- tid_tcstatus_a == 1) {
+ TCStatusReg tidTCStatus =
+ tc->readRegOtherThread(TCStatus + Ctrl_Base_DepTag, tid);
+ TCHaltReg tidTCHalt =
+ tc->readRegOtherThread(TCHalt + Ctrl_Base_DepTag, tid);
+ TCBindReg tidTCBind =
+ tc->readRegOtherThread(TCBind + Ctrl_Base_DepTag, tid);
+
+ if (tidTCBind.curVPE == tcBind.curVPE &&
+ tidTCBind.curTC == tcBind.curTC &&
+ tidTCStatus.da == 1 &&
+ tidTCHalt.h == 0 &&
+ tidTCStatus.a == 1) {
ok = 1;
}
}
if (ok == 1) {
- unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
- tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0));
- warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->threadId());
+ TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus);
+ tcStatus.a = 0;
+ tc->setMiscReg(TCStatus, tcStatus);
+ warn("%i: Deactivating Hardware Thread Context #%i",
+ curTick, tc->threadId());
}
} else if (src_reg > 0) {
if (src_reg && !yield_mask != 0) {
- unsigned vpe_control = tc->readMiscReg(VPEControl);
- tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2));
+ VPEControlReg vpeControl = tc->readMiscReg(VPEControl);
+ vpeControl.excpt = 2;
+ tc->setMiscReg(VPEControl, vpeControl);
fault = new ThreadFault();
} else {
- //tc->setThreadRescheduleCondition(src_reg & yield_mask);
}
} else if (src_reg != -2) {
- unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
- unsigned vpe_control = tc->readMiscRegNoEffect(VPEControl);
- unsigned tcstatus_dt = bits(tcstatus, TCS_DT);
- unsigned vpe_control_ysi = bits(vpe_control, VPEC_YSI);
+ TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus);
+ VPEControlReg vpeControl = tc->readMiscRegNoEffect(VPEControl);
- if (vpe_control_ysi == 1 && tcstatus_dt == 1 ) {
- tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 4));
+ if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) {
+ vpeControl.excpt = 4;
fault = new ThreadFault();
} else {
- //tc->ScheduleOtherThreads();
- //std::cerr << "T" << tc->threadId() << "YIELD: Schedule Other Threads.\n" << std::endl;
- //tc->suspend();
- // Save last known PC in TCRestart
- // @TODO: Needs to check if this is a branch and if so, take previous instruction
- //tc->setMiscRegWithEffect(TCRestart, tc->readNextPC());
}
}
@@ -258,17 +237,12 @@ updateStatusView(TC *tc)
{
// TCStatus' register view must be the same as
// Status register view for CU, MX, KSU bits
- MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
- MiscReg status = tc->readMiscRegNoEffect(Status);
-
- unsigned cu_bits = bits(tc_status, TCS_TCU_HI, TCS_TCU_LO);
- replaceBits(status, S_CU_HI, S_CU_LO, cu_bits);
-
- unsigned mx_bits = bits(tc_status, TCS_TMX);
- replaceBits(status, S_MX, S_MX, mx_bits);
+ TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus);
+ StatusReg status = tc->readMiscRegNoEffect(Status);
- unsigned ksu_bits = bits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO);
- replaceBits(status, S_KSU_HI, S_KSU_LO, ksu_bits);
+ status.cu = tcStatus.tcu;
+ status.mx = tcStatus.tmx;
+ status.ksu = tcStatus.tksu;
tc->setMiscRegNoEffect(Status, status);
}
@@ -281,19 +255,14 @@ updateTCStatusView(TC *tc)
{
// TCStatus' register view must be the same as
// Status register view for CU, MX, KSU bits
- MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
- MiscReg status = tc->readMiscRegNoEffect(Status);
-
- unsigned cu_bits = bits(status, S_CU_HI, S_CU_LO);
- replaceBits(tc_status, TCS_TCU_HI, TCS_TCU_LO, cu_bits);
-
- unsigned mx_bits = bits(status, S_MX, S_MX);
- replaceBits(tc_status, TCS_TMX, mx_bits);
+ TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus);
+ StatusReg status = tc->readMiscRegNoEffect(Status);
- unsigned ksu_bits = bits(status, S_KSU_HI, S_KSU_LO);
- replaceBits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO, ksu_bits);
+ tcStatus.tcu = status.cu;
+ tcStatus.tmx = status.mx;
+ tcStatus.tksu = status.ksu;
- tc->setMiscRegNoEffect(TCStatus, tc_status);
+ tc->setMiscRegNoEffect(TCStatus, tcStatus);
}
} // namespace MipsISA
diff --git a/src/arch/mips/mt_constants.hh b/src/arch/mips/mt_constants.hh
index 3f26f5cba..e27798f89 100755
--- a/src/arch/mips/mt_constants.hh
+++ b/src/arch/mips/mt_constants.hh
@@ -33,89 +33,71 @@
#define __ARCH_MIPS_MT_CONSTANTS_HH__
#include "arch/mips/types.hh"
+#include "base/bitunion.hh"
namespace MipsISA
{
-// MVPControl
-const unsigned MVPC_EVP = 0;
-const unsigned MVPC_CUR_VPE_HI = 3;
-const unsigned MVPC_CUR_VPE_LO = 0;
-// MVPConf0
-const unsigned MVPC0_TCA = 15;
-const unsigned MVPC0_PVPE_HI = 13;
-const unsigned MVPC0_PVPE_LO = 10;
-const unsigned MVPC0_PTC_HI = 7;
-const unsigned MVPC0_PTC_LO = 0;
-
-//VPEControl
-const unsigned VPEC_YSI = 21;
-const unsigned VPEC_EXCPT_HI = 18;
-const unsigned VPEC_EXCPT_LO = 16;
-const unsigned VPEC_TE = 15;
-const unsigned VPEC_TARG_TC_HI = 7;
-const unsigned VPEC_TARG_TC_LO = 0;
-
-//VPEConf0
-const unsigned VPEC0_MVP = 1;
-
-//TCBind
-const unsigned TCB_CUR_VPE_HI = 3;
-const unsigned TCB_CUR_VPE_LO = 0;
-const unsigned TCB_CUR_TC_HI = 28;
-const unsigned TCB_CUR_TC_LO = 21;
-
-
-//TCStatus
-const unsigned TCS_TCU_HI = 31;
-const unsigned TCS_TCU_LO = 28;
-const unsigned TCS_TMX = 27;
-const unsigned TCS_DT = 20;
-const unsigned TCS_DA = 15;
-const unsigned TCS_A = 13;
-const unsigned TCS_TKSU_HI = 12;
-const unsigned TCS_TKSU_LO = 11;
-const unsigned TCS_IXMT = 7;
-const unsigned TCS_ASID_HI = 7;
-const unsigned TCS_ASID_LO = 7;
-
-const unsigned TCSTATUS_TCU_HI = 31;
-const unsigned TCSTATUS_TCU_LO = 28;
-const unsigned TCSTATUS_TMX = 27;
-const unsigned TCSTATUS_RNST_HI = 24;
-const unsigned TCSTATUS_RNST_LO = 23;
-const unsigned TCSTATUS_TDS = 21;
-const unsigned TCSTATUS_DT = 20;
-const unsigned TCSTATUS_DA = 15;
-const unsigned TCSTATUS_A = 13;
-const unsigned TCSTATUS_TKSU_HI = 12;
-const unsigned TCSTATUS_TKSU_LO = 11;
-const unsigned TCSTATUS_IXMT = 7;
-const unsigned TCSTATUS_ASID_HI = 7;
-const unsigned TCSTATUS_ASID_LO = 7;
-
-//TCHalt
-const unsigned TCH_H = 0;
-
-//Status
-const unsigned S_CU_HI = 31;
-const unsigned S_CU_LO = 28;
-const unsigned S_MX = 24;
-const unsigned S_KSU_HI = 4;
-const unsigned S_KSU_LO = 3;
-
-// Config0
-const unsigned CFG_M = 31;
-
-// Config1
-const unsigned CFG1_M = 31;
-
-// Config2
-const unsigned CFG2_M = 31;
-
-// Config3
-const unsigned CFG3_M = 31;
-const unsigned CFG3_MT = 2;
+BitUnion32(MVPControlReg)
+ Bitfield<3> cpa;
+ Bitfield<2> stlb;
+ Bitfield<1> vpc;
+ Bitfield<0> evp;
+EndBitUnion(MVPControlReg)
+
+BitUnion32(MVPConf0Reg)
+ Bitfield<31> m;
+ Bitfield<29> tlbs;
+ Bitfield<28> gs;
+ Bitfield<27> pcp;
+ Bitfield<25, 16> ptlbe;
+ Bitfield<15> tca;
+ Bitfield<13, 10> pvpe;
+ Bitfield<7, 0> ptc;
+EndBitUnion(MVPConf0Reg)
+
+BitUnion32(VPEControlReg)
+ Bitfield<21> ysi;
+ Bitfield<18, 16> excpt;
+ Bitfield<15> te;
+ Bitfield<7, 0> targTC;
+EndBitUnion(VPEControlReg)
+
+BitUnion32(VPEConf0Reg)
+ Bitfield<31> m;
+ Bitfield<28, 21> xtc;
+ Bitfield<19> tcs;
+ Bitfield<18> scs;
+ Bitfield<17> dcs;
+ Bitfield<16> ics;
+ Bitfield<1> mvp;
+ Bitfield<0> vpa;
+EndBitUnion(VPEConf0Reg)
+
+BitUnion32(TCBindReg)
+ Bitfield<28, 21> curTC;
+ Bitfield<20, 18> a0;
+ Bitfield<17> tbe;
+ Bitfield<3, 0> curVPE;
+EndBitUnion(TCBindReg)
+
+BitUnion32(TCStatusReg)
+ Bitfield<31, 28> tcu;
+ Bitfield<27> tmx;
+ Bitfield<24, 23> rnst;
+ Bitfield<21> tds;
+ Bitfield<20> dt;
+ Bitfield<19, 16> impl;
+ Bitfield<15> da;
+ Bitfield<13> a;
+ Bitfield<12, 11> tksu;
+ Bitfield<10> ixmt;
+ Bitfield<7, 0> asid;
+EndBitUnion(TCStatusReg)
+
+BitUnion32(TCHaltReg)
+ Bitfield<0> h;
+EndBitUnion(TCHaltReg)
} // namespace MipsISA
diff --git a/src/arch/mips/pagetable.cc b/src/arch/mips/pagetable.cc
index 5a2d9de7c..b4304060c 100644
--- a/src/arch/mips/pagetable.cc
+++ b/src/arch/mips/pagetable.cc
@@ -37,42 +37,42 @@
namespace MipsISA
{
+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::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);
+}
- 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);
- }
}
diff --git a/src/arch/mips/pagetable.hh b/src/arch/mips/pagetable.hh
index bbed94194..cd269f1af 100755
--- a/src/arch/mips/pagetable.hh
+++ b/src/arch/mips/pagetable.hh
@@ -41,59 +41,62 @@
namespace MipsISA {
- struct VAddr
- {
- static const int ImplBits = 43;
- static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
- static const Addr UnImplMask = ~ImplMask;
+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; }
+ 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 vpn() const { return (addr & ImplMask) >> PageShift; }
+ Addr page() const { return addr & Page_Mask; }
+ Addr offset() const { return addr & PageOffset; }
- Addr level3() const
- { return MipsISA::PteAddr(addr >> PageShift); }
- Addr level2() const
- { return MipsISA::PteAddr(addr >> (NPtePageShift + PageShift)); }
- Addr level1() const
- { return MipsISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
- };
+ Addr level3() const
+ { return MipsISA::PteAddr(addr >> PageShift); }
+ Addr level2() const
+ { return MipsISA::PteAddr(addr >> (NPtePageShift + PageShift)); }
+ Addr level1() const
+ { return MipsISA::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
+// ITB/DTB page table entry
+struct PTE
+{
+ Addr Mask;
+ Addr VPN;
+ uint8_t asid;
- bool G; // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit
+ bool G;
- /* 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 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)
+ /* 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;
+ /*
+ * 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);
- };
+ bool Valid() { return (V0 | V1); };
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
};
#endif // __ARCH_MIPS_PAGETABLE_H__
diff --git a/src/arch/mips/pra_constants.hh b/src/arch/mips/pra_constants.hh
index 85b33339d..971501493 100755
--- a/src/arch/mips/pra_constants.hh
+++ b/src/arch/mips/pra_constants.hh
@@ -32,463 +32,298 @@
#define __ARCH_MIPS_PRA_CONSTANTS_HH__
#include "arch/mips/types.hh"
-//#include "config/full_system.hh"
+#include "base/bitunion.hh"
namespace MipsISA
{
- // See MIPS32(R) Architecture Reference Manual Volume - III
- // This header file uses definitions from Revision 2.50
-
- // Index Status Register - CP0 Reg 0, Sel 0
-
- const unsigned Index_P_HI = 31;
- const unsigned Index_P_LO = 31;
- // Need to figure out how to put in the TLB specific bits here
- // For now, we assume that the entire length is used by the index field
- // In reality, Index_HI = N-1, where Ceiling(log2(TLB Entries))=N
- const unsigned Index_HI = 30;
- const unsigned Index_LO = 0;
-
- // CP0 Reg 0, Sel 1-3 are MT registers, see mt_constants.hh
-
- // Random Register - CP0 Reg 1, Sel 0
- // This has a problem similar to the Index_HI fields. We'll keep both consistent at 30 for now
- const unsigned Random_HI = 30;
- const unsigned Random_LO = 0;
-
- // EntryLo0 - CP0 Reg2, Sel 0 - Table 8-6, ARM Vol-3
- const unsigned EntryLo0_Fill_HI = 31; // See Table 8-8, ARM Vol III
- const unsigned EntryLo0_Fill_LO = 30;
- const unsigned EntryLo0_PFN_HI = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
- const unsigned EntryLo0_PFN_LO = 6;
- const unsigned EntryLo0_C_HI = 5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
- const unsigned EntryLo0_C_LO = 3;
- const unsigned EntryLo0_D_HI = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
- const unsigned EntryLo0_D_LO = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
- const unsigned EntryLo0_V_HI = 1; // Valid Bit
- const unsigned EntryLo0_V_LO = 1; // Valid Bit
- const unsigned EntryLo0_G_HI = 0; // Global Bit. From the ARM Vol-III, Table 8-5:
- const unsigned EntryLo0_G_LO = 0; // Global Bit. From the ARM Vol-III, Table 8-5:
- // On a TLB write, the logical AND of the G bits from EntryLo0 and EntryLo1
- // becomes the G bit in the TLB entry. If the TLB entry G bit is 1, ASID comparisons are
- // ignored during TLB matches. On a read from a TLB entry, the G bits of both Lo0 and Lo1
- // reflect the state of the TLB G bit.
-
- // EntryLo1 - CP0 Reg3, Sel 0
- const unsigned EntryLo1_G_HI = 0;
- const unsigned EntryLo1_G_LO = 0;
- const unsigned EntryLo1_V_HI = 1; // Valid Bit
- const unsigned EntryLo1_V_LO = 1; // Valid Bit
- const unsigned EntryLo1_D_HI = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
- const unsigned EntryLo1_D_LO = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
- const unsigned EntryLo1_C_HI = 5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
- const unsigned EntryLo1_C_LO = 3;
- const unsigned EntryLo1_PFN_HI = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
- const unsigned EntryLo1_PFN_LO = 6;
- const unsigned EntryLo1_Fill_LO = 30;
- const unsigned EntryLo1_Fill_HI = 31; // See Table 8-8, ARM Vol III
-
-
- // Context Register - CP0 Reg 4, Sel 0
- const unsigned Context_PTEBase_HI = 31; // Used by the OS to point into current PTE array
- const unsigned Context_PTEBase_LO = 23;
- const unsigned Context_BadVPN2_HI = 22; // This is written by hardware on a TLB exception. Contains bits 31-13 of the
- const unsigned Context_BadVPN2_LO = 4; // virtual address
- // Bits 3-0 are zeros
-
- // PageMask Register - CP0 Reg 5, Sel 0
- // Bits 31-29 are 0
- const unsigned PageMask_Mask_HI = 28; // (Table 8-10, ARM Vol-III) The Mask field is a bit mask in which a "1" indicates that
- const unsigned PageMask_Mask_LO = 13; // the corresponding bit of the virtual address should not participate in the TLB match
- const unsigned PageMask_MaskX_HI = 12; // See Table 8-10, ARM Vol-III
- const unsigned PageMask_MaskX_LO = 11;
- // Bits 10-0 are zero
-
-
- // PageGrain Register - CP0 Reg 5, Sel 1
- const unsigned PageGrain_ASE_UP_HI = 31; // ASE specific bits (SmartMIPS)
- const unsigned PageGrain_ASE_UP_LO = 30; //
- const unsigned PageGrain_ELPA = 29; // Used to enable support for large physical addresses in MIPS64 processors, unused in MIPS32
- const unsigned PageGrain_ESP = 28; // Enables support for 1KB pages (1==enabled,0==disabled), See ARM Vol-III, Table 8-12
- const unsigned PageGrain_ESP_HI = 28; // Enables support for 1KB pages (1==enabled,0==disabled), See ARM Vol-III, Table 8-12
- const unsigned PageGrain_ESP_LO = 28; // Enables support for 1KB pages (1==enabled,0==disabled), See ARM Vol-III, Table 8-12
- const unsigned PageGrain_ASE_DN_HI = 12;
- const unsigned PageGrain_ASE_DN_LO = 8;
- // Bits 27-13, 7-0 are zeros
-
- // Wired Register - CPO Reg 6, Sel 0
- // See note on Index register (CP0, Sel0) above
- const unsigned Wired_HI = 30;
- const unsigned Wired_LO = 0;
-
-
- // HWREna Register - CP0 Reg 7, Sel 0
- const unsigned HWREna_IMPL_HI = 31; // These bits enable access to implementation dependent hardware registers 31
- const unsigned HWREna_IMPL_LO = 30; // and 30
- const unsigned HWREna_Mask_HI = 3; // Each bit enables access to a particular hardware register. If bit 'n' is 1, HW Reg n is accessible
- const unsigned HWREna_Mask_LO = 0; // See the RDHWR instruction for more details
-
-
- // BadVAddr Register - CP0 Reg 8, Sel 0
- const unsigned BadVAddr_HI = 31;
- const unsigned BadVAddr_LO = 0;
-
- // Count Register - CP0 Reg 9, Sel 0
- const unsigned Count_HI = 31;
- const unsigned Count_LO = 0;
-
- // EntryHI Register - CP0 Reg 10, Sel 0
- const unsigned EntryHi_VPN2_HI = 31; // This field is written by hardware on a TLB exception or on a TLB read
- const unsigned EntryHi_VPN2_LO = 13; // and is written by software before a TLB write
- const unsigned EntryHi_VPN2X_HI = 12; // Extension to support 1KB pages
- const unsigned EntryHi_VPN2X_LO = 11;
- const unsigned EntryHi_ASID_HI = 7; // Address space identifier
- const unsigned EntryHi_ASID_LO = 0;
-
- // Compare Register - CP0 Reg 11, Sel 0
- const unsigned Compare_HI = 31; // Used in conjunction with Count
- const unsigned Compare_LO = 0;
-
- // Status Register - CP Reg 12, Sel 0
- const unsigned Status_IE_HI = 0;
- const unsigned Status_IE_LO = 0;
-
- const unsigned Status_EXL = 1;
- const unsigned Status_EXL_HI = 1;
- const unsigned Status_EXL_LO = 1;
- const unsigned Status_ERL_HI = 2;
- const unsigned Status_ERL_LO = 2;
- const unsigned Status_R0 = 3;
- const unsigned Status_UM = 4;
- const unsigned Status_KSU_HI = 4; // R0 and UM are also aliased as KSU
- const unsigned Status_KSU_LO = 3;
- const unsigned Status_UX = 5;
- const unsigned Status_SX = 6;
- const unsigned Status_KX = 7;
- const unsigned Status_IM0 = 8;
- const unsigned Status_IM1 = 9;
- const unsigned Status_IM2 = 10;
- const unsigned Status_IM3 = 11;
- const unsigned Status_IM4 = 12;
- const unsigned Status_IM5 = 13;
- const unsigned Status_IM6 = 14;
- const unsigned Status_IM7 = 15;
- const unsigned Status_IPL_HI = 15; // IM7..IM2 are also aliased as IPL
- const unsigned Status_IPL_LO = 10;
- const unsigned Status_IMPL_HI = 17;
- const unsigned Status_IMPL_LO = 16;
- const unsigned Status_NMI = 19;
- const unsigned Status_SR = 20;
- const unsigned Status_TS = 21;
- const unsigned Status_BEV = 22;
- const unsigned Status_BEV_HI = 22;
- const unsigned Status_BEV_LO = 22;
- const unsigned Status_PX = 23;
- const unsigned Status_MX = 24;
- const unsigned Status_RE = 25;
- const unsigned Status_FR = 26;
- const unsigned Status_RP = 27;
- const unsigned Status_CU3_HI = 31;
- const unsigned Status_CU3_LO = 31;
- const unsigned Status_CU2_HI = 30;
- const unsigned Status_CU2_LO = 30;
- const unsigned Status_CU1_HI = 29;
- const unsigned Status_CU1_LO = 29;
- const unsigned Status_CU0_HI = 28;
- const unsigned Status_CU0_LO = 28;
-
- // IntCtl Register - CP0 Reg 12, Sel 1
- // Interrupt System status and control
- const unsigned IntCtl_IPTI_HI = 31;
- const unsigned IntCtl_IPTI_LO = 29;
- const unsigned IntCtl_IPPCI_HI = 28;
- const unsigned IntCtl_IPPCI_LO = 26;
- const unsigned IntCtl_VS_HI = 9;
- const unsigned IntCtl_VS_LO = 5;
- // Bits 26-10, 4-0 are zeros
-
- // SRSCtl Register - CP0 Reg 12, Sel 2
- // Shadow Register Set Status and Control
- const unsigned SRSCtl_HSS_HI=29; // Highest Shadow Set
- const unsigned SRSCtl_HSS_LO=26;
- const unsigned SRSCtl_EICSS_HI=21; //EIC interrupt mode shadow set
- const unsigned SRSCtl_EICSS_LO=18;
- const unsigned SRSCtl_ESS_HI=15; // Exception Shadow Set
- const unsigned SRSCtl_ESS_LO=12;
- const unsigned SRSCtl_PSS_HI=9; // Previous Shadow Set
- const unsigned SRSCtl_PSS_LO=6;
- const unsigned SRSCtl_CSS_HI=3; // Current Shadow Set
- const unsigned SRSCtl_CSS_LO=0;
-
- // SRSMap Register - CP0 Reg 12, Sel 3
- // Shadow Set IPL mapping
- const unsigned SRSMap_SSV7_HI = 31; // Shadow sets for particular vector numbers (7..0)
- const unsigned SRSMap_SSV7_LO = 28;
- const unsigned SRSMap_SSV6_HI = 27;
- const unsigned SRSMap_SSV6_LO = 24;
- const unsigned SRSMap_SSV5_HI = 23;
- const unsigned SRSMap_SSV5_LO = 20;
- const unsigned SRSMap_SSV4_HI = 19;
- const unsigned SRSMap_SSV4_LO = 16;
- const unsigned SRSMap_SSV3_HI = 15;
- const unsigned SRSMap_SSV3_LO = 12;
- const unsigned SRSMap_SSV2_HI = 11;
- const unsigned SRSMap_SSV2_LO = 8;
- const unsigned SRSMap_SSV1_HI = 7;
- const unsigned SRSMap_SSV1_LO = 4;
- const unsigned SRSMap_SSV0_HI = 3;
- const unsigned SRSMap_SSV0_LO = 20;
-
- // Cause Register - CP0 Reg 13, Sel 0
- const unsigned Cause_BD_HI = 31;
- const unsigned Cause_BD_LO = 31;
- const unsigned Cause_TI_HI = 30;
- const unsigned Cause_TI_LO = 30;
- const unsigned Cause_CE_HI = 29;
- const unsigned Cause_CE_LO = 28;
- const unsigned Cause_DC = 27;
- const unsigned Cause_PCI = 26;
- const unsigned Cause_IV = 24;
- const unsigned Cause_WP = 23;
- const unsigned Cause_RIPL_HI = 15; // The individual bits of RIPL are also available as IP7..IP5
- const unsigned Cause_RIPL_LO = 10;
- const unsigned Cause_IP7 = 15;
- const unsigned Cause_IP6 = 14;
- const unsigned Cause_IP5 = 13;
- const unsigned Cause_IP4 = 12;
- const unsigned Cause_IP3 = 11;
- const unsigned Cause_IP2 = 10;
- const unsigned Cause_IP1 = 9;
- const unsigned Cause_IP0 = 8;
- const unsigned Cause_EXCCODE_HI = 6;
- const unsigned Cause_EXCCODE_LO = 2;
- // All intermediate undefined bits must be ZERO
-
-
- // EPC Register - CP0 Reg 14, Sel 0
- // Exception Program Counter
- const unsigned EPC_HI = 31;
- const unsigned EPC_LO = 0;
-
- // PRId Register - CP0 Reg 15, Sel 0
- // Processor Identification register
- const unsigned PRIdCoOp_HI = 31;
- const unsigned PRIdCoOp_LO = 24;
- const unsigned PRIdCoID_HI = 23;
- const unsigned PRIdCoID_LO = 16;
- const unsigned PRIdProc_ID_HI = 15;
- const unsigned PRIdProc_ID_LO = 8;
- const unsigned PRIdRev_HI = 7;
- const unsigned PRIdRev_LO = 0;
-
-
- // EBase Register - CP0 Reg 15, Sel 1
- // Exception Base Register
- const unsigned EBase_MSB = 31; // MUST BE = 1
- const unsigned EBase_EXCEPTION_Base_HI = 29;
- const unsigned EBase_EXCEPTION_Base_LO = 12;
- const unsigned EBase_CPUNum_HI = 9;
- const unsigned EBase_CPUNum_LO = 0;
- // Undefined bits must be zero
-
- // Config Register - CP0 Reg 16, Sel 0
- const unsigned Config_M = 31;
- const unsigned Config_K23_HI = 30;
- const unsigned Config_K23_LO = 28;
- const unsigned Config_KU_HI = 27;
- const unsigned Config_KU_LO = 25;
- const unsigned Config_IMPL_HI = 24;
- const unsigned Config_IMPL_LO = 16;
- const unsigned Config_BE_HI = 15;
- const unsigned Config_BE_LO = 15;
- const unsigned Config_AT_HI = 14;
- const unsigned Config_AT_LO = 13;
- const unsigned Config_AR_HI = 12;
- const unsigned Config_AR_LO = 10;
- const unsigned Config_MT_HI = 9;
- const unsigned Config_MT_LO = 7;
- const unsigned Config_VI_HI = 3;
- const unsigned Config_VI_LO = 3;
- const unsigned Config_K0_HI = 2;
- const unsigned Config_K0_LO = 0;
-
- // Config1 Register - CP0 Reg 16, Sel 1
- const unsigned Config1_M = 31;
- const unsigned Config1_MMUSize_HI = 30;
- const unsigned Config1_MMUSize_LO = 25;
- const unsigned Config1_IS_HI = 24;
- const unsigned Config1_IS_LO = 22;
- const unsigned Config1_IL_HI = 21;
- const unsigned Config1_IL_LO = 19;
- const unsigned Config1_IA_HI = 18;
- const unsigned Config1_IA_LO = 16;
- const unsigned Config1_DS_HI = 15;
- const unsigned Config1_DS_LO = 13;
- const unsigned Config1_DL_HI = 12;
- const unsigned Config1_DL_LO = 10;
- const unsigned Config1_DA_HI = 9;
- const unsigned Config1_DA_LO = 7;
- const unsigned Config1_C2_HI = 6;
- const unsigned Config1_C2_LO = 6;
- const unsigned Config1_MD_HI = 5;
- const unsigned Config1_MD_LO = 5;
- const unsigned Config1_PC_HI = 4;
- const unsigned Config1_PC_LO = 4;
- const unsigned Config1_WR_HI = 3;
- const unsigned Config1_WR_LO = 3;
- const unsigned Config1_CA_HI = 2;
- const unsigned Config1_CA_LO = 2;
- const unsigned Config1_EP_HI = 1;
- const unsigned Config1_EP_LO = 1;
- const unsigned Config1_FP_HI = 0;
- const unsigned Config1_FP_LO = 0;
-
-
- // Config2 Register - CP0 Reg 16, Sel 2
- const unsigned Config2_M = 31;
- const unsigned Config2_TU_HI = 30;
- const unsigned Config2_TU_LO = 28;
- const unsigned Config2_TS_HI = 27;
- const unsigned Config2_TS_LO = 24;
- const unsigned Config2_TL_HI = 23;
- const unsigned Config2_TL_LO = 20;
- const unsigned Config2_TA_HI = 19;
- const unsigned Config2_TA_LO = 16;
- const unsigned Config2_SU_HI = 15;
- const unsigned Config2_SU_LO = 12;
- const unsigned Config2_SS_HI = 11;
- const unsigned Config2_SS_LO = 8;
- const unsigned Config2_SL_HI = 7;
- const unsigned Config2_SL_LO = 4;
- const unsigned Config2_SA_HI = 3;
- const unsigned Config2_SA_LO = 0;
-
- // Config3 Register - CP0 Reg 16, Sel 3
- const unsigned Config3_M = 31;
- const unsigned Config3_DSPP_HI = 10;
- const unsigned Config3_DSPP_LO = 10;
- const unsigned Config3_LPA_HI=7;
- const unsigned Config3_LPA_LO=7;
- const unsigned Config3_VEIC_HI=6;
- const unsigned Config3_VEIC_LO=6;
- const unsigned Config3_VINT_HI=5;
- const unsigned Config3_VINT_LO=5;
- const unsigned Config3_SP=4;
- const unsigned Config3_SP_HI=4;
- const unsigned Config3_SP_LO=4;
- const unsigned Config3_MT_HI=2;
- const unsigned Config3_MT_LO=2;
- const unsigned Config3_SM_HI=1;
- const unsigned Config3_SM_LO=1;
- const unsigned Config3_TL_HI=0;
- const unsigned Config3_TL_LO=0;
-
-
- // LLAddr Register - CP0 Reg 17, Sel 0
- // Load Linked Address (Physical)
- const unsigned LLAddr_PAddr_HI = 31;
- const unsigned LLAddr_PAddr_LO = 0;
-
-
-
- // WatchLo Register - CP0 Reg 18, Sel 0-n
- // See WatchHi to determine how many pairs of these registers are available
- const unsigned WatchLo_VAddr_HI = 31;
- const unsigned WatchLo_VAddr_LO = 3;
- const unsigned WatchLo_I = 2;
- const unsigned WatchLo_R = 1;
- const unsigned WatchLo_W = 0;
-
-
- // WatchHi Register - CP0 Reg 19, Sel 0-n
- const unsigned WatchHi_M = 31; // If M = 1, another pair of WatchHi/Lo registers exist
- const unsigned WatchHi_G = 30;
- const unsigned WatchHi_ASID_HI = 23;
- const unsigned WatchHi_ASID_LO = 16;
- const unsigned WatchHi_Mask_HI = 11;
- const unsigned WatchHi_Mask_LO = 3;
- const unsigned WatchHi_I = 2;
- const unsigned WatchHi_R = 1;
- const unsigned WatchHi_W = 0;
-
- // Debug Register - CP0 Reg 23, Sel 0
-
- // TraceControl Register - CP0 Reg 23, Sel 1
- // TraceControl2 Register - CP0 Reg 23, Sel 2
- // UserTraceData Register - CP0 Reg 23, Sel 3
- // TraceBPC Register - CP0 Reg 23, Sel 4
- // DEPC Register - CP0 Reg 24, Sel 0
-
-
- // PerfCnt Register - CP0 Reg 25, Sel 0-n
- // Each Perf. counter that exists is mapped onto even-odd select pairs of Reg 25
- // Even values are control registers, odd values are the actual counter
- // The format for the control reg is:
- const unsigned PerfCntCtl_M = 31; // Is there another pair of perf counter registers?
- const unsigned PerfCntCtl_W = 30;
- const unsigned PerfCntCtl_Event_HI = 10;
- const unsigned PerfCntCtl_Event_LO = 5;
- const unsigned PerfCntCtl_IE = 4;
- const unsigned PerfCntCtl_U = 3;
- const unsigned PerfCntCtl_S = 2;
- const unsigned PerfCntCtl_K = 1;
- const unsigned PerfCntCtl_EXL = 0;
-
- // The format for the counter is a 32-bit value (or 64-bit for MIPS64)
- const unsigned PerfCnt_Count_HI = 31;
- const unsigned PerfCnt_Count_LO = 0;
-
- // ErrCtl Register - CP0 Reg 26, Sel 0
- // This is implementation dependent, not defined by the ISA
-
- // CacheErr Register - CP0 Reg 27, Sel 0
- // NOTE: Page 65 of the ARM, Volume-III indicates that there are four sel. values (0-3)
- // used by the CacheErr registers. However, on page 134, only one sel value is shown
- const unsigned Cache_Err_ER = 31;
- const unsigned Cache_Err_EC = 30;
- const unsigned Cache_Err_ED = 29;
- const unsigned Cache_Err_ET = 28;
- const unsigned Cache_Err_ES = 27;
- const unsigned Cache_Err_EE = 26;
- const unsigned Cache_Err_EB = 25;
- const unsigned Cache_Err_IMPL_HI = 24;
- const unsigned Cache_Err_IMPL_LO = 22;
- const unsigned Cache_Err_Index_HI = 21;
- const unsigned Cache_Err_Index_LO = 0;
-
- // TagLo Register - CP0 Reg 28 - Even Selects (0,2)
- const unsigned TagLo_PTagLo_HI = 31;
- const unsigned TagLo_PTagLo_LO = 8;
- const unsigned TagLo_PState_HI = 7;
- const unsigned TagLo_PState_LO = 6;
- const unsigned TagLo_L = 5;
- const unsigned TagLo_IMPL_HI = 4;
- const unsigned TagLo_IMPL_LO = 3;
- const unsigned TagLo_P = 0;
- // undefined bits must be written 0
-
-
- // DataLo Register - CP0 Reg 28 - Odd Selects (1,3)
- const unsigned DataLo_HI = 31;
- const unsigned DataLo_LO = 0;
-
- // TagHi Register - CP0 Reg 29 - Even Selects (0,2)
- // Not defined by the architecture
-
- // DataHi Register - CP0 Reg 29 - Odd Selects (1,3)
- const unsigned DataHi_HI = 31;
- const unsigned DataHi_LO = 0;
-
-
- // ErrorEPC - CP0 Reg 30, Sel 0
- const unsigned ErrorPC_HI = 31;
- const unsigned ErrorPC_LO = 0;
-
- // DESAVE - CP0 Reg 31, Sel 0
-
-
-
+BitUnion32(IndexReg)
+ Bitfield<31> p;
+ // Need to figure out how to put in the TLB specific bits here
+ // For now, we assume that the entire length is used by the index
+ // field In reality, Index_HI = N-1, where
+ // N = Ceiling(log2(TLB Entries))
+ Bitfield<30, 0> index;
+EndBitUnion(IndexReg)
+
+BitUnion32(RandomReg)
+ // This has a problem similar to the IndexReg index field. We'll keep
+ // both consistent at 30 for now
+ Bitfield<30, 0> random;
+EndBitUnion(RandomReg)
+
+BitUnion64(EntryLoReg)
+ Bitfield<63, 30> fill;
+ Bitfield<29, 6> pfn; // Page frame number
+ Bitfield<5, 3> c; // Coherency attribute
+ Bitfield<2> d; // Dirty Bit
+ Bitfield<1> v; // Valid Bit
+ Bitfield<0> g; // Global Bit
+EndBitUnion(EntryLoReg)
+
+BitUnion64(ContextReg)
+ Bitfield<63, 23> pteBase;
+ Bitfield<22, 4> badVPN2;
+ // Bits 3-0 are 0
+EndBitUnion(ContextReg)
+
+BitUnion32(PageMaskReg)
+ // Bits 31-29 are 0
+ Bitfield<28, 13> mask;
+ Bitfield<12, 11> maskx;
+ // Bits 10-0 are zero
+EndBitUnion(PageMaskReg)
+
+BitUnion32(PageGrainReg)
+ Bitfield<31, 30> aseUp;
+ Bitfield<29> elpa;
+ Bitfield<28> esp;
+ // Bits 27-13 are zeros
+ Bitfield<12, 8> aseDn;
+ // Bits 7-0 are zeros
+EndBitUnion(PageGrainReg)
+
+BitUnion32(WiredReg)
+ // See note on Index register above
+ Bitfield<30, 0> wired;
+EndBitUnion(WiredReg)
+
+BitUnion32(HWREnaReg)
+ Bitfield<31, 30> impl;
+ Bitfield<3, 0> mask;
+EndBitUnion(HWREnaReg)
+
+BitUnion64(EntryHiReg)
+ Bitfield<63, 62> r;
+ Bitfield<61, 40> fill;
+ Bitfield<39, 13> vpn2;
+ Bitfield<12, 11> vpn2x;
+ Bitfield<7, 0> asid;
+EndBitUnion(EntryHiReg)
+
+BitUnion32(StatusReg)
+ SubBitUnion(cu, 31, 28)
+ Bitfield<31> cu3;
+ Bitfield<30> cu2;
+ Bitfield<29> cu1;
+ Bitfield<28> cu0;
+ EndSubBitUnion(cu)
+ Bitfield<27> rp;
+ Bitfield<26> fr;
+ Bitfield<25> re;
+ Bitfield<24> mx;
+ Bitfield<23> px;
+ Bitfield<22> bev;
+ Bitfield<21> ts;
+ Bitfield<20> sr;
+ Bitfield<19> nmi;
+ // Bit 18 is zero
+ Bitfield<17, 16> impl;
+ Bitfield<15, 10> ipl;
+ SubBitUnion(im, 15, 8)
+ Bitfield<15> im7;
+ Bitfield<14> im6;
+ Bitfield<13> im5;
+ Bitfield<12> im4;
+ Bitfield<11> im3;
+ Bitfield<10> im2;
+ Bitfield<9> im1;
+ Bitfield<8> im0;
+ EndSubBitUnion(im)
+ Bitfield<7> kx;
+ Bitfield<6> sx;
+ Bitfield<5> ux;
+ Bitfield<4, 3> ksu;
+ Bitfield<4> um;
+ Bitfield<3> r0;
+ Bitfield<2> erl;
+ Bitfield<1> exl;
+ Bitfield<0> ie;
+EndBitUnion(StatusReg)
+
+BitUnion32(IntCtlReg)
+ Bitfield<31, 29> ipti;
+ Bitfield<28, 26> ippci;
+ // Bits 26-10 are zeros
+ Bitfield<9, 5> vs;
+ // Bits 4-0 are zeros
+EndBitUnion(IntCtlReg)
+
+BitUnion32(SRSCtlReg)
+ // Bits 31-30 are zeros
+ Bitfield<29, 26> hss;
+ // Bits 25-22 are zeros
+ Bitfield<21, 18> eicss;
+ // Bits 17-16 are zeros
+ Bitfield<15, 12> ess;
+ // Bits 11-10 are zeros
+ Bitfield<9, 6> pss;
+ // Bits 5-4 are zeros
+ Bitfield<3, 0> css;
+EndBitUnion(SRSCtlReg)
+
+BitUnion32(SRSMapReg)
+ Bitfield<31, 28> ssv7;
+ Bitfield<27, 24> ssv6;
+ Bitfield<23, 20> ssv5;
+ Bitfield<19, 16> ssv4;
+ Bitfield<15, 12> ssv3;
+ Bitfield<11, 8> ssv2;
+ Bitfield<7, 4> ssv1;
+ Bitfield<3, 0> ssv0;
+EndBitUnion(SRSMapReg)
+
+BitUnion32(CauseReg)
+ Bitfield<31> bd;
+ Bitfield<30> ti;
+ Bitfield<29, 28> ce;
+ Bitfield<27> dc;
+ Bitfield<26> pci;
+ // Bits 25-24 are zeros
+ Bitfield<23> iv;
+ Bitfield<22> wp;
+ // Bits 21-16 are zeros
+ Bitfield<15, 10> ripl;
+ SubBitUnion(ip, 15, 8)
+ Bitfield<15> ip7;
+ Bitfield<14> ip6;
+ Bitfield<13> ip5;
+ Bitfield<12> ip4;
+ Bitfield<11> ip3;
+ Bitfield<10> ip2;
+ Bitfield<9> ip1;
+ Bitfield<8> ip0;
+ EndSubBitUnion(ip);
+ // Bit 7 is zero
+ Bitfield<6, 2> excCode;
+ // Bits 1-0 are zeros
+EndBitUnion(CauseReg)
+
+BitUnion32(PRIdReg)
+ Bitfield<31, 24> coOp;
+ Bitfield<23, 16> coId;
+ Bitfield<15, 8> procId;
+ Bitfield<7, 0> rev;
+EndBitUnion(PRIdReg)
+
+BitUnion32(EBaseReg)
+ // Bit 31 is one
+ // Bit 30 is zero
+ Bitfield<29, 12> exceptionBase;
+ // Bits 11-10 are zeros
+ Bitfield<9, 9> cpuNum;
+EndBitUnion(EBaseReg)
+
+BitUnion32(ConfigReg)
+ Bitfield<31> m;
+ Bitfield<30, 28> k23;
+ Bitfield<27, 25> ku;
+ Bitfield<24, 16> impl;
+ Bitfield<15> be;
+ Bitfield<14, 13> at;
+ Bitfield<12, 10> ar;
+ Bitfield<9, 7> mt;
+ // Bits 6-4 are zeros
+ Bitfield<3> vi;
+ Bitfield<2, 0> k0;
+EndBitUnion(ConfigReg)
+
+BitUnion32(Config1Reg)
+ Bitfield<31> m;
+ Bitfield<30, 25> mmuSize;
+ Bitfield<24, 22> is;
+ Bitfield<21, 19> il;
+ Bitfield<18, 16> ia;
+ Bitfield<15, 13> ds;
+ Bitfield<12, 10> dl;
+ Bitfield<9, 7> da;
+ Bitfield<6> c2;
+ Bitfield<5> md;
+ Bitfield<4> pc;
+ Bitfield<3> wr;
+ Bitfield<2> ca;
+ Bitfield<1> ep;
+ Bitfield<0> fp;
+EndBitUnion(Config1Reg)
+
+BitUnion32(Config2Reg)
+ Bitfield<31> m;
+ Bitfield<30, 28> tu;
+ Bitfield<27, 24> ts;
+ Bitfield<23, 20> tl;
+ Bitfield<19, 16> ta;
+ Bitfield<15, 12> su;
+ Bitfield<11, 8> ss;
+ Bitfield<7, 4> sl;
+ Bitfield<3, 0> sa;
+EndBitUnion(Config2Reg)
+
+BitUnion32(Config3Reg)
+ Bitfield<31> m;
+ // Bits 30-11 are zeros
+ Bitfield<10> dspp;
+ // Bits 9-8 are zeros
+ Bitfield<7> lpa;
+ Bitfield<6> veic;
+ Bitfield<5> vint;
+ Bitfield<4> sp;
+ // Bit 3 is zero
+ Bitfield<2> mt;
+ Bitfield<1> sm;
+ Bitfield<0> tl;
+EndBitUnion(Config3Reg)
+
+BitUnion64(WatchLoReg)
+ Bitfield<63, 3> vaddr;
+ Bitfield<2> i;
+ Bitfield<1> r;
+ Bitfield<0> w;
+EndBitUnion(WatchLoReg)
+
+BitUnion32(WatchHiReg)
+ Bitfield<31> m;
+ Bitfield<30> g;
+ // Bits 29-24 are zeros
+ Bitfield<23, 16> asid;
+ // Bits 15-12 are zeros
+ Bitfield<11, 3> mask;
+ Bitfield<2> i;
+ Bitfield<1> r;
+ Bitfield<0> w;
+EndBitUnion(WatchHiReg)
+
+BitUnion32(PerfCntCtlReg)
+ Bitfield<31> m;
+ Bitfield<30> w;
+ // Bits 29-11 are zeros
+ Bitfield<10, 5> event;
+ Bitfield<4> ie;
+ Bitfield<3> u;
+ Bitfield<2> s;
+ Bitfield<1> k;
+ Bitfield<0> exl;
+EndBitUnion(PerfCntCtlReg)
+
+BitUnion32(CacheErrReg)
+ Bitfield<31> er;
+ Bitfield<30> ec;
+ Bitfield<29> ed;
+ Bitfield<28> et;
+ Bitfield<27> es;
+ Bitfield<26> ee;
+ Bitfield<25> eb;
+ Bitfield<24, 22> impl;
+ Bitfield<22, 0> index;
+EndBitUnion(CacheErrReg)
+
+BitUnion32(TagLoReg)
+ Bitfield<31, 8> pTagLo;
+ Bitfield<7, 6> pState;
+ Bitfield<5> l;
+ Bitfield<4, 3> impl;
+ // Bits 2-1 are zeros
+ Bitfield<0> p;
+EndBitUnion(TagLoReg)
} // namespace MipsISA
diff --git a/src/arch/mips/predecoder.hh b/src/arch/mips/predecoder.hh
index 01e2ee768..c20fe1f5f 100644
--- a/src/arch/mips/predecoder.hh
+++ b/src/arch/mips/predecoder.hh
@@ -40,57 +40,66 @@ class ThreadContext;
namespace MipsISA
{
- class Predecoder
+
+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()
{
- 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;
- }
-
- 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;
- }
- };
+ }
+
+ 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;
+ }
+
+ 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_MIPS_PREDECODER_HH__
diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc
index 04a9a0f18..f3bcb5e68 100644
--- a/src/arch/mips/stacktrace.cc
+++ b/src/arch/mips/stacktrace.cc
@@ -42,35 +42,8 @@
using namespace std;
using namespace MipsISA;
-ProcessInfo::ProcessInfo(ThreadContext *_tc)
- : tc(_tc)
-{
-// Addr addr = 0;
-
- VirtualPort *vp;
-
- vp = tc->getVirtPort();
-
-// if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
-// panic("thread info not compiled into kernel\n");
-// thread_info_size = vp->readGtoH<int32_t>(addr);
-
-// if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
-// panic("thread info not compiled into kernel\n");
-// task_struct_size = vp->readGtoH<int32_t>(addr);
-
-// if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
-// panic("thread info not compiled into kernel\n");
-// task_off = vp->readGtoH<int32_t>(addr);
-
-// if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
-// panic("thread info not compiled into kernel\n");
-// pid_off = vp->readGtoH<int32_t>(addr);
-
-// if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
-// panic("thread info not compiled into kernel\n");
-// name_off = vp->readGtoH<int32_t>(addr);
-}
+ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
+{}
Addr
ProcessInfo::task(Addr ksp) const
@@ -140,84 +113,17 @@ void
StackTrace::trace(ThreadContext *_tc, bool is_call)
{
tc = _tc;
- /* FIXME - Jaidev - What is IPR_DTB_CM in Alpha? */
bool usermode = 0;
- //(tc->readMiscReg(MipsISA::IPR_DTB_CM) & 0x18) != 0;
-
-// Addr pc = tc->readNextPC();
-// bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
-// pc <= tc->getSystemPtr()->kernelEnd;
if (usermode) {
stack.push_back(user);
return;
}
-
-// if (!kernel) {
-// stack.push_back(console);
-// return;
-// }
-
-// SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
-// Addr ksp = tc->readIntReg(MipsISA::StackPointerReg);
-// Addr bottom = ksp & ~0x3fff;
-// Addr addr;
-
-// if (is_call) {
-// if (!symtab->findNearestAddr(pc, addr))
-// panic("could not find address %#x", pc);
-
-// stack.push_back(addr);
-// pc = tc->readPC();
-// }
-
-// Addr ra;
-// int size;
-
-// while (ksp > bottom) {
-// if (!symtab->findNearestAddr(pc, addr))
-// panic("could not find symbol for pc=%#x", pc);
-// assert(pc >= addr && "symbol botch: callpc < func");
-
-// stack.push_back(addr);
-
-// if (isEntry(addr))
-// return;
-
-// if (decodePrologue(ksp, pc, addr, size, ra)) {
-// if (!ra)
-// return;
-
-// if (size <= 0) {
-// stack.push_back(unknown);
-// return;
-// }
-
-// pc = ra;
-// ksp += size;
-// } else {
-// stack.push_back(unknown);
-// return;
-// }
-
-// bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
-// pc <= tc->getSystemPtr()->kernelEnd;
-// if (!kernel)
-// return;
-
-// if (stack.size() >= 1000)
-// panic("unwinding too far");
-// }
-
-// panic("unwinding too far");
}
bool
StackTrace::isEntry(Addr addr)
{
- /* if (addr == tc->readMiscReg(MipsISA::IPR_PALtemp2))
- return true;*/
-
return false;
}
@@ -305,7 +211,6 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
int reg, disp;
if (decodeStack(inst, disp)) {
if (size) {
- // panic("decoding frame size again");
return true;
}
size += disp;
@@ -313,7 +218,6 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
if (!ra && reg == ReturnAddressReg) {
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
if (!ra) {
- // panic("no return address value pc=%#x\n", pc);
return false;
}
}
@@ -327,24 +231,6 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
void
StackTrace::dump()
{
- StringWrap name(tc->getCpuPtr()->name());
-// SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
-
- DPRINTFN("------ Stack ------\n");
-
-// string symbol;
-// for (int i = 0, size = stack.size(); i < size; ++i) {
-// Addr addr = stack[size - i - 1];
-// if (addr == user)
-// symbol = "user";
-// else if (addr == console)
-// symbol = "console";
-// else if (addr == unknown)
-// symbol = "unknown";
-// else
-// symtab->findSymbol(addr, symbol);
-
-// DPRINTFN("%#x: %s\n", addr, symbol);
-// }
+ panic("Stack trace dump not implemented.\n");
}
#endif
diff --git a/src/arch/mips/system.cc b/src/arch/mips/system.cc
index 73bc33161..57310fa77 100755
--- a/src/arch/mips/system.cc
+++ b/src/arch/mips/system.cc
@@ -45,22 +45,17 @@
using namespace LittleEndianGuest;
-MipsSystem::MipsSystem(Params *p)
- : System(p)
+MipsSystem::MipsSystem(Params *p) : System(p)
{
#if FULL_SYSTEM
if (p->bare_iron == true) {
hexFile = new HexFile(params()->hex_file_name);
- if(!hexFile->loadSections(&functionalPort,MipsISA::LoadAddrMask))
+ if (!hexFile->loadSections(&functionalPort))
panic("Could not load hex file\n");
}
Addr addr = 0;
- /* Comment out old Alpha Based Code
-
- Don't need the console before we start looking at booting linux */
-
consoleSymtab = new SymbolTable;
@@ -76,7 +71,7 @@ MipsSystem::MipsSystem(Params *p)
if (console == NULL)
fatal("Could not load console file %s", params()->console);
//Load program sections into memory
- console->loadSections(&functionalPort, MipsISA::LoadAddrMask);
+ console->loadSections(&functionalPort, MipsISA::LoadAddrMask);
//load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@@ -98,7 +93,6 @@ MipsSystem::MipsSystem(Params *p)
*/
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
warn("writing addr starting from %#x", addr);
- cout << "-" << endl;
virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
strlen(params()->boot_osflags.c_str()));
}
@@ -110,100 +104,42 @@ MipsSystem::MipsSystem(Params *p)
if (consoleSymtab->findAddress("m5_rpb", addr)) {
uint64_t data;
data = htog(params()->system_type);
- virtPort.write(addr+0x50, data);
+ virtPort.write(addr + 0x50, data);
data = htog(params()->system_rev);
- virtPort.write(addr+0x58, data);
- } else
+ virtPort.write(addr + 0x58, data);
+ } else {
panic("could not find hwrpb\n");
+ }
#endif
}
MipsSystem::~MipsSystem()
{
}
-#if FULL_SYSTEM
-/**
- * This function fixes up addresses that are used to match PCs for
- * hooking simulator events on to target function executions.
- *
- * Mips binaries may have multiple global offset table (GOT)
- * sections. A function that uses the GOT starts with a
- * two-instruction prolog which sets the global pointer (gp == r29) to
- * the appropriate GOT section. The proper gp value is calculated
- * based on the function address, which must be passed by the caller
- * in the procedure value register (pv aka t12 == r27). This sequence
- * looks like the following:
- *
- * opcode Ra Rb offset
- * ldah gp,X(pv) 09 29 27 X
- * lda gp,Y(gp) 08 29 29 Y
- *
- * for some constant offsets X and Y. The catch is that the linker
- * (or maybe even the compiler, I'm not sure) may recognize that the
- * caller and callee are using the same GOT section, making this
- * prolog redundant, and modify the call target to skip these
- * instructions. If we check for execution of the first instruction
- * of a function (the one the symbol points to) to detect when to skip
- * it, we'll miss all these modified calls. It might work to
- * unconditionally check for the third instruction, but not all
- * functions have this prolog, and there's some chance that those
- * first two instructions could have undesired consequences. So we do
- * the Right Thing and pattern-match the first two instructions of the
- * function to decide where to patch.
- *
- * Eventually this code should be moved into an ISA-specific file.
- */
+#if FULL_SYSTEM
Addr
MipsSystem::fixFuncEventAddr(Addr addr)
{
- /*
- // mask for just the opcode, Ra, and Rb fields (not the offset)
- const uint32_t inst_mask = 0xffff0000;
- // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27
- const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16);
- // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
- const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
-
- uint32_t i1 = virtPort.read<uint32_t>(addr);
- uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(MipsISA::MachInst));
-
- if ((i1 & inst_mask) == gp_ldah_pattern &&
- (i2 & inst_mask) == gp_lda_pattern) {
- Addr new_addr = addr + 2* sizeof(MipsISA::MachInst);
- DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
- return new_addr;
- } else {
- return addr;
- }*/
- return addr;
+ return addr;
}
-
void
MipsSystem::setMipsAccess(Addr access)
-{
- Addr addr = 0;
- if (consoleSymtab->findAddress("m5MipsAccess", addr)) {
- // virtPort.write(addr, htog(AlphaISA::Phys2K0Seg(access)));
- } else
- panic("could not find m5MipsAccess\n");
- }
+{}
#endif
bool
MipsSystem::breakpoint()
{
- return 0;
- // return remoteGDB[0]->trap(MIPS_KENTRY_INT);
+ return 0;
}
void
MipsSystem::serialize(std::ostream &os)
{
System::serialize(os);
- // consoleSymtab->serialize("console_symtab", os);
}
@@ -211,7 +147,6 @@ void
MipsSystem::unserialize(Checkpoint *cp, const std::string &section)
{
System::unserialize(cp,section);
- // consoleSymtab->unserialize("console_symtab", cp, section);
}
MipsSystem *
diff --git a/src/arch/mips/system.hh b/src/arch/mips/system.hh
index 13cd3a75f..cfdf316b3 100755
--- a/src/arch/mips/system.hh
+++ b/src/arch/mips/system.hh
@@ -54,10 +54,10 @@ class MipsSystem : public System
virtual bool breakpoint();
-/**
- * Serialization stuff
- */
public:
+ /**
+ * Serialization stuff
+ */
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
@@ -89,7 +89,8 @@ class MipsSystem : public System
#if FULL_SYSTEM
/** Add a function-based event to the console code. */
template <class T>
- T *addConsoleFuncEvent(const char *lbl)
+ T *
+ addConsoleFuncEvent(const char *lbl)
{
return addFuncEvent<T>(consoleSymtab, lbl);
}
diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc
index 18a29122c..37c1ecee3 100644
--- a/src/arch/mips/tlb.cc
+++ b/src/arch/mips/tlb.cc
@@ -56,16 +56,14 @@ using namespace MipsISA;
// MIPS TLB
//
-#define MODE2MASK(X) (1 << (X))
-
static inline mode_type
getOperatingMode(MiscReg Stat)
{
- if((Stat & 0x10000006) != 0 || (Stat & 0x18) ==0) {
+ if ((Stat & 0x10000006) != 0 || (Stat & 0x18) ==0) {
return mode_kernel;
- } else if((Stat & 0x18) == 0x8) {
+ } else if ((Stat & 0x18) == 0x8) {
return mode_supervisor;
- } else if((Stat & 0x18) == 0x10) {
+ } else if ((Stat & 0x18) == 0x10) {
return mode_user;
} else {
return mode_number;
@@ -76,9 +74,9 @@ getOperatingMode(MiscReg Stat)
TLB::TLB(const Params *p)
: BaseTLB(p), size(p->size), nlu(0)
{
- table = new MipsISA::PTE[size];
- memset(table, 0, sizeof(MipsISA::PTE[size]));
- smallPages=0;
+ table = new PTE[size];
+ memset(table, 0, sizeof(PTE[size]));
+ smallPages = 0;
}
TLB::~TLB()
@@ -92,23 +90,23 @@ MipsISA::PTE *
TLB::lookup(Addr vpn, uint8_t asn) const
{
// assume not found...
- MipsISA::PTE *retval = NULL;
+ PTE *retval = NULL;
PageTable::const_iterator i = lookupTable.find(vpn);
if (i != lookupTable.end()) {
while (i->first == vpn) {
int index = i->second;
- MipsISA::PTE *pte = &table[index];
+ PTE *pte = &table[index];
/* 1KB TLB Lookup code - from MIPS 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
+ if (((vpn & InvMask) == (VPN & InvMask)) &&
+ (pte->G || (asn == pte->asid))) {
+ // We have a VPN + ASID Match
retval = pte;
break;
- }
+ }
++i;
}
}
@@ -118,119 +116,96 @@ TLB::lookup(Addr vpn, uint8_t asn) const
return retval;
}
-MipsISA::PTE* TLB::getEntry(unsigned Index) const
+MipsISA::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
+int
+TLB::probeEntry(Addr vpn, uint8_t asn) const
{
// assume not found...
- MipsISA::PTE *retval = NULL;
- int Ind=-1;
+ 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;
- MipsISA::PTE *pte = &table[index];
+ PTE *pte = &table[index];
/* 1KB TLB Lookup code - from MIPS 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
+ 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(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind);
return Ind;
}
-Fault inline
+
+inline Fault
TLB::checkCacheability(RequestPtr &req)
{
- Addr VAddrUncacheable = 0xA0000000;
- // In MIPS, 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(Request::UNCACHEABLE);
- }
- return NoFault;
-}
-void TLB::insertAt(MipsISA::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);
+ Addr VAddrUncacheable = 0xA0000000;
+ // In MIPS, 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(Request::UNCACHEABLE);
}
- 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);
- }
-
+ return NoFault;
}
-// insert a new TLB entry
void
-TLB::insert(Addr addr, MipsISA::PTE &pte)
+TLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
{
- fatal("TLB Insert not yet implemented\n");
-
-
- /* MipsISA::VAddr vaddr = addr;
- if (table[nlu].valid) {
- Addr oldvpn = table[nlu].tag;
- PageTable::iterator i = lookupTable.find(oldvpn);
-
- if (i == lookupTable.end())
- panic("TLB entry not found in lookupTable");
-
- int index;
- while ((index = i->second) != nlu) {
- if (table[index].tag != oldvpn)
- panic("TLB entry not found in lookupTable");
-
- ++i;
+ 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);
}
-
- DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
-
- lookupTable.erase(i);
+ table[Index]=pte;
+ // Update fast lookup table
+ lookupTable.insert(make_pair(table[Index].VPN, Index));
}
+}
- DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
-
- table[nlu] = pte;
- table[nlu].tag = vaddr.vpn();
- table[nlu].valid = true;
-
- lookupTable.insert(make_pair(vaddr.vpn(), nlu));
- nextnlu();
- */
+// insert a new TLB entry
+void
+TLB::insert(Addr addr, PTE &pte)
+{
+ fatal("TLB Insert not yet implemented\n");
}
void
TLB::flushAll()
{
DPRINTF(TLB, "flushAll\n");
- memset(table, 0, sizeof(MipsISA::PTE[size]));
+ memset(table, 0, sizeof(PTE[size]));
lookupTable.clear();
nlu = 0;
}
@@ -328,113 +303,104 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
Process * p = tc->getProcessPtr();
Fault fault = p->pTable->translate(req);
- if(fault != NoFault)
+ if (fault != NoFault)
return fault;
return NoFault;
#else
- if(MipsISA::IsKSeg0(req->getVaddr()))
- {
- // Address will not be translated through TLB, set response, and go!
- req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr()));
- if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned())
- {
- AddressErrorFault *Flt = new AddressErrorFault();
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
- return Flt;
+ if (IsKSeg0(req->getVaddr())) {
+ // Address will not be translated through TLB, set response, and go!
+ req->setPaddr(KSeg02Phys(req->getVaddr()));
+ if (getOperatingMode(tc->readMiscReg(Status)) != mode_kernel ||
+ req->isMisaligned()) {
+ AddressErrorFault *Flt = new AddressErrorFault();
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+ return Flt;
}
- }
- else if(MipsISA::IsKSeg1(req->getVaddr()))
- {
- // Address will not be translated through TLB, set response, and go!
- req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr()));
- }
- else
- {
- /* This is an optimization - smallPages is updated every time a TLB operation is performed
- That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we
- do a TLB lookup */
+ } else if(IsKSeg1(req->getVaddr())) {
+ // Address will not be translated through TLB, set response, and go!
+ req->setPaddr(KSeg02Phys(req->getVaddr()));
+ } else {
+ /*
+ * This is an optimization - smallPages is updated every time a TLB
+ * operation is performed. That way, we don't need to look at
+ * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup
+ */
Addr VPN;
- if(smallPages==1){
- VPN=((req->getVaddr() >> 11));
+ if (smallPages == 1) {
+ VPN = ((req->getVaddr() >> 11));
} else {
- VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC);
+ VPN = ((req->getVaddr() >> 11) & 0xFFFFFFFC);
}
uint8_t Asid = req->getAsid();
- if(req->isMisaligned()){ // Unaligned address!
- AddressErrorFault *Flt = new AddressErrorFault();
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
- return Flt;
+ if (req->isMisaligned()) {
+ // Unaligned address!
+ AddressErrorFault *Flt = new AddressErrorFault();
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+ return Flt;
}
- MipsISA::PTE *pte = lookup(VPN,Asid);
- if(pte != NULL)
- {// Ok, found something
+ PTE *pte = lookup(VPN,Asid);
+ if (pte != NULL) {
+ // Ok, found something
/* Check for valid bits */
int EvenOdd;
bool Valid;
- if((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) ==0){
- // Check even bits
- Valid = pte->V0;
- EvenOdd = 0;
+ if ((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) == 0) {
+ // Check even bits
+ Valid = pte->V0;
+ EvenOdd = 0;
} else {
- // Check odd bits
- Valid = pte->V1;
- EvenOdd = 1;
+ // Check odd bits
+ Valid = pte->V1;
+ EvenOdd = 1;
}
- if(Valid == false)
- {//Invalid entry
+ if (Valid == false) {
+ //Invalid entry
ItbInvalidFault *Flt = new ItbInvalidFault();
/* EntryHi VPN, ASID fields must be set */
- Flt->EntryHi_Asid = Asid;
- Flt->EntryHi_VPN2 = (VPN>>2);
- Flt->EntryHi_VPN2X = (VPN & 0x3);
+ Flt->entryHiAsid = Asid;
+ Flt->entryHiVPN2 = (VPN >> 2);
+ Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
+ Flt->badVAddr = req->getVaddr();
/* Context must be set */
- Flt->Context_BadVPN2 = (VPN >> 2);
+ Flt->contextBadVPN2 = (VPN >> 2);
return Flt;
- }
- else
- {// Ok, this is really a match, set paddr
- // hits++;
+ } else {
+ // Ok, this is really a match, set paddr
Addr PAddr;
- if(EvenOdd == 0){
+ if (EvenOdd == 0) {
PAddr = pte->PFN0;
- }else{
+ } else {
PAddr = pte->PFN1;
}
- PAddr >>= (pte->AddrShiftAmount-12);
+ PAddr >>= (pte->AddrShiftAmount - 12);
PAddr <<= pte->AddrShiftAmount;
PAddr |= ((req->getVaddr()) & pte->OffsetMask);
req->setPaddr(PAddr);
-
-
}
- }
- else
- { // Didn't find any match, return a TLB Refill Exception
- // misses++;
- ItbRefillFault *Flt=new ItbRefillFault();
- /* EntryHi VPN, ASID fields must be set */
- Flt->EntryHi_Asid = Asid;
- Flt->EntryHi_VPN2 = (VPN>>2);
- Flt->EntryHi_VPN2X = (VPN & 0x3);
-
-
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
-
- /* Context must be set */
- Flt->Context_BadVPN2 = (VPN >> 2);
- return Flt;
+ } else {
+ // Didn't find any match, return a TLB Refill Exception
+ ItbRefillFault *Flt=new ItbRefillFault();
+ /* EntryHi VPN, ASID fields must be set */
+ Flt->entryHiAsid = Asid;
+ Flt->entryHiVPN2 = (VPN >> 2);
+ Flt->entryHiVPN2X = (VPN & 0x3);
+
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+
+ /* Context must be set */
+ Flt->contextBadVPN2 = (VPN >> 2);
+ return Flt;
}
}
- return checkCacheability(req);
+ return checkCacheability(req);
#endif
}
@@ -457,131 +423,118 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
Process * p = tc->getProcessPtr();
Fault fault = p->pTable->translate(req);
- if(fault != NoFault)
+ if (fault != NoFault)
return fault;
return NoFault;
#else
- if(MipsISA::IsKSeg0(req->getVaddr()))
- {
- // Address will not be translated through TLB, set response, and go!
- req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr()));
- if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned())
- {
- StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
-
- return Flt;
+ if (IsKSeg0(req->getVaddr())) {
+ // Address will not be translated through TLB, set response, and go!
+ req->setPaddr(KSeg02Phys(req->getVaddr()));
+ if (getOperatingMode(tc->readMiscReg(Status)) != mode_kernel ||
+ req->isMisaligned()) {
+ StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+
+ return Flt;
}
- }
- else if(MipsISA::IsKSeg1(req->getVaddr()))
- {
+ } else if(IsKSeg1(req->getVaddr())) {
// Address will not be translated through TLB, set response, and go!
- req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr()));
- }
- else
- {
- /* This is an optimization - smallPages is updated every time a TLB operation is performed
- That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we
- do a TLB lookup */
- Addr VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC);
- if(smallPages==1){
- VPN=((req->getVaddr() >> 11));
- }
- uint8_t Asid = req->getAsid();
- MipsISA::PTE *pte = lookup(VPN,Asid);
- if(req->isMisaligned()){ // Unaligned address!
- StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
- return Flt;
- }
- if(pte != NULL)
- {// Ok, found something
- /* Check for valid bits */
- int EvenOdd;
- bool Valid;
- bool Dirty;
- if(((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) ==0){
- // Check even bits
- Valid = pte->V0;
- Dirty = pte->D0;
- EvenOdd = 0;
-
- } else {
- // Check odd bits
- Valid = pte->V1;
- Dirty = pte->D1;
- EvenOdd = 1;
- }
-
- if(Valid == false)
- {//Invalid entry
- // invalids++;
- DtbInvalidFault *Flt = new DtbInvalidFault();
- /* EntryHi VPN, ASID fields must be set */
- Flt->EntryHi_Asid = Asid;
- Flt->EntryHi_VPN2 = (VPN>>2);
- Flt->EntryHi_VPN2X = (VPN & 0x3);
-
-
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
-
- /* Context must be set */
- Flt->Context_BadVPN2 = (VPN >> 2);
-
- return Flt;
+ req->setPaddr(KSeg02Phys(req->getVaddr()));
+ } else {
+ /*
+ * This is an optimization - smallPages is updated every time a TLB
+ * operation is performed. That way, we don't need to look at
+ * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup
+ */
+ Addr VPN = ((req->getVaddr() >> 11) & 0xFFFFFFFC);
+ if (smallPages == 1) {
+ VPN = ((req->getVaddr() >> 11));
+ }
+ uint8_t Asid = req->getAsid();
+ PTE *pte = lookup(VPN, Asid);
+ if (req->isMisaligned()) {
+ // Unaligned address!
+ StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+ return Flt;
+ }
+ if (pte != NULL) {
+ // Ok, found something
+ /* Check for valid bits */
+ int EvenOdd;
+ bool Valid;
+ bool Dirty;
+ if (((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) == 0) {
+ // Check even bits
+ Valid = pte->V0;
+ Dirty = pte->D0;
+ EvenOdd = 0;
+ } else {
+ // Check odd bits
+ Valid = pte->V1;
+ Dirty = pte->D1;
+ EvenOdd = 1;
}
- else
- {// Ok, this is really a match, set paddr
- // hits++;
- if(!Dirty)
- {
- TLBModifiedFault *Flt = new TLBModifiedFault();
- /* EntryHi VPN, ASID fields must be set */
- Flt->EntryHi_Asid = Asid;
- Flt->EntryHi_VPN2 = (VPN>>2);
- Flt->EntryHi_VPN2X = (VPN & 0x3);
-
-
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
-
- /* Context must be set */
- Flt->Context_BadVPN2 = (VPN >> 2);
- return Flt;
+ if (Valid == false) {
+ //Invalid entry
+ DtbInvalidFault *Flt = new DtbInvalidFault();
+ /* EntryHi VPN, ASID fields must be set */
+ Flt->entryHiAsid = Asid;
+ Flt->entryHiVPN2 = (VPN>>2);
+ Flt->entryHiVPN2X = (VPN & 0x3);
+
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+
+ /* Context must be set */
+ Flt->contextBadVPN2 = (VPN >> 2);
+
+ return Flt;
+ } else {
+ // Ok, this is really a match, set paddr
+ if (!Dirty) {
+ TLBModifiedFault *Flt = new TLBModifiedFault();
+ /* EntryHi VPN, ASID fields must be set */
+ Flt->entryHiAsid = Asid;
+ Flt->entryHiVPN2 = (VPN >> 2);
+ Flt->entryHiVPN2X = (VPN & 0x3);
+
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+
+ /* Context must be set */
+ Flt->contextBadVPN2 = (VPN >> 2);
+ return Flt;
}
- Addr PAddr;
- if(EvenOdd == 0){
- PAddr = pte->PFN0;
- }else{
- PAddr = pte->PFN1;
- }
- PAddr >>= (pte->AddrShiftAmount-12);
- PAddr <<= pte->AddrShiftAmount;
- PAddr |= ((req->getVaddr()) & pte->OffsetMask);
- req->setPaddr(PAddr);
+ Addr PAddr;
+ if (EvenOdd == 0) {
+ PAddr = pte->PFN0;
+ } else {
+ PAddr = pte->PFN1;
+ }
+ PAddr >>= (pte->AddrShiftAmount - 12);
+ PAddr <<= pte->AddrShiftAmount;
+ PAddr |= ((req->getVaddr()) & pte->OffsetMask);
+ req->setPaddr(PAddr);
}
- }
- else
- { // Didn't find any match, return a TLB Refill Exception
- // misses++;
- DtbRefillFault *Flt=new DtbRefillFault();
- /* EntryHi VPN, ASID fields must be set */
- Flt->EntryHi_Asid = Asid;
- Flt->EntryHi_VPN2 = (VPN>>2);
- Flt->EntryHi_VPN2X = (VPN & 0x3);
-
-
- /* BadVAddr must be set */
- Flt->BadVAddr = req->getVaddr();
-
- /* Context must be set */
- Flt->Context_BadVPN2 = (VPN >> 2);
- return Flt;
+ } else {
+ // Didn't find any match, return a TLB Refill Exception
+ DtbRefillFault *Flt = new DtbRefillFault();
+ /* EntryHi VPN, ASID fields must be set */
+ Flt->entryHiAsid = Asid;
+ Flt->entryHiVPN2 = (VPN >> 2);
+ Flt->entryHiVPN2X = (VPN & 0x3);
+
+ /* BadVAddr must be set */
+ Flt->badVAddr = req->getVaddr();
+
+ /* Context must be set */
+ Flt->contextBadVPN2 = (VPN >> 2);
+ return Flt;
}
}
return checkCacheability(req);
@@ -609,7 +562,7 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
MipsISA::PTE &
TLB::index(bool advance)
{
- MipsISA::PTE *pte = &table[nlu];
+ PTE *pte = &table[nlu];
if (advance)
nextnlu();
@@ -620,5 +573,5 @@ TLB::index(bool advance)
MipsISA::TLB *
MipsTLBParams::create()
{
- return new MipsISA::TLB(this);
+ return new TLB(this);
}
diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh
index f203d7d57..c7ef6afe1 100644
--- a/src/arch/mips/types.hh
+++ b/src/arch/mips/types.hh
@@ -35,42 +35,43 @@
namespace MipsISA
{
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
-
- typedef uint64_t LargestRead;
-
- //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
- };
+
+typedef uint32_t MachInst;
+typedef uint64_t ExtMachInst;
+
+typedef uint64_t LargestRead;
+
+//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
+};
struct CoreSpecific {
/* Note: It looks like it will be better to allow simulator users
@@ -81,7 +82,8 @@ struct CoreSpecific {
-jpp
*/
// MIPS CP0 State - First individual variables
- // Page numbers refer to revision 2.50 (July 2005) of the MIPS32 ARM, Volume III (PRA)
+ // Page numbers refer to revision 2.50 (July 2005) of the MIPS32 ARM,
+ // Volume III (PRA)
unsigned CP0_IntCtl_IPTI; // Page 93, IP Timer Interrupt
unsigned CP0_IntCtl_IPPCI; // Page 94, IP Performance Counter Interrupt
unsigned CP0_SrsCtl_HSS; // Page 95, Highest Implemented Shadow Set
@@ -89,7 +91,8 @@ struct CoreSpecific {
unsigned CP0_PRId_CompanyID; // Page 105, Company ID - (0-255, 1=>MIPS)
unsigned CP0_PRId_ProcessorID; // Page 105
unsigned CP0_PRId_Revision; // Page 105
- unsigned CP0_EBase_CPUNum; // Page 106, CPU Number in a multiprocessor system
+ unsigned CP0_EBase_CPUNum; // Page 106, CPU Number in a multiprocessor
+ //system
unsigned CP0_Config_BE; // Page 108, Big/Little Endian mode
unsigned CP0_Config_AT; //Page 109
unsigned CP0_Config_AR; //Page 109
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
index 4723d6301..ac90ce45e 100644
--- a/src/arch/mips/utility.cc
+++ b/src/arch/mips/utility.cc
@@ -38,6 +38,7 @@
#include "base/misc.hh"
#if FULL_SYSTEM
+#include "arch/mips/registers.hh"
#include "arch/mips/vtophys.hh"
#include "mem/vport.hh"
#endif
@@ -52,16 +53,16 @@ uint64_t
getArgument(ThreadContext *tc, int number, bool fp)
{
#if FULL_SYSTEM
- if (number < NumArgumentRegs) {
+ if (number < 4) {
if (fp)
- return tc->readFloatRegBits(ArgumentReg[number]);
+ return tc->readFloatRegBits(FirstArgumentReg + number);
else
- return tc->readIntReg(ArgumentReg[number]);
+ return tc->readIntReg(FirstArgumentReg + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort();
uint64_t arg = vp->read<uint64_t>(sp +
- (number-NumArgumentRegs) * sizeof(uint64_t));
+ (number - 4) * sizeof(uint64_t));
return arg;
}
#else
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index 23c965bd4..37cd838e5 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -45,87 +45,88 @@ class ThreadContext;
namespace MipsISA {
- uint64_t getArgument(ThreadContext *tc, int number, bool fp);
-
- ////////////////////////////////////////////////////////////////////////
- //
- // 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);
-
- static inline bool
- inUserMode(ThreadContext *tc)
- {
- MiscReg Stat = tc->readMiscReg(MipsISA::Status);
- MiscReg Dbg = tc->readMiscReg(MipsISA::Debug);
-
- if((Stat & 0x10000006) == 0 // EXL, ERL or CU0 set, CP0 accessible
- && (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
- && (Stat & 0x00000018) != 0) { // KSU = 0, kernel mode is base mode
- // Unable to use Status_CU0, etc directly, using bitfields & masks
- return true;
- } else {
- return false;
- }
+uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+
+////////////////////////////////////////////////////////////////////////
+//
+// 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);
+
+static inline bool
+inUserMode(ThreadContext *tc)
+{
+ MiscReg Stat = tc->readMiscReg(MipsISA::Status);
+ MiscReg Dbg = tc->readMiscReg(MipsISA::Debug);
+
+ if ((Stat & 0x10000006) == 0 && // EXL, ERL or CU0 set, CP0 accessible
+ (Dbg & 0x40000000) == 0 && // DM bit set, CP0 accessible
+ (Stat & 0x00000018) != 0) { // KSU = 0, kernel mode is base mode
+ // Unable to use Status_CU0, etc directly, using bitfields & masks
+ return true;
+ } else {
+ return false;
}
+}
+
+// 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 (not necessarily the size
+// of real instructions for PISA)
+static inline size_t fetchInstSize() {
+ return sizeof(MachInst);
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// Register File Utility Functions
+//
+static inline MachInst makeRegisterCopy(int dest, int src) {
+ panic("makeRegisterCopy not implemented");
+ return 0;
+}
+
+template <class CPU>
+void zeroRegisters(CPU *cpu);
+
+////////////////////////////////////////////////////////////////////////
+//
+// Translation stuff
+//
+inline Addr
+TruncPage(Addr addr)
+{ return addr & ~(PageBytes - 1); }
+
+inline Addr
+RoundPage(Addr addr)
+{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
+
+////////////////////////////////////////////////////////////////////////
+//
+// CPU Utility
+//
+void startupCPU(ThreadContext *tc, int cpuId);
+
+void copyRegs(ThreadContext *src, ThreadContext *dest);
+void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
- // 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 (not necessarily the size
- // of real instructions for PISA)
- static inline size_t fetchInstSize() {
- return sizeof(MachInst);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Register File Utility Functions
- //
- static inline MachInst makeRegisterCopy(int dest, int src) {
- panic("makeRegisterCopy not implemented");
- return 0;
- }
-
- template <class CPU>
- void zeroRegisters(CPU *cpu);
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Translation stuff
- //
- inline Addr
- TruncPage(Addr addr)
- { return addr & ~(PageBytes - 1); }
-
- inline Addr
- RoundPage(Addr addr)
- { return (addr + PageBytes - 1) & ~(PageBytes - 1); }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CPU Utility
- //
- void startupCPU(ThreadContext *tc, int cpuId);
-
- void copyRegs(ThreadContext *src, ThreadContext *dest);
- void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
};
diff --git a/src/arch/mips/vtophys.cc b/src/arch/mips/vtophys.cc
index dc212862b..08e1a1e1c 100755
--- a/src/arch/mips/vtophys.cc
+++ b/src/arch/mips/vtophys.cc
@@ -53,7 +53,8 @@ MipsISA::vtophys(Addr vaddr)
else if(MipsISA::IsKSeg1(vaddr))
paddr = MipsISA::KSeg12Phys(vaddr);
else
- panic("vtophys: ptbr is not set on virtual lookup for vaddr %#x", vaddr);
+ panic("vtophys: ptbr is not set on "
+ "virtual lookup for vaddr %#x", vaddr);
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
@@ -63,7 +64,6 @@ MipsISA::vtophys(Addr vaddr)
Addr
MipsISA::vtophys(ThreadContext *tc, Addr addr)
{
-
fatal("VTOPHYS: Unimplemented on MIPS\n");
}
diff --git a/src/dev/mips/Malta.py b/src/dev/mips/Malta.py
index d215bf329..740aa4a7f 100755
--- a/src/dev/mips/Malta.py
+++ b/src/dev/mips/Malta.py
@@ -42,10 +42,12 @@ class MaltaCChip(BasicPioDevice):
class MaltaIO(BasicPioDevice):
type = 'MaltaIO'
- time = Param.UInt64(1136073600,
+ time = Param.Time('01/01/2009',
"System time to use (0 for actual time, default is 1/1/06)")
+ year_is_bcd = Param.Bool(False,
+ "The RTC should interpret the year as a BCD value")
malta = Param.Malta(Parent.any, "Malta")
- frequency = Param.Frequency('1050Hz', "frequency of interrupts")
+ frequency = Param.Frequency('1024Hz', "frequency of interrupts")
class MaltaPChip(BasicPioDevice):
type = 'MaltaPChip'
diff --git a/src/dev/mips/SConscript b/src/dev/mips/SConscript
index e83e47ebd..982d87266 100755
--- a/src/dev/mips/SConscript
+++ b/src/dev/mips/SConscript
@@ -36,7 +36,6 @@ if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'mips':
SimObject('Malta.py')
TraceFlag('Malta')
- TraceFlag('MC146818')
Source('backdoor.cc')
Source('malta.cc')
diff --git a/src/dev/mips/backdoor.cc b/src/dev/mips/backdoor.cc
index 313f12567..a1247fbd0 100755
--- a/src/dev/mips/backdoor.cc
+++ b/src/dev/mips/backdoor.cc
@@ -84,7 +84,7 @@ void
MipsBackdoor::startup()
{
system->setMipsAccess(pioAddr);
- mipsAccess->numCPUs = system->getNumCPUs();
+ mipsAccess->numCPUs = system->numContexts();
mipsAccess->kernStart = MipsISA::Phys2K0Seg(system->getKernelStart());
mipsAccess->kernEnd = MipsISA::Phys2K0Seg(system->getKernelEnd());
mipsAccess->entryPoint = MipsISA::Phys2K0Seg(system->getKernelEntry());
diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc
index 21e79d999..1401fe9ee 100755
--- a/src/dev/mips/malta.cc
+++ b/src/dev/mips/malta.cc
@@ -69,51 +69,38 @@ Malta::intrFrequency()
void
Malta::postConsoleInt()
{
- //panic("Malta::postConsoleInt() has not been implemented.");
- io->postIntr(0x10/*HW4*/);//see {Linux-src}/arch/mips/mips-boards/sim/sim_setup.c
+ //see {Linux-src}/arch/mips/mips-boards/sim/sim_setup.c
+ io->postIntr(0x10/*HW4*/);
}
void
Malta::clearConsoleInt()
{
- //FIXME: implement clearConsoleInt()
- //warn("Malta::clearConsoleInt() has not been implemented.");
+ //FIXME: implement clearConsoleInt()
io->clearIntr(0x10/*HW4*/);
}
void
Malta::postPciInt(int line)
{
- panic("Malta::postPciInt() has not been implemented.");
- //cchip->postDRIR(line);
+ panic("Malta::postPciInt() has not been implemented.");
}
void
Malta::clearPciInt(int line)
{
- panic("Malta::clearPciInt() has not been implemented.");
- //cchip->clearDRIR(line);
+ panic("Malta::clearPciInt() has not been implemented.");
}
Addr
Malta::pciToDma(Addr pciAddr) const
{
- panic("Malta::pciToDma() has not been implemented.");
- return pchip->translatePciToDma(pciAddr);
-}
-
-
-Addr
-Malta::calcConfigAddr(int bus, int dev, int func)
-{
- panic("Malta::calcConfigAddr() has not been implemented.");
- return pchip->calcConfigAddr(bus, dev, func);
+ panic("Malta::pciToDma() has not been implemented.");
}
void
Malta::serialize(std::ostream &os)
{
-
SERIALIZE_ARRAY(intr_sum_type, Malta::Max_CPUs);
}
diff --git a/src/dev/mips/malta.hh b/src/dev/mips/malta.hh
index 5569c7c90..69ae004b3 100755
--- a/src/dev/mips/malta.hh
+++ b/src/dev/mips/malta.hh
@@ -120,10 +120,26 @@ class Malta : public Platform
virtual Addr pciToDma(Addr pciAddr) const;
- /**
- * Calculate the configuration address given a bus/dev/func.
- */
- virtual Addr calcConfigAddr(int bus, int dev, int func);
+ Addr
+ calcPciConfigAddr(int bus, int dev, int func)
+ {
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+ }
+
+ Addr
+ calcPciIOAddr(Addr addr)
+ {
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+ }
+
+ Addr
+ calcPciMemAddr(Addr addr)
+ {
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+ }
/**
* Serialize this object to the given output stream.
diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc
index b56694f1e..7f04789db 100755
--- a/src/dev/mips/malta_io.cc
+++ b/src/dev/mips/malta_io.cc
@@ -40,8 +40,8 @@
#include <string>
#include <vector>
+#include "base/time.hh"
#include "base/trace.hh"
-#include "dev/pitreg.h"
#include "dev/rtcreg.h"
#include "dev/mips/malta_cchip.hh"
#include "dev/mips/malta.hh"
@@ -56,419 +56,15 @@
using namespace std;
using namespace TheISA;
-MaltaIO::RTC::RTC(const string &name, Malta* t, Tick i)
- : _name(name), event(t, i), addr(0)
+MaltaIO::RTC::RTC(const string &name, const MaltaIOParams *p)
+ : MC146818(p->malta, name, p->time, p->year_is_bcd, p->frequency),
+ malta(p->malta)
{
- memset(clock_data, 0, sizeof(clock_data));
- stat_regA = RTCA_32768HZ | RTCA_1024HZ;
- stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;
}
-void
-MaltaIO::RTC::set_time(time_t t)
-{
- struct tm tm;
- gmtime_r(&t, &tm);
-
- sec = tm.tm_sec;
- min = tm.tm_min;
- hour = tm.tm_hour;
- wday = tm.tm_wday + 1;
- mday = tm.tm_mday;
- mon = tm.tm_mon + 1;
- year = tm.tm_year;
-
- DPRINTFN("Real-time clock set to %s", asctime(&tm));
-}
-
-void
-MaltaIO::RTC::writeAddr(const uint8_t data)
-{
- panic("MaltaIO::RTC::writeAddr has not been implemented for malta");
- /*
- if (data <= RTC_STAT_REGD)
- addr = data;
- else
- panic("RTC addresses over 0xD are not implemented.\n");
- */
-}
-
-void
-MaltaIO::RTC::writeData(const uint8_t data)
-{
- panic("MaltaIO::RTC::writeData has not been implemented for malta");
- /*
- if (addr < RTC_STAT_REGA)
- clock_data[addr] = data;
- else {
- switch (addr) {
- case RTC_STAT_REGA:
- if (data != (RTCA_32768HZ | RTCA_1024HZ))
- panic("Unimplemented RTC register A value write!\n");
- stat_regA = data;
- break;
- case RTC_STAT_REGB:
- if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))
- panic("Write to RTC reg B bits that are not implemented!\n");
-
- if (data & RTCB_PRDC_IE) {
- if (!event.scheduled())
- event.scheduleIntr();
- } else {
- if (event.scheduled())
- event.deschedule();
- }
- stat_regB = data;
- break;
- case RTC_STAT_REGC:
- case RTC_STAT_REGD:
- panic("RTC status registers C and D are not implemented.\n");
- break;
- }
- }
- */
-
-}
-
-uint8_t
-MaltaIO::RTC::readData()
-{
- panic("MaltaIO::RTC::readData() has not been implemented for malta");
- /*
- if (addr < RTC_STAT_REGA)
- return clock_data[addr];
- else {
- switch (addr) {
- case RTC_STAT_REGA:
- // toggle UIP bit for linux
- stat_regA ^= RTCA_UIP;
- return stat_regA;
- break;
- case RTC_STAT_REGB:
- return stat_regB;
- break;
- case RTC_STAT_REGC:
- case RTC_STAT_REGD:
- return 0x00;
- break;
- default:
- panic("Shouldn't be here");
- }
- }
- */
-}
-
-void
-MaltaIO::RTC::serialize(const string &base, ostream &os)
-{
- paramOut(os, base + ".addr", addr);
- arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data));
- paramOut(os, base + ".stat_regA", stat_regA);
- paramOut(os, base + ".stat_regB", stat_regB);
-}
-
-void
-MaltaIO::RTC::unserialize(const string &base, Checkpoint *cp,
- const string &section)
-{
- paramIn(cp, section, base + ".addr", addr);
- arrayParamIn(cp, section, base + ".clock_data", clock_data,
- sizeof(clock_data));
- paramIn(cp, section, base + ".stat_regA", stat_regA);
- paramIn(cp, section, base + ".stat_regB", stat_regB);
-
- // We're not unserializing the event here, but we need to
- // rescehedule the event since curTick was moved forward by the
- // checkpoint
- event.reschedule(curTick + event.interval);
-}
-
-MaltaIO::RTC::RTCEvent::RTCEvent(Malta*t, Tick i)
- : Event(&mainEventQueue), malta(t), interval(i)
-{
- DPRINTF(MC146818, "RTC Event Initilizing\n");
- warn("MaltaIO::RTC::RTCEvent::process() RTC interrupt has been disabled.");
- //schedule(curTick + interval);
-}
-
-void
-MaltaIO::RTC::RTCEvent::scheduleIntr()
-{
- panic("MaltaIO::RTC::RTCEvent::scheduleIntr() has not been implemented for malta");
- //schedule(curTick + interval);
-}
-
-void
-MaltaIO::RTC::RTCEvent::process()
-{
- DPRINTF(MC146818, "RTC Timer Interrupt\n");
- schedule(curTick + interval);
- //Actually interrupt the processor here
- malta->cchip->postRTC();
-}
-
-const char *
-MaltaIO::RTC::RTCEvent::description() const
-{
- return "malta RTC interrupt";
-}
-
-MaltaIO::PITimer::PITimer(const string &name)
- : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),
- counter2(name + ".counter2")
-{
- counter[0] = &counter0;
- counter[1] = &counter0;
- counter[2] = &counter0;
-}
-
-void
-MaltaIO::PITimer::writeControl(const uint8_t data)
-{
- panic("MaltoIO::PITimer::writeControl(data) not implemented inside malta_io.cc");
- /*
- int rw;
- int sel;
-
- sel = GET_CTRL_SEL(data);
-
- if (sel == PIT_READ_BACK)
- panic("PITimer Read-Back Command is not implemented.\n");
-
- rw = GET_CTRL_RW(data);
-
- if (rw == PIT_RW_LATCH_COMMAND)
- counter[sel]->latchCount();
- else {
- counter[sel]->setRW(rw);
- counter[sel]->setMode(GET_CTRL_MODE(data));
- counter[sel]->setBCD(GET_CTRL_BCD(data));
- }
- */
-}
-
-void
-MaltaIO::PITimer::serialize(const string &base, ostream &os)
-{
- // serialize the counters
- counter0.serialize(base + ".counter0", os);
- counter1.serialize(base + ".counter1", os);
- counter2.serialize(base + ".counter2", os);
-}
-
-void
-MaltaIO::PITimer::unserialize(const string &base, Checkpoint *cp,
- const string &section)
-{
- // unserialze the counters
- counter0.unserialize(base + ".counter0", cp, section);
- counter1.unserialize(base + ".counter1", cp, section);
- counter2.unserialize(base + ".counter2", cp, section);
-}
-
-MaltaIO::PITimer::Counter::Counter(const string &name)
- : _name(name), event(this), count(0), latched_count(0), period(0),
- mode(0), output_high(false), latch_on(false), read_byte(LSB),
- write_byte(LSB)
-{
-
-}
-
-void
-MaltaIO::PITimer::Counter::latchCount()
-{
- panic("MaltoIO::PITimer::latchCount(...) not implemented inside malta_io.cc");
- // behave like a real latch
- /*
- if(!latch_on) {
- latch_on = true;
- read_byte = LSB;
- latched_count = count;
- }
- */
-}
-
-uint8_t
-MaltaIO::PITimer::Counter::read()
-{
- panic("MaltoIO::PITimer::Count::read(...) not implemented inside malta_io.cc");
- return 0;
- /*
- if (latch_on) {
- switch (read_byte) {
- case LSB:
- read_byte = MSB;
- return (uint8_t)latched_count;
- break;
- case MSB:
- read_byte = LSB;
- latch_on = false;
- return latched_count >> 8;
- break;
- default:
- panic("Shouldn't be here");
- }
- } else {
- switch (read_byte) {
- case LSB:
- read_byte = MSB;
- return (uint8_t)count;
- break;
- case MSB:
- read_byte = LSB;
- return count >> 8;
- break;
- default:
- panic("Shouldn't be here");
- }
- }
- */
-}
-
-void
-MaltaIO::PITimer::Counter::write(const uint8_t data)
-{
- panic("MaltoIO::PITimer::Counter::write(...) not implemented inside malta_io.cc");
- /*
- switch (write_byte) {
- case LSB:
- count = (count & 0xFF00) | data;
-
- if (event.scheduled())
- event.deschedule();
- output_high = false;
- write_byte = MSB;
- break;
-
- case MSB:
- count = (count & 0x00FF) | (data << 8);
- period = count;
-
- if (period > 0) {
- DPRINTF(Malta, "Timer set to curTick + %d\n",
- count * event.interval);
- event.schedule(curTick + count * event.interval);
- }
- write_byte = LSB;
- break;
- }
- */
-}
-
-void
-MaltaIO::PITimer::Counter::setRW(int rw_val)
-{
- panic("MaltoIO::PITimer::Counter::setRW(...) not implemented inside malta_io.cc");
- /*
- if (rw_val != PIT_RW_16BIT)
- panic("Only LSB/MSB read/write is implemented.\n");
- */
-}
-
-void
-MaltaIO::PITimer::Counter::setMode(int mode_val)
-{
- panic("MaltoIO::PITimer::Counter::setMode(...) not implemented inside malta_io.cc");
- /*
- if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN &&
- mode_val != PIT_MODE_SQWAVE)
- panic("PIT mode %#x is not implemented: \n", mode_val);
-
- mode = mode_val;
- */
-}
-
-void
-MaltaIO::PITimer::Counter::setBCD(int bcd_val)
-{
- panic("MaltoIO::PITimer::Counter::setBCD(...) not implemented inside malta_io.cc");
- /*
- if (bcd_val != PIT_BCD_FALSE)
- panic("PITimer does not implement BCD counts.\n");
- */
-}
-
-bool
-MaltaIO::PITimer::Counter::outputHigh()
-{
- panic("MaltoIO::PITimer::Counter::outputHigh(...) not implemented inside malta_io.cc");
- return false;
- /*
- return output_high;
- */
-}
-
-void
-MaltaIO::PITimer::Counter::serialize(const string &base, ostream &os)
-{
- paramOut(os, base + ".count", count);
- paramOut(os, base + ".latched_count", latched_count);
- paramOut(os, base + ".period", period);
- paramOut(os, base + ".mode", mode);
- paramOut(os, base + ".output_high", output_high);
- paramOut(os, base + ".latch_on", latch_on);
- paramOut(os, base + ".read_byte", read_byte);
- paramOut(os, base + ".write_byte", write_byte);
-
- Tick event_tick = 0;
- if (event.scheduled())
- event_tick = event.when();
- paramOut(os, base + ".event_tick", event_tick);
-}
-
-void
-MaltaIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp,
- const string &section)
-{
- paramIn(cp, section, base + ".count", count);
- paramIn(cp, section, base + ".latched_count", latched_count);
- paramIn(cp, section, base + ".period", period);
- paramIn(cp, section, base + ".mode", mode);
- paramIn(cp, section, base + ".output_high", output_high);
- paramIn(cp, section, base + ".latch_on", latch_on);
- paramIn(cp, section, base + ".read_byte", read_byte);
- paramIn(cp, section, base + ".write_byte", write_byte);
-
- Tick event_tick;
- paramIn(cp, section, base + ".event_tick", event_tick);
- if (event_tick)
- event.schedule(event_tick);
-}
-
-MaltaIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
- : Event(&mainEventQueue)
-{
- interval = (Tick)(Clock::Float::s / 1193180.0);
- counter = c_ptr;
-}
-
-void
-MaltaIO::PITimer::Counter::CounterEvent::process()
-{
- panic("MaltaIO::PITimer::Counter::CounterEvent::process(...) not implemented inside malta_io.cc");
- /*
- DPRINTF(Malta, "Timer Interrupt\n");
- switch (counter->mode) {
- case PIT_MODE_INTTC:
- counter->output_high = true;
- case PIT_MODE_RATEGEN:
- case PIT_MODE_SQWAVE:
- break;
- default:
- panic("Unimplemented PITimer mode.\n");
- }
- */
-}
-
-const char *
-MaltaIO::PITimer::Counter::CounterEvent::description() const
-{
- return "malta 8254 Interval timer";
-}
-
-MaltaIO::MaltaIO(Params *p)
- : BasicPioDevice(p), malta(p->malta), pitimer(p->name + "pitimer"),
- rtc(p->name + ".rtc", p->malta, p->frequency)
+MaltaIO::MaltaIO(const Params *p)
+ : BasicPioDevice(p), malta(p->malta),
+ pitimer(this, p->name + "pitimer"), rtc(p->name + ".rtc", p)
{
pioSize = 0x100;
@@ -489,155 +85,15 @@ MaltaIO::frequency() const
Tick
MaltaIO::read(PacketPtr pkt)
{
- panic("MaltaIO::read(...) not implemented inside malta_io.cc");
- return pioDelay;
- /*
- assert(pkt->result == Packet::Unknown);
- assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
-
- Addr daddr = pkt->getAddr() - pioAddr;
-
- DPRINTF(Malta, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(),
- pkt->getSize(), daddr);
-
- pkt->allocate();
-
- if (pkt->getSize() == sizeof(uint8_t)) {
- switch(daddr) {
- // PIC1 mask read
- case TSDEV_PIC1_MASK:
- pkt->set(~mask1);
- break;
- case TSDEV_PIC2_MASK:
- pkt->set(~mask2);
- break;
- case TSDEV_PIC1_ISR:
- // !!! If this is modified 64bit case needs to be too
- // Pal code has to do a 64 bit physical read because there is
- // no load physical byte instruction
- pkt->set(picr);
- break;
- case TSDEV_PIC2_ISR:
- // PIC2 not implemnted... just return 0
- pkt->set(0x00);
- break;
- case TSDEV_TMR0_DATA:
- pkt->set(pitimer.counter0.read());
- break;
- case TSDEV_TMR1_DATA:
- pkt->set(pitimer.counter1.read());
- break;
- case TSDEV_TMR2_DATA:
- pkt->set(pitimer.counter2.read());
- break;
- case TSDEV_RTC_DATA:
- pkt->set(rtc.readData());
- break;
- case TSDEV_CTRL_PORTB:
- if (pitimer.counter2.outputHigh())
- pkt->set(PORTB_SPKR_HIGH);
- else
- pkt->set(0x00);
- break;
- default:
- panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize());
- }
- } else if (pkt->getSize() == sizeof(uint64_t)) {
- if (daddr == TSDEV_PIC1_ISR)
- pkt->set<uint64_t>(picr);
- else
- panic("I/O Read - invalid addr - va %#x size %d\n",
- pkt->getAddr(), pkt->getSize());
- } else {
- panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize());
- }
- pkt->result = Packet::Success;
+ panic("MaltaIO::read(...) not implemented inside malta_io.cc");
return pioDelay;
- */
}
Tick
MaltaIO::write(PacketPtr pkt)
{
- panic("MaltaIO::write(...) not implemented inside malta_io.cc");
- return pioDelay;
- /*
- assert(pkt->result == Packet::Unknown);
- assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
- Addr daddr = pkt->getAddr() - pioAddr;
-
- DPRINTF(Malta, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
- pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>());
-
- assert(pkt->getSize() == sizeof(uint8_t));
- warn ("GOT HERE daddr=0x%x\n", daddr);
- switch(daddr) {
- case TSDEV_PIC1_MASK:
- mask1 = ~(pkt->get<uint8_t>());
- if ((picr & mask1) && !picInterrupting) {
- picInterrupting = true;
- malta->cchip->postDRIR(55);
- DPRINTF(Malta, "posting pic interrupt to cchip\n");
- }
- if ((!(picr & mask1)) && picInterrupting) {
- picInterrupting = false;
- malta->cchip->clearDRIR(55);
- DPRINTF(Malta, "clearing pic interrupt\n");
- }
- break;
- case TSDEV_PIC2_MASK:
- mask2 = pkt->get<uint8_t>();
- //PIC2 Not implemented to interrupt
- break;
- case TSDEV_PIC1_ACK:
- // clear the interrupt on the PIC
- picr &= ~(1 << (pkt->get<uint8_t>() & 0xF));
- if (!(picr & mask1))
- malta->cchip->clearDRIR(55);
- break;
- case TSDEV_DMA1_MODE:
- mode1 = pkt->get<uint8_t>();
- break;
- case TSDEV_DMA2_MODE:
- mode2 = pkt->get<uint8_t>();
- break;
- case TSDEV_TMR0_DATA:
- pitimer.counter0.write(pkt->get<uint8_t>());
- break;
- case TSDEV_TMR1_DATA:
- pitimer.counter1.write(pkt->get<uint8_t>());
- break;
- case TSDEV_TMR2_DATA:
- pitimer.counter2.write(pkt->get<uint8_t>());
- break;
- case TSDEV_TMR_CTRL:
- pitimer.writeControl(pkt->get<uint8_t>());
- break;
- case TSDEV_RTC_ADDR:
- rtc.writeAddr(pkt->get<uint8_t>());
- break;
- case TSDEV_RTC_DATA:
- rtc.writeData(pkt->get<uint8_t>());
- break;
- case TSDEV_KBD:
- case TSDEV_DMA1_CMND:
- case TSDEV_DMA2_CMND:
- case TSDEV_DMA1_MMASK:
- case TSDEV_DMA2_MMASK:
- case TSDEV_PIC2_ACK:
- case TSDEV_DMA1_RESET:
- case TSDEV_DMA2_RESET:
- case TSDEV_DMA1_MASK:
- case TSDEV_DMA2_MASK:
- case TSDEV_CTRL_PORTB:
- break;
- default:
- panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>());
- }
-
- pkt->result = Packet::Success;
+ panic("MaltaIO::write(...) not implemented inside malta_io.cc");
return pioDelay;
- */
}
void
@@ -651,7 +107,7 @@ void
MaltaIO::clearIntr(uint8_t interrupt)
{
malta->cchip->clearIntr(interrupt);
- DPRINTF(Malta, "posting pic interrupt to cchip\n");
+ DPRINTF(Malta, "clear pic interrupt to cchip\n");
}
void
diff --git a/src/dev/mips/malta_io.hh b/src/dev/mips/malta_io.hh
index e24a1d8cb..38da5adea 100755
--- a/src/dev/mips/malta_io.hh
+++ b/src/dev/mips/malta_io.hh
@@ -37,11 +37,13 @@
#ifndef __DEV_MALTA_IO_HH__
#define __DEV_MALTA_IO_HH__
-#include "dev/io_device.hh"
#include "base/range.hh"
#include "dev/mips/malta.hh"
-#include "sim/eventq.hh"
+#include "dev/intel_8254_timer.hh"
+#include "dev/io_device.hh"
+#include "dev/mc146818.hh"
#include "params/MaltaIO.hh"
+#include "sim/eventq.hh"
/**
* Malta I/O device is a catch all for all the south bridge stuff we care
@@ -51,235 +53,21 @@ class MaltaIO : public BasicPioDevice
{
private:
struct tm tm;
- public:
- /** Post an Interrupt to the CPU */
- void postIntr(uint8_t interrupt);
-
- /** Clear an Interrupt to the CPU */
- void clearIntr(uint8_t interrupt);
protected:
- /** Real-Time Clock (MC146818) */
- class RTC
- {
- private:
- /** Event for RTC periodic interrupt */
- struct RTCEvent : public Event
- {
- /** A pointer back to malta to create interrupt the processor. */
- Malta* malta;
- Tick interval;
-
- RTCEvent(Malta* t, Tick i);
-
- /** Schedule the RTC periodic interrupt */
- void scheduleIntr();
-
- /** Event process to occur at interrupt*/
- virtual void process();
-
- /** Event description */
- virtual const char *description() const;
- };
-
- private:
- std::string _name;
- const std::string &name() const { return _name; }
-
- /** RTC periodic interrupt event */
- RTCEvent event;
-
- /** Current RTC register address/index */
- int addr;
- /** Data for real-time clock function */
- union {
- uint8_t clock_data[10];
-
- struct {
- uint8_t sec;
- uint8_t sec_alrm;
- uint8_t min;
- uint8_t min_alrm;
- uint8_t hour;
- uint8_t hour_alrm;
- uint8_t wday;
- uint8_t mday;
- uint8_t mon;
- uint8_t year;
- };
- };
-
- /** RTC status register A */
- uint8_t stat_regA;
-
- /** RTC status register B */
- uint8_t stat_regB;
-
- public:
- RTC(const std::string &name, Malta* t, Tick i);
-
- /** Set the initial RTC time/date */
- void set_time(time_t t);
-
- /** RTC address port: write address of RTC RAM data to access */
- void writeAddr(const uint8_t data);
-
- /** RTC write data */
- void writeData(const uint8_t data);
-
-
-
- /** RTC read data */
- uint8_t readData();
-
- /**
- * Serialize this object to the given output stream.
- * @param base The base name of the counter object.
- * @param os The stream to serialize to.
- */
- void serialize(const std::string &base, std::ostream &os);
-
- /**
- * Reconstruct the state of this object from a checkpoint.
- * @param base The base name of the counter object.
- * @param cp The checkpoint use.
- * @param section The section name of this object
- */
- void unserialize(const std::string &base, Checkpoint *cp,
- const std::string &section);
- };
-
- /** Programmable Interval Timer (Intel 8254) */
- class PITimer
+ class RTC : public MC146818
{
- /** Counter element for PIT */
- class Counter
- {
- /** Event for counter interrupt */
- class CounterEvent : public Event
- {
- private:
- /** Pointer back to Counter */
- Counter* counter;
- Tick interval;
-
- public:
- CounterEvent(Counter*);
-
- /** Event process */
- virtual void process();
-
- /** Event description */
- virtual const char *description() const;
-
- friend class Counter;
- };
-
- private:
- std::string _name;
- const std::string &name() const { return _name; }
-
- CounterEvent event;
-
- /** Current count value */
- uint16_t count;
-
- /** Latched count */
- uint16_t latched_count;
-
- /** Interrupt period */
- uint16_t period;
-
- /** Current mode of operation */
- uint8_t mode;
-
- /** Output goes high when the counter reaches zero */
- bool output_high;
-
- /** State of the count latch */
- bool latch_on;
-
- /** Set of values for read_byte and write_byte */
- enum {LSB, MSB};
-
- /** Determine which byte of a 16-bit count value to read/write */
- uint8_t read_byte, write_byte;
-
- public:
- Counter(const std::string &name);
-
- /** Latch the current count (if one is not already latched) */
- void latchCount();
-
- /** Set the read/write mode */
- void setRW(int rw_val);
-
- /** Set operational mode */
- void setMode(int mode_val);
-
- /** Set count encoding */
- void setBCD(int bcd_val);
-
- /** Read a count byte */
- uint8_t read();
-
- /** Write a count byte */
- void write(const uint8_t data);
-
- /** Is the output high? */
- bool outputHigh();
-
- /**
- * Serialize this object to the given output stream.
- * @param base The base name of the counter object.
- * @param os The stream to serialize to.
- */
- void serialize(const std::string &base, std::ostream &os);
-
- /**
- * Reconstruct the state of this object from a checkpoint.
- * @param base The base name of the counter object.
- * @param cp The checkpoint use.
- * @param section The section name of this object
- */
- void unserialize(const std::string &base, Checkpoint *cp,
- const std::string &section);
- };
-
- private:
- std::string _name;
- const std::string &name() const { return _name; }
-
- /** PIT has three seperate counters */
- Counter *counter[3];
-
public:
- /** Public way to access individual counters (avoid array accesses) */
- Counter counter0;
- Counter counter1;
- Counter counter2;
-
- PITimer(const std::string &name);
+ Malta *malta;
+ RTC(const std::string &name, const MaltaIOParams *p);
- /** Write control word */
- void writeControl(const uint8_t data);
-
- /**
- * Serialize this object to the given output stream.
- * @param base The base name of the counter object.
- * @param os The stream to serialize to.
- */
- void serialize(const std::string &base, std::ostream &os);
-
- /**
- * Reconstruct the state of this object from a checkpoint.
- * @param base The base name of the counter object.
- * @param cp The checkpoint use.
- * @param section The section name of this object
- */
- void unserialize(const std::string &base, Checkpoint *cp,
- const std::string &section);
+ protected:
+ void handleEvent()
+ {
+ //Actually interrupt the processor here
+ malta->cchip->postRTC();
+ }
};
/** Mask of the PIC1 */
@@ -304,7 +92,7 @@ class MaltaIO : public BasicPioDevice
Malta *malta;
/** Intel 8253 Periodic Interval Timer */
- PITimer pitimer;
+ Intel8254Timer pitimer;
RTC rtc;
@@ -329,17 +117,21 @@ class MaltaIO : public BasicPioDevice
return dynamic_cast<const Params *>(_params);
}
- public:
/**
* Initialize all the data for devices supported by Malta I/O.
* @param p pointer to Params struct
*/
- MaltaIO(Params *p);
+ MaltaIO(const Params *p);
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
+ /** Post an Interrupt to the CPU */
+ void postIntr(uint8_t interrupt);
+
+ /** Clear an Interrupt to the CPU */
+ void clearIntr(uint8_t interrupt);
/**
* Serialize this object to the given output stream.