summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/sparc/asi.cc7
-rw-r--r--src/arch/sparc/asi.hh1
-rw-r--r--src/arch/sparc/miscregfile.cc74
-rw-r--r--src/arch/sparc/miscregfile.hh20
-rw-r--r--src/arch/sparc/regfile.cc86
-rw-r--r--src/arch/sparc/tlb.cc28
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);