Add two workarounds for broken MP tables:
- Attempt to handle PCI devices where the interrupt is an ISA/EISA interrupt according to the mp table. - Attempt to handle multiple IO APIC pins connected to the same PCI or ISA/EISA interrupt source. Print a warning if this happens, since performance is suboptimal. This workaround is only used for PCI devices. With these two workarounds, the -SMP kernel is capable of running on my Asus P/I-P65UP5 motherboard when version 1.4 of the MP table is disabled.
This commit is contained in:
parent
300e9a7696
commit
5758c2de94
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=34990
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.40 1998/03/07 21:34:59 dyson Exp $
|
||||
* $Id: smp.h,v 1.41 1998/04/01 20:38:28 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -112,6 +112,7 @@ void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci.c,v 1.80 1997/11/07 08:53:28 phk Exp $
|
||||
* $Id: pci.c,v 1.81 1998/01/24 02:54:47 eivind Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -340,9 +340,25 @@ pci_readcfg(pcicfgregs *probe)
|
||||
int airq;
|
||||
|
||||
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
undirect_pci_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
if (airq >= 0) {
|
||||
/* PCI specific entry found in MP table */
|
||||
if (airq != cfg->intline) {
|
||||
undirect_pci_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* PCI interrupts might be redirected to the
|
||||
* ISA bus according to some MP tables. Use the
|
||||
* same methods as used by the ISA devices
|
||||
* devices to find the proper IOAPIC int pin.
|
||||
*/
|
||||
airq = isa_apic_pin(cfg->intline);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
/* XXX: undirect_pci_irq() ? */
|
||||
undirect_isa_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* APIC_IO */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mpapic.c,v 1.27 1997/12/08 18:36:02 fsmp Exp $
|
||||
* $Id: mpapic.c,v 1.28 1998/03/03 19:54:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -164,7 +164,7 @@ io_apic_setup(int apic)
|
||||
if (apic == 0) {
|
||||
maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */
|
||||
for (pin = 0; pin < maxpin; ++pin) {
|
||||
int bus, bustype;
|
||||
int bus;
|
||||
|
||||
/* we only deal with vectored INTs here */
|
||||
if (apic_int_type(apic, pin) != 0)
|
||||
@ -174,21 +174,12 @@ io_apic_setup(int apic)
|
||||
bus = apic_src_bus_id(apic, pin);
|
||||
if (bus == -1)
|
||||
continue;
|
||||
bustype = apic_bus_type(bus);
|
||||
|
||||
/* the "ISA" type INTerrupts */
|
||||
if ((bustype == ISA) || (bustype == EISA)) {
|
||||
flags = DEFAULT_ISA_FLAGS;
|
||||
}
|
||||
|
||||
/* PCI or other bus */
|
||||
else {
|
||||
flags = DEFAULT_FLAGS;
|
||||
level = trigger(apic, pin, &flags);
|
||||
if (level == 1)
|
||||
apic_pin_trigger[apic] |= (1 << pin);
|
||||
polarity(apic, pin, &flags, level);
|
||||
}
|
||||
flags = DEFAULT_FLAGS;
|
||||
level = trigger(apic, pin, &flags);
|
||||
if (level == 1)
|
||||
apic_pin_trigger[apic] |= (1 << pin);
|
||||
polarity(apic, pin, &flags, level);
|
||||
|
||||
/* program the appropriate registers */
|
||||
select = pin * 2 + IOAPIC_REDTBL0; /* register */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.40 1998/03/07 21:34:59 dyson Exp $
|
||||
* $Id: smp.h,v 1.41 1998/04/01 20:38:28 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -112,6 +112,7 @@ void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $
|
||||
* $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq)
|
||||
}
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
|
||||
/*
|
||||
@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
if (bustype != ISA &&
|
||||
bustype != EISA &&
|
||||
bustype != PCI)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (intr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
for (ointr = intr + 1; ointr < nintrs; ointr++) {
|
||||
if (INTTYPE(ointr) != 0)
|
||||
continue;
|
||||
if (bus != SRCBUSID(ointr))
|
||||
continue;
|
||||
if (bustype == PCI) {
|
||||
if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
|
||||
continue;
|
||||
if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
|
||||
continue;
|
||||
}
|
||||
if (bustype == ISA || bustype == EISA) {
|
||||
if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
|
||||
continue;
|
||||
}
|
||||
if (INTPIN(intr) == INTPIN(ointr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
#undef SRCBUSID
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTTYPE
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci.c,v 1.80 1997/11/07 08:53:28 phk Exp $
|
||||
* $Id: pci.c,v 1.81 1998/01/24 02:54:47 eivind Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -340,9 +340,25 @@ pci_readcfg(pcicfgregs *probe)
|
||||
int airq;
|
||||
|
||||
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
undirect_pci_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
if (airq >= 0) {
|
||||
/* PCI specific entry found in MP table */
|
||||
if (airq != cfg->intline) {
|
||||
undirect_pci_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* PCI interrupts might be redirected to the
|
||||
* ISA bus according to some MP tables. Use the
|
||||
* same methods as used by the ISA devices
|
||||
* devices to find the proper IOAPIC int pin.
|
||||
*/
|
||||
airq = isa_apic_pin(cfg->intline);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
/* XXX: undirect_pci_irq() ? */
|
||||
undirect_isa_irq(cfg->intline);
|
||||
cfg->intline = airq;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* APIC_IO */
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci_compat.c,v 1.5 1997/08/21 07:05:48 fsmp Exp $
|
||||
* $Id: pci_compat.c,v 1.6 1997/08/21 08:42:59 fsmp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -164,13 +164,57 @@ int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
|
||||
int
|
||||
pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
{
|
||||
int error;
|
||||
#ifdef APIC_IO
|
||||
int nextpin, muxcnt;
|
||||
#endif
|
||||
if (cfg->intpin != 0) {
|
||||
int irq = cfg->intline;
|
||||
void *dev_instance = (void *)-1; /* XXX use cfg->devdata */
|
||||
void *idesc;
|
||||
|
||||
idesc = intr_create(dev_instance, irq, func, arg, maskptr, 0);
|
||||
return (intr_connect(idesc) == 0);
|
||||
error = intr_connect(idesc);
|
||||
if (error != 0)
|
||||
return 0;
|
||||
#ifdef APIC_IO
|
||||
nextpin = next_apic_pin(irq);
|
||||
|
||||
if (nextpin < 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Attempt handling of some broken mp tables.
|
||||
*
|
||||
* It's OK to yell (since the mp tables are broken).
|
||||
*
|
||||
* Hanging in the boot is not OK
|
||||
*/
|
||||
|
||||
muxcnt = 2;
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
while (muxcnt < 5 && nextpin >= 0) {
|
||||
muxcnt++;
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
}
|
||||
if (muxcnt >= 5) {
|
||||
printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt);
|
||||
|
||||
nextpin = next_apic_pin(irq);
|
||||
while (nextpin >= 0) {
|
||||
idesc = intr_create(dev_instance, nextpin, func, arg,
|
||||
maskptr, 0);
|
||||
error = intr_connect(idesc);
|
||||
if (error != 0)
|
||||
return 0;
|
||||
printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.40 1998/03/07 21:34:59 dyson Exp $
|
||||
* $Id: smp.h,v 1.41 1998/04/01 20:38:28 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -112,6 +112,7 @@ void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
|
Loading…
Reference in New Issue
Block a user