This commit is contained in:
Nathan Binkert 2008-09-27 07:25:04 -07:00
parent 83f3bff643
commit 819023b8e2

View file

@ -37,140 +37,150 @@
#include "base/compiler.hh"
#include "cpu/thread_context.hh"
namespace AlphaISA
namespace AlphaISA {
class Interrupts
{
class Interrupts
private:
bool newInfoSet;
int newIpl;
int newSummary;
protected:
uint64_t interrupts[NumInterruptLevels];
uint64_t intstatus;
public:
Interrupts()
{
protected:
uint64_t interrupts[NumInterruptLevels];
uint64_t intstatus;
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
newInfoSet = false;
}
public:
Interrupts()
{
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
newInfoSet = false;
}
void
post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
void post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
if (index < 0 || index >= sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
interrupts[int_num] |= 1 << index;
intstatus |= (ULL(1) << int_num);
}
interrupts[int_num] |= 1 << index;
intstatus |= (ULL(1) << int_num);
}
void
clear(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
void clear(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
panic("int_num out of bounds\n");
if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
if (index < 0 || index >= sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
interrupts[int_num] &= ~(1 << index);
if (interrupts[int_num] == 0)
intstatus &= ~(ULL(1) << int_num);
}
interrupts[int_num] &= ~(1 << index);
if (interrupts[int_num] == 0)
intstatus &= ~(ULL(1) << int_num);
}
void
clear_all()
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
void clear_all()
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
}
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
}
void
serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
}
void serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
}
void
unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
}
void unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
}
bool
check_interrupts(ThreadContext *tc) const
{
return (intstatus != 0) && !(tc->readPC() & 0x3);
}
bool check_interrupts(ThreadContext * tc) const
{
return (intstatus != 0) && !(tc->readPC() & 0x3);
}
Fault
getInterrupt(ThreadContext *tc)
{
int ipl = 0;
int summary = 0;
Fault getInterrupt(ThreadContext * tc)
{
int ipl = 0;
int summary = 0;
if (tc->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
if (tc->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
if (tc->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
}
if (tc->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
}
}
}
uint64_t interrupts = intstatus;
if (interrupts) {
for (int i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = i;
summary |= (ULL(1) << i);
}
uint64_t interrupts = intstatus;
if (interrupts) {
for (int i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = i;
summary |= (ULL(1) << i);
}
}
if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
newIpl = ipl;
newSummary = summary;
newInfoSet = true;
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
return new InterruptFault;
} else {
return NoFault;
}
}
void updateIntrInfo(ThreadContext *tc)
{
assert(newInfoSet);
tc->setMiscRegNoEffect(IPR_ISR, newSummary);
tc->setMiscRegNoEffect(IPR_INTID, newIpl);
newInfoSet = false;
if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
newIpl = ipl;
newSummary = summary;
newInfoSet = true;
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
return new InterruptFault;
} else {
return NoFault;
}
}
uint64_t get_vec(int int_num)
{
panic("Shouldn't be called for Alpha\n");
M5_DUMMY_RETURN
}
void
updateIntrInfo(ThreadContext *tc)
{
assert(newInfoSet);
tc->setMiscRegNoEffect(IPR_ISR, newSummary);
tc->setMiscRegNoEffect(IPR_INTID, newIpl);
newInfoSet = false;
}
private:
bool newInfoSet;
int newIpl;
int newSummary;
};
}
uint64_t
get_vec(int int_num)
{
panic("Shouldn't be called for Alpha\n");
M5_DUMMY_RETURN;
}
};
#endif
} // namespace AlphaISA
#endif // __ARCH_ALPHA_INTERRUPT_HH__