diff -r 4bafb394707a sys/src/9/pc/devpccard.c --- a/sys/src/9/pc/devpccard.c Sun Feb 28 13:31:49 2021 +0100 +++ b/sys/src/9/pc/devpccard.c Sun Feb 28 17:49:51 2021 +0100 @@ -520,7 +520,6 @@ static int initialized; Pcidev *pci; int i; - uchar intl; char *p; if (initialized) @@ -539,9 +538,9 @@ /* Find all CardBus controllers */ pci = nil; - intl = 0xff; while ((pci = pcimatch(pci, 0, 0)) != nil) { uvlong baddr; + int size; Cardbus *cb; uchar pin; @@ -633,23 +632,20 @@ pcicfgw8(cb->pci, 0xD4, 0xCA); } - baddr = pcicfgr32(cb->pci, PciBAR0); - if (baddr == 0) { - int size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000; + size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000; + baddr = (ulong)pcicfgr32(cb->pci, PciBAR0); + if (baddr == 0 || upaalloc(baddr, size, 0) == -1) { baddr = upaalloc(-1ULL, size, size); if(baddr == -1) continue; pcicfgw32(cb->pci, PciBAR0, (ulong)baddr); - cb->regs = (ulong *)vmap(baddr, size); } - else - cb->regs = (ulong *)vmap(baddr, 4096); + cb->regs = (ulong *)vmap(baddr, size); if(cb->regs == nil) continue; cb->state = SlotEmpty; - if (intl != 0xff && intl != pci->intl) - intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus"); + intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus"); /* Don't really know what to do with this... */ i82365probe(cb, LegacyAddr, LegacyAddr + 1); @@ -778,9 +774,8 @@ configure(Cardbus *cb) { int i, r; - Pcidev *pci; - uvlong romlen, memlen, membase, rombase, bar; - ulong iobase, iolen, size; + ulong iobase, iolen; + uvlong membase, memlen; if(DEBUG) print("configuring slot %ld (%s)\n", cb - cbslots, states[cb->state]); @@ -796,23 +791,10 @@ } /* Scan the CardBus for new PCI devices */ - pciscan(pcicfgr8(cb->pci, PciSBN), &cb->pci->bridge); + pciscan(pcicfgr8(cb->pci, PciSBN), &cb->pci->bridge, cp->pci); - /* - * size the devices on the bus, reserve a minimum for devices arriving later, - * allow for ROM space, allocate space, and set the cardbus mapping registers - */ - pcibussize(cb->pci->bridge, &memlen, &iolen); /* TO DO: need initial alignments */ - - romlen = 0; - for(pci = cb->pci->bridge; pci != nil; pci = pci->list){ - size = pcibarsize(pci, PciEBAR0); - if(size > 0){ - pci->rom.bar = -1; - pci->rom.size = size; - romlen += size; - } - } + /* size the devices on the bus, reserve a minimum for devices arriving later */ + pcibussize(cb->pci->bridge, &memlen, &iolen); if(iolen < 512) iolen = 512; @@ -820,8 +802,6 @@ if(iobase == -1) return; - rombase = memlen; - memlen += romlen; if(memlen < 1*1024*1024) memlen = 1*1024*1024; membase = upaalloc(-1ULL, memlen, 4*1024*1024); /* TO DO: better alignment */ @@ -832,68 +812,20 @@ pcicfgw32(cb->pci, PciCBILR0, iobase + iolen-1); pcicfgw32(cb->pci, PciCBIBR1, 0); pcicfgw32(cb->pci, PciCBILR1, 0); + cb->pci->ioa.bar = iobase; + cp->pci->ioa.siz = iolen; pcicfgw32(cb->pci, PciCBMBR0, (ulong)membase); pcicfgw32(cb->pci, PciCBMLR0, (ulong)membase + memlen-1); pcicfgw32(cb->pci, PciCBMBR1, 0); pcicfgw32(cb->pci, PciCBMLR1, 0); + cp->pci->mema.bar = membase; + cb->pci->mema.siz = memlen; -// pcibussize(cb->pci->bridge, &membase, &iobase); /* now assign them */ - rombase += membase; + /* Route interrupts to INTA#/B# */ + pcicfgw16(cb->pci, PciBCR, pcicfgr16(cb->pci, PciBCR) & ~(1 << 7)); - for(pci = cb->pci->bridge; pci != nil; pci = pci->list){ - r = pcicfgr16(pci, PciPCR); - r &= ~(PciPCR_IO|PciPCR_MEM); - pcicfgw16(pci, PciPCR, r); - - /* - * Treat the found device as an ordinary PCI card. - * It seems that the CIS is not always present in - * CardBus cards. - * XXX, need to support multifunction cards - */ - for(i = 0; i < Nbars; i++) { - if(pci->mem[i].size == 0) - continue; - bar = pci->mem[i].bar; - if(bar & 1) - bar += iobase; - else - bar += membase; - pci->mem[i].bar = bar; - pcicfgw32(pci, PciBAR0 + 4*i, bar); - if((bar & 1) == 0){ - print("%T mem[%d] %8.8llux %d\n", pci->tbdf, i, bar, pci->mem[i].size); - if(bar & 0x80){ /* TO DO: enable prefetch */ - ; - } - } - } - if((size = pcibarsize(pci, PciEBAR0)) > 0) { /* TO DO: can this be done by pci.c? */ - pci->rom.bar = rombase; - pci->rom.size = size; - rombase += size; - pcicfgw32(pci, PciEBAR0, pci->rom.bar); - } - - /* Set the basic PCI registers for the device */ - pci->pcr = pcicfgr16(pci, PciPCR); - pci->pcr |= PciPCR_IO|PciPCR_MEM|PciPCR_Master; - pci->cls = 8; - pci->ltr = 64; - pcicfgw16(pci, PciPCR, pci->pcr); - pcicfgw8(pci, PciCLS, pci->cls); - pcicfgw8(pci, PciLTR, pci->ltr); - - if (pcicfgr8(pci, PciINTP)) { - pci->intl = pcicfgr8(cb->pci, PciINTL); - pcicfgw8(pci, PciINTL, pci->intl); - - /* Route interrupts to INTA#/B# */ - pcicfgw16(cb->pci, PciBCR, - pcicfgr16(cb->pci, PciBCR) & ~(1 << 7)); - } - } + pcibusmap(cb->pci->bridge, &membase, &iobase, 1); } static void diff -r 4bafb394707a sys/src/9/pc/mp.c --- a/sys/src/9/pc/mp.c Sun Feb 28 13:31:49 2021 +0100 +++ b/sys/src/9/pc/mp.c Sun Feb 28 17:49:51 2021 +0100 @@ -351,13 +351,19 @@ if(bus == nil){ /* - * if the PCI device is behind a PCI-PCI bridge thats not described - * by the MP or ACPI tables then walk up the bus translating interrupt - * pin to parent bus. + * if the PCI device is behind a bridge thats not described + * by the MP or ACPI tables then walk up the bus translating + * interrupt pin to parent bus. */ if(pci != nil && pci->parent != nil && pin > 0){ - pin = ((dno+(pin-1))%4)+1; pci = pci->parent; + if(pci->ccrb == 6 && pci->ccru == 7){ + /* Cardbus bridge, use controllers interrupt pin */ + pin = pcicfgr8(pci, PciINTP); + } else { + /* PCI-PCI bridge */ + pin = ((dno+(pin-1))%4)+1; + } bno = BUSBNO(pci->tbdf); dno = BUSDNO(pci->tbdf); goto Findbus; diff -r 4bafb394707a sys/src/9/pc/pcipc.c --- a/sys/src/9/pc/pcipc.c Sun Feb 28 13:31:49 2021 +0100 +++ b/sys/src/9/pc/pcipc.c Sun Feb 28 17:49:51 2021 +0100 @@ -688,7 +688,7 @@ list = &pciroot; for(bno = 0; bno <= pcimaxbno; bno++) { int sbno = bno; - bno = pciscan(bno, list); + bno = pciscan(bno, list, nil); while(*list) list = &(*list)->link; diff -r 4bafb394707a sys/src/9/port/pci.c --- a/sys/src/9/port/pci.c Sun Feb 28 13:31:49 2021 +0100 +++ b/sys/src/9/port/pci.c Sun Feb 28 17:49:51 2021 +0100 @@ -643,9 +643,9 @@ } int -pciscan(int bno, Pcidev **list) +pciscan(int bno, Pcidev **list, Pcidev *parent) { - return pcilscan(bno, list, nil); + return pcilscan(bno, list, parent); } void diff -r 4bafb394707a sys/src/9/port/pci.h --- a/sys/src/9/port/pci.h Sun Feb 28 13:31:49 2021 +0100 +++ b/sys/src/9/port/pci.h Sun Feb 28 17:49:51 2021 +0100 @@ -228,7 +228,7 @@ extern int pcicfgr8(Pcidev* pcidev, int rno); extern void pcicfgw8(Pcidev* pcidev, int rno, int data); -extern int pciscan(int bno, Pcidev **list); +extern int pciscan(int bno, Pcidev **list, Pcidev *parent); extern void pcibusmap(Pcidev *root, uvlong *pmema, ulong *pioa, int wrreg); extern void pcibussize(Pcidev *root, uvlong *msize, ulong *iosize);