summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/sparc/asi.cc8
-rw-r--r--src/arch/sparc/asi.hh2
-rw-r--r--src/arch/sparc/faults.cc3
-rw-r--r--src/arch/sparc/isa/decoder.isa1
-rw-r--r--src/arch/sparc/miscregfile.cc7
-rw-r--r--src/arch/sparc/tlb.cc30
-rw-r--r--src/arch/sparc/ua2005.cc211
7 files changed, 161 insertions, 101 deletions
diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc
index 49d3193eb..b307ade33 100644
--- a/src/arch/sparc/asi.cc
+++ b/src/arch/sparc/asi.cc
@@ -295,7 +295,13 @@ namespace SparcISA
bool AsiIsReg(ASI asi)
{
- return AsiIsMmu(asi) || AsiIsScratchPad(asi);
+ return AsiIsMmu(asi) || AsiIsScratchPad(asi) | AsiIsSparcError(asi);
+ }
+
+ bool AsiIsSparcError(ASI asi)
+ {
+ return asi == ASI_SPARC_ERROR_EN_REG ||
+ asi == ASI_SPARC_ERROR_STATUS_REG;
}
}
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 485f217ad..166c3867e 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -269,7 +269,7 @@ namespace SparcISA
bool AsiIsHPriv(ASI);
bool AsiIsReg(ASI);
bool AsiIsInterrupt(ASI);
-
+ bool AsiIsSparcError(ASI);
};
#endif // __ARCH_SPARC_ASI_HH__
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 9a29f24d5..78b2b4b76 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -528,7 +528,7 @@ void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscRe
void SparcFaultBase::invoke(ThreadContext * tc)
{
- panic("Invoking a second fault!\n");
+ //panic("Invoking a second fault!\n");
FaultBase::invoke(tc);
countStat()++;
@@ -561,6 +561,7 @@ void SparcFaultBase::invoke(ThreadContext * tc)
}
else if(TL == MaxTL)
{
+ panic("Should go to error state here.. crap\n");
//Do error_state somehow?
//Probably inject a WDR fault using the interrupt mechanism.
//What should the PC and NPC be set to?
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index a355816ac..b893797b0 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -1004,6 +1004,7 @@ decode OP default Unknown::unknown()
Asi = Tstate<31:24>;
Ccr = Tstate<39:32>;
Gl = Tstate<42:40>;
+ Hpstate = Htstate;
NPC = Tnpc;
NNPC = Tnpc + 4;
Tl = Tl - 1;
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 47b4771d9..48abad32a 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -305,13 +305,15 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
return mbits(tc->getCpuPtr()->instCount() - (tick &
mask(63)),62,2) | mbits(tick,63,63) ;
case MISCREG_FPRS:
- panic("FPU not implemented\n");
+ warn("FPRS register read and FPU stuff not really implemented\n");
+ return fprs;
case MISCREG_PCR:
case MISCREG_PIC:
panic("Performance Instrumentation not impl\n");
/** Floating Point Status Register */
case MISCREG_FSR:
- panic("Floating Point not implemented\n");
+ warn("Reading FSR Floating Point not implemented\n");
+ break;
case MISCREG_SOFTINT_CLR:
case MISCREG_SOFTINT_SET:
panic("Can read from softint clr/set\n");
@@ -356,6 +358,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
asi = val;
break;
case MISCREG_FPRS:
+ warn("FPU not really implemented writing %#X to FPRS\n", val);
fprs = val;
break;
case MISCREG_TICK:
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 3ac3e5c9c..c05434797 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -328,6 +328,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n",
vaddr, req->getSize());
+ DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n",
+ pstate, hpstate, lsuIm, part_id);
assert(req->getAsi() == ASI_IMPLICIT);
@@ -360,7 +362,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
return new InstructionAccessException;
}
- if (lsuIm) {
+ if (!lsuIm) {
e = lookup(req->getVaddr(), part_id, true);
real = true;
context = 0;
@@ -416,7 +418,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
asi = (ASI)req->getAsi();
DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
vaddr, size, asi);
-
+ DPRINTF(TLB, "TLB: pstate: %#X hpstate: %#X lsudm: %#X part_id: %#X\n",
+ pstate, hpstate, lsuDm, part_id);
if (asi == ASI_IMPLICIT)
implicit = true;
@@ -489,6 +492,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
goto handleScratchRegAccess;
if (AsiIsQueue(asi))
goto handleQueueRegAccess;
+ if (AsiIsSparcError(asi))
+ goto handleSparcErrorRegAccess;
if (!AsiIsReal(asi) && !AsiIsNucleus(asi))
panic("Accessing ASI %#X. Should we?\n", asi);
@@ -560,6 +565,19 @@ handleQueueRegAccess:
}
goto regAccessOk;
+handleSparcErrorRegAccess:
+ if (!hpriv) {
+ if (priv) {
+ writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ return new DataAccessException;
+ } else {
+ writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ return new PrivilegedAction;
+ }
+ }
+ goto regAccessOk;
+
+
regAccessOk:
handleMmuRegAccess:
DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
@@ -675,7 +693,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
Addr va = pkt->getAddr();
ASI asi = (ASI)pkt->req->getAsi();
- DPRINTF(IPR, "Memory Mapped IPR Write: asi=#%X a=%#x d=%#X\n",
+ DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
(uint32_t)asi, va, data);
switch (asi) {
@@ -696,7 +714,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
}
break;
case ASI_QUEUE:
- assert(mbits(va,13,6) == va);
+ assert(mbits(data,13,6) == data);
tc->setMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD +
(va >> 4) - 0x3c, data);
break;
@@ -748,6 +766,10 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
assert(va == 0);
tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG, data);
break;
+ case ASI_SPARC_ERROR_EN_REG:
+ case ASI_SPARC_ERROR_STATUS_REG:
+ warn("Ignoring write to SPARC ERROR regsiter\n");
+ break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
tc->setMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3), data);
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index 32bc2a44b..2bc8981ac 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -43,79 +43,99 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
int64_t time;
int oldLevel, newLevel;
switch (miscReg) {
- /* Full system only ASRs */
- case MISCREG_SOFTINT:
- // Check if we are going to interrupt because of something
- oldLevel = InterruptLevel(softint);
- newLevel = InterruptLevel(val);
- setReg(miscReg, val);
- if (newLevel > oldLevel)
- ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
- //tc->getCpuPtr()->checkInterrupts = true;
- panic("SOFTINT not implemented\n");
- break;
-
- case MISCREG_SOFTINT_CLR:
- return setRegWithEffect(miscReg, ~val & softint, tc);
- case MISCREG_SOFTINT_SET:
- return setRegWithEffect(miscReg, val | softint, tc);
-
- case MISCREG_TICK_CMPR:
- if (tickCompare == NULL)
- tickCompare = new TickCompareEvent(this, tc);
- setReg(miscReg, val);
- if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
+ /* Full system only ASRs */
+ case MISCREG_SOFTINT:
+ // Check if we are going to interrupt because of something
+ oldLevel = InterruptLevel(softint);
+ newLevel = InterruptLevel(val);
+ setReg(miscReg, val);
+ //if (newLevel > oldLevel)
+ ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
+ //tc->getCpuPtr()->checkInterrupts = true;
+ //panic("SOFTINT not implemented\n");
+ warn("Writing to softint not really supported, writing: %#x\n", val);
+ break;
+
+ case MISCREG_SOFTINT_CLR:
+ return setRegWithEffect(miscReg, ~val & softint, tc);
+ case MISCREG_SOFTINT_SET:
+ return setRegWithEffect(miscReg, val | softint, tc);
+
+ case MISCREG_TICK_CMPR:
+ if (tickCompare == NULL)
+ tickCompare = new TickCompareEvent(this, tc);
+ setReg(miscReg, val);
+ if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
tickCompare->deschedule();
- time = (tick_cmpr & mask(63)) - (tick & mask(63));
- if (!(tick_cmpr & ~mask(63)) && time > 0)
- tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
- break;
-
- case MISCREG_STICK_CMPR:
- if (sTickCompare == NULL)
- sTickCompare = new STickCompareEvent(this, tc);
- setReg(miscReg, val);
- if ((stick_cmpr & mask(63)) && sTickCompare->scheduled())
- sTickCompare->deschedule();
- time = (stick_cmpr & mask(63)) - (stick & mask(63));
- if (!(stick_cmpr & ~mask(63)) && time > 0)
- sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
- break;
-
- case MISCREG_PIL:
- setReg(miscReg, val);
- //tc->getCpuPtr()->checkInterrupts;
- // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
- panic("PIL not implemented\n");
- break;
-
- case MISCREG_HVER:
- panic("Shouldn't be writing HVER\n");
-
- case MISCREG_HTBA:
- // clear lower 7 bits on writes.
- setReg(miscReg, val & ULL(~0x7FFF));
- break;
-
- case MISCREG_HSTICK_CMPR:
- if (hSTickCompare == NULL)
- hSTickCompare = new HSTickCompareEvent(this, tc);
- setReg(miscReg, val);
- if ((hstick_cmpr & mask(63)) && hSTickCompare->scheduled())
- hSTickCompare->deschedule();
- time = (hstick_cmpr & mask(63)) - (stick & mask(63));
- if (!(hstick_cmpr & ~mask(63)) && time > 0)
- hSTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
- break;
-
- case MISCREG_HPSTATE:
- case MISCREG_HTSTATE:
- case MISCREG_STRAND_STS_REG:
- setReg(miscReg, val);
- break;
-
- default:
- panic("Invalid write to FS misc register\n");
+ time = (tick_cmpr & mask(63)) - (tick & mask(63));
+ if (!(tick_cmpr & ~mask(63)) && time > 0)
+ tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ warn ("writing to TICK compare register %#X\n", val);
+ break;
+
+ case MISCREG_STICK_CMPR:
+ if (sTickCompare == NULL)
+ sTickCompare = new STickCompareEvent(this, tc);
+ setReg(miscReg, val);
+ if ((stick_cmpr & mask(63)) && sTickCompare->scheduled())
+ sTickCompare->deschedule();
+ time = (stick_cmpr & mask(63)) - (stick & mask(63));
+ if (!(stick_cmpr & ~mask(63)) && time > 0)
+ sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ warn ("writing to sTICK compare register value %#X\n", val);
+ break;
+
+ case MISCREG_PIL:
+ setReg(miscReg, val);
+ //tc->getCpuPtr()->checkInterrupts;
+ // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
+ // panic("PIL not implemented\n");
+ warn ("PIL not implemented writing %#X\n", val);
+ break;
+
+ case MISCREG_HVER:
+ panic("Shouldn't be writing HVER\n");
+
+ case MISCREG_HTBA:
+ // clear lower 7 bits on writes.
+ setReg(miscReg, val & ULL(~0x7FFF));
+ break;
+
+ 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:
+ setReg(miscReg, val);
+ tc->getCpuPtr()->checkInterrupts = true;
+ break;
+
+ case MISCREG_HSTICK_CMPR:
+ if (hSTickCompare == NULL)
+ hSTickCompare = new HSTickCompareEvent(this, tc);
+ setReg(miscReg, val);
+ if ((hstick_cmpr & mask(63)) && hSTickCompare->scheduled())
+ hSTickCompare->deschedule();
+ time = (hstick_cmpr & mask(63)) - (stick & mask(63));
+ if (!(hstick_cmpr & ~mask(63)) && time > 0)
+ hSTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ warn ("writing to hsTICK compare register value %#X\n", val);
+ break;
+
+ case MISCREG_HPSTATE:
+ // i.d. is always set on any hpstate write
+ setReg(miscReg, val | 1 << 11);
+ break;
+ case MISCREG_HTSTATE:
+ case MISCREG_STRAND_STS_REG:
+ setReg(miscReg, val);
+ break;
+
+ default:
+ panic("Invalid write to FS misc register\n");
}
}
@@ -123,26 +143,33 @@ MiscReg
MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
{
switch (miscReg) {
-
- /* Privileged registers. */
- case MISCREG_SOFTINT:
- case MISCREG_TICK_CMPR:
- case MISCREG_STICK_CMPR:
- case MISCREG_PIL:
- case MISCREG_HPSTATE:
- case MISCREG_HINTP:
- case MISCREG_HTSTATE:
- case MISCREG_STRAND_STS_REG:
- case MISCREG_HSTICK_CMPR:
- return readReg(miscReg) ;
-
- case MISCREG_HTBA:
- return readReg(miscReg) & ULL(~0x7FFF);
- case MISCREG_HVER:
- return NWindows | MaxTL << 8 | MaxGL << 16;
-
- default:
- panic("Invalid read to FS misc register\n");
+ /* Privileged registers. */
+ 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:
+ case MISCREG_SOFTINT:
+ case MISCREG_TICK_CMPR:
+ case MISCREG_STICK_CMPR:
+ case MISCREG_PIL:
+ case MISCREG_HPSTATE:
+ case MISCREG_HINTP:
+ case MISCREG_HTSTATE:
+ case MISCREG_STRAND_STS_REG:
+ case MISCREG_HSTICK_CMPR:
+ return readReg(miscReg) ;
+
+ case MISCREG_HTBA:
+ return readReg(miscReg) & ULL(~0x7FFF);
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
+
+ default:
+ panic("Invalid read to FS misc register\n");
}
}
/*