- I/O APIC signal handling rewritten ("backported" from qemu)

- don't flood the logfile if APIC EOI has no effect
- fixed a warning in the APIC code
- TODO: fix IRQ 0 handling, implement ExtINT
This commit is contained in:
Volker Ruppert 2006-01-01 11:33:06 +00:00
parent ff7f41541f
commit 97e1f39d8f
4 changed files with 49 additions and 64 deletions

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: apic.cc,v 1.70 2005-12-26 19:42:09 sshwarts Exp $ // $Id: apic.cc,v 1.71 2006-01-01 11:33:06 vruppert Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -645,7 +645,7 @@ void bx_local_apic_c::receive_EOI(Bit32u value)
BX_DEBUG(("%s: Wrote 0x%x to EOI", cpu->name, value)); BX_DEBUG(("%s: Wrote 0x%x to EOI", cpu->name, value));
int vec = highest_priority_int (isr); int vec = highest_priority_int (isr);
if (vec < 0) { if (vec < 0) {
BX_INFO(("EOI written without any bit in ISR")); BX_DEBUG(("EOI written without any bit in ISR"));
} else { } else {
if (vec != (int) spurious_vector) { if (vec != (int) spurious_vector) {
BX_DEBUG(("%s: local apic received EOI, hopefully for vector 0x%02x", cpu->name, vec)); BX_DEBUG(("%s: local apic received EOI, hopefully for vector 0x%02x", cpu->name, vec));
@ -818,7 +818,7 @@ void bx_local_apic_c::service_local_apic(void)
// shadow_error_status |= APIC_ERR_TX_ACCEPT_ERR; // shadow_error_status |= APIC_ERR_TX_ACCEPT_ERR;
return; return;
} }
if ((first_irr & 0xf0) <= (task_priority & 0xf0)) { if ((first_irr & 0xf0) <= (int)(task_priority & 0xf0)) {
BX_DEBUG(("local apic (%s): not delivering int%02X because task_priority is %X", cpu->name, first_irr, task_priority)); BX_DEBUG(("local apic (%s): not delivering int%02X because task_priority is %X", cpu->name, first_irr, task_priority));
return; return;
} }

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: ioapic.cc,v 1.21 2005-12-31 14:46:21 vruppert Exp $ // $Id: ioapic.cc,v 1.22 2006-01-01 11:33:06 vruppert Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
#include <stdio.h> #include <stdio.h>
@ -133,42 +133,28 @@ void bx_ioapic_c::write(Bit32u address, Bit32u *value, unsigned len)
} }
} }
void bx_ioapic_c::raise_irq(unsigned num, unsigned from) void bx_ioapic_c::set_irq_level(Bit8u int_in, bx_bool level)
{ {
unsigned vector; BX_DEBUG(("set_irq_level(): INTIN%d: level=%d", int_in, level));
if (int_in < BX_IOAPIC_NUM_PINS) {
if (from == BX_IOAPIC_INT_FROM_ISA) { Bit32u bit = 1<<int_in;
if ((num == 0) || (num == 2) || (num == 13)) return; bx_io_redirect_entry_t *entry = ioredtbl + int_in;
} entry->parse_value();
vector = num; if (entry->trig_mode) {
BX_DEBUG(("IOAPIC: received vector %d", vector)); // level triggered
if (vector <= BX_APIC_LAST_VECTOR) { if (level) {
Bit32u bit = 1<<vector; irr |= bit;
if ((irr & bit) == 0) { service_ioapic ();
irr |= bit; } else {
service_ioapic (); irr &= ~bit;
}
} else {
// edge triggered
if (level) {
irr |= bit;
service_ioapic ();
}
} }
} else {
BX_PANIC(("IOAPIC: vector %d out of range", vector));
}
}
void bx_ioapic_c::lower_irq (unsigned num, unsigned from)
{
unsigned vector;
if (from == BX_IOAPIC_INT_FROM_ISA) {
if ((num == 0) || (num == 2) || (num == 13)) return;
}
BX_DEBUG(("IOAPIC: interrupt %d went away", num));
vector = num;
if (vector <= BX_APIC_LAST_VECTOR) {
Bit32u bit = 1<<vector;
if ((irr & bit) != 0) {
irr &= ~bit;
}
} else {
BX_PANIC(("IOAPIC: vector %d out of range", vector));
} }
} }
@ -178,22 +164,27 @@ void bx_ioapic_c::service_ioapic ()
// look in IRR and deliver any interrupts that are not masked. // look in IRR and deliver any interrupts that are not masked.
BX_DEBUG(("IOAPIC: servicing")); BX_DEBUG(("IOAPIC: servicing"));
for (unsigned bit=0; bit < BX_IOAPIC_NUM_PINS; bit++) { for (unsigned bit=0; bit < BX_IOAPIC_NUM_PINS; bit++) {
if (irr & (1<<bit)) { Bit32u mask = 1<<bit;
if (irr & mask) {
bx_io_redirect_entry_t *entry = ioredtbl + bit; bx_io_redirect_entry_t *entry = ioredtbl + bit;
entry->parse_value(); entry->parse_value();
if (! entry->masked) { if (! entry->masked) {
// clear irr bit and deliver // clear irr bit and deliver
bx_bool done = deliver (entry->dest, entry->dest_mode, entry->delivery_mode, entry->vector, entry->polarity, entry->trig_mode); if (entry->delivery_mode == 7) {
if (done) { BX_PANIC(("ExtINT not implemented yet"));
irr &= ~(1<<bit); }
entry->delivery_status = 0; bx_bool done = deliver (entry->dest, entry->dest_mode, entry->delivery_mode, entry->vector, entry->polarity, entry->trig_mode);
stuck = 0; if (done) {
} else { if (! entry->trig_mode)
entry->delivery_status = 1; irr &= ~mask;
stuck++; entry->delivery_status = 0;
if (stuck > 5) stuck = 0;
BX_INFO(("vector %#x stuck?\n", entry->vector)); } else {
} entry->delivery_status = 1;
stuck++;
if (stuck > 5)
BX_INFO(("vector %#x stuck?\n", entry->vector));
}
} }
} }
} }

View File

@ -1,15 +1,10 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: ioapic.h,v 1.12 2005-12-31 14:46:21 vruppert Exp $ // $Id: ioapic.h,v 1.13 2006-01-01 11:33:06 vruppert Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
extern class bx_ioapic_c bx_ioapic; extern class bx_ioapic_c bx_ioapic;
#define BX_IOAPIC_NUM_PINS (0x18) #define BX_IOAPIC_NUM_PINS (0x18)
#define BX_IOAPIC_INT_FROM_ISA 0
#define BX_IOAPIC_INT_FROM_PIC 1
#define BX_IOAPIC_INT_FROM_PCI 2
#define BX_IOAPIC_INT_FROM_MB 3
#define BX_IOAPIC_INT_FROM_SMI 4
// use the same version as 82093 IOAPIC (0x00170011) // use the same version as 82093 IOAPIC (0x00170011)
#define BX_IOAPIC_VERSION_ID (((BX_IOAPIC_NUM_PINS - 1) << 16) | 0x11) #define BX_IOAPIC_VERSION_ID (((BX_IOAPIC_NUM_PINS - 1) << 16) | 0x11)
@ -56,8 +51,7 @@ public:
virtual void reset (unsigned type); virtual void reset (unsigned type);
virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len); virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
virtual void write(Bit32u address, Bit32u *value, unsigned len); virtual void write(Bit32u address, Bit32u *value, unsigned len);
void raise_irq(unsigned num, unsigned from); void set_irq_level(Bit8u int_in, bx_bool level);
void lower_irq(unsigned num, unsigned from);
void service_ioapic (); void service_ioapic ();
virtual bx_apic_type_t get_type () { return APIC_TYPE_IOAPIC; } virtual bx_apic_type_t get_type () { return APIC_TYPE_IOAPIC; }
}; };

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: pic.cc,v 1.37 2005-12-31 14:46:21 vruppert Exp $ // $Id: pic.cc,v 1.38 2006-01-01 11:33:06 vruppert Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2002 MandrakeSoft S.A. // Copyright (C) 2002 MandrakeSoft S.A.
@ -618,8 +618,8 @@ bx_pic_c::lower_irq(unsigned irq_no)
{ {
#if BX_SUPPORT_APIC #if BX_SUPPORT_APIC
// forward this function call to the ioapic too // forward this function call to the ioapic too
if (DEV_ioapic_present()) { if (DEV_ioapic_present() && (irq_no != 0) && (irq_no != 2)) {
bx_devices.ioapic->lower_irq(irq_no, BX_IOAPIC_INT_FROM_ISA); bx_devices.ioapic->set_irq_level(irq_no, 0);
} }
#endif #endif
@ -648,8 +648,8 @@ bx_pic_c::raise_irq(unsigned irq_no)
{ {
#if BX_SUPPORT_APIC #if BX_SUPPORT_APIC
// forward this function call to the ioapic too // forward this function call to the ioapic too
if (DEV_ioapic_present()) { if (DEV_ioapic_present() && (irq_no != 0) && (irq_no != 2)) {
bx_devices.ioapic->raise_irq(irq_no, BX_IOAPIC_INT_FROM_ISA); bx_devices.ioapic->set_irq_level(irq_no, 1);
} }
#endif #endif