summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/SConscript1
-rw-r--r--src/arch/sparc/isa/decoder.isa42
-rw-r--r--src/arch/sparc/miscregfile.cc29
-rw-r--r--src/arch/sparc/miscregfile.hh4
-rw-r--r--src/arch/sparc/mmaped_ipr.hh9
-rw-r--r--src/arch/sparc/system.cc5
-rw-r--r--src/arch/sparc/tlb.cc30
-rw-r--r--src/arch/sparc/ua2005.cc178
8 files changed, 162 insertions, 136 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index a0a6112de..c2ef97bfa 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -60,6 +60,7 @@ full_system_sources = Split('''
stacktrace.cc
system.cc
tlb.cc
+ ua2005.cc
vtophys.cc
''')
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index a355816ac..781958c77 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -377,7 +377,9 @@ decode OP default Unknown::unknown()
//1 should cause an illegal instruction exception
0x02: NoPriv::rdccr({{Rd = Ccr;}});
0x03: NoPriv::rdasi({{Rd = Asi;}});
- 0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
+ 0x04: PrivCheck::rdtick(
+ {{ Rd = xc->readMiscRegWithEffect(MISCREG_TICK);}},
+ {{Tick<63:>}});
0x05: NoPriv::rdpc({{
if(Pstate<3:>)
Rd = (xc->readPC())<31:0>;
@@ -403,9 +405,15 @@ decode OP default Unknown::unknown()
}});
//0x14-0x15 should cause an illegal instruction exception
0x16: Priv::rdsoftint({{Rd = Softint;}});
- 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
- 0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}});
- 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
+ 0x17: Priv::rdtick_cmpr({{
+ Rd = xc->readMiscRegWithEffect(MISCREG_TICK_CMPR);
+ }});
+ 0x18: PrivCheck::rdstick({{
+ Rd = xc->readMiscRegWithEffect(MISCREG_STICK);
+ }}, {{Stick<63:>}});
+ 0x19: Priv::rdstick_cmpr({{
+ Rd = xc->readMiscRegWithEffect(MISCREG_STICK_CMPR);
+ }});
0x1A: Priv::rdstrand_sts_reg({{
if(Pstate<2:> && !Hpstate<2:>)
Rd = StrandStsReg<0:>;
@@ -429,7 +437,9 @@ decode OP default Unknown::unknown()
0x05: HPriv::rdhprhtba({{Rd = Htba;}});
0x06: HPriv::rdhprhver({{Rd = Hver;}});
//0x07-0x1E should cause an illegal instruction exception
- 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
+ 0x1F: HPriv::rdhprhstick_cmpr({{
+ Rd = xc->readMiscRegWithEffect(MISCREG_HSTICK_CMPR);
+ }});
}
0x2A: decode RS1 {
0x00: Priv::rdprtpc({{
@@ -452,7 +462,9 @@ decode OP default Unknown::unknown()
return new IllegalInstruction;
Rd = Tt;
}});
- 0x04: Priv::rdprtick({{Rd = Tick;}});
+ 0x04: Priv::rdprtick({{
+ Rd = xc->readMiscRegWithEffect(MISCREG_TICK);
+ }});
0x05: Priv::rdprtba({{Rd = Tba;}});
0x06: Priv::rdprpstate({{Rd = Pstate;}});
0x07: Priv::rdprtl({{Rd = Tl;}});
@@ -542,13 +554,17 @@ decode OP default Unknown::unknown()
0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}});
0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}});
0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
- 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
+ 0x17: Priv::wrtick_cmpr({{
+ xc->setMiscRegWithEffect(MISCREG_TICK_CMPR, Rs1 ^ Rs2_or_imm13);
+ }});
0x18: NoPriv::wrstick({{
if(!Hpstate<2:>)
return new IllegalInstruction;
- Stick = Rs1 ^ Rs2_or_imm13;
+ xc->setMiscRegWithEffect(MISCREG_STICK, Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x19: Priv::wrstick_cmpr({{
+ xc->setMiscRegWithEffect(MISCREG_STICK_CMPR, Rs1 ^ Rs2_or_imm13);
}});
- 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
0x1A: Priv::wrstrand_sts_reg({{
if(Pstate<2:> && !Hpstate<2:>)
StrandStsReg = StrandStsReg<63:1> |
@@ -605,7 +621,9 @@ decode OP default Unknown::unknown()
else
Tt = Rs1 ^ Rs2_or_imm13;
}});
- 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+ 0x04: HPriv::wrprtick({{
+ xc->setMiscRegWithEffect(MISCREG_TICK, Rs1 ^ Rs2_or_imm13);
+ }});
0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
0x07: Priv::wrprtl({{
@@ -642,7 +660,9 @@ decode OP default Unknown::unknown()
//0x04 should cause an illegal instruction exception
0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}});
//0x06-0x01D should cause an illegal instruction exception
- 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
+ 0x1F: HPriv::wrhprhstick_cmpr({{
+ xc->setMiscRegWithEffect(MISCREG_HSTICK_CMPR, Rs1 ^ Rs2_or_imm13);
+ }});
}
0x34: decode OPF{
format BasicOperate{
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index d2164155f..046d811e0 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -72,7 +72,7 @@ void MiscRegFile::clear()
y = 0;
ccr = 0;
asi = 0;
- tick = 0;
+ tick = ULL(1) << 63;
fprs = 0;
gsr = 0;
softint = 0;
@@ -282,10 +282,19 @@ MiscReg MiscRegFile::readReg(int miscReg)
MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
{
switch (miscReg) {
+ // tick and stick are aliased to each other in niagra
+ case MISCREG_STICK:
case MISCREG_TICK:
case MISCREG_PRIVTICK:
- return tc->getCpuPtr()->curCycle() - (tick & mask(63)) |
- (tick & ~(mask(63))) << 63;
+ // I'm not sure why legion ignores the lowest two bits, but we'll go
+ // with it
+ // change from curCycle() to instCount() until we're done with legion
+ DPRINTFN("Instruction Count when STICK read: %#X\n",
+ tc->getCpuPtr()->instCount());
+ uint64_t t1 = mbits(tc->getCpuPtr()->instCount() - (tick &
+ mask(63)),62,2);
+ uint64_t t2 = mbits(tick,63,63) ;
+ return t1 | t2;
case MISCREG_FPRS:
panic("FPU not implemented\n");
case MISCREG_PCR:
@@ -296,13 +305,13 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
panic("Floating Point not implemented\n");
//We'll include this only in FS so we don't need the SparcSystem type around
//in SE.
-#if FULL_SYSTEM
+/*#if FULL_SYSTEM
case MISCREG_STICK:
SparcSystem *sys;
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
-#endif
+#endif*/
case MISCREG_HVER:
return NWindows | MaxTL << 8 | MaxGL << 16;
}
@@ -518,8 +527,10 @@ void MiscRegFile::setRegWithEffect(int miscReg,
SparcSystem *sys;
#endif
switch (miscReg) {
+ case MISCREG_STICK:
case MISCREG_TICK:
- tick = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ // change from curCycle() to instCount() until we're done with legion
+ tick = tc->getCpuPtr()->instCount() - val & ~Bit64;
tick |= val & Bit64;
break;
case MISCREG_FPRS:
@@ -575,12 +586,14 @@ void MiscRegFile::setRegWithEffect(int miscReg,
//We'll include this only in FS so we don't need the SparcSystem type around
//in SE.
#if FULL_SYSTEM
- case MISCREG_STICK:
+ // @todo figure out how we're actualy going to do this. In niagra the
+ // registers are aliased to the same thing (see tick above)
+ /*case MISCREG_STICK:
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
stick |= val & Bit64;
- break;
+ break;*/
case MISCREG_STICK_CMPR:
if (sTickCompare == NULL)
sTickCompare = new STickCompareEvent(this, tc);
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index e7779d333..916c23028 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -213,6 +213,10 @@ namespace SparcISA
// 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
+ void setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext *tc);
+ MiscReg readFSRegWithEffect(int miscReg, ThreadContext * tc);
+
/** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */
void processTickCompare(ThreadContext *tc);
diff --git a/src/arch/sparc/mmaped_ipr.hh b/src/arch/sparc/mmaped_ipr.hh
index d87d127b0..b11c16754 100644
--- a/src/arch/sparc/mmaped_ipr.hh
+++ b/src/arch/sparc/mmaped_ipr.hh
@@ -37,6 +37,7 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
+#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "mem/packet.hh"
#include "arch/sparc/tlb.hh"
@@ -47,14 +48,22 @@ namespace SparcISA
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
+#if FULL_SYSTEM
return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
+#else
+ panic("Shouldn't have a memory mapped register in SE\n");
+#endif
}
inline Tick
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
+#if FULL_SYSTEM
return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
+#else
+ panic("Shouldn't have a memory mapped register in SE\n");
+#endif
}
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index 72c87f0ad..da83d86fc 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -155,6 +155,11 @@ SparcSystem::SparcSystem(Params *p)
if (!hypervisor->loadLocalSymbols(debugSymbolTable))
panic("could not load hypervisor symbols\n");
+ // Strip off the rom address so when the hypervisor is copied into memory we
+ // have symbols still
+ if (!hypervisor->loadLocalSymbols(debugSymbolTable, 0xFFFFFF))
+ panic("could not load hypervisor symbols\n");
+
if (!nvram->loadGlobalSymbols(debugSymbolTable))
panic("could not load reset symbols\n");
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 5fde4d36d..51f867612 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -29,10 +29,11 @@
*/
#include "arch/sparc/asi.hh"
-#include "arch/sparc/tlb.hh"
-#include "sim/builder.hh"
#include "arch/sparc/miscregfile.hh"
+#include "arch/sparc/tlb.hh"
+#include "base/trace.hh"
#include "cpu/thread_context.hh"
+#include "sim/builder.hh"
/* @todo remove some of the magic constants. -- ali
* */
@@ -72,6 +73,10 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
MapIter i;
TlbEntry *new_entry;
+
+ DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x, pid=%d cid=%d r=%d\n",
+ va, partition_id, context_id, (int)real);
+
int x = -1;
for (x = 0; x < size; x++) {
if (!tlb[x].valid || !tlb[x].used) {
@@ -104,6 +109,7 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
i->second->used = false;
usedEntries--;
}
+ DPRINTF(TLB, "TLB: Found conflicting entry, deleting it\n");
lookupTable.erase(i);
}
@@ -127,6 +133,8 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id)
TlbRange tr;
TlbEntry *t;
+ DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
+ va, partition_id, context_id, real);
// Assemble full address structure
tr.va = va;
tr.size = va + MachineBytes;
@@ -137,8 +145,10 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id)
// Try to find the entry
i = lookupTable.find(tr);
if (i == lookupTable.end()) {
+ DPRINTF(TLB, "TLB: No valid entry found\n");
return NULL;
}
+ DPRINTF(TLB, "TLB: Valid entry found\n");
// Mark the entries used bit and clear other used bits in needed
t = i->second;
@@ -279,6 +289,8 @@ void
ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
bool se, FaultTypes ft, int asi)
{
+ DPRINTF(TLB, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n",
+ (int)write, ct, ft, asi);
TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
}
@@ -286,6 +298,8 @@ void
DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
bool se, FaultTypes ft, int asi)
{
+ DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
+ a, (int)write, ct, ft, asi);
TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
}
@@ -308,6 +322,9 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
bool real = false;
TlbEntry *e;
+ DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n",
+ vaddr, req->getSize());
+
assert(req->getAsi() == ASI_IMPLICIT);
if (tl > 0) {
@@ -385,14 +402,17 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
bool implicit = false;
bool real = false;
Addr vaddr = req->getVaddr();
+ Addr size = req->getSize();
ContextType ct;
int context;
ASI asi;
TlbEntry *e;
-
asi = (ASI)req->getAsi();
+ DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
+ vaddr, size, asi);
+
if (asi == ASI_IMPLICIT)
implicit = true;
@@ -432,7 +452,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
// If the asi is unaligned trap
- if (AsiIsBlock(asi) && vaddr & 0x3f || vaddr & 0x7) {
+ if (vaddr & size-1) {
writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
return new MemAddressNotAligned;
}
@@ -478,6 +498,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (e == NULL || !e->valid) {
tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
vaddr & ~BytesInPageMask | context);
+ DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n");
if (real)
return new DataRealTranslationMiss;
else
@@ -516,6 +537,7 @@ handleScratchRegAccess:
return new DataAccessException;
}
handleMmuRegAccess:
+ DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
req->setMmapedIpr(true);
req->setPaddr(req->getVaddr());
return NoFault;
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index 6493ddfd5..32bc2a44b 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -28,27 +28,32 @@
* Authors: Ali Saidi
*/
-#include "arch/sparc/regfile.hh"
+#include "arch/sparc/miscregfile.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
-Fault
-SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
+using namespace SparcISA;
+
+void
+MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext *tc)
{
int64_t time;
- SparcSystem *sys;
+ int oldLevel, newLevel;
switch (miscReg) {
/* Full system only ASRs */
case MISCREG_SOFTINT:
- if (isNonPriv())
- return new PrivilegedOpcode;
// Check if we are going to interrupt because of something
- int oldLevel = InterruptLevel(softint);
- int newLevel = InterruptLevel(val);
+ 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;
- return NoFault;
+ panic("SOFTINT not implemented\n");
+ break;
case MISCREG_SOFTINT_CLR:
return setRegWithEffect(miscReg, ~val & softint, tc);
@@ -56,152 +61,100 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
return setRegWithEffect(miscReg, val | softint, tc);
case MISCREG_TICK_CMPR:
- if (isNonPriv())
- return new PrivilegedOpcode;
if (tickCompare == NULL)
tickCompare = new TickCompareEvent(this, tc);
setReg(miscReg, val);
- if (tick_cmprFields.int_dis && tickCompare.scheduled())
- tickCompare.deschedule();
- time = tick_cmprFields.tick_cmpr - tickFields.counter;
- if (!tick_cmprFields.int_dis && time > 0)
- tickCompare.schedule(time * tc->getCpuPtr()->cycles(1));
- return NoFault;
-
- case MISCREG_STICK:
- if (isNonPriv())
- return new PrivilegedOpcode;
- if (isPriv())
- return new PrivilegedAction;
- sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
- assert(sys != NULL);
- sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
- stickFields.npt = val & Bit64 ? 1 : 0;
- return NoFault;
+ 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 (isNonPriv())
- return new PrivilegedOpcode;
if (sTickCompare == NULL)
sTickCompare = new STickCompareEvent(this, tc);
- sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
- assert(sys != NULL);
setReg(miscReg, val);
- if (stick_cmprFields.int_dis && sTickCompare.scheduled())
- sTickCompare.deschedule();
- time = stick_cmprFields.tick_cmpr - sys->sysTick;
- if (!stick_cmprFields.int_dis && time > 0)
- sTickCompare.schedule(time * Clock::Int::ns);
- return NoFault;
-
- /* Fullsystem only Priv registers. */
+ 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:
- if (FULL_SYSTEM) {
- setReg(miscReg, val);
- //tc->getCpuPtr()->checkInterrupts;
- // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
- return NoFault;
- } else
- panic("PIL not implemented for syscall emulation\n");
-
- /* Hyper privileged registers */
- case MISCREG_HPSTATE:
- case MISCREG_HINTP:
setReg(miscReg, val);
- return NoFault;
- case MISCREG_HTSTATE:
- if (tl == 0)
- return new IllegalInstruction;
- setReg(miscReg, val);
- return NoFault;
+ //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));
- return NoFault;
+ break;
- case MISCREG_STRAND_STS_REG:
- setReg(miscReg, strandStatusReg);
- return NoFault;
case MISCREG_HSTICK_CMPR:
- if (isNonPriv())
- return new PrivilegedOpcode;
if (hSTickCompare == NULL)
hSTickCompare = new HSTickCompareEvent(this, tc);
- sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
- assert(sys != NULL);
setReg(miscReg, val);
- if (hstick_cmprFields.int_dis && hSTickCompare.scheduled())
- hSTickCompare.deschedule();
- int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick;
- if (!hstick_cmprFields.int_dis && time > 0)
- hSTickCompare.schedule(time * Clock::Int::ns);
- return NoFault;
+ 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:
- return new IllegalInstruction;
+ panic("Invalid write to FS misc register\n");
}
}
MiscReg
-MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
+MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
{
switch (miscReg) {
/* Privileged registers. */
case MISCREG_SOFTINT:
- if (isNonPriv()) {
- fault = new PrivilegedOpcode;
- return 0;
- }
- return readReg(miscReg);
case MISCREG_TICK_CMPR:
- if (isNonPriv()) {
- fault = new PrivilegedOpcode;
- return 0;
- }
- return readReg(miscReg);
- case MISCREG_STICK:
- SparcSystem *sys;
- if (stickFields.npt && !isNonPriv()) {
- fault = new PrivilegedAction;
- return 0;
- }
- sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
- assert(sys != NULL);
- return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63;
case MISCREG_STICK_CMPR:
- if (isNonPriv()) {
- fault = new PrivilegedOpcode;
- return 0;
- }
- return readReg(miscReg);
-
-
- /* Hyper privileged registers */
+ case MISCREG_PIL:
case MISCREG_HPSTATE:
case MISCREG_HINTP:
- return readReg(miscReg);
case MISCREG_HTSTATE:
- if (tl == 0) {
- fault = new IllegalInstruction;
- return 0;
- }
- return readReg(miscReg);
+ 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;
- case MISCREG_STRAND_STS_REG:
- return strandStatusReg;
- case MISCREG_HSTICK_CMPR:
- return hstick_cmpr;
default:
- fault = new IllegalInstruction;
- return 0;
+ panic("Invalid read to FS misc register\n");
}
}
+/*
+ In Niagra STICK==TICK so this isn't needed
+ case MISCREG_STICK:
+ SparcSystem *sys;
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
+*/
+
+
void
MiscRegFile::processTickCompare(ThreadContext *tc)
@@ -221,4 +174,3 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
panic("tick compare not implemented\n");
}
-}; // namespace SparcISA