- 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:
parent
ff7f41541f
commit
97e1f39d8f
@ -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.
|
||||
@ -645,7 +645,7 @@ void bx_local_apic_c::receive_EOI(Bit32u value)
|
||||
BX_DEBUG(("%s: Wrote 0x%x to EOI", cpu->name, value));
|
||||
int vec = highest_priority_int (isr);
|
||||
if (vec < 0) {
|
||||
BX_INFO(("EOI written without any bit in ISR"));
|
||||
BX_DEBUG(("EOI written without any bit in ISR"));
|
||||
} else {
|
||||
if (vec != (int) spurious_vector) {
|
||||
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;
|
||||
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));
|
||||
return;
|
||||
}
|
||||
|
@ -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>
|
||||
@ -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;
|
||||
|
||||
if (from == BX_IOAPIC_INT_FROM_ISA) {
|
||||
if ((num == 0) || (num == 2) || (num == 13)) return;
|
||||
}
|
||||
vector = num;
|
||||
BX_DEBUG(("IOAPIC: received vector %d", vector));
|
||||
if (vector <= BX_APIC_LAST_VECTOR) {
|
||||
Bit32u bit = 1<<vector;
|
||||
if ((irr & bit) == 0) {
|
||||
irr |= bit;
|
||||
service_ioapic ();
|
||||
BX_DEBUG(("set_irq_level(): INTIN%d: level=%d", int_in, level));
|
||||
if (int_in < BX_IOAPIC_NUM_PINS) {
|
||||
Bit32u bit = 1<<int_in;
|
||||
bx_io_redirect_entry_t *entry = ioredtbl + int_in;
|
||||
entry->parse_value();
|
||||
if (entry->trig_mode) {
|
||||
// level triggered
|
||||
if (level) {
|
||||
irr |= bit;
|
||||
service_ioapic ();
|
||||
} else {
|
||||
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.
|
||||
BX_DEBUG(("IOAPIC: servicing"));
|
||||
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;
|
||||
entry->parse_value();
|
||||
if (! entry->masked) {
|
||||
// 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 (done) {
|
||||
irr &= ~(1<<bit);
|
||||
entry->delivery_status = 0;
|
||||
stuck = 0;
|
||||
} else {
|
||||
entry->delivery_status = 1;
|
||||
stuck++;
|
||||
if (stuck > 5)
|
||||
BX_INFO(("vector %#x stuck?\n", entry->vector));
|
||||
}
|
||||
// clear irr bit and deliver
|
||||
if (entry->delivery_mode == 7) {
|
||||
BX_PANIC(("ExtINT not implemented yet"));
|
||||
}
|
||||
bx_bool done = deliver (entry->dest, entry->dest_mode, entry->delivery_mode, entry->vector, entry->polarity, entry->trig_mode);
|
||||
if (done) {
|
||||
if (! entry->trig_mode)
|
||||
irr &= ~mask;
|
||||
entry->delivery_status = 0;
|
||||
stuck = 0;
|
||||
} else {
|
||||
entry->delivery_status = 1;
|
||||
stuck++;
|
||||
if (stuck > 5)
|
||||
BX_INFO(("vector %#x stuck?\n", entry->vector));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
#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)
|
||||
#define BX_IOAPIC_VERSION_ID (((BX_IOAPIC_NUM_PINS - 1) << 16) | 0x11)
|
||||
@ -56,8 +51,7 @@ public:
|
||||
virtual void reset (unsigned type);
|
||||
virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
|
||||
virtual void write(Bit32u address, Bit32u *value, unsigned len);
|
||||
void raise_irq(unsigned num, unsigned from);
|
||||
void lower_irq(unsigned num, unsigned from);
|
||||
void set_irq_level(Bit8u int_in, bx_bool level);
|
||||
void service_ioapic ();
|
||||
virtual bx_apic_type_t get_type () { return APIC_TYPE_IOAPIC; }
|
||||
};
|
||||
|
@ -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.
|
||||
@ -618,8 +618,8 @@ bx_pic_c::lower_irq(unsigned irq_no)
|
||||
{
|
||||
#if BX_SUPPORT_APIC
|
||||
// forward this function call to the ioapic too
|
||||
if (DEV_ioapic_present()) {
|
||||
bx_devices.ioapic->lower_irq(irq_no, BX_IOAPIC_INT_FROM_ISA);
|
||||
if (DEV_ioapic_present() && (irq_no != 0) && (irq_no != 2)) {
|
||||
bx_devices.ioapic->set_irq_level(irq_no, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -648,8 +648,8 @@ bx_pic_c::raise_irq(unsigned irq_no)
|
||||
{
|
||||
#if BX_SUPPORT_APIC
|
||||
// forward this function call to the ioapic too
|
||||
if (DEV_ioapic_present()) {
|
||||
bx_devices.ioapic->raise_irq(irq_no, BX_IOAPIC_INT_FROM_ISA);
|
||||
if (DEV_ioapic_present() && (irq_no != 0) && (irq_no != 2)) {
|
||||
bx_devices.ioapic->set_irq_level(irq_no, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user