summaryrefslogtreecommitdiff
path: root/src/arch/x86/interrupts.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-19 02:43:22 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-19 02:43:22 -0700
commit641513fe08f21d38b5aaf92638657ed3e2d37962 (patch)
treeb20b2e8647057389de26f8b2e09fd043c1c46950 /src/arch/x86/interrupts.cc
parent9549694ecd1cc80e2b690631ea58d14778d368af (diff)
downloadgem5-641513fe08f21d38b5aaf92638657ed3e2d37962.tar.xz
X86: Start implementing the interrupt command register in the local APIC.
Diffstat (limited to 'src/arch/x86/interrupts.cc')
-rw-r--r--src/arch/x86/interrupts.cc49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index 0603069a7..7043840d2 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -60,6 +60,7 @@
#include "arch/x86/intmessage.hh"
#include "cpu/base.hh"
#include "mem/packet_access.hh"
+#include "sim/system.hh"
int
divideFromConf(uint32_t conf)
@@ -366,14 +367,6 @@ X86ISA::Interrupts::readReg(ApicRegIndex reg)
case APIC_ERROR_STATUS:
regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
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:
{
if (apicTimerEvent.scheduled()) {
@@ -459,12 +452,40 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
}
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");
+ {
+ InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
+ // Check if we're already sending an IPI.
+ if (low.deliveryStatus) {
+ newVal = low;
+ break;
+ }
+ low = val;
+ 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;
case APIC_LVT_TIMER:
case APIC_LVT_THERMAL_SENSOR: