diff options
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 §ion) + void + unserialize(Checkpoint *cp, const std::string §ion) { 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 §ion) +{ + 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 §ion) - { - 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 §ion); - }; + bool Valid() { return (V0 | V1); }; + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; }; #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 §ion) { 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 §ion); @@ -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 §ion) -{ - 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 §ion) -{ - // 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 §ion) -{ - 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 §ion); - }; - - /** 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 §ion); - }; - - 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 §ion); + 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. |