mp: cleanup allocvector, allow sharing of edge triggered interrupts, more southbridges
parent
b3d47c3a3a
commit
6e8d0bf500
|
@ -259,7 +259,6 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/)
|
||||||
el = intr->flags & PcmpELMASK;
|
el = intr->flags & PcmpELMASK;
|
||||||
|
|
||||||
switch(intr->intr){
|
switch(intr->intr){
|
||||||
|
|
||||||
default: /* PcmpINT */
|
default: /* PcmpINT */
|
||||||
v |= ApicFIXED; /* no-op */
|
v |= ApicFIXED; /* no-op */
|
||||||
break;
|
break;
|
||||||
|
@ -598,7 +597,6 @@ mpinit(void)
|
||||||
if(getconf("*mp") != nil)
|
if(getconf("*mp") != nil)
|
||||||
mpoverride(&p, &e);
|
mpoverride(&p, &e);
|
||||||
while(p < e) switch(*p){
|
while(p < e) switch(*p){
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n",
|
print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n",
|
||||||
*p, e-p);
|
*p, e-p);
|
||||||
|
@ -738,20 +736,32 @@ mpintrcpu(void)
|
||||||
return mpapic[i].apicno;
|
return mpapic[i].apicno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hardcoded VectorAPIC and stuff. bad. */
|
/*
|
||||||
|
* With the APIC a unique vector can be assigned to each
|
||||||
|
* request to enable an interrupt. There are two reasons this
|
||||||
|
* is a good idea:
|
||||||
|
* 1) to prevent lost interrupts, no more than 2 interrupts
|
||||||
|
* should be assigned per block of 16 vectors (there is an
|
||||||
|
* in-service entry and a holding entry for each priority
|
||||||
|
* level and there is one priority level per block of 16
|
||||||
|
* interrupts).
|
||||||
|
* 2) each input pin on the IOAPIC will receive a different
|
||||||
|
* vector regardless of whether the devices on that pin use
|
||||||
|
* the same IRQ as devices on another pin.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
allocvector(void)
|
allocvector(void)
|
||||||
{
|
{
|
||||||
static int round = 0, num = 1;
|
static int round = 0, num = 0;
|
||||||
static Lock l;
|
static Lock l;
|
||||||
int vno;
|
int vno;
|
||||||
|
|
||||||
lock(&l);
|
lock(&l);
|
||||||
if(num >= 24) {
|
vno = VectorAPIC + num;
|
||||||
if(++round >= 8) round = 0;
|
if(vno < MaxVectorAPIC-7)
|
||||||
num = 1;
|
num += 8;
|
||||||
}
|
else
|
||||||
vno = 64 + num++ * 8 + round;
|
num = ++round % 8;
|
||||||
unlock(&l);
|
unlock(&l);
|
||||||
return vno;
|
return vno;
|
||||||
}
|
}
|
||||||
|
@ -780,7 +790,7 @@ mpintrenablex(Vctl* v, int tbdf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(bus == nil){
|
if(bus == nil){
|
||||||
print("ioapicirq: can't find bus type %d, number %d\n", type, bno);
|
print("mpintrenable: can't find bus type %d, number %d\n", type, bno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +806,6 @@ mpintrenablex(Vctl* v, int tbdf)
|
||||||
irq = (dno<<2)|(n-1);
|
irq = (dno<<2)|(n-1);
|
||||||
else
|
else
|
||||||
irq = -1;
|
irq = -1;
|
||||||
//print("pcidev %uX: irq %uX v->irq %uX\n", tbdf, irq, v->irq);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
irq = v->irq;
|
irq = v->irq;
|
||||||
|
@ -810,7 +819,6 @@ mpintrenablex(Vctl* v, int tbdf)
|
||||||
continue;
|
continue;
|
||||||
if(0){
|
if(0){
|
||||||
PCMPintr* p = aintr->intr;
|
PCMPintr* p = aintr->intr;
|
||||||
|
|
||||||
print("mpintrenablex: bus %d intin %d irq %d\n",
|
print("mpintrenablex: bus %d intin %d irq %d\n",
|
||||||
p->busno, p->intin, p->irq);
|
p->busno, p->intin, p->irq);
|
||||||
}
|
}
|
||||||
|
@ -828,55 +836,34 @@ mpintrenablex(Vctl* v, int tbdf)
|
||||||
ioapicrdtr(apic, aintr->intr->intin, 0, &lo);
|
ioapicrdtr(apic, aintr->intr->intin, 0, &lo);
|
||||||
if(!(lo & ApicIMASK)){
|
if(!(lo & ApicIMASK)){
|
||||||
vno = lo & 0xFF;
|
vno = lo & 0xFF;
|
||||||
//print("%s vector %d (!imask)\n", v->name, vno);
|
if(0) print("%s vector %d (!imask)\n", v->name, vno);
|
||||||
n = mpintrinit(bus, aintr->intr, vno, v->irq);
|
n = mpintrinit(bus, aintr->intr, vno, v->irq);
|
||||||
n |= ApicPHYSICAL; /* no-op */
|
n |= ApicPHYSICAL; /* no-op */
|
||||||
lo &= ~(ApicRemoteIRR|ApicDELIVS);
|
lo &= ~(ApicRemoteIRR|ApicDELIVS);
|
||||||
if(n != lo || !(n & ApicLEVEL)){
|
if(n != lo){
|
||||||
print("mpintrenable: multiple botch irq %d, tbdf %uX, lo %8.8uX, n %8.8uX\n",
|
print("mpintrenable: multiple botch irq %d, tbdf %uX, lo %8.8uX, n %8.8uX\n",
|
||||||
v->irq, tbdf, lo, n);
|
v->irq, tbdf, lo, n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->isr = lapicisr;
|
v->isr = lapicisr;
|
||||||
v->eoi = lapiceoi;
|
v->eoi = lapiceoi;
|
||||||
|
|
||||||
return vno;
|
return vno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* With the APIC a unique vector can be assigned to each
|
|
||||||
* request to enable an interrupt. There are two reasons this
|
|
||||||
* is a good idea:
|
|
||||||
* 1) to prevent lost interrupts, no more than 2 interrupts
|
|
||||||
* should be assigned per block of 16 vectors (there is an
|
|
||||||
* in-service entry and a holding entry for each priority
|
|
||||||
* level and there is one priority level per block of 16
|
|
||||||
* interrupts).
|
|
||||||
* 2) each input pin on the IOAPIC will receive a different
|
|
||||||
* vector regardless of whether the devices on that pin use
|
|
||||||
* the same IRQ as devices on another pin.
|
|
||||||
*/
|
|
||||||
vno = allocvector();
|
vno = allocvector();
|
||||||
hi = mpintrcpu()<<24;
|
hi = mpintrcpu()<<24;
|
||||||
lo = mpintrinit(bus, aintr->intr, vno, v->irq);
|
lo = mpintrinit(bus, aintr->intr, vno, v->irq);
|
||||||
//print("lo 0x%uX: busno %d intr %d vno %d irq %d elcr 0x%uX\n",
|
|
||||||
// lo, bus->busno, aintr->intr->irq, vno,
|
|
||||||
// v->irq, i8259elcr);
|
|
||||||
if(lo & ApicIMASK)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
lo |= ApicPHYSICAL; /* no-op */
|
lo |= ApicPHYSICAL; /* no-op */
|
||||||
|
if(lo & ApicIMASK){
|
||||||
|
print("mpintrenable: disabled irq %d, tbdf %uX, lo %8.8uX, hi %8.8uX\n",
|
||||||
|
v->irq, tbdf, lo, hi);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if((apic->flags & PcmpEN) && apic->type == PcmpIOAPIC)
|
if((apic->flags & PcmpEN) && apic->type == PcmpIOAPIC)
|
||||||
ioapicrdtw(apic, aintr->intr->intin, hi, lo);
|
ioapicrdtw(apic, aintr->intr->intin, hi, lo);
|
||||||
//else
|
|
||||||
// print("lo not enabled 0x%uX %d\n",
|
|
||||||
// apic->flags, apic->type);
|
|
||||||
|
|
||||||
v->isr = lapicisr;
|
v->isr = lapicisr;
|
||||||
v->eoi = lapiceoi;
|
v->eoi = lapiceoi;
|
||||||
|
|
||||||
return vno;
|
return vno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,7 +890,7 @@ msiintrenable(Vctl *v)
|
||||||
return -1;
|
return -1;
|
||||||
pci = pcimatchtbdf(tbdf);
|
pci = pcimatchtbdf(tbdf);
|
||||||
if(pci == nil) {
|
if(pci == nil) {
|
||||||
print("msiintrenable: could not find Pcidev for tbdf %.8x\n", tbdf);
|
print("msiintrenable: could not find Pcidev for tbdf %uX\n", tbdf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cap = pcicap(pci, PciCapMSI);
|
cap = pcicap(pci, PciCapMSI);
|
||||||
|
@ -916,7 +903,6 @@ msiintrenable(Vctl *v)
|
||||||
if(ok64) pcicfgw32(pci, cap + MSIAddr + 4, 0);
|
if(ok64) pcicfgw32(pci, cap + MSIAddr + 4, 0);
|
||||||
pcicfgw16(pci, cap + (ok64 ? MSIData64 : MSIData32), vno | (1<<14));
|
pcicfgw16(pci, cap + (ok64 ? MSIData64 : MSIData32), vno | (1<<14));
|
||||||
pcicfgw16(pci, cap + MSICtrl, 1);
|
pcicfgw16(pci, cap + MSICtrl, 1);
|
||||||
print("msiintrenable: success with tbdf %.8x, vector %d, cpu %d\n", tbdf, vno, cpu);
|
|
||||||
v->isr = lapicisr;
|
v->isr = lapicisr;
|
||||||
v->eoi = lapiceoi;
|
v->eoi = lapiceoi;
|
||||||
return vno;
|
return vno;
|
||||||
|
@ -973,7 +959,7 @@ mpintrenable(Vctl* v)
|
||||||
if(vno != -1)
|
if(vno != -1)
|
||||||
return vno;
|
return vno;
|
||||||
}
|
}
|
||||||
print("mpintrenable: out of choices eisa %d isa %d tbdf %#ux irq %d\n",
|
print("mpintrenable: out of choices eisa %d isa %d tbdf %uX irq %d\n",
|
||||||
mpeisabus, mpisabus, v->tbdf, v->irq);
|
mpeisabus, mpisabus, v->tbdf, v->irq);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,6 +658,12 @@ static Bridge southbridges[] = {
|
||||||
{ 0x8086, 0x2670, pIIxget, pIIxset }, /* Intel 632xesb */
|
{ 0x8086, 0x2670, pIIxget, pIIxset }, /* Intel 632xesb */
|
||||||
{ 0x8086, 0x27b8, pIIxget, pIIxset }, /* Intel 82801GB */
|
{ 0x8086, 0x27b8, pIIxget, pIIxset }, /* Intel 82801GB */
|
||||||
{ 0x8086, 0x27b9, pIIxget, pIIxset }, /* Intel 82801GBM */
|
{ 0x8086, 0x27b9, pIIxget, pIIxset }, /* Intel 82801GBM */
|
||||||
|
{ 0x8086, 0x27bd, pIIxget, pIIxset }, /* Intel 82801GB/GR */
|
||||||
|
{ 0x8086, 0x3a16, pIIxget, pIIxset }, /* Intel 82801JIR */
|
||||||
|
{ 0x8086, 0x3a40, pIIxget, pIIxset }, /* Intel 82801JI */
|
||||||
|
{ 0x8086, 0x3a42, pIIxget, pIIxset }, /* Intel 82801JI */
|
||||||
|
{ 0x8086, 0x3a48, pIIxget, pIIxset }, /* Intel 82801JI */
|
||||||
|
{ 0x8086, 0x2916, pIIxget, pIIxset }, /* Intel 82801? */
|
||||||
{ 0x8086, 0x2810, pIIxget, pIIxset }, /* Intel 82801HB/HR (ich8/r) */
|
{ 0x8086, 0x2810, pIIxget, pIIxset }, /* Intel 82801HB/HR (ich8/r) */
|
||||||
{ 0x8086, 0x2812, pIIxget, pIIxset }, /* Intel 82801HH (ich8dh) */
|
{ 0x8086, 0x2812, pIIxget, pIIxset }, /* Intel 82801HH (ich8dh) */
|
||||||
{ 0x8086, 0x2912, pIIxget, pIIxset }, /* Intel 82801ih ich9dh */
|
{ 0x8086, 0x2912, pIIxget, pIIxset }, /* Intel 82801ih ich9dh */
|
||||||
|
@ -672,6 +678,7 @@ static Bridge southbridges[] = {
|
||||||
{ 0x8086, 0x3a48, pIIxget, pIIxset }, /* Intel 82801ji */
|
{ 0x8086, 0x3a48, pIIxget, pIIxset }, /* Intel 82801ji */
|
||||||
{ 0x8086, 0x3b06, pIIxget, pIIxset }, /* Intel 82801? ibex peak */
|
{ 0x8086, 0x3b06, pIIxget, pIIxset }, /* Intel 82801? ibex peak */
|
||||||
{ 0x8086, 0x3b14, pIIxget, pIIxset }, /* Intel 82801? 3420 */
|
{ 0x8086, 0x3b14, pIIxget, pIIxset }, /* Intel 82801? 3420 */
|
||||||
|
{ 0x8086, 0x1c52, pIIxget, pIIxset }, /* Intel 82q65 cougar point pch */
|
||||||
{ 0x8086, 0x1c54, pIIxget, pIIxset }, /* Intel 82q67 cougar point pch */
|
{ 0x8086, 0x1c54, pIIxget, pIIxset }, /* Intel 82q67 cougar point pch */
|
||||||
{ 0x1106, 0x0586, viaget, viaset }, /* Viatech 82C586 */
|
{ 0x1106, 0x0586, viaget, viaset }, /* Viatech 82C586 */
|
||||||
{ 0x1106, 0x0596, viaget, viaset }, /* Viatech 82C596 */
|
{ 0x1106, 0x0596, viaget, viaset }, /* Viatech 82C596 */
|
||||||
|
@ -684,15 +691,16 @@ static Bridge southbridges[] = {
|
||||||
{ 0x1039, 0x0496, pIIxget, pIIxset }, /* SI 496 */
|
{ 0x1039, 0x0496, pIIxget, pIIxset }, /* SI 496 */
|
||||||
{ 0x1078, 0x0100, cyrixget, cyrixset }, /* Cyrix 5530 Legacy */
|
{ 0x1078, 0x0100, cyrixget, cyrixset }, /* Cyrix 5530 Legacy */
|
||||||
|
|
||||||
{ 0x1022, 0x746B, nil, nil }, /* AMD 8111 */
|
{ 0x1022, 0x746b, nil, nil }, /* AMD 8111 */
|
||||||
{ 0x10DE, 0x00D1, nil, nil }, /* NVIDIA nForce 3 */
|
{ 0x10de, 0x00d1, nil, nil }, /* NVIDIA nForce 3 */
|
||||||
{ 0x10DE, 0x00E0, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
{ 0x10de, 0x00e0, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
||||||
{ 0x10DE, 0x00E1, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
{ 0x10de, 0x00e1, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
||||||
{ 0x1166, 0x0200, nil, nil }, /* ServerWorks ServerSet III LE */
|
{ 0x1166, 0x0200, nil, nil }, /* ServerWorks ServerSet III LE */
|
||||||
{ 0x1002, 0x4377, nil, nil }, /* ATI Radeon Xpress 200M */
|
{ 0x1002, 0x4377, nil, nil }, /* ATI Radeon Xpress 200M */
|
||||||
{ 0x1002, 0x4372, nil, nil }, /* ATI SB400 */
|
{ 0x1002, 0x4372, nil, nil }, /* ATI SB400 */
|
||||||
{ 0x1002, 0x9601, nil, nil }, /* AMD SB710 */
|
{ 0x1002, 0x9601, nil, nil }, /* AMD SB710 */
|
||||||
{ 0x1002, 0x438D, nil, nil }, /* AMD SB600 */
|
{ 0x1002, 0x438d, nil, nil }, /* AMD SB600 */
|
||||||
|
{ 0x1002, 0x439d, nil, nil }, /* AMD SB810 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Slot Slot;
|
typedef struct Slot Slot;
|
||||||
|
@ -986,7 +994,7 @@ pcicfginit(void)
|
||||||
fmtinstall('T', tbdffmt);
|
fmtinstall('T', tbdffmt);
|
||||||
|
|
||||||
if(p = getconf("*pcimaxbno"))
|
if(p = getconf("*pcimaxbno"))
|
||||||
pcimaxbno = strtoul(p, 0, 0) & 0xff;
|
pcimaxbno = strtoul(p, 0, 0);
|
||||||
if(p = getconf("*pcimaxdno")){
|
if(p = getconf("*pcimaxdno")){
|
||||||
n = strtoul(p, 0, 0);
|
n = strtoul(p, 0, 0);
|
||||||
if(n < pcimaxdno)
|
if(n < pcimaxdno)
|
||||||
|
|
Loading…
Reference in New Issue