X86: Start implementing the interrupt command register in the local APIC.
This commit is contained in:
parent
9549694ecd
commit
641513fe08
3 changed files with 52 additions and 14 deletions
|
@ -31,6 +31,8 @@
|
||||||
#ifndef __ARCH_X86_APICREGS_HH__
|
#ifndef __ARCH_X86_APICREGS_HH__
|
||||||
#define __ARCH_X86_APICREGS_HH__
|
#define __ARCH_X86_APICREGS_HH__
|
||||||
|
|
||||||
|
#include "base/bitunion.hh"
|
||||||
|
|
||||||
namespace X86ISA
|
namespace X86ISA
|
||||||
{
|
{
|
||||||
enum ApicRegIndex
|
enum ApicRegIndex
|
||||||
|
@ -86,6 +88,20 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
return (ApicRegIndex)(APIC_INTERRUPT_REQUEST_BASE + index);
|
return (ApicRegIndex)(APIC_INTERRUPT_REQUEST_BASE + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BitUnion32(InterruptCommandRegLow)
|
||||||
|
Bitfield<7, 0> vector;
|
||||||
|
Bitfield<10, 8> deliveryMode;
|
||||||
|
Bitfield<11> destMode;
|
||||||
|
Bitfield<12> deliveryStatus;
|
||||||
|
Bitfield<14> level;
|
||||||
|
Bitfield<15> trigger;
|
||||||
|
Bitfield<19, 18> destShorthand;
|
||||||
|
EndBitUnion(InterruptCommandRegLow)
|
||||||
|
|
||||||
|
BitUnion32(InterruptCommandRegHigh)
|
||||||
|
Bitfield<31, 24> destination;
|
||||||
|
EndBitUnion(InterruptCommandRegHigh)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "arch/x86/intmessage.hh"
|
#include "arch/x86/intmessage.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
int
|
int
|
||||||
divideFromConf(uint32_t conf)
|
divideFromConf(uint32_t conf)
|
||||||
|
@ -366,14 +367,6 @@ X86ISA::Interrupts::readReg(ApicRegIndex reg)
|
||||||
case APIC_ERROR_STATUS:
|
case APIC_ERROR_STATUS:
|
||||||
regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
|
regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
|
||||||
break;
|
break;
|
||||||
case APIC_INTERRUPT_COMMAND_LOW:
|
|
||||||
panic("Local APIC Interrupt Command low"
|
|
||||||
" register unimplemented.\n");
|
|
||||||
break;
|
|
||||||
case APIC_INTERRUPT_COMMAND_HIGH:
|
|
||||||
panic("Local APIC Interrupt Command high"
|
|
||||||
" register unimplemented.\n");
|
|
||||||
break;
|
|
||||||
case APIC_CURRENT_COUNT:
|
case APIC_CURRENT_COUNT:
|
||||||
{
|
{
|
||||||
if (apicTimerEvent.scheduled()) {
|
if (apicTimerEvent.scheduled()) {
|
||||||
|
@ -459,12 +452,40 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case APIC_INTERRUPT_COMMAND_LOW:
|
case APIC_INTERRUPT_COMMAND_LOW:
|
||||||
panic("Local APIC Interrupt Command low"
|
{
|
||||||
" register unimplemented.\n");
|
InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
|
||||||
|
// Check if we're already sending an IPI.
|
||||||
|
if (low.deliveryStatus) {
|
||||||
|
newVal = low;
|
||||||
break;
|
break;
|
||||||
case APIC_INTERRUPT_COMMAND_HIGH:
|
}
|
||||||
panic("Local APIC Interrupt Command high"
|
low = val;
|
||||||
" register unimplemented.\n");
|
InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
|
||||||
|
// Record that an IPI is being sent.
|
||||||
|
low.deliveryStatus = 1;
|
||||||
|
TriggerIntMessage message;
|
||||||
|
message.destination = high.destination;
|
||||||
|
message.vector = low.vector;
|
||||||
|
message.deliveryMode = low.deliveryMode;
|
||||||
|
message.destMode = low.destMode;
|
||||||
|
message.level = low.level;
|
||||||
|
message.trigger = low.trigger;
|
||||||
|
bool timing = sys->getMemoryMode() == Enums::timing;
|
||||||
|
switch (low.destShorthand) {
|
||||||
|
case 0:
|
||||||
|
intPort->sendMessage(message, timing);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
panic("Self IPIs aren't implemented.\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
panic("Broadcast including self IPIs aren't implemented.\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
panic("Broadcast excluding self IPIs aren't implemented.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case APIC_LVT_TIMER:
|
case APIC_LVT_TIMER:
|
||||||
case APIC_LVT_THERMAL_SENSOR:
|
case APIC_LVT_THERMAL_SENSOR:
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "arch/x86/x86_traits.hh"
|
#include "arch/x86/x86_traits.hh"
|
||||||
#include "base/bitunion.hh"
|
#include "base/bitunion.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
#include "mem/packet_access.hh"
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue