From 03be92f23b36ba69bfee179f97cd5af23c0f6e2c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 6 Dec 2006 19:25:53 -0500 Subject: [PATCH] Handle access to ASI_QUEUE Add function for interrupt ASIs add all the new MISCREGs to the copyMiscRegs() file src/arch/sparc/asi.cc: src/arch/sparc/asi.hh: Add function for interrupt ASIs src/arch/sparc/miscregfile.cc: src/arch/sparc/miscregfile.hh: Add QUEUE asi/misc registers src/arch/sparc/regfile.cc: add all the new MISCREGs to the copyMiscRegs() file src/arch/sparc/tlb.cc: Handle access to ASI_QUEUE --HG-- extra : convert_revision : 7a14450485816e6ee3bc8c80b462a13e1edf0ba0 --- src/arch/sparc/asi.cc | 7 +++ src/arch/sparc/asi.hh | 1 + src/arch/sparc/miscregfile.cc | 74 +++++++++++++++++++++++++++++- src/arch/sparc/miscregfile.hh | 20 ++++++++ src/arch/sparc/regfile.cc | 86 +++++++++++++++++++++++++++++++++++ src/arch/sparc/tlb.cc | 28 ++++++++++++ 6 files changed, 214 insertions(+), 2 deletions(-) diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc index c8f2c1366..49d3193eb 100644 --- a/src/arch/sparc/asi.cc +++ b/src/arch/sparc/asi.cc @@ -256,6 +256,13 @@ namespace SparcISA return asi == ASI_QUEUE; } + bool AsiIsInterrupt(ASI asi) + { + return asi == ASI_SWVR_INTR_RECEIVE || + asi == ASI_SWVR_UDB_INTR_W || + asi == ASI_SWVR_UDB_INTR_R ; + } + bool AsiIsMmu(ASI asi) { return asi == ASI_MMU || diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh index e683605e8..485f217ad 100644 --- a/src/arch/sparc/asi.hh +++ b/src/arch/sparc/asi.hh @@ -268,6 +268,7 @@ namespace SparcISA bool AsiIsPriv(ASI); bool AsiIsHPriv(ASI); bool AsiIsReg(ASI); + bool AsiIsInterrupt(ASI); }; diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 8f2bcf4ae..47b4771d9 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -269,7 +269,22 @@ MiscReg MiscRegFile::readReg(int miscReg) return scratchPad[6]; case MISCREG_SCRATCHPAD_R7: return scratchPad[7]; - + case MISCREG_QUEUE_CPU_MONDO_HEAD: + return cpu_mondo_head; + case MISCREG_QUEUE_CPU_MONDO_TAIL: + return cpu_mondo_tail; + case MISCREG_QUEUE_DEV_MONDO_HEAD: + return dev_mondo_head; + case MISCREG_QUEUE_DEV_MONDO_TAIL: + return dev_mondo_tail; + case MISCREG_QUEUE_RES_ERROR_HEAD: + return res_error_head; + case MISCREG_QUEUE_RES_ERROR_TAIL: + return res_error_tail; + case MISCREG_QUEUE_NRES_ERROR_HEAD: + return nres_error_head; + case MISCREG_QUEUE_NRES_ERROR_TAIL: + return nres_error_tail; default: panic("Miscellaneous register %d not implemented\n", miscReg); } @@ -310,6 +325,14 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) case MISCREG_HVER: case MISCREG_STRAND_STS_REG: case MISCREG_HSTICK_CMPR: + case MISCREG_QUEUE_CPU_MONDO_HEAD: + case MISCREG_QUEUE_CPU_MONDO_TAIL: + case MISCREG_QUEUE_DEV_MONDO_HEAD: + case MISCREG_QUEUE_DEV_MONDO_TAIL: + case MISCREG_QUEUE_RES_ERROR_HEAD: + case MISCREG_QUEUE_RES_ERROR_TAIL: + case MISCREG_QUEUE_NRES_ERROR_HEAD: + case MISCREG_QUEUE_NRES_ERROR_TAIL: #if FULL_SYSTEM return readFSRegWithEffect(miscReg, tc); #else @@ -522,6 +545,30 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) case MISCREG_SCRATCHPAD_R7: scratchPad[7] = val; break; + case MISCREG_QUEUE_CPU_MONDO_HEAD: + cpu_mondo_head = val; + break; + case MISCREG_QUEUE_CPU_MONDO_TAIL: + cpu_mondo_tail = val; + break; + case MISCREG_QUEUE_DEV_MONDO_HEAD: + dev_mondo_head = val; + break; + case MISCREG_QUEUE_DEV_MONDO_TAIL: + dev_mondo_tail = val; + break; + case MISCREG_QUEUE_RES_ERROR_HEAD: + res_error_head = val; + break; + case MISCREG_QUEUE_RES_ERROR_TAIL: + res_error_tail = val; + break; + case MISCREG_QUEUE_NRES_ERROR_HEAD: + nres_error_head = val; + break; + case MISCREG_QUEUE_NRES_ERROR_TAIL: + nres_error_tail = val; + break; default: panic("Miscellaneous register %d not implemented\n", miscReg); @@ -568,6 +615,14 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_HVER: case MISCREG_STRAND_STS_REG: case MISCREG_HSTICK_CMPR: + case MISCREG_QUEUE_CPU_MONDO_HEAD: + case MISCREG_QUEUE_CPU_MONDO_TAIL: + case MISCREG_QUEUE_DEV_MONDO_HEAD: + case MISCREG_QUEUE_DEV_MONDO_TAIL: + case MISCREG_QUEUE_RES_ERROR_HEAD: + case MISCREG_QUEUE_RES_ERROR_TAIL: + case MISCREG_QUEUE_NRES_ERROR_HEAD: + case MISCREG_QUEUE_NRES_ERROR_TAIL: #if FULL_SYSTEM setFSRegWithEffect(miscReg, val, tc); return; @@ -627,6 +682,14 @@ void MiscRegFile::serialize(std::ostream & os) SERIALIZE_SCALAR(dTlbSfar); SERIALIZE_SCALAR(dTlbTagAccess); SERIALIZE_ARRAY(scratchPad,8); + SERIALIZE_SCALAR(cpu_mondo_head); + SERIALIZE_SCALAR(cpu_mondo_tail); + SERIALIZE_SCALAR(dev_mondo_head); + SERIALIZE_SCALAR(dev_mondo_tail); + SERIALIZE_SCALAR(res_error_head); + SERIALIZE_SCALAR(res_error_tail); + SERIALIZE_SCALAR(nres_error_head); + SERIALIZE_SCALAR(nres_error_tail); } void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) @@ -678,4 +741,11 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) UNSERIALIZE_SCALAR(dTlbSfar); UNSERIALIZE_SCALAR(dTlbTagAccess); UNSERIALIZE_ARRAY(scratchPad,8); -} + UNSERIALIZE_SCALAR(cpu_mondo_head); + UNSERIALIZE_SCALAR(cpu_mondo_tail); + UNSERIALIZE_SCALAR(dev_mondo_head); + UNSERIALIZE_SCALAR(dev_mondo_tail); + UNSERIALIZE_SCALAR(res_error_head); + UNSERIALIZE_SCALAR(res_error_tail); + UNSERIALIZE_SCALAR(nres_error_head); + UNSERIALIZE_SCALAR(nres_error_tail);} diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 260a3344b..3b8a977cc 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -126,6 +126,17 @@ namespace SparcISA MISCREG_SCRATCHPAD_R5, MISCREG_SCRATCHPAD_R6, MISCREG_SCRATCHPAD_R7, + + /* CPU Queue Registers */ + MISCREG_QUEUE_CPU_MONDO_HEAD, + MISCREG_QUEUE_CPU_MONDO_TAIL, + MISCREG_QUEUE_DEV_MONDO_HEAD, /* 70 */ + MISCREG_QUEUE_DEV_MONDO_TAIL, + MISCREG_QUEUE_RES_ERROR_HEAD, + MISCREG_QUEUE_RES_ERROR_TAIL, + MISCREG_QUEUE_NRES_ERROR_HEAD, + MISCREG_QUEUE_NRES_ERROR_TAIL, + MISCREG_NUMMISCREGS }; @@ -210,6 +221,15 @@ namespace SparcISA uint64_t scratchPad[8]; + uint64_t cpu_mondo_head; + uint64_t cpu_mondo_tail; + uint64_t dev_mondo_head; + uint64_t dev_mondo_tail; + uint64_t res_error_head; + uint64_t res_error_tail; + uint64_t nres_error_head; + uint64_t nres_error_tail; + // These need to check the int_dis field and if 0 then // set appropriate bit in softint and checkinterrutps on the cpu #if FULL_SYSTEM diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 06ba13423..5d8ac6a17 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -254,6 +254,92 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) // FSR dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR)); + + //Strand Status Register + dest->setMiscReg(MISCREG_STRAND_STS_REG, + src->readMiscReg(MISCREG_STRAND_STS_REG)); + + // MMU Registers + dest->setMiscReg(MISCREG_MMU_P_CONTEXT, + src->readMiscReg(MISCREG_MMU_P_CONTEXT)); + dest->setMiscReg(MISCREG_MMU_S_CONTEXT, + src->readMiscReg(MISCREG_MMU_S_CONTEXT)); + dest->setMiscReg(MISCREG_MMU_PART_ID, + src->readMiscReg(MISCREG_MMU_PART_ID)); + dest->setMiscReg(MISCREG_MMU_LSU_CTRL, + src->readMiscReg(MISCREG_MMU_LSU_CTRL)); + + dest->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0, + src->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0)); + dest->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1, + src->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1)); + dest->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG, + src->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG)); + dest->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0, + src->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0)); + dest->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1, + src->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1)); + dest->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG, + src->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)); + dest->setMiscReg(MISCREG_MMU_ITLB_SFSR, + src->readMiscReg(MISCREG_MMU_ITLB_SFSR)); + dest->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, + src->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS)); + + dest->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0, + src->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0)); + dest->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1, + src->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1)); + dest->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG, + src->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG)); + dest->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0, + src->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0)); + dest->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1, + src->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1)); + dest->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG, + src->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)); + dest->setMiscReg(MISCREG_MMU_DTLB_SFSR, + src->readMiscReg(MISCREG_MMU_DTLB_SFSR)); + dest->setMiscReg(MISCREG_MMU_DTLB_SFAR, + src->readMiscReg(MISCREG_MMU_DTLB_SFAR)); + dest->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, + src->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS)); + + // Scratchpad Registers + dest->setMiscReg(MISCREG_SCRATCHPAD_R0, + src->readMiscReg(MISCREG_SCRATCHPAD_R0)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R1, + src->readMiscReg(MISCREG_SCRATCHPAD_R1)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R2, + src->readMiscReg(MISCREG_SCRATCHPAD_R2)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R3, + src->readMiscReg(MISCREG_SCRATCHPAD_R3)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R4, + src->readMiscReg(MISCREG_SCRATCHPAD_R4)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R5, + src->readMiscReg(MISCREG_SCRATCHPAD_R5)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R6, + src->readMiscReg(MISCREG_SCRATCHPAD_R6)); + dest->setMiscReg(MISCREG_SCRATCHPAD_R7, + src->readMiscReg(MISCREG_SCRATCHPAD_R7)); + + // Queue Registers + dest->setMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD, + src->readMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD)); + dest->setMiscReg(MISCREG_QUEUE_CPU_MONDO_TAIL, + src->readMiscReg(MISCREG_QUEUE_CPU_MONDO_TAIL)); + dest->setMiscReg(MISCREG_QUEUE_DEV_MONDO_HEAD, + src->readMiscReg(MISCREG_QUEUE_DEV_MONDO_HEAD)); + dest->setMiscReg(MISCREG_QUEUE_DEV_MONDO_TAIL, + src->readMiscReg(MISCREG_QUEUE_DEV_MONDO_TAIL)); + dest->setMiscReg(MISCREG_QUEUE_RES_ERROR_HEAD, + src->readMiscReg(MISCREG_QUEUE_RES_ERROR_HEAD)); + dest->setMiscReg(MISCREG_QUEUE_RES_ERROR_TAIL, + src->readMiscReg(MISCREG_QUEUE_RES_ERROR_TAIL)); + dest->setMiscReg(MISCREG_QUEUE_NRES_ERROR_HEAD, + src->readMiscReg(MISCREG_QUEUE_NRES_ERROR_HEAD)); + dest->setMiscReg(MISCREG_QUEUE_NRES_ERROR_TAIL, + src->readMiscReg(MISCREG_QUEUE_NRES_ERROR_TAIL)); } void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 3ab40ce63..3ac3e5c9c 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -31,6 +31,7 @@ #include "arch/sparc/asi.hh" #include "arch/sparc/miscregfile.hh" #include "arch/sparc/tlb.hh" +#include "base/bitfield.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" @@ -479,11 +480,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) panic("Twin ASIs not supported\n"); if (AsiIsPartialStore(asi)) panic("Partial Store ASIs not supported\n"); + if (AsiIsInterrupt(asi)) + panic("Interrupt ASIs not supported\n"); if (AsiIsMmu(asi)) goto handleMmuRegAccess; if (AsiIsScratchPad(asi)) goto handleScratchRegAccess; + if (AsiIsQueue(asi)) + goto handleQueueRegAccess; if (!AsiIsReal(asi) && !AsiIsNucleus(asi)) panic("Accessing ASI %#X. Should we?\n", asi); @@ -542,6 +547,20 @@ handleScratchRegAccess: writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } + goto regAccessOk; + +handleQueueRegAccess: + if (!priv && !hpriv) { + writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + return new PrivilegedAction; + } + if (priv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) { + writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + return new DataAccessException; + } + goto regAccessOk; + +regAccessOk: handleMmuRegAccess: DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n"); req->setMmapedIpr(true); @@ -575,6 +594,10 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) goto doMmuReadError; } break; + case ASI_QUEUE: + pkt->set(tc->readMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD + + (va >> 4) - 0x3c)); + break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0)); @@ -672,6 +695,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) goto doMmuWriteError; } break; + case ASI_QUEUE: + assert(mbits(va,13,6) == va); + tc->setMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD + + (va >> 4) - 0x3c, data); + break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0, data);