mostly implemented SOFTINT relevant interrupt stuff.
src/arch/sparc/interrupts.hh: add in thread_context.hh to get access to tc. get rid of stubs that don't make sense right now. implement checking and get softint interrupts src/arch/sparc/miscregfile.cc: softint should be OR-ed on a write. src/arch/sparc/miscregfile.hh: add some enums for state fields for easy access to bitmasks of HPSTATE and PSTATE regs. src/arch/sparc/ua2005.cc: implement writing SOFTINT, PSTATE, PIL, and HPSTATE properly, add helpful info to panic for bad reg write. --HG-- extra : convert_revision : d12d1147b508121075ee9be4599693554d4b9eae
This commit is contained in:
parent
03be92f23b
commit
da6c1f5b09
4 changed files with 60 additions and 28 deletions
|
@ -32,51 +32,62 @@
|
||||||
#define __ARCH_SPARC_INTERRUPT_HH__
|
#define __ARCH_SPARC_INTERRUPT_HH__
|
||||||
|
|
||||||
#include "arch/sparc/faults.hh"
|
#include "arch/sparc/faults.hh"
|
||||||
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
class Interrupts
|
class Interrupts
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Fault interrupts[NumInterruptLevels];
|
|
||||||
bool requested[NumInterruptLevels];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Interrupts()
|
Interrupts()
|
||||||
{
|
{
|
||||||
for(int x = 0; x < NumInterruptLevels; x++)
|
|
||||||
{
|
|
||||||
interrupts[x] = new InterruptLevelN(x);
|
|
||||||
requested[x] = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void post(int int_num, int index)
|
void post(int int_num, int index)
|
||||||
{
|
{
|
||||||
if(int_num < 0 || int_num >= NumInterruptLevels)
|
|
||||||
panic("int_num out of bounds\n");
|
|
||||||
|
|
||||||
requested[int_num] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(int int_num, int index)
|
void clear(int int_num, int index)
|
||||||
{
|
{
|
||||||
requested[int_num] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_all()
|
void clear_all()
|
||||||
{
|
{
|
||||||
for(int x = 0; x < NumInterruptLevels; x++)
|
|
||||||
requested[x] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_interrupts(ThreadContext * tc) const
|
bool check_interrupts(ThreadContext * tc) const
|
||||||
{
|
{
|
||||||
|
// so far only handle softint interrupts
|
||||||
|
int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
|
||||||
|
if (int_level)
|
||||||
return true;
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault getInterrupt(ThreadContext * tc)
|
Fault getInterrupt(ThreadContext * tc)
|
||||||
{
|
{
|
||||||
|
// conditioning the softint interrups
|
||||||
|
if (tc->readMiscReg(MISCREG_HPSTATE) & hpriv) {
|
||||||
|
// if running in privileged mode, then pend the interrupt
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
} else {
|
||||||
|
int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
|
||||||
|
if ((int_level <= tc->readMiscReg(MISCREG_PIL)) ||
|
||||||
|
!(tc->readMiscReg(MISCREG_PSTATE) & ie)) {
|
||||||
|
// if PIL or no interrupt enabled, then pend the interrupt
|
||||||
|
return NoFault;
|
||||||
|
} else {
|
||||||
|
return new InterruptLevelN(int_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateIntrInfo(ThreadContext * tc)
|
void updateIntrInfo(ThreadContext * tc)
|
||||||
|
|
|
@ -369,7 +369,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
|
||||||
gsr = val;
|
gsr = val;
|
||||||
break;
|
break;
|
||||||
case MISCREG_SOFTINT:
|
case MISCREG_SOFTINT:
|
||||||
softint = val;
|
softint |= val;
|
||||||
break;
|
break;
|
||||||
case MISCREG_TICK_CMPR:
|
case MISCREG_TICK_CMPR:
|
||||||
tick_cmpr = val;
|
tick_cmpr = val;
|
||||||
|
|
|
@ -140,6 +140,24 @@ namespace SparcISA
|
||||||
MISCREG_NUMMISCREGS
|
MISCREG_NUMMISCREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum HPStateFields {
|
||||||
|
id = 0x800, // this impl. dependent (id) field must always be '1' for T1000
|
||||||
|
ibe = 0x400,
|
||||||
|
red = 0x20,
|
||||||
|
hpriv = 0x4,
|
||||||
|
tlz = 0x1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PStateFields {
|
||||||
|
cle = 0x200,
|
||||||
|
tle = 0x100,
|
||||||
|
mm = 0xC0,
|
||||||
|
pef = 0x10,
|
||||||
|
am = 0x8,
|
||||||
|
priv = 0x4,
|
||||||
|
ie = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
||||||
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
||||||
|
|
||||||
|
|
|
@ -41,18 +41,12 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
int64_t time;
|
int64_t time;
|
||||||
int oldLevel, newLevel;
|
|
||||||
switch (miscReg) {
|
switch (miscReg) {
|
||||||
/* Full system only ASRs */
|
/* Full system only ASRs */
|
||||||
case MISCREG_SOFTINT:
|
case MISCREG_SOFTINT:
|
||||||
// Check if we are going to interrupt because of something
|
// Check if we are going to interrupt because of something
|
||||||
oldLevel = InterruptLevel(softint);
|
|
||||||
newLevel = InterruptLevel(val);
|
|
||||||
setReg(miscReg, val);
|
setReg(miscReg, val);
|
||||||
if (newLevel > oldLevel)
|
tc->getCpuPtr()->checkInterrupts = true;
|
||||||
; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
|
|
||||||
//tc->getCpuPtr()->checkInterrupts = true;
|
|
||||||
panic("SOFTINT not implemented\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MISCREG_SOFTINT_CLR:
|
case MISCREG_SOFTINT_CLR:
|
||||||
|
@ -82,11 +76,17 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
|
||||||
sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
|
sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MISCREG_PIL:
|
case MISCREG_PSTATE:
|
||||||
|
if (val & ie && !(pstate & ie)) {
|
||||||
|
tc->getCpuPtr()->checkInterrupts = true;
|
||||||
|
}
|
||||||
|
setReg(miscReg, val);
|
||||||
|
|
||||||
|
case MISCREG_PIL:
|
||||||
|
if (val < pil) {
|
||||||
|
tc->getCpuPtr()->checkInterrupts = true;
|
||||||
|
}
|
||||||
setReg(miscReg, val);
|
setReg(miscReg, val);
|
||||||
//tc->getCpuPtr()->checkInterrupts;
|
|
||||||
// MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
|
|
||||||
panic("PIL not implemented\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MISCREG_HVER:
|
case MISCREG_HVER:
|
||||||
|
@ -109,13 +109,16 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MISCREG_HPSTATE:
|
case MISCREG_HPSTATE:
|
||||||
|
// T1000 spec says impl. dependent val must always be 1
|
||||||
|
setReg(miscReg, val | id);
|
||||||
|
|
||||||
case MISCREG_HTSTATE:
|
case MISCREG_HTSTATE:
|
||||||
case MISCREG_STRAND_STS_REG:
|
case MISCREG_STRAND_STS_REG:
|
||||||
setReg(miscReg, val);
|
setReg(miscReg, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("Invalid write to FS misc register\n");
|
panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue