diff options
Diffstat (limited to 'src/arch')
28 files changed, 1053 insertions, 1530 deletions
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/faults.cc b/src/arch/mips/faults.cc index 347d041a3..01d31e14f 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 + 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); } - // 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!) + replaceBits(stat, Status_EXL_HI, Status_EXL_LO, 1); + tc->setMiscRegNoEffect(MipsISA::Status, stat); + + // 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 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); } -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; + 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); } -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(MipsISA::BadVAddr, BadVAddr); + // Set new PC + Addr HandlerBase; + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::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(MipsISA::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(MipsISA::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(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; + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::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(MipsISA::BadVAddr, BadVAddr); + + // Set new PC + Addr HandlerBase; + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::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(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; + // Offset 0x180 - General Exception Vector + HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); + setHandlerPC(HandlerBase,tc); + DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n", + HandlerBase, tc->readMiscReg(MipsISA::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(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!! + // See MIPS ARM Vol 3, Revision 2, Page 38 + if (bits(stat, Status_EXL) == 1) { + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + } else { + // Offset 0x000 + HandlerBase = tc->readMiscReg(MipsISA::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(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!! + // See MIPS ARM Vol 3, Revision 2, Page 38 + if(bits(stat, Status_EXL) == 1) { + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + } else { + // Offset 0x000 + HandlerBase = tc->readMiscReg(MipsISA::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(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 - 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(MipsISA::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(MipsISA::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; + + 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); + } - 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, "(%x) - ResetFault::invoke : PC set to %x", + (unsigned)tc, (unsigned)tc->readPC()); #endif - // Set Coprocessor 1 (Floating Point) To Usable - tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000); + // Set Coprocessor 1 (Floating Point) To Usable + tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000); } -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(MipsISA::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 + MiscReg cause = tc->readMiscReg(MipsISA::Cause); + replaceBits(cause, Cause_CE_HI, Cause_CE_LO, coProcID); + tc->setMiscRegNoEffect(MipsISA::Cause, cause); + + Addr HandlerBase; + // Offset 0x180 - General Exception Vector + HandlerBase = vect() + tc->readMiscReg(MipsISA::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..f2b304e95 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 @@ -54,9 +53,9 @@ class MipsFault : public FaultBase Addr EntryHi_VPN2X; Addr Context_BadVPN2; #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..207bb15da 100755 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -38,201 +38,102 @@ namespace MipsISA { -static inline uint8_t getCauseIP_(ThreadContext *tc) { + +static inline uint8_t +getCauseIP(ThreadContext *tc) { MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause); - uint8_t IP_ = bits(cause,Cause_IP7, Cause_IP0); - return IP_; + return bits(cause, Cause_IP7, Cause_IP0); } -static inline void setCauseIP_(ThreadContext *tc, uint8_t val) { +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); + replaceBits(cause, Cause_IP7, Cause_IP0, val); + tc->setMiscRegNoEffect(MipsISA::Cause, cause); } -/* - 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; - } - -*/ -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 - { + // Interrupts must be enabled, error level must be 0 or interrupts + // inhibited, and exception level must be 0 or interrupts inhibited + if (bits(status, Status_IE_LO) == 1 && + bits(status, Status_ERL_HI, Status_ERL_LO) == 0 && + bits(status, Status_EXL_HI, Status_EXL_LO) == 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){ + uint8_t InterruptMask = bits(status, Status_IM7, Status_IM0); + uint8_t InterruptPending = getCauseIP(tc); + // InterruptMask and InterruptPending are already correctly aligned + if (InterruptMask && InterruptPending){ DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", - IM, IP); + InterruptMask, InterruptPending); 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); @@ -240,34 +141,32 @@ bool Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const 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); + uint8_t intstatus = getCauseIP(tc); intstatus |= 1 << IPTI; - setCauseIP_(tc, intstatus); + setCauseIP(tc, intstatus); } - return (getCauseIP_(tc) != 0); + return (getCauseIP(tc) != 0); } - - - - } diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index af71e4636..13d4f8512 100755 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -31,97 +31,27 @@ #ifndef __ARCH_MIPS_INTERRUPT_HH__ #define __ARCH_MIPS_INTERRUPT_HH__ - #include "arch/mips/faults.hh" #include "base/compiler.hh" - - namespace MipsISA { + class Interrupts { - /* - 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() { - //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, 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 +69,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 +78,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 +95,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 a3538435c..6ef6f9f41 100644 --- a/src/arch/mips/isa.cc +++ b/src/arch/mips/isa.cc @@ -447,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 @@ -486,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) @@ -515,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 @@ -586,8 +580,6 @@ ISA::CP0Event::process() cp0->updateCPU(); break; } - - //cp0EventRemoveList.push(this); } const char * 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 0307b37be..a6363e191 100755 --- a/src/arch/mips/mt.hh +++ b/src/arch/mips/mt.hh @@ -51,7 +51,6 @@ namespace MipsISA { - template <class TC> inline unsigned getVirtProcNum(TC *tc) @@ -76,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()); } } @@ -93,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()); } } 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/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..ac900b6db 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, MipsISA::LoadAddrMask)) 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)) @@ -110,100 +105,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 +148,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..3a8d400ae 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,68 +303,66 @@ 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_VPN2 = (VPN >> 2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ @@ -398,43 +371,36 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) /* Context must be set */ Flt->Context_BadVPN2 = (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->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; } } - 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->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 { + // Ok, this is really a match, set paddr + 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; } - 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->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; } } 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.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"); } |