diff options
-rw-r--r-- | src/arch/mips/faults.cc | 216 | ||||
-rw-r--r-- | src/arch/mips/faults.hh | 10 | ||||
-rwxr-xr-x | src/arch/mips/interrupts.cc | 52 | ||||
-rwxr-xr-x | src/arch/mips/interrupts.hh | 25 | ||||
-rw-r--r-- | src/arch/mips/isa/decoder.isa | 4 | ||||
-rwxr-xr-x | src/arch/mips/pra_constants.hh | 36 | ||||
-rwxr-xr-x | src/arch/mips/system.cc | 3 | ||||
-rw-r--r-- | src/arch/mips/tlb.cc | 58 | ||||
-rw-r--r-- | src/arch/mips/utility.cc | 9 | ||||
-rwxr-xr-x | src/dev/mips/Malta.py | 6 | ||||
-rwxr-xr-x | src/dev/mips/SConscript | 1 | ||||
-rwxr-xr-x | src/dev/mips/backdoor.cc | 2 | ||||
-rwxr-xr-x | src/dev/mips/malta.cc | 25 | ||||
-rwxr-xr-x | src/dev/mips/malta.hh | 24 | ||||
-rwxr-xr-x | src/dev/mips/malta_io.cc | 564 | ||||
-rwxr-xr-x | src/dev/mips/malta_io.hh | 248 |
16 files changed, 280 insertions, 1003 deletions
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc index 01d31e14f..6faab054f 100644 --- a/src/arch/mips/faults.cc +++ b/src/arch/mips/faults.cc @@ -175,49 +175,44 @@ MipsFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc) } void -MipsFault::setExceptionState(ThreadContext *tc, uint8_t ExcCode) +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) { + StatusReg status = tc->readMiscReg(Status); + if (status.exl != 1 && status.bev != 1) { // SRS Ctl is modified only if Status_EXL and Status_BEV are not set - 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); + SRSCtlReg srsCtl = tc->readMiscReg(SRSCtl); + srsCtl.pss = srsCtl.css; + srsCtl.css = srsCtl.ess; + tc->setMiscRegNoEffect(SRSCtl, srsCtl); } // set EXL bit (don't care if it is already set!) - replaceBits(stat, Status_EXL_HI, Status_EXL_LO, 1); - tc->setMiscRegNoEffect(MipsISA::Status, stat); + status.exl = 1; + tc->setMiscRegNoEffect(Status, status); // write EPC // CHECK ME or FIXME or FIX ME or POSSIBLE HACK // Check to see if the exception occurred in the branch delay slot DPRINTF(MipsPRA, "PC: %x, NextPC: %x, NNPC: %x\n", tc->readPC(), tc->readNextPC(), tc->readNextNPC()); - int C_BD = 0; + int bd = 0; if (tc->readPC() + sizeof(MachInst) != tc->readNextPC()) { - tc->setMiscRegNoEffect(MipsISA::EPC, tc->readPC() - sizeof(MachInst)); + tc->setMiscRegNoEffect(EPC, tc->readPC() - sizeof(MachInst)); // In the branch delay slot? set CAUSE_31 - C_BD = 1; + bd = 1; } else { - tc->setMiscRegNoEffect(MipsISA::EPC, tc->readPC()); + tc->setMiscRegNoEffect(EPC, tc->readPC()); // In the branch delay slot? reset CAUSE_31 - C_BD = 0; + 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); + CauseReg cause = tc->readMiscReg(Cause); + cause.excCode = excCode; + cause.bd = bd; + cause.ce = 0; + tc->setMiscRegNoEffect(Cause, cause); } void @@ -228,12 +223,12 @@ ArithmeticFault::invoke(ThreadContext *tc) // Set new PC Addr HandlerBase; - MiscReg stat = tc->readMiscReg(MipsISA::Status); + StatusReg status = tc->readMiscReg(Status); // Here, the handler is dependent on BEV, which is not modified by // setExceptionState() - if (bits(stat, Status_BEV) == 0 ) { + if (!status.bev) { // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); } else { HandlerBase = 0xBFC00200; } @@ -245,12 +240,12 @@ StoreAddressErrorFault::invoke(ThreadContext *tc) { DPRINTF(MipsPRA, "%s encountered.\n", name()); setExceptionState(tc, 0x5); - tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); } @@ -263,7 +258,7 @@ TrapFault::invoke(ThreadContext *tc) // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); } @@ -275,7 +270,7 @@ BreakpointFault::invoke(ThreadContext *tc) // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); } @@ -284,23 +279,24 @@ DtbInvalidFault::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); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); + EntryHiReg entryHi = tc->readMiscReg(EntryHi); + entryHi.asid = entryHiAsid; + entryHi.vpn2 = entryHiVPN2; + entryHi.vpn2x = entryHiVPN2X; + tc->setMiscRegNoEffect(EntryHi, entryHi); + + ContextReg context = tc->readMiscReg(Context); + context.badVPN2 = contextBadVPN2; + tc->setMiscRegNoEffect(Context, context); setExceptionState(tc, 0x3); // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); - setHandlerPC(HandlerBase,tc); + HandlerBase = vect() + tc->readMiscReg(EBase); + setHandlerPC(HandlerBase, tc); } void @@ -308,12 +304,12 @@ AddressErrorFault::invoke(ThreadContext *tc) { DPRINTF(MipsPRA, "%s encountered.\n", name()); setExceptionState(tc, 0x4); - tc->setMiscRegNoEffect(MipsISA::BadVAddr, BadVAddr); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); } @@ -322,50 +318,51 @@ 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); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); + EntryHiReg entryHi = tc->readMiscReg(EntryHi); + entryHi.asid = entryHiAsid; + entryHi.vpn2 = entryHiVPN2; + entryHi.vpn2x = entryHiVPN2X; + tc->setMiscRegNoEffect(EntryHi, entryHi); + + ContextReg context = tc->readMiscReg(Context); + context.badVPN2 = contextBadVPN2; + tc->setMiscRegNoEffect(Context, context); // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase= vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase,tc); - DPRINTF(MipsPRA,"Exception Handler At: %x , EPC set to %x\n", - HandlerBase, tc->readMiscReg(MipsISA::EPC)); + DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n", + HandlerBase, tc->readMiscReg(EPC)); } void ItbRefillFault::invoke(ThreadContext *tc) { - DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), BadVAddr); + 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); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); + EntryHiReg entryHi = tc->readMiscReg(EntryHi); + entryHi.asid = entryHiAsid; + entryHi.vpn2 = entryHiVPN2; + entryHi.vpn2x = entryHiVPN2X; + tc->setMiscRegNoEffect(EntryHi, entryHi); + ContextReg context = tc->readMiscReg(Context); + context.badVPN2 = contextBadVPN2; + tc->setMiscRegNoEffect(Context, context); + + StatusReg status = tc->readMiscReg(Status); // Since handler depends on EXL bit, must check EXL bit before setting it!! // See MIPS ARM Vol 3, Revision 2, Page 38 - if (bits(stat, Status_EXL) == 1) { + if (status.exl == 1) { // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); } else { // Offset 0x000 - HandlerBase = tc->readMiscReg(MipsISA::EBase); + HandlerBase = tc->readMiscReg(EBase); } setExceptionState(tc, 0x2); @@ -378,25 +375,26 @@ 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); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); + EntryHiReg entryHi = tc->readMiscReg(EntryHi); + entryHi.asid = entryHiAsid; + entryHi.vpn2 = entryHiVPN2; + entryHi.vpn2x = entryHiVPN2X; + tc->setMiscRegNoEffect(EntryHi, entryHi); + + ContextReg context = tc->readMiscReg(Context); + context.badVPN2 = contextBadVPN2; + tc->setMiscRegNoEffect(Context, context); + + StatusReg status = tc->readMiscReg(Status); // Since handler depends on EXL bit, must check EXL bit before setting it!! // See MIPS ARM Vol 3, Revision 2, Page 38 - if(bits(stat, Status_EXL) == 1) { + if (status.exl) { // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); } else { // Offset 0x000 - HandlerBase = tc->readMiscReg(MipsISA::EBase); + HandlerBase = tc->readMiscReg(EBase); } setExceptionState(tc, 0x3); @@ -408,20 +406,21 @@ 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); + tc->setMiscRegNoEffect(BadVAddr, badVAddr); + EntryHiReg entryHi = tc->readMiscReg(EntryHi); + entryHi.asid = entryHiAsid; + entryHi.vpn2 = entryHiVPN2; + entryHi.vpn2x = entryHiVPN2X; + tc->setMiscRegNoEffect(EntryHi, entryHi); + + ContextReg context = tc->readMiscReg(Context); + context.badVPN2 = contextBadVPN2; + tc->setMiscRegNoEffect(Context, context); // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setExceptionState(tc, 0x1); setHandlerPC(HandlerBase, tc); @@ -436,7 +435,7 @@ SystemCallFault::invoke(ThreadContext *tc) // Set new PC Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); } @@ -448,13 +447,13 @@ InterruptFault::invoke(ThreadContext *tc) setExceptionState(tc, 0x0A); Addr HandlerBase; - uint8_t IV = bits(tc->readMiscRegNoEffect(MipsISA::Cause), Cause_IV); - if (IV) { + CauseReg cause = tc->readMiscRegNoEffect(Cause); + if (cause.iv) { // Offset 200 for release 2 - HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(MipsISA::EBase); + HandlerBase = 0x20 + vect() + tc->readMiscRegNoEffect(EBase); } else { //Ofset at 180 for release 1 - HandlerBase = vect() + tc->readMiscRegNoEffect(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscRegNoEffect(EBase); } setHandlerPC(HandlerBase, tc); @@ -472,12 +471,13 @@ ResetFault::invoke(ThreadContext *tc) 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, "ResetFault::invoke : PC set to %x", tc->readPC()); #endif // Set Coprocessor 1 (Floating Point) To Usable - tc->setMiscReg(MipsISA::Status, MipsISA::Status | 0x20000000); + StatusReg status = tc->readMiscRegNoEffect(Status); + status.cu.cu1 = 1; + tc->setMiscReg(Status, status); } void @@ -488,7 +488,7 @@ ReservedInstructionFault::invoke(ThreadContext *tc) setExceptionState(tc, 0x0A); Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscRegNoEffect(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscRegNoEffect(EBase); setHandlerPC(HandlerBase, tc); #else panic("%s encountered.\n", name()); @@ -517,13 +517,13 @@ CoprocessorUnusableFault::invoke(ThreadContext *tc) 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); + CauseReg cause = tc->readMiscReg(Cause); + cause.ce = coProcID; + tc->setMiscRegNoEffect(Cause, cause); Addr HandlerBase; // Offset 0x180 - General Exception Vector - HandlerBase = vect() + tc->readMiscReg(MipsISA::EBase); + HandlerBase = vect() + tc->readMiscReg(EBase); setHandlerPC(HandlerBase, tc); #else diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh index f2b304e95..7a001d390 100644 --- a/src/arch/mips/faults.hh +++ b/src/arch/mips/faults.hh @@ -47,11 +47,11 @@ class MipsFault : public FaultBase virtual bool skipFaultingInstruction() {return false;} virtual bool setRestartAddress() {return true;} public: - Addr BadVAddr; - Addr EntryHi_Asid; - Addr EntryHi_VPN2; - Addr EntryHi_VPN2X; - Addr Context_BadVPN2; + Addr badVAddr; + Addr entryHiAsid; + Addr entryHiVPN2; + Addr entryHiVPN2X; + Addr contextBadVPN2; #if FULL_SYSTEM void invoke(ThreadContext * tc) {}; void setExceptionState(ThreadContext *, uint8_t); diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc index 207bb15da..4b1f37856 100755 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -31,25 +31,26 @@ * Korey Sewell */ -#include "arch/mips/pra_constants.hh" +#include "arch/mips/interrupts.hh" #include "arch/mips/isa_traits.hh" +#include "arch/mips/pra_constants.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" -#include "arch/mips/interrupts.hh" namespace MipsISA { static inline uint8_t getCauseIP(ThreadContext *tc) { - MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause); - return bits(cause, Cause_IP7, Cause_IP0); + CauseReg cause = tc->readMiscRegNoEffect(Cause); + return cause.ip; } static inline void -setCauseIP_(ThreadContext *tc, uint8_t val) { - MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause); - replaceBits(cause, Cause_IP7, Cause_IP0, val); - tc->setMiscRegNoEffect(MipsISA::Cause, cause); +setCauseIP(ThreadContext *tc, uint8_t val) { + CauseReg cause = tc->readMiscRegNoEffect(Cause); + cause.ip = val; + tc->setMiscRegNoEffect(Cause, cause); } void @@ -110,21 +111,17 @@ Interrupts::getInterrupt(ThreadContext * tc) DPRINTF(Interrupt, "Interrupts getInterrupt\n"); //Check if there are any outstanding interrupts - MiscReg status = tc->readMiscRegNoEffect(MipsISA::Status); + StatusReg status = tc->readMiscRegNoEffect(Status); // Interrupts must be enabled, error level must be 0 or interrupts // inhibited, and exception level must be 0 or interrupts inhibited - if (bits(status, Status_IE_LO) == 1 && - bits(status, Status_ERL_HI, Status_ERL_LO) == 0 && - bits(status, Status_EXL_HI, Status_EXL_LO) == 0) { + if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) { // Software interrupts & hardware interrupts are handled in software. // So if any interrupt that isn't masked is detected, jump to interrupt // handler - uint8_t InterruptMask = bits(status, Status_IM7, Status_IM0); - uint8_t InterruptPending = getCauseIP(tc); - // InterruptMask and InterruptPending are already correctly aligned - if (InterruptMask && InterruptPending){ + CauseReg cause = tc->readMiscRegNoEffect(Cause); + if (status.im && cause.ip) { DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", - InterruptMask, InterruptPending); + (unsigned)status.im, (unsigned)cause.ip); return new InterruptFault; } } @@ -135,8 +132,8 @@ Interrupts::getInterrupt(ThreadContext * tc) bool Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const { - MiscReg compare = tc->readMiscRegNoEffect(MipsISA::Compare); - MiscReg count = tc->readMiscRegNoEffect(MipsISA::Count); + MiscReg compare = tc->readMiscRegNoEffect(Compare); + MiscReg count = tc->readMiscRegNoEffect(Count); if (compare == count && count != 0) return true; return false; @@ -156,13 +153,10 @@ Interrupts::interruptsPending(ThreadContext *tc) const if (onCpuTimerInterrupt(tc)) { DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); //determine timer interrupt IP # - MiscReg intctl = tc->readMiscRegNoEffect(MipsISA::IntCtl); - uint8_t IPTI = bits(intctl, IntCtl_IPTI_HI, IntCtl_IPTI_LO); - //set intstatus to correspond - //post(IPTI, tc); - uint8_t intstatus = getCauseIP(tc); - intstatus |= 1 << IPTI; - setCauseIP(tc, intstatus); + IntCtlReg intCtl = tc->readMiscRegNoEffect(IntCtl); + uint8_t intStatus = getCauseIP(tc); + intStatus |= 1 << intCtl.ipti; + setCauseIP(tc, intStatus); } return (getCauseIP(tc) != 0); @@ -170,3 +164,9 @@ Interrupts::interruptsPending(ThreadContext *tc) const } } + +MipsISA::Interrupts * +MipsInterruptsParams::create() +{ + return new MipsISA::Interrupts(this); +} diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index 13d4f8512..c852bc9d0 100755 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -31,20 +31,41 @@ #ifndef __ARCH_MIPS_INTERRUPT_HH__ #define __ARCH_MIPS_INTERRUPT_HH__ +#include <string> + #include "arch/mips/faults.hh" #include "base/compiler.hh" +#include "base/misc.hh" +#include "params/MipsInterrupts.hh" +#include "sim/serialize.hh" +#include "sim/sim_object.hh" + +class BaseCPU; +class Checkpoint; namespace MipsISA { -class Interrupts +class Interrupts : public SimObject { public: - Interrupts() + typedef MipsInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + + Interrupts(Params * p) : SimObject(p) { newInfoSet = false; } + void + setCPU(BaseCPU *_cpu) + {} + // post(int int_num, int index) is responsible // for posting an interrupt. It sets a bit // in intstatus corresponding to Cause IP*. The diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 7a6d5db05..60bc15513 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -771,7 +771,7 @@ decode OPCODE_HI default Unknown::unknown() { NewEntry.OffsetMask = ((1<<NewEntry.AddrShiftAmount)-1); MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr(); - Config3Reg config3 = Config3 + Config3Reg config3 = Config3; PageGrainReg pageGrain = PageGrain; int SP = 0; if (bits(config3, config3.sp) == 1 && @@ -836,7 +836,7 @@ decode OPCODE_HI default Unknown::unknown() { NewEntry.OffsetMask = ((1 << NewEntry.AddrShiftAmount) - 1); MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr(); - Config3Reg config3 = Config3 + Config3Reg config3 = Config3; PageGrainReg pageGrain = PageGrain; int SP = 0; if (bits(config3, config3.sp) == 1 && diff --git a/src/arch/mips/pra_constants.hh b/src/arch/mips/pra_constants.hh index 129f4185f..971501493 100755 --- a/src/arch/mips/pra_constants.hh +++ b/src/arch/mips/pra_constants.hh @@ -120,14 +120,16 @@ BitUnion32(StatusReg) // Bit 18 is zero Bitfield<17, 16> impl; Bitfield<15, 10> ipl; - Bitfield<15> im7; - Bitfield<14> im6; - Bitfield<13> im5; - Bitfield<12> im4; - Bitfield<11> im3; - Bitfield<10> im2; - Bitfield<9> im1; - Bitfield<8> im0; + SubBitUnion(im, 15, 8) + Bitfield<15> im7; + Bitfield<14> im6; + Bitfield<13> im5; + Bitfield<12> im4; + Bitfield<11> im3; + Bitfield<10> im2; + Bitfield<9> im1; + Bitfield<8> im0; + EndSubBitUnion(im) Bitfield<7> kx; Bitfield<6> sx; Bitfield<5> ux; @@ -182,14 +184,16 @@ BitUnion32(CauseReg) Bitfield<22> wp; // Bits 21-16 are zeros Bitfield<15, 10> ripl; - Bitfield<15> ip7; - Bitfield<14> ip6; - Bitfield<13> ip5; - Bitfield<12> ip4; - Bitfield<11> ip3; - Bitfield<10> ip2; - Bitfield<9> ip1; - Bitfield<8> ip0; + SubBitUnion(ip, 15, 8) + Bitfield<15> ip7; + Bitfield<14> ip6; + Bitfield<13> ip5; + Bitfield<12> ip4; + Bitfield<11> ip3; + Bitfield<10> ip2; + Bitfield<9> ip1; + Bitfield<8> ip0; + EndSubBitUnion(ip); // Bit 7 is zero Bitfield<6, 2> excCode; // Bits 1-0 are zeros diff --git a/src/arch/mips/system.cc b/src/arch/mips/system.cc index ac900b6db..57310fa77 100755 --- a/src/arch/mips/system.cc +++ b/src/arch/mips/system.cc @@ -51,7 +51,7 @@ MipsSystem::MipsSystem(Params *p) : System(p) #if FULL_SYSTEM if (p->bare_iron == true) { hexFile = new HexFile(params()->hex_file_name); - if (!hexFile->loadSections(&functionalPort, MipsISA::LoadAddrMask)) + if (!hexFile->loadSections(&functionalPort)) panic("Could not load hex file\n"); } @@ -93,7 +93,6 @@ MipsSystem::MipsSystem(Params *p) : System(p) */ if (consoleSymtab->findAddress("env_booted_osflags", addr)) { warn("writing addr starting from %#x", addr); - cout << "-" << endl; virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), strlen(params()->boot_osflags.c_str())); } diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index 3a8d400ae..37c1ecee3 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -315,7 +315,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) req->isMisaligned()) { AddressErrorFault *Flt = new AddressErrorFault(); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); return Flt; } } else if(IsKSeg1(req->getVaddr())) { @@ -338,7 +338,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) // Unaligned address! AddressErrorFault *Flt = new AddressErrorFault(); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); return Flt; } PTE *pte = lookup(VPN,Asid); @@ -361,15 +361,15 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) //Invalid entry ItbInvalidFault *Flt = new ItbInvalidFault(); /* EntryHi VPN, ASID fields must be set */ - Flt->EntryHi_Asid = Asid; - Flt->EntryHi_VPN2 = (VPN >> 2); - Flt->EntryHi_VPN2X = (VPN & 0x3); + Flt->entryHiAsid = Asid; + Flt->entryHiVPN2 = (VPN >> 2); + Flt->entryHiVPN2X = (VPN & 0x3); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); /* Context must be set */ - Flt->Context_BadVPN2 = (VPN >> 2); + Flt->contextBadVPN2 = (VPN >> 2); return Flt; } else { // Ok, this is really a match, set paddr @@ -388,15 +388,15 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) // 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); + Flt->entryHiAsid = Asid; + Flt->entryHiVPN2 = (VPN >> 2); + Flt->entryHiVPN2X = (VPN & 0x3); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); /* Context must be set */ - Flt->Context_BadVPN2 = (VPN >> 2); + Flt->contextBadVPN2 = (VPN >> 2); return Flt; } } @@ -435,7 +435,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) req->isMisaligned()) { StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); return Flt; } @@ -458,7 +458,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) // Unaligned address! StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); return Flt; } if (pte != NULL) { @@ -483,15 +483,15 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) //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); + Flt->entryHiAsid = Asid; + Flt->entryHiVPN2 = (VPN>>2); + Flt->entryHiVPN2X = (VPN & 0x3); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); /* Context must be set */ - Flt->Context_BadVPN2 = (VPN >> 2); + Flt->contextBadVPN2 = (VPN >> 2); return Flt; } else { @@ -499,15 +499,15 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 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); + Flt->entryHiAsid = Asid; + Flt->entryHiVPN2 = (VPN >> 2); + Flt->entryHiVPN2X = (VPN & 0x3); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); /* Context must be set */ - Flt->Context_BadVPN2 = (VPN >> 2); + Flt->contextBadVPN2 = (VPN >> 2); return Flt; } Addr PAddr; @@ -525,15 +525,15 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) // 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); + Flt->entryHiAsid = Asid; + Flt->entryHiVPN2 = (VPN >> 2); + Flt->entryHiVPN2X = (VPN & 0x3); /* BadVAddr must be set */ - Flt->BadVAddr = req->getVaddr(); + Flt->badVAddr = req->getVaddr(); /* Context must be set */ - Flt->Context_BadVPN2 = (VPN >> 2); + Flt->contextBadVPN2 = (VPN >> 2); return Flt; } } diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index 4723d6301..ac90ce45e 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -38,6 +38,7 @@ #include "base/misc.hh" #if FULL_SYSTEM +#include "arch/mips/registers.hh" #include "arch/mips/vtophys.hh" #include "mem/vport.hh" #endif @@ -52,16 +53,16 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM - if (number < NumArgumentRegs) { + if (number < 4) { if (fp) - return tc->readFloatRegBits(ArgumentReg[number]); + return tc->readFloatRegBits(FirstArgumentReg + number); else - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(FirstArgumentReg + number); } else { Addr sp = tc->readIntReg(StackPointerReg); VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read<uint64_t>(sp + - (number-NumArgumentRegs) * sizeof(uint64_t)); + (number - 4) * sizeof(uint64_t)); return arg; } #else diff --git a/src/dev/mips/Malta.py b/src/dev/mips/Malta.py index d215bf329..740aa4a7f 100755 --- a/src/dev/mips/Malta.py +++ b/src/dev/mips/Malta.py @@ -42,10 +42,12 @@ class MaltaCChip(BasicPioDevice): class MaltaIO(BasicPioDevice): type = 'MaltaIO' - time = Param.UInt64(1136073600, + time = Param.Time('01/01/2009', "System time to use (0 for actual time, default is 1/1/06)") + year_is_bcd = Param.Bool(False, + "The RTC should interpret the year as a BCD value") malta = Param.Malta(Parent.any, "Malta") - frequency = Param.Frequency('1050Hz', "frequency of interrupts") + frequency = Param.Frequency('1024Hz', "frequency of interrupts") class MaltaPChip(BasicPioDevice): type = 'MaltaPChip' diff --git a/src/dev/mips/SConscript b/src/dev/mips/SConscript index e83e47ebd..982d87266 100755 --- a/src/dev/mips/SConscript +++ b/src/dev/mips/SConscript @@ -36,7 +36,6 @@ if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'mips': SimObject('Malta.py') TraceFlag('Malta') - TraceFlag('MC146818') Source('backdoor.cc') Source('malta.cc') diff --git a/src/dev/mips/backdoor.cc b/src/dev/mips/backdoor.cc index 313f12567..a1247fbd0 100755 --- a/src/dev/mips/backdoor.cc +++ b/src/dev/mips/backdoor.cc @@ -84,7 +84,7 @@ void MipsBackdoor::startup() { system->setMipsAccess(pioAddr); - mipsAccess->numCPUs = system->getNumCPUs(); + mipsAccess->numCPUs = system->numContexts(); mipsAccess->kernStart = MipsISA::Phys2K0Seg(system->getKernelStart()); mipsAccess->kernEnd = MipsISA::Phys2K0Seg(system->getKernelEnd()); mipsAccess->entryPoint = MipsISA::Phys2K0Seg(system->getKernelEntry()); diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc index 21e79d999..1401fe9ee 100755 --- a/src/dev/mips/malta.cc +++ b/src/dev/mips/malta.cc @@ -69,51 +69,38 @@ Malta::intrFrequency() void Malta::postConsoleInt() { - //panic("Malta::postConsoleInt() has not been implemented."); - io->postIntr(0x10/*HW4*/);//see {Linux-src}/arch/mips/mips-boards/sim/sim_setup.c + //see {Linux-src}/arch/mips/mips-boards/sim/sim_setup.c + io->postIntr(0x10/*HW4*/); } void Malta::clearConsoleInt() { - //FIXME: implement clearConsoleInt() - //warn("Malta::clearConsoleInt() has not been implemented."); + //FIXME: implement clearConsoleInt() io->clearIntr(0x10/*HW4*/); } void Malta::postPciInt(int line) { - panic("Malta::postPciInt() has not been implemented."); - //cchip->postDRIR(line); + panic("Malta::postPciInt() has not been implemented."); } void Malta::clearPciInt(int line) { - panic("Malta::clearPciInt() has not been implemented."); - //cchip->clearDRIR(line); + panic("Malta::clearPciInt() has not been implemented."); } Addr Malta::pciToDma(Addr pciAddr) const { - panic("Malta::pciToDma() has not been implemented."); - return pchip->translatePciToDma(pciAddr); -} - - -Addr -Malta::calcConfigAddr(int bus, int dev, int func) -{ - panic("Malta::calcConfigAddr() has not been implemented."); - return pchip->calcConfigAddr(bus, dev, func); + panic("Malta::pciToDma() has not been implemented."); } void Malta::serialize(std::ostream &os) { - SERIALIZE_ARRAY(intr_sum_type, Malta::Max_CPUs); } diff --git a/src/dev/mips/malta.hh b/src/dev/mips/malta.hh index 5569c7c90..69ae004b3 100755 --- a/src/dev/mips/malta.hh +++ b/src/dev/mips/malta.hh @@ -120,10 +120,26 @@ class Malta : public Platform virtual Addr pciToDma(Addr pciAddr) const; - /** - * Calculate the configuration address given a bus/dev/func. - */ - virtual Addr calcConfigAddr(int bus, int dev, int func); + Addr + calcPciConfigAddr(int bus, int dev, int func) + { + panic("Need implementation\n"); + M5_DUMMY_RETURN + } + + Addr + calcPciIOAddr(Addr addr) + { + panic("Need implementation\n"); + M5_DUMMY_RETURN + } + + Addr + calcPciMemAddr(Addr addr) + { + panic("Need implementation\n"); + M5_DUMMY_RETURN + } /** * Serialize this object to the given output stream. diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc index b56694f1e..7f04789db 100755 --- a/src/dev/mips/malta_io.cc +++ b/src/dev/mips/malta_io.cc @@ -40,8 +40,8 @@ #include <string> #include <vector> +#include "base/time.hh" #include "base/trace.hh" -#include "dev/pitreg.h" #include "dev/rtcreg.h" #include "dev/mips/malta_cchip.hh" #include "dev/mips/malta.hh" @@ -56,419 +56,15 @@ using namespace std; using namespace TheISA; -MaltaIO::RTC::RTC(const string &name, Malta* t, Tick i) - : _name(name), event(t, i), addr(0) +MaltaIO::RTC::RTC(const string &name, const MaltaIOParams *p) + : MC146818(p->malta, name, p->time, p->year_is_bcd, p->frequency), + malta(p->malta) { - memset(clock_data, 0, sizeof(clock_data)); - stat_regA = RTCA_32768HZ | RTCA_1024HZ; - stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; } -void -MaltaIO::RTC::set_time(time_t t) -{ - struct tm tm; - gmtime_r(&t, &tm); - - sec = tm.tm_sec; - min = tm.tm_min; - hour = tm.tm_hour; - wday = tm.tm_wday + 1; - mday = tm.tm_mday; - mon = tm.tm_mon + 1; - year = tm.tm_year; - - DPRINTFN("Real-time clock set to %s", asctime(&tm)); -} - -void -MaltaIO::RTC::writeAddr(const uint8_t data) -{ - panic("MaltaIO::RTC::writeAddr has not been implemented for malta"); - /* - if (data <= RTC_STAT_REGD) - addr = data; - else - panic("RTC addresses over 0xD are not implemented.\n"); - */ -} - -void -MaltaIO::RTC::writeData(const uint8_t data) -{ - panic("MaltaIO::RTC::writeData has not been implemented for malta"); - /* - if (addr < RTC_STAT_REGA) - clock_data[addr] = data; - else { - switch (addr) { - case RTC_STAT_REGA: - if (data != (RTCA_32768HZ | RTCA_1024HZ)) - panic("Unimplemented RTC register A value write!\n"); - stat_regA = data; - break; - case RTC_STAT_REGB: - if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) - panic("Write to RTC reg B bits that are not implemented!\n"); - - if (data & RTCB_PRDC_IE) { - if (!event.scheduled()) - event.scheduleIntr(); - } else { - if (event.scheduled()) - event.deschedule(); - } - stat_regB = data; - break; - case RTC_STAT_REGC: - case RTC_STAT_REGD: - panic("RTC status registers C and D are not implemented.\n"); - break; - } - } - */ - -} - -uint8_t -MaltaIO::RTC::readData() -{ - panic("MaltaIO::RTC::readData() has not been implemented for malta"); - /* - if (addr < RTC_STAT_REGA) - return clock_data[addr]; - else { - switch (addr) { - case RTC_STAT_REGA: - // toggle UIP bit for linux - stat_regA ^= RTCA_UIP; - return stat_regA; - break; - case RTC_STAT_REGB: - return stat_regB; - break; - case RTC_STAT_REGC: - case RTC_STAT_REGD: - return 0x00; - break; - default: - panic("Shouldn't be here"); - } - } - */ -} - -void -MaltaIO::RTC::serialize(const string &base, ostream &os) -{ - paramOut(os, base + ".addr", addr); - arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); - paramOut(os, base + ".stat_regA", stat_regA); - paramOut(os, base + ".stat_regB", stat_regB); -} - -void -MaltaIO::RTC::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - paramIn(cp, section, base + ".addr", addr); - arrayParamIn(cp, section, base + ".clock_data", clock_data, - sizeof(clock_data)); - paramIn(cp, section, base + ".stat_regA", stat_regA); - paramIn(cp, section, base + ".stat_regB", stat_regB); - - // We're not unserializing the event here, but we need to - // rescehedule the event since curTick was moved forward by the - // checkpoint - event.reschedule(curTick + event.interval); -} - -MaltaIO::RTC::RTCEvent::RTCEvent(Malta*t, Tick i) - : Event(&mainEventQueue), malta(t), interval(i) -{ - DPRINTF(MC146818, "RTC Event Initilizing\n"); - warn("MaltaIO::RTC::RTCEvent::process() RTC interrupt has been disabled."); - //schedule(curTick + interval); -} - -void -MaltaIO::RTC::RTCEvent::scheduleIntr() -{ - panic("MaltaIO::RTC::RTCEvent::scheduleIntr() has not been implemented for malta"); - //schedule(curTick + interval); -} - -void -MaltaIO::RTC::RTCEvent::process() -{ - DPRINTF(MC146818, "RTC Timer Interrupt\n"); - schedule(curTick + interval); - //Actually interrupt the processor here - malta->cchip->postRTC(); -} - -const char * -MaltaIO::RTC::RTCEvent::description() const -{ - return "malta RTC interrupt"; -} - -MaltaIO::PITimer::PITimer(const string &name) - : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), - counter2(name + ".counter2") -{ - counter[0] = &counter0; - counter[1] = &counter0; - counter[2] = &counter0; -} - -void -MaltaIO::PITimer::writeControl(const uint8_t data) -{ - panic("MaltoIO::PITimer::writeControl(data) not implemented inside malta_io.cc"); - /* - int rw; - int sel; - - sel = GET_CTRL_SEL(data); - - if (sel == PIT_READ_BACK) - panic("PITimer Read-Back Command is not implemented.\n"); - - rw = GET_CTRL_RW(data); - - if (rw == PIT_RW_LATCH_COMMAND) - counter[sel]->latchCount(); - else { - counter[sel]->setRW(rw); - counter[sel]->setMode(GET_CTRL_MODE(data)); - counter[sel]->setBCD(GET_CTRL_BCD(data)); - } - */ -} - -void -MaltaIO::PITimer::serialize(const string &base, ostream &os) -{ - // serialize the counters - counter0.serialize(base + ".counter0", os); - counter1.serialize(base + ".counter1", os); - counter2.serialize(base + ".counter2", os); -} - -void -MaltaIO::PITimer::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - // unserialze the counters - counter0.unserialize(base + ".counter0", cp, section); - counter1.unserialize(base + ".counter1", cp, section); - counter2.unserialize(base + ".counter2", cp, section); -} - -MaltaIO::PITimer::Counter::Counter(const string &name) - : _name(name), event(this), count(0), latched_count(0), period(0), - mode(0), output_high(false), latch_on(false), read_byte(LSB), - write_byte(LSB) -{ - -} - -void -MaltaIO::PITimer::Counter::latchCount() -{ - panic("MaltoIO::PITimer::latchCount(...) not implemented inside malta_io.cc"); - // behave like a real latch - /* - if(!latch_on) { - latch_on = true; - read_byte = LSB; - latched_count = count; - } - */ -} - -uint8_t -MaltaIO::PITimer::Counter::read() -{ - panic("MaltoIO::PITimer::Count::read(...) not implemented inside malta_io.cc"); - return 0; - /* - if (latch_on) { - switch (read_byte) { - case LSB: - read_byte = MSB; - return (uint8_t)latched_count; - break; - case MSB: - read_byte = LSB; - latch_on = false; - return latched_count >> 8; - break; - default: - panic("Shouldn't be here"); - } - } else { - switch (read_byte) { - case LSB: - read_byte = MSB; - return (uint8_t)count; - break; - case MSB: - read_byte = LSB; - return count >> 8; - break; - default: - panic("Shouldn't be here"); - } - } - */ -} - -void -MaltaIO::PITimer::Counter::write(const uint8_t data) -{ - panic("MaltoIO::PITimer::Counter::write(...) not implemented inside malta_io.cc"); - /* - switch (write_byte) { - case LSB: - count = (count & 0xFF00) | data; - - if (event.scheduled()) - event.deschedule(); - output_high = false; - write_byte = MSB; - break; - - case MSB: - count = (count & 0x00FF) | (data << 8); - period = count; - - if (period > 0) { - DPRINTF(Malta, "Timer set to curTick + %d\n", - count * event.interval); - event.schedule(curTick + count * event.interval); - } - write_byte = LSB; - break; - } - */ -} - -void -MaltaIO::PITimer::Counter::setRW(int rw_val) -{ - panic("MaltoIO::PITimer::Counter::setRW(...) not implemented inside malta_io.cc"); - /* - if (rw_val != PIT_RW_16BIT) - panic("Only LSB/MSB read/write is implemented.\n"); - */ -} - -void -MaltaIO::PITimer::Counter::setMode(int mode_val) -{ - panic("MaltoIO::PITimer::Counter::setMode(...) not implemented inside malta_io.cc"); - /* - if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN && - mode_val != PIT_MODE_SQWAVE) - panic("PIT mode %#x is not implemented: \n", mode_val); - - mode = mode_val; - */ -} - -void -MaltaIO::PITimer::Counter::setBCD(int bcd_val) -{ - panic("MaltoIO::PITimer::Counter::setBCD(...) not implemented inside malta_io.cc"); - /* - if (bcd_val != PIT_BCD_FALSE) - panic("PITimer does not implement BCD counts.\n"); - */ -} - -bool -MaltaIO::PITimer::Counter::outputHigh() -{ - panic("MaltoIO::PITimer::Counter::outputHigh(...) not implemented inside malta_io.cc"); - return false; - /* - return output_high; - */ -} - -void -MaltaIO::PITimer::Counter::serialize(const string &base, ostream &os) -{ - paramOut(os, base + ".count", count); - paramOut(os, base + ".latched_count", latched_count); - paramOut(os, base + ".period", period); - paramOut(os, base + ".mode", mode); - paramOut(os, base + ".output_high", output_high); - paramOut(os, base + ".latch_on", latch_on); - paramOut(os, base + ".read_byte", read_byte); - paramOut(os, base + ".write_byte", write_byte); - - Tick event_tick = 0; - if (event.scheduled()) - event_tick = event.when(); - paramOut(os, base + ".event_tick", event_tick); -} - -void -MaltaIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - paramIn(cp, section, base + ".count", count); - paramIn(cp, section, base + ".latched_count", latched_count); - paramIn(cp, section, base + ".period", period); - paramIn(cp, section, base + ".mode", mode); - paramIn(cp, section, base + ".output_high", output_high); - paramIn(cp, section, base + ".latch_on", latch_on); - paramIn(cp, section, base + ".read_byte", read_byte); - paramIn(cp, section, base + ".write_byte", write_byte); - - Tick event_tick; - paramIn(cp, section, base + ".event_tick", event_tick); - if (event_tick) - event.schedule(event_tick); -} - -MaltaIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) - : Event(&mainEventQueue) -{ - interval = (Tick)(Clock::Float::s / 1193180.0); - counter = c_ptr; -} - -void -MaltaIO::PITimer::Counter::CounterEvent::process() -{ - panic("MaltaIO::PITimer::Counter::CounterEvent::process(...) not implemented inside malta_io.cc"); - /* - DPRINTF(Malta, "Timer Interrupt\n"); - switch (counter->mode) { - case PIT_MODE_INTTC: - counter->output_high = true; - case PIT_MODE_RATEGEN: - case PIT_MODE_SQWAVE: - break; - default: - panic("Unimplemented PITimer mode.\n"); - } - */ -} - -const char * -MaltaIO::PITimer::Counter::CounterEvent::description() const -{ - return "malta 8254 Interval timer"; -} - -MaltaIO::MaltaIO(Params *p) - : BasicPioDevice(p), malta(p->malta), pitimer(p->name + "pitimer"), - rtc(p->name + ".rtc", p->malta, p->frequency) +MaltaIO::MaltaIO(const Params *p) + : BasicPioDevice(p), malta(p->malta), + pitimer(this, p->name + "pitimer"), rtc(p->name + ".rtc", p) { pioSize = 0x100; @@ -489,155 +85,15 @@ MaltaIO::frequency() const Tick MaltaIO::read(PacketPtr pkt) { - panic("MaltaIO::read(...) not implemented inside malta_io.cc"); - return pioDelay; - /* - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - Addr daddr = pkt->getAddr() - pioAddr; - - DPRINTF(Malta, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), - pkt->getSize(), daddr); - - pkt->allocate(); - - if (pkt->getSize() == sizeof(uint8_t)) { - switch(daddr) { - // PIC1 mask read - case TSDEV_PIC1_MASK: - pkt->set(~mask1); - break; - case TSDEV_PIC2_MASK: - pkt->set(~mask2); - break; - case TSDEV_PIC1_ISR: - // !!! If this is modified 64bit case needs to be too - // Pal code has to do a 64 bit physical read because there is - // no load physical byte instruction - pkt->set(picr); - break; - case TSDEV_PIC2_ISR: - // PIC2 not implemnted... just return 0 - pkt->set(0x00); - break; - case TSDEV_TMR0_DATA: - pkt->set(pitimer.counter0.read()); - break; - case TSDEV_TMR1_DATA: - pkt->set(pitimer.counter1.read()); - break; - case TSDEV_TMR2_DATA: - pkt->set(pitimer.counter2.read()); - break; - case TSDEV_RTC_DATA: - pkt->set(rtc.readData()); - break; - case TSDEV_CTRL_PORTB: - if (pitimer.counter2.outputHigh()) - pkt->set(PORTB_SPKR_HIGH); - else - pkt->set(0x00); - break; - default: - panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); - } - } else if (pkt->getSize() == sizeof(uint64_t)) { - if (daddr == TSDEV_PIC1_ISR) - pkt->set<uint64_t>(picr); - else - panic("I/O Read - invalid addr - va %#x size %d\n", - pkt->getAddr(), pkt->getSize()); - } else { - panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); - } - pkt->result = Packet::Success; + panic("MaltaIO::read(...) not implemented inside malta_io.cc"); return pioDelay; - */ } Tick MaltaIO::write(PacketPtr pkt) { - panic("MaltaIO::write(...) not implemented inside malta_io.cc"); - return pioDelay; - /* - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = pkt->getAddr() - pioAddr; - - DPRINTF(Malta, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>()); - - assert(pkt->getSize() == sizeof(uint8_t)); - warn ("GOT HERE daddr=0x%x\n", daddr); - switch(daddr) { - case TSDEV_PIC1_MASK: - mask1 = ~(pkt->get<uint8_t>()); - if ((picr & mask1) && !picInterrupting) { - picInterrupting = true; - malta->cchip->postDRIR(55); - DPRINTF(Malta, "posting pic interrupt to cchip\n"); - } - if ((!(picr & mask1)) && picInterrupting) { - picInterrupting = false; - malta->cchip->clearDRIR(55); - DPRINTF(Malta, "clearing pic interrupt\n"); - } - break; - case TSDEV_PIC2_MASK: - mask2 = pkt->get<uint8_t>(); - //PIC2 Not implemented to interrupt - break; - case TSDEV_PIC1_ACK: - // clear the interrupt on the PIC - picr &= ~(1 << (pkt->get<uint8_t>() & 0xF)); - if (!(picr & mask1)) - malta->cchip->clearDRIR(55); - break; - case TSDEV_DMA1_MODE: - mode1 = pkt->get<uint8_t>(); - break; - case TSDEV_DMA2_MODE: - mode2 = pkt->get<uint8_t>(); - break; - case TSDEV_TMR0_DATA: - pitimer.counter0.write(pkt->get<uint8_t>()); - break; - case TSDEV_TMR1_DATA: - pitimer.counter1.write(pkt->get<uint8_t>()); - break; - case TSDEV_TMR2_DATA: - pitimer.counter2.write(pkt->get<uint8_t>()); - break; - case TSDEV_TMR_CTRL: - pitimer.writeControl(pkt->get<uint8_t>()); - break; - case TSDEV_RTC_ADDR: - rtc.writeAddr(pkt->get<uint8_t>()); - break; - case TSDEV_RTC_DATA: - rtc.writeData(pkt->get<uint8_t>()); - break; - case TSDEV_KBD: - case TSDEV_DMA1_CMND: - case TSDEV_DMA2_CMND: - case TSDEV_DMA1_MMASK: - case TSDEV_DMA2_MMASK: - case TSDEV_PIC2_ACK: - case TSDEV_DMA1_RESET: - case TSDEV_DMA2_RESET: - case TSDEV_DMA1_MASK: - case TSDEV_DMA2_MASK: - case TSDEV_CTRL_PORTB: - break; - default: - panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>()); - } - - pkt->result = Packet::Success; + panic("MaltaIO::write(...) not implemented inside malta_io.cc"); return pioDelay; - */ } void @@ -651,7 +107,7 @@ void MaltaIO::clearIntr(uint8_t interrupt) { malta->cchip->clearIntr(interrupt); - DPRINTF(Malta, "posting pic interrupt to cchip\n"); + DPRINTF(Malta, "clear pic interrupt to cchip\n"); } void diff --git a/src/dev/mips/malta_io.hh b/src/dev/mips/malta_io.hh index e24a1d8cb..38da5adea 100755 --- a/src/dev/mips/malta_io.hh +++ b/src/dev/mips/malta_io.hh @@ -37,11 +37,13 @@ #ifndef __DEV_MALTA_IO_HH__ #define __DEV_MALTA_IO_HH__ -#include "dev/io_device.hh" #include "base/range.hh" #include "dev/mips/malta.hh" -#include "sim/eventq.hh" +#include "dev/intel_8254_timer.hh" +#include "dev/io_device.hh" +#include "dev/mc146818.hh" #include "params/MaltaIO.hh" +#include "sim/eventq.hh" /** * Malta I/O device is a catch all for all the south bridge stuff we care @@ -51,235 +53,21 @@ class MaltaIO : public BasicPioDevice { private: struct tm tm; - public: - /** Post an Interrupt to the CPU */ - void postIntr(uint8_t interrupt); - - /** Clear an Interrupt to the CPU */ - void clearIntr(uint8_t interrupt); protected: - /** Real-Time Clock (MC146818) */ - class RTC - { - private: - /** Event for RTC periodic interrupt */ - struct RTCEvent : public Event - { - /** A pointer back to malta to create interrupt the processor. */ - Malta* malta; - Tick interval; - - RTCEvent(Malta* t, Tick i); - - /** Schedule the RTC periodic interrupt */ - void scheduleIntr(); - - /** Event process to occur at interrupt*/ - virtual void process(); - - /** Event description */ - virtual const char *description() const; - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - /** RTC periodic interrupt event */ - RTCEvent event; - - /** Current RTC register address/index */ - int addr; - /** Data for real-time clock function */ - union { - uint8_t clock_data[10]; - - struct { - uint8_t sec; - uint8_t sec_alrm; - uint8_t min; - uint8_t min_alrm; - uint8_t hour; - uint8_t hour_alrm; - uint8_t wday; - uint8_t mday; - uint8_t mon; - uint8_t year; - }; - }; - - /** RTC status register A */ - uint8_t stat_regA; - - /** RTC status register B */ - uint8_t stat_regB; - - public: - RTC(const std::string &name, Malta* t, Tick i); - - /** Set the initial RTC time/date */ - void set_time(time_t t); - - /** RTC address port: write address of RTC RAM data to access */ - void writeAddr(const uint8_t data); - - /** RTC write data */ - void writeData(const uint8_t data); - - - - /** RTC read data */ - uint8_t readData(); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); - }; - - /** Programmable Interval Timer (Intel 8254) */ - class PITimer + class RTC : public MC146818 { - /** Counter element for PIT */ - class Counter - { - /** Event for counter interrupt */ - class CounterEvent : public Event - { - private: - /** Pointer back to Counter */ - Counter* counter; - Tick interval; - - public: - CounterEvent(Counter*); - - /** Event process */ - virtual void process(); - - /** Event description */ - virtual const char *description() const; - - friend class Counter; - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - CounterEvent event; - - /** Current count value */ - uint16_t count; - - /** Latched count */ - uint16_t latched_count; - - /** Interrupt period */ - uint16_t period; - - /** Current mode of operation */ - uint8_t mode; - - /** Output goes high when the counter reaches zero */ - bool output_high; - - /** State of the count latch */ - bool latch_on; - - /** Set of values for read_byte and write_byte */ - enum {LSB, MSB}; - - /** Determine which byte of a 16-bit count value to read/write */ - uint8_t read_byte, write_byte; - - public: - Counter(const std::string &name); - - /** Latch the current count (if one is not already latched) */ - void latchCount(); - - /** Set the read/write mode */ - void setRW(int rw_val); - - /** Set operational mode */ - void setMode(int mode_val); - - /** Set count encoding */ - void setBCD(int bcd_val); - - /** Read a count byte */ - uint8_t read(); - - /** Write a count byte */ - void write(const uint8_t data); - - /** Is the output high? */ - bool outputHigh(); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - /** PIT has three seperate counters */ - Counter *counter[3]; - public: - /** Public way to access individual counters (avoid array accesses) */ - Counter counter0; - Counter counter1; - Counter counter2; - - PITimer(const std::string &name); + Malta *malta; + RTC(const std::string &name, const MaltaIOParams *p); - /** Write control word */ - void writeControl(const uint8_t data); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); + protected: + void handleEvent() + { + //Actually interrupt the processor here + malta->cchip->postRTC(); + } }; /** Mask of the PIC1 */ @@ -304,7 +92,7 @@ class MaltaIO : public BasicPioDevice Malta *malta; /** Intel 8253 Periodic Interval Timer */ - PITimer pitimer; + Intel8254Timer pitimer; RTC rtc; @@ -329,17 +117,21 @@ class MaltaIO : public BasicPioDevice return dynamic_cast<const Params *>(_params); } - public: /** * Initialize all the data for devices supported by Malta I/O. * @param p pointer to Params struct */ - MaltaIO(Params *p); + MaltaIO(const Params *p); virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); + /** Post an Interrupt to the CPU */ + void postIntr(uint8_t interrupt); + + /** Clear an Interrupt to the CPU */ + void clearIntr(uint8_t interrupt); /** * Serialize this object to the given output stream. |