X86: Put in initial implementation of the local APIC.
--HG-- extra : convert_revision : 1708a93d96b819e64ed456c75dbb5325ac8114a8
This commit is contained in:
parent
98d2ca403e
commit
43ecce5fda
6 changed files with 416 additions and 9 deletions
|
@ -123,6 +123,84 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg)
|
||||||
|
|
||||||
MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
|
MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
|
||||||
{
|
{
|
||||||
|
if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) {
|
||||||
|
if (miscReg >= MISCREG_APIC_IN_SERVICE(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_IN_SERVICE(15)) {
|
||||||
|
panic("Local APIC In-Service registers are unimplemented.\n");
|
||||||
|
}
|
||||||
|
if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) {
|
||||||
|
panic("Local APIC Trigger Mode registers are unimplemented.\n");
|
||||||
|
}
|
||||||
|
if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) {
|
||||||
|
panic("Local APIC Interrupt Request registers "
|
||||||
|
"are unimplemented.\n");
|
||||||
|
}
|
||||||
|
switch (miscReg) {
|
||||||
|
case MISCREG_APIC_TASK_PRIORITY:
|
||||||
|
panic("Local APIC Task Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_ARBITRATION_PRIORITY:
|
||||||
|
panic("Local APIC Arbitration Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_PROCESSOR_PRIORITY:
|
||||||
|
panic("Local APIC Processor Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_EOI:
|
||||||
|
panic("Local APIC EOI register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LOGICAL_DESTINATION:
|
||||||
|
panic("Local APIC Logical Destination register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_DESTINATION_FORMAT:
|
||||||
|
panic("Local APIC Destination Format register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR:
|
||||||
|
panic("Local APIC Spurious Interrupt Vector"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_ERROR_STATUS:
|
||||||
|
panic("Local APIC Error Status register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INTERRUPT_COMMAND_LOW:
|
||||||
|
panic("Local APIC Interrupt Command low"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INTERRUPT_COMMAND_HIGH:
|
||||||
|
panic("Local APIC Interrupt Command high"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_TIMER:
|
||||||
|
panic("Local APIC LVT Timer register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_THERMAL_SENSOR:
|
||||||
|
panic("Local APIC LVT Thermal Sensor register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
|
||||||
|
panic("Local APIC LVT Performance Monitoring Counters"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_LINT0:
|
||||||
|
panic("Local APIC LVT LINT0 register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_LINT1:
|
||||||
|
panic("Local APIC LVT LINT1 register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_ERROR:
|
||||||
|
panic("Local APIC LVT Error register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INITIAL_COUNT:
|
||||||
|
panic("Local APIC Initial Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_CURRENT_COUNT:
|
||||||
|
panic("Local APIC Current Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_DIVIDE_COUNT:
|
||||||
|
panic("Local APIC Divide Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return readRegNoEffect(miscReg);
|
return readRegNoEffect(miscReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +221,92 @@ void MiscRegFile::setReg(int miscReg,
|
||||||
const MiscReg &val, ThreadContext * tc)
|
const MiscReg &val, ThreadContext * tc)
|
||||||
{
|
{
|
||||||
MiscReg newVal = val;
|
MiscReg newVal = val;
|
||||||
|
if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) {
|
||||||
|
if (miscReg >= MISCREG_APIC_IN_SERVICE(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_IN_SERVICE(15)) {
|
||||||
|
panic("Local APIC In-Service registers are unimplemented.\n");
|
||||||
|
}
|
||||||
|
if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) {
|
||||||
|
panic("Local APIC Trigger Mode registers are unimplemented.\n");
|
||||||
|
}
|
||||||
|
if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) &&
|
||||||
|
miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) {
|
||||||
|
panic("Local APIC Interrupt Request registers "
|
||||||
|
"are unimplemented.\n");
|
||||||
|
}
|
||||||
|
switch (miscReg) {
|
||||||
|
case MISCREG_APIC_ID:
|
||||||
|
panic("Local APIC ID register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_VERSION:
|
||||||
|
panic("Local APIC Version register is read only.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_TASK_PRIORITY:
|
||||||
|
panic("Local APIC Task Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_ARBITRATION_PRIORITY:
|
||||||
|
panic("Local APIC Arbitration Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_PROCESSOR_PRIORITY:
|
||||||
|
panic("Local APIC Processor Priority register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_EOI:
|
||||||
|
panic("Local APIC EOI register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LOGICAL_DESTINATION:
|
||||||
|
panic("Local APIC Logical Destination register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_DESTINATION_FORMAT:
|
||||||
|
panic("Local APIC Destination Format register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR:
|
||||||
|
panic("Local APIC Spurious Interrupt Vector"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_ERROR_STATUS:
|
||||||
|
panic("Local APIC Error Status register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INTERRUPT_COMMAND_LOW:
|
||||||
|
panic("Local APIC Interrupt Command low"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INTERRUPT_COMMAND_HIGH:
|
||||||
|
panic("Local APIC Interrupt Command high"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_TIMER:
|
||||||
|
panic("Local APIC LVT Timer register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_THERMAL_SENSOR:
|
||||||
|
panic("Local APIC LVT Thermal Sensor register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
|
||||||
|
panic("Local APIC LVT Performance Monitoring Counters"
|
||||||
|
" register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_LINT0:
|
||||||
|
panic("Local APIC LVT LINT0 register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_LINT1:
|
||||||
|
panic("Local APIC LVT LINT1 register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_LVT_ERROR:
|
||||||
|
panic("Local APIC LVT Error register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_INITIAL_COUNT:
|
||||||
|
panic("Local APIC Initial Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_CURRENT_COUNT:
|
||||||
|
panic("Local APIC Current Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
case MISCREG_APIC_DIVIDE_COUNT:
|
||||||
|
panic("Local APIC Divide Count register unimplemented.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setRegNoEffect(miscReg, newVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch(miscReg)
|
switch(miscReg)
|
||||||
{
|
{
|
||||||
case MISCREG_CR0:
|
case MISCREG_CR0:
|
||||||
|
|
|
@ -339,6 +339,41 @@ namespace X86ISA
|
||||||
|
|
||||||
//XXX Add "Model-Specific Registers"
|
//XXX Add "Model-Specific Registers"
|
||||||
|
|
||||||
|
MISCREG_APIC_BASE,
|
||||||
|
|
||||||
|
MISCREG_APIC_START,
|
||||||
|
MISCREG_APIC_ID = MISCREG_APIC_START,
|
||||||
|
MISCREG_APIC_VERSION,
|
||||||
|
MISCREG_APIC_TASK_PRIORITY,
|
||||||
|
MISCREG_APIC_ARBITRATION_PRIORITY,
|
||||||
|
MISCREG_APIC_PROCESSOR_PRIORITY,
|
||||||
|
MISCREG_APIC_EOI,
|
||||||
|
MISCREG_APIC_LOGICAL_DESTINATION,
|
||||||
|
MISCREG_APIC_DESTINATION_FORMAT,
|
||||||
|
MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR,
|
||||||
|
|
||||||
|
MISCREG_APIC_IN_SERVICE_BASE,
|
||||||
|
|
||||||
|
MISCREG_APIC_TRIGGER_MODE_BASE = MISCREG_APIC_IN_SERVICE_BASE + 16,
|
||||||
|
|
||||||
|
MISCREG_APIC_INTERRUPT_REQUEST_BASE =
|
||||||
|
MISCREG_APIC_TRIGGER_MODE_BASE + 16,
|
||||||
|
|
||||||
|
MISCREG_APIC_ERROR_STATUS = MISCREG_APIC_INTERRUPT_REQUEST_BASE + 16,
|
||||||
|
MISCREG_APIC_INTERRUPT_COMMAND_LOW,
|
||||||
|
MISCREG_APIC_INTERRUPT_COMMAND_HIGH,
|
||||||
|
MISCREG_APIC_LVT_TIMER,
|
||||||
|
MISCREG_APIC_LVT_THERMAL_SENSOR,
|
||||||
|
MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS,
|
||||||
|
MISCREG_APIC_LVT_LINT0,
|
||||||
|
MISCREG_APIC_LVT_LINT1,
|
||||||
|
MISCREG_APIC_LVT_ERROR,
|
||||||
|
MISCREG_APIC_INITIAL_COUNT,
|
||||||
|
MISCREG_APIC_CURRENT_COUNT,
|
||||||
|
MISCREG_APIC_DIVIDE_COUNT,
|
||||||
|
MISCREG_APIC_END = MISCREG_APIC_DIVIDE_COUNT,
|
||||||
|
|
||||||
|
// "Fake" MSRs for internally implemented devices
|
||||||
MISCREG_PCI_CONFIG_ADDRESS,
|
MISCREG_PCI_CONFIG_ADDRESS,
|
||||||
|
|
||||||
NUM_MISCREGS
|
NUM_MISCREGS
|
||||||
|
@ -446,6 +481,24 @@ namespace X86ISA
|
||||||
return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
|
return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline MiscRegIndex
|
||||||
|
MISCREG_APIC_IN_SERVICE(int index)
|
||||||
|
{
|
||||||
|
return (MiscRegIndex)(MISCREG_APIC_IN_SERVICE_BASE + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline MiscRegIndex
|
||||||
|
MISCREG_APIC_TRIGGER_MODE(int index)
|
||||||
|
{
|
||||||
|
return (MiscRegIndex)(MISCREG_APIC_TRIGGER_MODE_BASE + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline MiscRegIndex
|
||||||
|
MISCREG_APIC_INTERRUPT_REQUEST(int index)
|
||||||
|
{
|
||||||
|
return (MiscRegIndex)(MISCREG_APIC_INTERRUPT_REQUEST_BASE + index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type to describe the condition code bits of the RFLAGS register,
|
* A type to describe the condition code bits of the RFLAGS register,
|
||||||
* plus two flags, EZF and ECF, which are only visible to microcode.
|
* plus two flags, EZF and ECF, which are only visible to microcode.
|
||||||
|
@ -794,6 +847,16 @@ namespace X86ISA
|
||||||
*/
|
*/
|
||||||
BitUnion64(TR)
|
BitUnion64(TR)
|
||||||
EndBitUnion(TR)
|
EndBitUnion(TR)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local APIC Base Register
|
||||||
|
*/
|
||||||
|
BitUnion64(LocalApicBase)
|
||||||
|
Bitfield<51, 12> base;
|
||||||
|
Bitfield<11> enable;
|
||||||
|
Bitfield<8> bsp;
|
||||||
|
EndBitUnion(LocalApicBase)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_X86_INTREGS_HH__
|
#endif // __ARCH_X86_INTREGS_HH__
|
||||||
|
|
|
@ -78,7 +78,15 @@ namespace X86ISA
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
panic("Shouldn't have a memory mapped register in SE\n");
|
panic("Shouldn't have a memory mapped register in SE\n");
|
||||||
#else
|
#else
|
||||||
|
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
|
||||||
|
if (index == MISCREG_PCI_CONFIG_ADDRESS ||
|
||||||
|
(index >= MISCREG_APIC_START &&
|
||||||
|
index <= MISCREG_APIC_END)) {
|
||||||
|
pkt->set((uint32_t)(xc->readMiscReg(pkt->getAddr() /
|
||||||
|
sizeof(MiscReg))));
|
||||||
|
} else {
|
||||||
pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg)));
|
pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg)));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return xc->getCpuPtr()->ticks(1);
|
return xc->getCpuPtr()->ticks(1);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +98,9 @@ namespace X86ISA
|
||||||
panic("Shouldn't have a memory mapped register in SE\n");
|
panic("Shouldn't have a memory mapped register in SE\n");
|
||||||
#else
|
#else
|
||||||
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
|
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
|
||||||
if (index == MISCREG_PCI_CONFIG_ADDRESS) {
|
if (index == MISCREG_PCI_CONFIG_ADDRESS ||
|
||||||
|
(index >= MISCREG_APIC_START &&
|
||||||
|
index <= MISCREG_APIC_END)) {
|
||||||
xc->setMiscReg(index, gtoh(pkt->get<uint32_t>()));
|
xc->setMiscReg(index, gtoh(pkt->get<uint32_t>()));
|
||||||
} else {
|
} else {
|
||||||
xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg),
|
xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg),
|
||||||
|
|
|
@ -108,8 +108,8 @@ TLB::insert(Addr vpn, TlbEntry &entry)
|
||||||
entryList.push_front(newEntry);
|
entryList.push_front(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
TlbEntry *
|
TLB::EntryList::iterator
|
||||||
TLB::lookup(Addr va, bool update_lru)
|
TLB::lookupIt(Addr va, bool update_lru)
|
||||||
{
|
{
|
||||||
//TODO make this smarter at some point
|
//TODO make this smarter at some point
|
||||||
EntryList::iterator entry;
|
EntryList::iterator entry;
|
||||||
|
@ -117,15 +117,25 @@ TLB::lookup(Addr va, bool update_lru)
|
||||||
if ((*entry)->vaddr <= va && (*entry)->vaddr + (*entry)->size > va) {
|
if ((*entry)->vaddr <= va && (*entry)->vaddr + (*entry)->size > va) {
|
||||||
DPRINTF(TLB, "Matched vaddr %#x to entry starting at %#x "
|
DPRINTF(TLB, "Matched vaddr %#x to entry starting at %#x "
|
||||||
"with size %#x.\n", va, (*entry)->vaddr, (*entry)->size);
|
"with size %#x.\n", va, (*entry)->vaddr, (*entry)->size);
|
||||||
TlbEntry *e = *entry;
|
|
||||||
if (update_lru) {
|
if (update_lru) {
|
||||||
|
entryList.push_front(*entry);
|
||||||
entryList.erase(entry);
|
entryList.erase(entry);
|
||||||
entryList.push_front(e);
|
entry = entryList.begin();
|
||||||
}
|
}
|
||||||
return e;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlbEntry *
|
||||||
|
TLB::lookup(Addr va, bool update_lru)
|
||||||
|
{
|
||||||
|
EntryList::iterator entry = lookupIt(va, update_lru);
|
||||||
|
if (entry == entryList.end())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
else
|
||||||
|
return *entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
@ -206,6 +216,9 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
|
||||||
case 0x10:
|
case 0x10:
|
||||||
regNum = MISCREG_TSC;
|
regNum = MISCREG_TSC;
|
||||||
break;
|
break;
|
||||||
|
case 0x1B:
|
||||||
|
regNum = MISCREG_APIC_BASE;
|
||||||
|
break;
|
||||||
case 0xFE:
|
case 0xFE:
|
||||||
regNum = MISCREG_MTRRCAP;
|
regNum = MISCREG_MTRRCAP;
|
||||||
break;
|
break;
|
||||||
|
@ -578,6 +591,148 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
|
||||||
DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
|
DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
|
||||||
req->setPaddr(vaddr);
|
req->setPaddr(vaddr);
|
||||||
}
|
}
|
||||||
|
// Check for an access to the local APIC
|
||||||
|
LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE);
|
||||||
|
Addr baseAddr = localApicBase.base << 12;
|
||||||
|
Addr paddr = req->getPaddr();
|
||||||
|
if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) {
|
||||||
|
req->setMmapedIpr(true);
|
||||||
|
// Check alignment
|
||||||
|
if (paddr & ((32/8) - 1))
|
||||||
|
return new GeneralProtection(0);
|
||||||
|
// Check access size
|
||||||
|
if (req->getSize() != (32/8))
|
||||||
|
return new GeneralProtection(0);
|
||||||
|
MiscReg regNum;
|
||||||
|
switch (paddr - baseAddr)
|
||||||
|
{
|
||||||
|
case 0x20:
|
||||||
|
regNum = MISCREG_APIC_ID;
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
regNum = MISCREG_APIC_VERSION;
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
regNum = MISCREG_APIC_TASK_PRIORITY;
|
||||||
|
break;
|
||||||
|
case 0x90:
|
||||||
|
regNum = MISCREG_APIC_ARBITRATION_PRIORITY;
|
||||||
|
break;
|
||||||
|
case 0xA0:
|
||||||
|
regNum = MISCREG_APIC_PROCESSOR_PRIORITY;
|
||||||
|
break;
|
||||||
|
case 0xB0:
|
||||||
|
regNum = MISCREG_APIC_EOI;
|
||||||
|
break;
|
||||||
|
case 0xD0:
|
||||||
|
regNum = MISCREG_APIC_LOGICAL_DESTINATION;
|
||||||
|
break;
|
||||||
|
case 0xE0:
|
||||||
|
regNum = MISCREG_APIC_DESTINATION_FORMAT;
|
||||||
|
break;
|
||||||
|
case 0xF0:
|
||||||
|
regNum = MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR;
|
||||||
|
break;
|
||||||
|
case 0x100:
|
||||||
|
case 0x108:
|
||||||
|
case 0x110:
|
||||||
|
case 0x118:
|
||||||
|
case 0x120:
|
||||||
|
case 0x128:
|
||||||
|
case 0x130:
|
||||||
|
case 0x138:
|
||||||
|
case 0x140:
|
||||||
|
case 0x148:
|
||||||
|
case 0x150:
|
||||||
|
case 0x158:
|
||||||
|
case 0x160:
|
||||||
|
case 0x168:
|
||||||
|
case 0x170:
|
||||||
|
case 0x178:
|
||||||
|
regNum = MISCREG_APIC_IN_SERVICE(
|
||||||
|
(paddr - baseAddr - 0x100) / 0x8);
|
||||||
|
break;
|
||||||
|
case 0x180:
|
||||||
|
case 0x188:
|
||||||
|
case 0x190:
|
||||||
|
case 0x198:
|
||||||
|
case 0x1A0:
|
||||||
|
case 0x1A8:
|
||||||
|
case 0x1B0:
|
||||||
|
case 0x1B8:
|
||||||
|
case 0x1C0:
|
||||||
|
case 0x1C8:
|
||||||
|
case 0x1D0:
|
||||||
|
case 0x1D8:
|
||||||
|
case 0x1E0:
|
||||||
|
case 0x1E8:
|
||||||
|
case 0x1F0:
|
||||||
|
case 0x1F8:
|
||||||
|
regNum = MISCREG_APIC_TRIGGER_MODE(
|
||||||
|
(paddr - baseAddr - 0x180) / 0x8);
|
||||||
|
break;
|
||||||
|
case 0x200:
|
||||||
|
case 0x208:
|
||||||
|
case 0x210:
|
||||||
|
case 0x218:
|
||||||
|
case 0x220:
|
||||||
|
case 0x228:
|
||||||
|
case 0x230:
|
||||||
|
case 0x238:
|
||||||
|
case 0x240:
|
||||||
|
case 0x248:
|
||||||
|
case 0x250:
|
||||||
|
case 0x258:
|
||||||
|
case 0x260:
|
||||||
|
case 0x268:
|
||||||
|
case 0x270:
|
||||||
|
case 0x278:
|
||||||
|
regNum = MISCREG_APIC_INTERRUPT_REQUEST(
|
||||||
|
(paddr - baseAddr - 0x200) / 0x8);
|
||||||
|
break;
|
||||||
|
case 0x280:
|
||||||
|
regNum = MISCREG_APIC_ERROR_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x300:
|
||||||
|
regNum = MISCREG_APIC_INTERRUPT_COMMAND_LOW;
|
||||||
|
break;
|
||||||
|
case 0x310:
|
||||||
|
regNum = MISCREG_APIC_INTERRUPT_COMMAND_HIGH;
|
||||||
|
break;
|
||||||
|
case 0x320:
|
||||||
|
regNum = MISCREG_APIC_LVT_TIMER;
|
||||||
|
break;
|
||||||
|
case 0x330:
|
||||||
|
regNum = MISCREG_APIC_LVT_THERMAL_SENSOR;
|
||||||
|
break;
|
||||||
|
case 0x340:
|
||||||
|
regNum = MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS;
|
||||||
|
break;
|
||||||
|
case 0x350:
|
||||||
|
regNum = MISCREG_APIC_LVT_LINT0;
|
||||||
|
break;
|
||||||
|
case 0x360:
|
||||||
|
regNum = MISCREG_APIC_LVT_LINT1;
|
||||||
|
break;
|
||||||
|
case 0x370:
|
||||||
|
regNum = MISCREG_APIC_LVT_ERROR;
|
||||||
|
break;
|
||||||
|
case 0x380:
|
||||||
|
regNum = MISCREG_APIC_INITIAL_COUNT;
|
||||||
|
break;
|
||||||
|
case 0x390:
|
||||||
|
regNum = MISCREG_APIC_CURRENT_COUNT;
|
||||||
|
break;
|
||||||
|
case 0x3E0:
|
||||||
|
regNum = MISCREG_APIC_DIVIDE_COUNT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// A reserved register field.
|
||||||
|
return new GeneralProtection(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
req->setPaddr(regNum * sizeof(MiscReg));
|
||||||
|
}
|
||||||
return NoFault;
|
return NoFault;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,8 @@ namespace X86ISA
|
||||||
friend class FakeITLBFault;
|
friend class FakeITLBFault;
|
||||||
friend class FakeDTLBFault;
|
friend class FakeDTLBFault;
|
||||||
|
|
||||||
|
typedef std::list<TlbEntry *> EntryList;
|
||||||
|
|
||||||
bool _allowNX;
|
bool _allowNX;
|
||||||
uint32_t configAddress;
|
uint32_t configAddress;
|
||||||
|
|
||||||
|
@ -108,6 +110,10 @@ namespace X86ISA
|
||||||
|
|
||||||
void setConfigAddress(uint32_t addr);
|
void setConfigAddress(uint32_t addr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
EntryList::iterator lookupIt(Addr va, bool update_lru = true);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -128,7 +134,6 @@ namespace X86ISA
|
||||||
|
|
||||||
TlbEntry * tlb;
|
TlbEntry * tlb;
|
||||||
|
|
||||||
typedef std::list<TlbEntry *> EntryList;
|
|
||||||
EntryList freeList;
|
EntryList freeList;
|
||||||
EntryList entryList;
|
EntryList entryList;
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,16 @@ void initCPU(ThreadContext *tc, int cpuId)
|
||||||
// TODO Turn on the APIC. This should be handled elsewhere but it isn't
|
// TODO Turn on the APIC. This should be handled elsewhere but it isn't
|
||||||
// currently being handled at all.
|
// currently being handled at all.
|
||||||
|
|
||||||
|
LocalApicBase lApicBase = 0;
|
||||||
|
lApicBase.base = 0xFEE00000 >> 12;
|
||||||
|
lApicBase.enable = 1;
|
||||||
|
lApicBase.bsp = (cpuId == 0);
|
||||||
|
tc->setMiscReg(MISCREG_APIC_BASE, lApicBase);
|
||||||
|
|
||||||
|
tc->setMiscRegNoEffect(MISCREG_APIC_ID, cpuId << 24);
|
||||||
|
|
||||||
|
tc->setMiscRegNoEffect(MISCREG_APIC_VERSION, (5 << 16) | 0x14);
|
||||||
|
|
||||||
// TODO Set the SMRAM base address (SMBASE) to 0x00030000
|
// TODO Set the SMRAM base address (SMBASE) to 0x00030000
|
||||||
|
|
||||||
tc->setMiscReg(MISCREG_VM_CR, 0);
|
tc->setMiscReg(MISCREG_VM_CR, 0);
|
||||||
|
|
Loading…
Reference in a new issue