- 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.
|
// 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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user