merge
This commit is contained in:
commit
d3ebd02bef
111 changed files with 2400 additions and 5125 deletions
|
@ -9,6 +9,7 @@
|
|||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "sysreg.h"
|
||||
|
||||
typedef struct Mbox Mbox;
|
||||
|
|
|
@ -183,28 +183,9 @@ extern void screeninit(void);
|
|||
|
||||
extern int isaconfig(char*, int, ISAConf*);
|
||||
|
||||
/* pci */
|
||||
typedef struct Pcidev Pcidev;
|
||||
extern int pcicfgr32(Pcidev* pcidev, int rno);
|
||||
extern void pcicfgw32(Pcidev* pcidev, int rno, int data);
|
||||
extern int pcicfgr16(Pcidev* pcidev, int rno);
|
||||
extern void pcicfgw16(Pcidev* pcidev, int rno, int data);
|
||||
extern int pcicfgr8(Pcidev* pcidev, int rno);
|
||||
extern void pcicfgw8(Pcidev* pcidev, int rno, int data);
|
||||
extern Pcidev* pcimatch(Pcidev* prev, int vid, int did);
|
||||
extern Pcidev* pcimatchtbdf(int tbdf);
|
||||
extern void pcisetioe(Pcidev* p);
|
||||
extern void pciclrioe(Pcidev* p);
|
||||
extern void pcisetbme(Pcidev* p);
|
||||
extern void pciclrbme(Pcidev* p);
|
||||
extern void pcisetmwi(Pcidev* p);
|
||||
extern void pciclrmwi(Pcidev* p);
|
||||
extern int pcicap(Pcidev *p, int cap);
|
||||
extern int pcinextcap(Pcidev *pci, int offset);
|
||||
extern int pcihtcap(Pcidev *p, int cap);
|
||||
extern int pcigetpms(Pcidev* p);
|
||||
extern int pcisetpms(Pcidev* p, int state);
|
||||
extern void pcienable(Pcidev *p);
|
||||
extern void pcidisable(Pcidev *p);
|
||||
/* pcibcm */
|
||||
extern int pcicfgrw8(int tbdf, int rno, int data, int read);
|
||||
extern int pcicfgrw16(int tbdf, int rno, int data, int read);
|
||||
extern int pcicfgrw32(int tbdf, int rno, int data, int read);
|
||||
extern void pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a);
|
||||
extern void pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "sysreg.h"
|
||||
#include "../port/error.h"
|
||||
|
|
|
@ -6,233 +6,5 @@ enum {
|
|||
IRQether = IRQgic + 29,
|
||||
};
|
||||
|
||||
/*
|
||||
* PCI
|
||||
*/
|
||||
enum {
|
||||
BusCBUS = 0, /* Corollary CBUS */
|
||||
BusCBUSII, /* Corollary CBUS II */
|
||||
BusEISA, /* Extended ISA */
|
||||
BusFUTURE, /* IEEE Futurebus */
|
||||
BusINTERN, /* Internal bus */
|
||||
BusISA, /* Industry Standard Architecture */
|
||||
BusMBI, /* Multibus I */
|
||||
BusMBII, /* Multibus II */
|
||||
BusMCA, /* Micro Channel Architecture */
|
||||
BusMPI, /* MPI */
|
||||
BusMPSA, /* MPSA */
|
||||
BusNUBUS, /* Apple Macintosh NuBus */
|
||||
BusPCI, /* Peripheral Component Interconnect */
|
||||
BusPCMCIA, /* PC Memory Card International Association */
|
||||
BusTC, /* DEC TurboChannel */
|
||||
BusVL, /* VESA Local bus */
|
||||
BusVME, /* VMEbus */
|
||||
BusXPRESS, /* Express System Bus */
|
||||
};
|
||||
|
||||
#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
|
||||
#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
|
||||
#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
|
||||
#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
|
||||
#define BUSTYPE(tbdf) ((tbdf)>>24)
|
||||
#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
|
||||
|
||||
enum { /* type 0 & type 1 pre-defined header */
|
||||
PciVID = 0x00, /* vendor ID */
|
||||
PciDID = 0x02, /* device ID */
|
||||
PciPCR = 0x04, /* command */
|
||||
PciPSR = 0x06, /* status */
|
||||
PciRID = 0x08, /* revision ID */
|
||||
PciCCRp = 0x09, /* programming interface class code */
|
||||
PciCCRu = 0x0A, /* sub-class code */
|
||||
PciCCRb = 0x0B, /* base class code */
|
||||
PciCLS = 0x0C, /* cache line size */
|
||||
PciLTR = 0x0D, /* latency timer */
|
||||
PciHDT = 0x0E, /* header type */
|
||||
PciBST = 0x0F, /* BIST */
|
||||
|
||||
PciBAR0 = 0x10, /* base address */
|
||||
PciBAR1 = 0x14,
|
||||
|
||||
PciCAP = 0x34, /* capabilities pointer */
|
||||
PciINTL = 0x3C, /* interrupt line */
|
||||
PciINTP = 0x3D, /* interrupt pin */
|
||||
};
|
||||
|
||||
/* ccrb (base class code) values; controller types */
|
||||
enum {
|
||||
Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
|
||||
Pcibcstore = 1, /* mass storage */
|
||||
Pcibcnet = 2, /* network */
|
||||
Pcibcdisp = 3, /* display */
|
||||
Pcibcmmedia = 4, /* multimedia */
|
||||
Pcibcmem = 5, /* memory */
|
||||
Pcibcbridge = 6, /* bridge */
|
||||
Pcibccomm = 7, /* simple comms (e.g., serial) */
|
||||
Pcibcbasesys = 8, /* base system */
|
||||
Pcibcinput = 9, /* input */
|
||||
Pcibcdock = 0xa, /* docking stations */
|
||||
Pcibcproc = 0xb, /* processors */
|
||||
Pcibcserial = 0xc, /* serial bus (e.g., USB) */
|
||||
Pcibcwireless = 0xd, /* wireless */
|
||||
Pcibcintell = 0xe, /* intelligent i/o */
|
||||
Pcibcsatcom = 0xf, /* satellite comms */
|
||||
Pcibccrypto = 0x10, /* encryption/decryption */
|
||||
Pcibcdacq = 0x11, /* data acquisition & signal proc. */
|
||||
};
|
||||
|
||||
/* ccru (sub-class code) values; common cases only */
|
||||
enum {
|
||||
/* mass storage */
|
||||
Pciscscsi = 0, /* SCSI */
|
||||
Pciscide = 1, /* IDE (ATA) */
|
||||
Pciscsata = 6, /* SATA */
|
||||
|
||||
/* network */
|
||||
Pciscether = 0, /* Ethernet */
|
||||
|
||||
/* display */
|
||||
Pciscvga = 0, /* VGA */
|
||||
Pciscxga = 1, /* XGA */
|
||||
Pcisc3d = 2, /* 3D */
|
||||
|
||||
/* bridges */
|
||||
Pcischostpci = 0, /* host/pci */
|
||||
Pciscpcicpci = 1, /* pci/pci */
|
||||
|
||||
/* simple comms */
|
||||
Pciscserial = 0, /* 16450, etc. */
|
||||
Pciscmultiser = 1, /* multiport serial */
|
||||
|
||||
/* serial bus */
|
||||
Pciscusb = 3, /* USB */
|
||||
};
|
||||
|
||||
enum { /* type 0 pre-defined header */
|
||||
PciCIS = 0x28, /* cardbus CIS pointer */
|
||||
PciSVID = 0x2C, /* subsystem vendor ID */
|
||||
PciSID = 0x2E, /* subsystem ID */
|
||||
PciEBAR0 = 0x30, /* expansion ROM base address */
|
||||
PciMGNT = 0x3E, /* burst period length */
|
||||
PciMLT = 0x3F, /* maximum latency between bursts */
|
||||
};
|
||||
|
||||
enum { /* type 1 pre-defined header */
|
||||
PciPBN = 0x18, /* primary bus number */
|
||||
PciSBN = 0x19, /* secondary bus number */
|
||||
PciUBN = 0x1A, /* subordinate bus number */
|
||||
PciSLTR = 0x1B, /* secondary latency timer */
|
||||
PciIBR = 0x1C, /* I/O base */
|
||||
PciILR = 0x1D, /* I/O limit */
|
||||
PciSPSR = 0x1E, /* secondary status */
|
||||
PciMBR = 0x20, /* memory base */
|
||||
PciMLR = 0x22, /* memory limit */
|
||||
PciPMBR = 0x24, /* prefetchable memory base */
|
||||
PciPMLR = 0x26, /* prefetchable memory limit */
|
||||
PciPUBR = 0x28, /* prefetchable base upper 32 bits */
|
||||
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
|
||||
PciIUBR = 0x30, /* I/O base upper 16 bits */
|
||||
PciIULR = 0x32, /* I/O limit upper 16 bits */
|
||||
PciEBAR1 = 0x28, /* expansion ROM base address */
|
||||
PciBCR = 0x3E, /* bridge control register */
|
||||
};
|
||||
|
||||
enum { /* type 2 pre-defined header */
|
||||
PciCBExCA = 0x10,
|
||||
PciCBSPSR = 0x16,
|
||||
PciCBPBN = 0x18, /* primary bus number */
|
||||
PciCBSBN = 0x19, /* secondary bus number */
|
||||
PciCBUBN = 0x1A, /* subordinate bus number */
|
||||
PciCBSLTR = 0x1B, /* secondary latency timer */
|
||||
PciCBMBR0 = 0x1C,
|
||||
PciCBMLR0 = 0x20,
|
||||
PciCBMBR1 = 0x24,
|
||||
PciCBMLR1 = 0x28,
|
||||
PciCBIBR0 = 0x2C, /* I/O base */
|
||||
PciCBILR0 = 0x30, /* I/O limit */
|
||||
PciCBIBR1 = 0x34, /* I/O base */
|
||||
PciCBILR1 = 0x38, /* I/O limit */
|
||||
PciCBSVID = 0x40, /* subsystem vendor ID */
|
||||
PciCBSID = 0x42, /* subsystem ID */
|
||||
PciCBLMBAR = 0x44, /* legacy mode base address */
|
||||
};
|
||||
|
||||
enum {
|
||||
/* bar bits */
|
||||
Barioaddr = 1<<0, /* vs. memory addr */
|
||||
Barwidthshift = 1,
|
||||
Barwidthmask = 3,
|
||||
Barwidth32 = 0,
|
||||
Barwidth64 = 2,
|
||||
Barprefetch = 1<<3,
|
||||
};
|
||||
|
||||
enum
|
||||
{ /* command register */
|
||||
IOen = (1<<0),
|
||||
MEMen = (1<<1),
|
||||
MASen = (1<<2),
|
||||
MemWrInv = (1<<4),
|
||||
PErrEn = (1<<6),
|
||||
SErrEn = (1<<8),
|
||||
};
|
||||
|
||||
/* capabilities */
|
||||
enum {
|
||||
PciCapPMG = 0x01, /* power management */
|
||||
PciCapAGP = 0x02,
|
||||
PciCapVPD = 0x03, /* vital product data */
|
||||
PciCapSID = 0x04, /* slot id */
|
||||
PciCapMSI = 0x05,
|
||||
PciCapCHS = 0x06, /* compact pci hot swap */
|
||||
PciCapPCIX = 0x07,
|
||||
PciCapHTC = 0x08, /* hypertransport irq conf */
|
||||
PciCapVND = 0x09, /* vendor specific information */
|
||||
PciCapPCIe = 0x10,
|
||||
PciCapMSIX = 0x11,
|
||||
PciCapSATA = 0x12,
|
||||
PciCapHSW = 0x0c, /* hot swap */
|
||||
};
|
||||
|
||||
typedef struct Pcidev Pcidev;
|
||||
struct Pcidev
|
||||
{
|
||||
int tbdf; /* type+bus+device+function */
|
||||
ushort vid; /* vendor ID */
|
||||
ushort did; /* device ID */
|
||||
|
||||
ushort pcr;
|
||||
|
||||
uchar rid;
|
||||
uchar ccrp;
|
||||
uchar ccru;
|
||||
uchar ccrb;
|
||||
uchar cls;
|
||||
uchar ltr;
|
||||
|
||||
struct {
|
||||
uvlong bar; /* base address */
|
||||
int size;
|
||||
} mem[6];
|
||||
|
||||
uchar intl; /* interrupt line */
|
||||
|
||||
Pcidev* list;
|
||||
Pcidev* link; /* next device on this bno */
|
||||
|
||||
Pcidev* parent; /* up a bus */
|
||||
Pcidev* bridge; /* down a bus */
|
||||
|
||||
int pmrb; /* power management register block */
|
||||
|
||||
struct {
|
||||
uvlong bar;
|
||||
int size;
|
||||
} ioa, mema;
|
||||
};
|
||||
|
||||
#define PCIWINDOW 0
|
||||
#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
|
||||
|
||||
#pragma varargck type "T" int
|
||||
#pragma varargck type "T" uint
|
||||
|
|
|
@ -103,6 +103,7 @@ trap.$O main.$O: /sys/include/tos.h
|
|||
l.$O cache.v8.$O mmu.$O rebootcode.$O: mem.h
|
||||
l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O rebootcode.$O: sysreg.h
|
||||
main.$O: rebootcode.i
|
||||
pcibcm.$O: ../port/pci.h
|
||||
|
||||
devmouse.$O mouse.$O screen.$O: screen.h
|
||||
usbdwc.$O: dwcotg.h ../port/usb.h
|
||||
|
|
310
sys/src/9/bcm64/pcibcm.c
Normal file
310
sys/src/9/bcm64/pcibcm.c
Normal file
|
@ -0,0 +1,310 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
/* bcmstb PCIe controller registers */
|
||||
enum{
|
||||
RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 = 0x0188/4,
|
||||
RC_CFG_PRIV1_ID_VAL3 = 0x043c/4,
|
||||
RC_DL_MDIO_ADDR = 0x1100/4,
|
||||
RC_DL_MDIO_WR_DATA = 0x1104/4,
|
||||
RC_DL_MDIO_RD_DATA = 0x1108/4,
|
||||
MISC_MISC_CTRL = 0x4008/4,
|
||||
MISC_CPU_2_PCIE_MEM_WIN0_LO = 0x400c/4,
|
||||
MISC_CPU_2_PCIE_MEM_WIN0_HI = 0x4010/4,
|
||||
MISC_RC_BAR1_CONFIG_LO = 0x402c/4,
|
||||
MISC_RC_BAR2_CONFIG_LO = 0x4034/4,
|
||||
MISC_RC_BAR2_CONFIG_HI = 0x4038/4,
|
||||
MISC_RC_BAR3_CONFIG_LO = 0x403c/4,
|
||||
MISC_MSI_BAR_CONFIG_LO = 0x4044/4,
|
||||
MISC_MSI_BAR_CONFIG_HI = 0x4048/4,
|
||||
MISC_MSI_DATA_CONFIG = 0x404c/4,
|
||||
MISC_EOI_CTRL = 0x4060/4,
|
||||
MISC_PCIE_CTRL = 0x4064/4,
|
||||
MISC_PCIE_STATUS = 0x4068/4,
|
||||
MISC_REVISION = 0x406c/4,
|
||||
MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT = 0x4070/4,
|
||||
MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI = 0x4080/4,
|
||||
MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI = 0x4084/4,
|
||||
MISC_HARD_PCIE_HARD_DEBUG = 0x4204/4,
|
||||
|
||||
INTR2_CPU_BASE = 0x4300/4,
|
||||
MSI_INTR2_BASE = 0x4500/4,
|
||||
INTR_STATUS = 0,
|
||||
INTR_SET,
|
||||
INTR_CLR,
|
||||
INTR_MASK_STATUS,
|
||||
INTR_MASK_SET,
|
||||
INTR_MASK_CLR,
|
||||
|
||||
EXT_CFG_INDEX = 0x9000/4,
|
||||
RGR1_SW_INIT_1 = 0x9210/4,
|
||||
EXT_CFG_DATA = 0x8000/4,
|
||||
|
||||
};
|
||||
|
||||
#define MSI_TARGET_ADDR 0xFFFFFFFFCULL
|
||||
|
||||
static u32int *regs = (u32int*)(VIRTIO1 + 0x500000);
|
||||
static Pcidev* pciroot;
|
||||
|
||||
static void*
|
||||
cfgaddr(int tbdf, int rno)
|
||||
{
|
||||
if(BUSBNO(tbdf) == 0 && BUSDNO(tbdf) == 0)
|
||||
return (uchar*)regs + rno;
|
||||
regs[EXT_CFG_INDEX] = BUSBNO(tbdf) << 20 | BUSDNO(tbdf) << 15 | BUSFNO(tbdf) << 12;
|
||||
coherence();
|
||||
return ((uchar*)®s[EXT_CFG_DATA]) + rno;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw32(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
u32int *p;
|
||||
|
||||
if((p = cfgaddr(tbdf, rno & ~3)) != nil){
|
||||
if(read)
|
||||
data = *p;
|
||||
else
|
||||
*p = data;
|
||||
} else {
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw16(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
u16int *p;
|
||||
|
||||
if((p = cfgaddr(tbdf, rno & ~1)) != nil){
|
||||
if(read)
|
||||
data = *p;
|
||||
else
|
||||
*p = data;
|
||||
} else {
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw8(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
u8int *p;
|
||||
|
||||
if((p = cfgaddr(tbdf, rno)) != nil){
|
||||
if(read)
|
||||
data = *p;
|
||||
else
|
||||
*p = data;
|
||||
} else {
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
enum {
|
||||
MSICtrl = 0x02, /* message control register (16 bit) */
|
||||
MSIAddr = 0x04, /* message address register (64 bit) */
|
||||
MSIData32 = 0x08, /* message data register for 32 bit MSI (16 bit) */
|
||||
MSIData64 = 0x0C, /* message data register for 64 bit MSI (16 bit) */
|
||||
};
|
||||
|
||||
typedef struct Pciisr Pciisr;
|
||||
struct Pciisr {
|
||||
void (*f)(Ureg*, void*);
|
||||
void *a;
|
||||
Pcidev *p;
|
||||
};
|
||||
|
||||
static Pciisr pciisr[32];
|
||||
static Lock pciisrlk;
|
||||
|
||||
void
|
||||
pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a)
|
||||
{
|
||||
int cap, ok64;
|
||||
u32int dat;
|
||||
u64int adr;
|
||||
Pcidev *p;
|
||||
Pciisr *isr;
|
||||
|
||||
if((p = pcimatchtbdf(tbdf)) == nil){
|
||||
print("pciintrenable: %T: unknown device\n", tbdf);
|
||||
return;
|
||||
}
|
||||
if((cap = pcicap(p, PciCapMSI)) < 0){
|
||||
print("pciintrenable: %T: no MSI cap\n", tbdf);
|
||||
return;
|
||||
}
|
||||
|
||||
lock(&pciisrlk);
|
||||
for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
|
||||
if(isr->p == p){
|
||||
isr->p = nil;
|
||||
regs[MSI_INTR2_BASE + INTR_MASK_SET] = 1 << (isr-pciisr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
|
||||
if(isr->p == nil){
|
||||
isr->p = p;
|
||||
isr->a = a;
|
||||
isr->f = f;
|
||||
regs[MSI_INTR2_BASE + INTR_CLR] = 1 << (isr-pciisr);
|
||||
regs[MSI_INTR2_BASE + INTR_MASK_CLR] = 1 << (isr-pciisr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock(&pciisrlk);
|
||||
|
||||
if(isr >= &pciisr[nelem(pciisr)]){
|
||||
print("pciintrenable: %T: out of isr slots\n", tbdf);
|
||||
return;
|
||||
}
|
||||
|
||||
adr = MSI_TARGET_ADDR;
|
||||
ok64 = (pcicfgr16(p, cap + MSICtrl) & (1<<7)) != 0;
|
||||
pcicfgw32(p, cap + MSIAddr, adr);
|
||||
if(ok64) pcicfgw32(p, cap + MSIAddr + 4, adr>>32);
|
||||
dat = regs[MISC_MSI_DATA_CONFIG];
|
||||
dat = ((dat >> 16) & (dat & 0xFFFF)) | (isr-pciisr);
|
||||
pcicfgw16(p, cap + (ok64 ? MSIData64 : MSIData32), dat);
|
||||
pcicfgw16(p, cap + MSICtrl, 1);
|
||||
}
|
||||
|
||||
void
|
||||
pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a)
|
||||
{
|
||||
Pciisr *isr;
|
||||
|
||||
lock(&pciisrlk);
|
||||
for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
|
||||
if(isr->p != nil && isr->p->tbdf == tbdf && isr->f == f && isr->a == a){
|
||||
regs[MSI_INTR2_BASE + INTR_MASK_SET] = 1 << (isr-pciisr);
|
||||
isr->p = nil;
|
||||
isr->f = nil;
|
||||
isr->a = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock(&pciisrlk);
|
||||
}
|
||||
|
||||
static void
|
||||
pciinterrupt(Ureg *ureg, void*)
|
||||
{
|
||||
Pciisr *isr;
|
||||
u32int sts;
|
||||
|
||||
sts = regs[MSI_INTR2_BASE + INTR_STATUS];
|
||||
if(sts == 0)
|
||||
return;
|
||||
regs[MSI_INTR2_BASE + INTR_CLR] = sts;
|
||||
for(isr = pciisr; sts != 0 && isr < &pciisr[nelem(pciisr)]; isr++, sts>>=1){
|
||||
if((sts & 1) != 0 && isr->f != nil)
|
||||
(*isr->f)(ureg, isr->a);
|
||||
}
|
||||
regs[MISC_EOI_CTRL] = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pcicfginit(void)
|
||||
{
|
||||
uvlong base, limit;
|
||||
ulong ioa;
|
||||
|
||||
fmtinstall('T', tbdffmt);
|
||||
|
||||
pciscan(0, &pciroot);
|
||||
if(pciroot == nil)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Work out how big the top bus is
|
||||
*/
|
||||
ioa = 0;
|
||||
base = soc.pciwin;
|
||||
pcibusmap(pciroot, &base, &ioa, 0);
|
||||
limit = base-1;
|
||||
|
||||
/*
|
||||
* Align the windows and map it
|
||||
*/
|
||||
base = soc.pciwin;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_LO] = base;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_HI] = base >> 32;
|
||||
base >>= 20, limit >>= 20;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT] = (base & 0xFFF) << 4 | (limit & 0xFFF) << 20;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI] = base >> 12;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI] = limit >> 12;
|
||||
|
||||
ioa = 0;
|
||||
base = soc.pciwin;
|
||||
pcibusmap(pciroot, &base, &ioa, 1);
|
||||
|
||||
pcihinv(pciroot);
|
||||
}
|
||||
|
||||
void
|
||||
pcibcmlink(void)
|
||||
{
|
||||
int log2dmasize = 30; // 1GB
|
||||
|
||||
regs[RGR1_SW_INIT_1] |= 3;
|
||||
delay(200);
|
||||
regs[RGR1_SW_INIT_1] &= ~2;
|
||||
regs[MISC_PCIE_CTRL] &= ~5;
|
||||
delay(200);
|
||||
|
||||
regs[MISC_HARD_PCIE_HARD_DEBUG] &= ~0x08000000;
|
||||
delay(200);
|
||||
|
||||
regs[MSI_INTR2_BASE + INTR_CLR] = -1;
|
||||
regs[MSI_INTR2_BASE + INTR_MASK_SET] = -1;
|
||||
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_LO] = 0;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_HI] = 0;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT] = 0;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI] = 0;
|
||||
regs[MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI] = 0;
|
||||
|
||||
// SCB_ACCESS_EN, CFG_READ_UR_MODE, MAX_BURST_SIZE_128, SCB0SIZE
|
||||
regs[MISC_MISC_CTRL] = 1<<12 | 1<<13 | 0<<20 | (log2dmasize-15)<<27;
|
||||
|
||||
regs[MISC_RC_BAR2_CONFIG_LO] = (log2dmasize-15);
|
||||
regs[MISC_RC_BAR2_CONFIG_HI] = 0;
|
||||
|
||||
regs[MISC_RC_BAR1_CONFIG_LO] = 0;
|
||||
regs[MISC_RC_BAR3_CONFIG_LO] = 0;
|
||||
|
||||
regs[MISC_MSI_BAR_CONFIG_LO] = MSI_TARGET_ADDR | 1;
|
||||
regs[MISC_MSI_BAR_CONFIG_HI] = MSI_TARGET_ADDR>>32;
|
||||
regs[MISC_MSI_DATA_CONFIG] = 0xFFF86540;
|
||||
intrenable(IRQpci, pciinterrupt, nil, BUSUNKNOWN, "pci");
|
||||
|
||||
// force to GEN2
|
||||
regs[(0xAC + 12)/4] = (regs[(0xAC + 12)/4] & ~15) | 2; // linkcap
|
||||
regs[(0xAC + 48)/4] = (regs[(0xAC + 48)/4] & ~15) | 2; // linkctl2
|
||||
|
||||
regs[RGR1_SW_INIT_1] &= ~1;
|
||||
delay(500);
|
||||
|
||||
if((regs[MISC_PCIE_STATUS] & 0x30) != 0x30){
|
||||
print("pcireset: phy link is down\n");
|
||||
return;
|
||||
}
|
||||
|
||||
regs[RC_CFG_PRIV1_ID_VAL3] = 0x060400;
|
||||
regs[RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1] &= ~0xC;
|
||||
regs[MISC_HARD_PCIE_HARD_DEBUG] |= 2;
|
||||
|
||||
pcicfginit();
|
||||
}
|
|
@ -26,7 +26,7 @@ dev
|
|||
|
||||
link
|
||||
gisb
|
||||
pci
|
||||
pcibcm
|
||||
archbcm4 pci
|
||||
usbxhci pci archbcm4
|
||||
ethergenet ethermii
|
||||
|
@ -49,7 +49,7 @@ misc
|
|||
dma
|
||||
gic
|
||||
vcore
|
||||
|
||||
pci pcibcm
|
||||
dtracysys
|
||||
dtracytimer
|
||||
|
||||
|
|
|
@ -130,31 +130,6 @@ extern int splflo(void);
|
|||
extern void sysprocsetup(Proc*);
|
||||
extern int isaconfig(char*, int, ISAConf*); /* only devusb.c */
|
||||
|
||||
/*
|
||||
* PCI
|
||||
*/
|
||||
ulong pcibarsize(Pcidev*, int);
|
||||
void pcibussize(Pcidev*, ulong*, ulong*);
|
||||
int pcicfgr8(Pcidev*, int);
|
||||
int pcicfgr16(Pcidev*, int);
|
||||
int pcicfgr32(Pcidev*, int);
|
||||
void pcicfgw8(Pcidev*, int, int);
|
||||
void pcicfgw16(Pcidev*, int, int);
|
||||
void pcicfgw32(Pcidev*, int, int);
|
||||
void pciclrbme(Pcidev*);
|
||||
void pciclrioe(Pcidev*);
|
||||
void pciclrmwi(Pcidev*);
|
||||
int pcigetpms(Pcidev*);
|
||||
void pcihinv(Pcidev*);
|
||||
uchar pciipin(Pcidev*, uchar);
|
||||
Pcidev* pcimatch(Pcidev*, int, int);
|
||||
Pcidev* pcimatchtbdf(int);
|
||||
void pcireset(void);
|
||||
int pciscan(int, Pcidev**);
|
||||
void pcisetbme(Pcidev*);
|
||||
void pcisetioe(Pcidev*);
|
||||
void pcisetmwi(Pcidev*);
|
||||
int pcisetpms(Pcidev*, int);
|
||||
int cas32(void*, u32int, u32int);
|
||||
int tas32(void*);
|
||||
|
||||
|
|
|
@ -27,168 +27,6 @@ enum {
|
|||
#define BUSTYPE(tbdf) ((tbdf)>>24)
|
||||
#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
|
||||
|
||||
/*
|
||||
* PCI support code.
|
||||
*/
|
||||
enum { /* type 0 & type 1 pre-defined header */
|
||||
PciVID = 0x00, /* vendor ID */
|
||||
PciDID = 0x02, /* device ID */
|
||||
PciPCR = 0x04, /* command */
|
||||
PciPSR = 0x06, /* status */
|
||||
PciRID = 0x08, /* revision ID */
|
||||
PciCCRp = 0x09, /* programming interface class code */
|
||||
PciCCRu = 0x0A, /* sub-class code */
|
||||
PciCCRb = 0x0B, /* base class code */
|
||||
PciCLS = 0x0C, /* cache line size */
|
||||
PciLTR = 0x0D, /* latency timer */
|
||||
PciHDT = 0x0E, /* header type */
|
||||
PciBST = 0x0F, /* BIST */
|
||||
};
|
||||
|
||||
/* ccrb (base class code) values; controller types */
|
||||
enum {
|
||||
Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
|
||||
Pcibcstore = 1, /* mass storage */
|
||||
Pcibcnet = 2, /* network */
|
||||
Pcibcdisp = 3, /* display */
|
||||
Pcibcmmedia = 4, /* multimedia */
|
||||
Pcibcmem = 5, /* memory */
|
||||
Pcibcbridge = 6, /* bridge */
|
||||
Pcibccomm = 7, /* simple comms (e.g., serial) */
|
||||
Pcibcbasesys = 8, /* base system */
|
||||
Pcibcinput = 9, /* input */
|
||||
Pcibcdock = 0xa, /* docking stations */
|
||||
Pcibcproc = 0xb, /* processors */
|
||||
Pcibcserial = 0xc, /* serial bus (e.g., USB) */
|
||||
Pcibcwireless = 0xd, /* wireless */
|
||||
Pcibcintell = 0xe, /* intelligent i/o */
|
||||
Pcibcsatcom = 0xf, /* satellite comms */
|
||||
Pcibccrypto = 0x10, /* encryption/decryption */
|
||||
Pcibcdacq = 0x11, /* data acquisition & signal proc. */
|
||||
};
|
||||
|
||||
/* ccru (sub-class code) values; common cases only */
|
||||
enum {
|
||||
/* mass storage */
|
||||
Pciscscsi = 0, /* SCSI */
|
||||
Pciscide = 1, /* IDE (ATA) */
|
||||
|
||||
/* network */
|
||||
Pciscether = 0, /* Ethernet */
|
||||
|
||||
/* display */
|
||||
Pciscvga = 0, /* VGA */
|
||||
Pciscxga = 1, /* XGA */
|
||||
Pcisc3d = 2, /* 3D */
|
||||
|
||||
/* bridges */
|
||||
Pcischostpci = 0, /* host/pci */
|
||||
Pciscpcicpci = 1, /* pci/pci */
|
||||
|
||||
/* simple comms */
|
||||
Pciscserial = 0, /* 16450, etc. */
|
||||
Pciscmultiser = 1, /* multiport serial */
|
||||
|
||||
/* serial bus */
|
||||
Pciscusb = 3, /* USB */
|
||||
};
|
||||
|
||||
enum { /* type 0 pre-defined header */
|
||||
PciCIS = 0x28, /* cardbus CIS pointer */
|
||||
PciSVID = 0x2C, /* subsystem vendor ID */
|
||||
PciSID = 0x2E, /* subsystem ID */
|
||||
PciEBAR0 = 0x30, /* expansion ROM base address */
|
||||
PciMGNT = 0x3E, /* burst period length */
|
||||
PciMLT = 0x3F, /* maximum latency between bursts */
|
||||
};
|
||||
|
||||
enum { /* type 1 pre-defined header */
|
||||
PciPBN = 0x18, /* primary bus number */
|
||||
PciSBN = 0x19, /* secondary bus number */
|
||||
PciUBN = 0x1A, /* subordinate bus number */
|
||||
PciSLTR = 0x1B, /* secondary latency timer */
|
||||
PciIBR = 0x1C, /* I/O base */
|
||||
PciILR = 0x1D, /* I/O limit */
|
||||
PciSPSR = 0x1E, /* secondary status */
|
||||
PciMBR = 0x20, /* memory base */
|
||||
PciMLR = 0x22, /* memory limit */
|
||||
PciPMBR = 0x24, /* prefetchable memory base */
|
||||
PciPMLR = 0x26, /* prefetchable memory limit */
|
||||
PciPUBR = 0x28, /* prefetchable base upper 32 bits */
|
||||
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
|
||||
PciIUBR = 0x30, /* I/O base upper 16 bits */
|
||||
PciIULR = 0x32, /* I/O limit upper 16 bits */
|
||||
PciEBAR1 = 0x28, /* expansion ROM base address */
|
||||
PciBCR = 0x3E, /* bridge control register */
|
||||
};
|
||||
|
||||
enum { /* type 2 pre-defined header */
|
||||
PciCBExCA = 0x10,
|
||||
PciCBSPSR = 0x16,
|
||||
PciCBPBN = 0x18, /* primary bus number */
|
||||
PciCBSBN = 0x19, /* secondary bus number */
|
||||
PciCBUBN = 0x1A, /* subordinate bus number */
|
||||
PciCBSLTR = 0x1B, /* secondary latency timer */
|
||||
PciCBMBR0 = 0x1C,
|
||||
PciCBMLR0 = 0x20,
|
||||
PciCBMBR1 = 0x24,
|
||||
PciCBMLR1 = 0x28,
|
||||
PciCBIBR0 = 0x2C, /* I/O base */
|
||||
PciCBILR0 = 0x30, /* I/O limit */
|
||||
PciCBIBR1 = 0x34, /* I/O base */
|
||||
PciCBILR1 = 0x38, /* I/O limit */
|
||||
PciCBSVID = 0x40, /* subsystem vendor ID */
|
||||
PciCBSID = 0x42, /* subsystem ID */
|
||||
PciCBLMBAR = 0x44, /* legacy mode base address */
|
||||
};
|
||||
|
||||
typedef struct Pcisiz Pcisiz;
|
||||
struct Pcisiz
|
||||
{
|
||||
Pcidev* dev;
|
||||
int siz;
|
||||
int bar;
|
||||
};
|
||||
|
||||
typedef struct Pcidev Pcidev;
|
||||
struct Pcidev
|
||||
{
|
||||
int tbdf; /* type+bus+device+function */
|
||||
ushort vid; /* vendor ID */
|
||||
ushort did; /* device ID */
|
||||
|
||||
ushort pcr;
|
||||
|
||||
uchar rid;
|
||||
uchar ccrp;
|
||||
uchar ccru;
|
||||
uchar ccrb;
|
||||
uchar cls;
|
||||
uchar ltr;
|
||||
|
||||
struct {
|
||||
ulong bar; /* base address */
|
||||
int size;
|
||||
} mem[6];
|
||||
|
||||
struct {
|
||||
ulong bar;
|
||||
int size;
|
||||
} rom;
|
||||
uchar intl; /* interrupt line */
|
||||
|
||||
Pcidev* list;
|
||||
Pcidev* link; /* next device on this bno */
|
||||
|
||||
Pcidev* bridge; /* down a bus */
|
||||
struct {
|
||||
ulong bar;
|
||||
int size;
|
||||
} ioa, mema;
|
||||
|
||||
int pmrb; /* power management register block */
|
||||
};
|
||||
|
||||
#define PCIWINDOW 0
|
||||
#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -65,21 +65,9 @@ void outs(int, ushort);
|
|||
void outss(int, void*, int);
|
||||
void outl(int, ulong);
|
||||
void outsl(int, void*, int);
|
||||
int pciscan(int, Pcidev **);
|
||||
ulong pcibarsize(Pcidev *, int);
|
||||
int pcicfgr8(Pcidev*, int);
|
||||
int pcicfgr16(Pcidev*, int);
|
||||
int pcicfgr32(Pcidev*, int);
|
||||
void pcicfgw8(Pcidev*, int, int);
|
||||
void pcicfgw16(Pcidev*, int, int);
|
||||
void pcicfgw32(Pcidev*, int, int);
|
||||
void pciclrbme(Pcidev*);
|
||||
void pcihinv(Pcidev*);
|
||||
uchar pciipin(Pcidev *, uchar);
|
||||
Pcidev* pcimatch(Pcidev*, int, int);
|
||||
Pcidev* pcimatchtbdf(int);
|
||||
void pcireset(void);
|
||||
void pcisetbme(Pcidev*);
|
||||
int pcicfgrw8(int, int, int, int);
|
||||
int pcicfgrw16(int, int, int, int);
|
||||
int pcicfgrw32(int, int, int, int);
|
||||
#define procrestore(p)
|
||||
void procsave(Proc*);
|
||||
void procsetup(Proc*);
|
||||
|
|
|
@ -31,150 +31,12 @@ typedef struct Vctl {
|
|||
void* a; /* argument to call it with */
|
||||
} Vctl;
|
||||
|
||||
enum {
|
||||
BusCBUS = 0, /* Corollary CBUS */
|
||||
BusCBUSII, /* Corollary CBUS II */
|
||||
BusEISA, /* Extended ISA */
|
||||
BusFUTURE, /* IEEE Futurebus */
|
||||
BusINTERN, /* Internal bus */
|
||||
BusISA, /* Industry Standard Architecture */
|
||||
BusMBI, /* Multibus I */
|
||||
BusMBII, /* Multibus II */
|
||||
BusMCA, /* Micro Channel Architecture */
|
||||
BusMPI, /* MPI */
|
||||
BusMPSA, /* MPSA */
|
||||
BusNUBUS, /* Apple Macintosh NuBus */
|
||||
BusPCI, /* Peripheral Component Interconnect */
|
||||
BusPCMCIA, /* PC Memory Card International Association */
|
||||
BusTC, /* DEC TurboChannel */
|
||||
BusVL, /* VESA Local bus */
|
||||
BusVME, /* VMEbus */
|
||||
BusXPRESS, /* Express System Bus */
|
||||
};
|
||||
|
||||
#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
|
||||
#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
|
||||
#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
|
||||
#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
|
||||
#define BUSTYPE(tbdf) ((tbdf)>>24)
|
||||
#define BUSDF(tbdf) ((tbdf)&0x000FF00)
|
||||
#define BUSBDF(tbdf) ((tbdf)&0x0FFFF00)
|
||||
#define BUSUNKNOWN (-1)
|
||||
|
||||
enum {
|
||||
MaxEISA = 16,
|
||||
EISAconfig = 0xC80,
|
||||
};
|
||||
|
||||
/*
|
||||
* PCI support code.
|
||||
*/
|
||||
enum { /* type 0 and type 1 pre-defined header */
|
||||
PciVID = 0x00, /* vendor ID */
|
||||
PciDID = 0x02, /* device ID */
|
||||
PciPCR = 0x04, /* command */
|
||||
PciPSR = 0x06, /* status */
|
||||
PciRID = 0x08, /* revision ID */
|
||||
PciCCRp = 0x09, /* programming interface class code */
|
||||
PciCCRu = 0x0A, /* sub-class code */
|
||||
PciCCRb = 0x0B, /* base class code */
|
||||
PciCLS = 0x0C, /* cache line size */
|
||||
PciLTR = 0x0D, /* latency timer */
|
||||
PciHDT = 0x0E, /* header type */
|
||||
PciBST = 0x0F, /* BIST */
|
||||
|
||||
PciBAR0 = 0x10, /* base address */
|
||||
PciBAR1 = 0x14,
|
||||
|
||||
PciINTL = 0x3C, /* interrupt line */
|
||||
PciINTP = 0x3D, /* interrupt pin */
|
||||
};
|
||||
|
||||
enum { /* type 0 pre-defined header */
|
||||
PciCIS = 0x28, /* cardbus CIS pointer */
|
||||
PciSVID = 0x2C, /* subsystem vendor ID */
|
||||
PciSID = 0x2E, /* subsystem ID */
|
||||
PciEBAR0 = 0x30, /* expansion ROM base address */
|
||||
PciMGNT = 0x3E, /* burst period length */
|
||||
PciMLT = 0x3F, /* maximum latency between bursts */
|
||||
};
|
||||
|
||||
enum { /* type 1 pre-defined header */
|
||||
PciPBN = 0x18, /* primary bus number */
|
||||
PciSBN = 0x19, /* secondary bus number */
|
||||
PciUBN = 0x1A, /* subordinate bus number */
|
||||
PciSLTR = 0x1B, /* secondary latency timer */
|
||||
PciIBR = 0x1C, /* I/O base */
|
||||
PciILR = 0x1D, /* I/O limit */
|
||||
PciSPSR = 0x1E, /* secondary status */
|
||||
PciMBR = 0x20, /* memory base */
|
||||
PciMLR = 0x22, /* memory limit */
|
||||
PciPMBR = 0x24, /* prefetchable memory base */
|
||||
PciPMLR = 0x26, /* prefetchable memory limit */
|
||||
PciPUBR = 0x28, /* prefetchable base upper 32 bits */
|
||||
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
|
||||
PciIUBR = 0x30, /* I/O base upper 16 bits */
|
||||
PciIULR = 0x32, /* I/O limit upper 16 bits */
|
||||
PciEBAR1 = 0x28, /* expansion ROM base address */
|
||||
PciBCR = 0x3E, /* bridge control register */
|
||||
};
|
||||
|
||||
enum { /* type 2 pre-defined header */
|
||||
PciCBExCA = 0x10,
|
||||
PciCBSPSR = 0x16,
|
||||
PciCBPBN = 0x18, /* primary bus number */
|
||||
PciCBSBN = 0x19, /* secondary bus number */
|
||||
PciCBUBN = 0x1A, /* subordinate bus number */
|
||||
PciCBSLTR = 0x1B, /* secondary latency timer */
|
||||
PciCBMBR0 = 0x1C,
|
||||
PciCBMLR0 = 0x20,
|
||||
PciCBMBR1 = 0x24,
|
||||
PciCBMLR1 = 0x28,
|
||||
PciCBIBR0 = 0x2C, /* I/O base */
|
||||
PciCBILR0 = 0x30, /* I/O limit */
|
||||
PciCBIBR1 = 0x34, /* I/O base */
|
||||
PciCBILR1 = 0x38, /* I/O limit */
|
||||
PciCBSVID = 0x40, /* subsystem vendor ID */
|
||||
PciCBSID = 0x42, /* subsystem ID */
|
||||
PciCBLMBAR = 0x44, /* legacy mode base address */
|
||||
};
|
||||
|
||||
typedef struct Pcisiz Pcisiz;
|
||||
struct Pcisiz
|
||||
{
|
||||
Pcidev* dev;
|
||||
int siz;
|
||||
int bar;
|
||||
};
|
||||
|
||||
typedef struct Pcidev Pcidev;
|
||||
typedef struct Pcidev {
|
||||
int tbdf; /* type+bus+device+function */
|
||||
ushort vid; /* vendor ID */
|
||||
ushort did; /* device ID */
|
||||
|
||||
uchar rid;
|
||||
uchar ccrp;
|
||||
uchar ccru;
|
||||
uchar ccrb;
|
||||
|
||||
struct {
|
||||
ulong bar; /* base address */
|
||||
int size;
|
||||
} mem[6];
|
||||
|
||||
uchar intl; /* interrupt line */
|
||||
|
||||
Pcidev* list;
|
||||
Pcidev* link; /* next device on this bno */
|
||||
|
||||
Pcidev* bridge; /* down a bus */
|
||||
struct {
|
||||
ulong bar;
|
||||
int size;
|
||||
} ioa, mema;
|
||||
ulong pcr;
|
||||
};
|
||||
|
||||
#define PCIWINDOW 0x80000000
|
||||
#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
|
||||
|
||||
#define BUSUNKNOWN (-1)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
CONF=mtx
|
||||
CONFLIST=mtx mtxcpu
|
||||
CONFLIST=mtx
|
||||
|
||||
objtype=power
|
||||
</$objtype/mkfile
|
||||
|
|
|
@ -20,11 +20,13 @@ dev
|
|||
ip arp chandial ip ipv6 ipaux iproute netif netlog nullmedium pktmedium inferno
|
||||
|
||||
link
|
||||
pcimtx
|
||||
ether2114x pci
|
||||
ethermedium
|
||||
netdevmedium
|
||||
|
||||
misc
|
||||
pci pcimtx
|
||||
uarti8250
|
||||
|
||||
ip
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
dev
|
||||
root
|
||||
cons
|
||||
swap
|
||||
arch
|
||||
pnp pci
|
||||
env
|
||||
pipe
|
||||
proc
|
||||
mnt
|
||||
srv
|
||||
dup
|
||||
ssl
|
||||
cap
|
||||
kprof
|
||||
uart
|
||||
rtc
|
||||
|
||||
ether netif
|
||||
ip arp chandial ip ipv6 ipaux iproute netif netlog nullmedium pktmedium inferno
|
||||
|
||||
link
|
||||
ether2114x pci
|
||||
ethermedium
|
||||
netdevmedium
|
||||
|
||||
misc
|
||||
uarti8250
|
||||
|
||||
ip
|
||||
tcp
|
||||
udp
|
||||
ipifc
|
||||
icmp
|
||||
icmp6
|
||||
|
||||
port
|
||||
int cpuserver = 1;
|
||||
|
||||
bootdir
|
||||
/$objtype/bin/paqfs
|
||||
/$objtype/bin/auth/factotum
|
||||
bootfs.paq
|
||||
boot
|
|
@ -1,908 +0,0 @@
|
|||
/*
|
||||
* PCI support code.
|
||||
*/
|
||||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define DBG if(0) pcilog
|
||||
|
||||
struct
|
||||
{
|
||||
char output[16384];
|
||||
int ptr;
|
||||
}PCICONS;
|
||||
|
||||
int
|
||||
pcilog(char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list arg;
|
||||
char buf[PRINTSIZE];
|
||||
|
||||
va_start(arg, fmt);
|
||||
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
|
||||
va_end(arg);
|
||||
|
||||
memmove(PCICONS.output+PCICONS.ptr, buf, n);
|
||||
PCICONS.ptr += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
enum
|
||||
{ /* configuration mechanism #1 */
|
||||
PciADDR = 0xCF8, /* CONFIG_ADDRESS */
|
||||
PciDATA = 0xCFC, /* CONFIG_DATA */
|
||||
|
||||
/* configuration mechanism #2 */
|
||||
PciCSE = 0xCF8, /* configuration space enable */
|
||||
PciFORWARD = 0xCFA, /* which bus */
|
||||
|
||||
MaxFNO = 7,
|
||||
MaxUBN = 255,
|
||||
};
|
||||
|
||||
enum
|
||||
{ /* command register */
|
||||
IOen = (1<<0),
|
||||
MEMen = (1<<1),
|
||||
MASen = (1<<2),
|
||||
MemWrInv = (1<<4),
|
||||
PErrEn = (1<<6),
|
||||
SErrEn = (1<<8),
|
||||
};
|
||||
|
||||
static Lock pcicfglock;
|
||||
static QLock pcicfginitlock;
|
||||
static int pcicfgmode = -1;
|
||||
static int pcimaxbno = 7;
|
||||
static int pcimaxdno;
|
||||
static Pcidev* pciroot;
|
||||
static Pcidev* pcilist;
|
||||
static Pcidev* pcitail;
|
||||
|
||||
static int pcicfgrw32(int, int, int, int);
|
||||
static int pcicfgrw8(int, int, int, int);
|
||||
|
||||
static char* bustypes[] = {
|
||||
"CBUSI",
|
||||
"CBUSII",
|
||||
"EISA",
|
||||
"FUTURE",
|
||||
"INTERN",
|
||||
"ISA",
|
||||
"MBI",
|
||||
"MBII",
|
||||
"MCA",
|
||||
"MPI",
|
||||
"MPSA",
|
||||
"NUBUS",
|
||||
"PCI",
|
||||
"PCMCIA",
|
||||
"TC",
|
||||
"VL",
|
||||
"VME",
|
||||
"XPRESS",
|
||||
};
|
||||
|
||||
#pragma varargck type "T" int
|
||||
|
||||
static int
|
||||
tbdffmt(Fmt* fmt)
|
||||
{
|
||||
char *p;
|
||||
int l, r, type, tbdf;
|
||||
|
||||
if((p = malloc(READSTR)) == nil)
|
||||
return fmtstrcpy(fmt, "(tbdfconv)");
|
||||
|
||||
switch(fmt->r){
|
||||
case 'T':
|
||||
tbdf = va_arg(fmt->args, int);
|
||||
type = BUSTYPE(tbdf);
|
||||
if(type < nelem(bustypes))
|
||||
l = snprint(p, READSTR, bustypes[type]);
|
||||
else
|
||||
l = snprint(p, READSTR, "%d", type);
|
||||
snprint(p+l, READSTR-l, ".%d.%d.%d",
|
||||
BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
|
||||
break;
|
||||
|
||||
default:
|
||||
snprint(p, READSTR, "(tbdfconv)");
|
||||
break;
|
||||
}
|
||||
r = fmtstrcpy(fmt, p);
|
||||
free(p);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ulong
|
||||
pcibarsize(Pcidev *p, int rno)
|
||||
{
|
||||
ulong v, size;
|
||||
|
||||
v = pcicfgrw32(p->tbdf, rno, 0, 1);
|
||||
pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
|
||||
size = pcicfgrw32(p->tbdf, rno, 0, 1);
|
||||
if(v & 1)
|
||||
size |= 0xFFFF0000;
|
||||
pcicfgrw32(p->tbdf, rno, v, 0);
|
||||
|
||||
return -(size & ~0x0F);
|
||||
}
|
||||
|
||||
static int
|
||||
pcisizcmp(void *a, void *b)
|
||||
{
|
||||
Pcisiz *aa, *bb;
|
||||
|
||||
aa = a;
|
||||
bb = b;
|
||||
return aa->siz - bb->siz;
|
||||
}
|
||||
|
||||
static ulong
|
||||
pcimask(ulong v)
|
||||
{
|
||||
ulong m;
|
||||
|
||||
m = BI2BY*sizeof(v);
|
||||
for(m = 1<<(m-1); m != 0; m >>= 1) {
|
||||
if(m & v)
|
||||
break;
|
||||
}
|
||||
|
||||
m--;
|
||||
if((v & m) == 0)
|
||||
return v;
|
||||
|
||||
v |= m;
|
||||
return v+1;
|
||||
}
|
||||
|
||||
static void
|
||||
pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg)
|
||||
{
|
||||
Pcidev *p;
|
||||
int ntb, i, size, rno, hole;
|
||||
ulong v, mema, ioa, sioa, smema, base, limit;
|
||||
Pcisiz *table, *tptr, *mtb, *itb;
|
||||
extern void qsort(void*, long, long, int (*)(void*, void*));
|
||||
|
||||
ioa = *pioa;
|
||||
mema = *pmema;
|
||||
|
||||
DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n",
|
||||
wrreg, root->tbdf, mema, ioa);
|
||||
|
||||
ntb = 0;
|
||||
for(p = root; p != nil; p = p->link)
|
||||
ntb++;
|
||||
|
||||
ntb *= (PciCIS-PciBAR0)/4;
|
||||
table = malloc(2*ntb*sizeof(Pcisiz));
|
||||
itb = table;
|
||||
mtb = table+ntb;
|
||||
|
||||
/*
|
||||
* Build a table of sizes
|
||||
*/
|
||||
for(p = root; p != nil; p = p->link) {
|
||||
if(p->ccrb == 0x06) {
|
||||
if(p->ccru == 0x04 && p->bridge != nil) {
|
||||
sioa = ioa;
|
||||
smema = mema;
|
||||
pcibusmap(p->bridge, &smema, &sioa, 0);
|
||||
|
||||
hole = pcimask(smema-mema);
|
||||
if(hole < (1<<20))
|
||||
hole = 1<<20;
|
||||
p->mema.size = hole;
|
||||
|
||||
hole = pcimask(sioa-ioa);
|
||||
if(hole < (1<<12))
|
||||
hole = 1<<12;
|
||||
|
||||
p->ioa.size = hole;
|
||||
|
||||
itb->dev = p;
|
||||
itb->bar = -1;
|
||||
itb->siz = p->ioa.size;
|
||||
itb++;
|
||||
|
||||
mtb->dev = p;
|
||||
mtb->bar = -1;
|
||||
mtb->siz = p->mema.size;
|
||||
mtb++;
|
||||
}
|
||||
if((pcicfgr8(p, PciHDT)&0x7f) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i = 0; i <= 5; i++) {
|
||||
rno = PciBAR0 + i*4;
|
||||
v = pcicfgrw32(p->tbdf, rno, 0, 1);
|
||||
size = pcibarsize(p, rno);
|
||||
if(size == 0)
|
||||
continue;
|
||||
|
||||
if(v & 1) {
|
||||
itb->dev = p;
|
||||
itb->bar = i;
|
||||
itb->siz = size;
|
||||
itb++;
|
||||
}
|
||||
else {
|
||||
mtb->dev = p;
|
||||
mtb->bar = i;
|
||||
mtb->siz = size;
|
||||
mtb++;
|
||||
}
|
||||
|
||||
p->mem[i].size = size;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort both tables IO smallest first, Memory largest
|
||||
*/
|
||||
qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp);
|
||||
tptr = table+ntb;
|
||||
qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp);
|
||||
|
||||
/*
|
||||
* Allocate IO address space on this bus
|
||||
*/
|
||||
for(tptr = table; tptr < itb; tptr++) {
|
||||
hole = tptr->siz;
|
||||
if(tptr->bar == -1)
|
||||
hole = 1<<12;
|
||||
ioa = (ioa+hole-1) & ~(hole-1);
|
||||
|
||||
p = tptr->dev;
|
||||
if(tptr->bar == -1)
|
||||
p->ioa.bar = ioa;
|
||||
else {
|
||||
p->pcr |= IOen;
|
||||
p->mem[tptr->bar].bar = ioa|1;
|
||||
if(wrreg)
|
||||
pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0);
|
||||
}
|
||||
|
||||
ioa += tptr->siz;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate Memory address space on this bus
|
||||
*/
|
||||
for(tptr = table+ntb; tptr < mtb; tptr++) {
|
||||
hole = tptr->siz;
|
||||
if(tptr->bar == -1)
|
||||
hole = 1<<20;
|
||||
mema = (mema+hole-1) & ~(hole-1);
|
||||
|
||||
p = tptr->dev;
|
||||
if(tptr->bar == -1)
|
||||
p->mema.bar = mema;
|
||||
else {
|
||||
p->pcr |= MEMen;
|
||||
p->mem[tptr->bar].bar = mema;
|
||||
if(wrreg)
|
||||
pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0);
|
||||
}
|
||||
mema += tptr->siz;
|
||||
}
|
||||
|
||||
*pmema = mema;
|
||||
*pioa = ioa;
|
||||
free(table);
|
||||
|
||||
if(wrreg == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Finally set all the bridge addresses & registers
|
||||
*/
|
||||
for(p = root; p != nil; p = p->link) {
|
||||
if(p->bridge == nil) {
|
||||
pcicfgrw8(p->tbdf, PciLTR, 64, 0);
|
||||
|
||||
p->pcr |= MASen;
|
||||
pcicfgrw32(p->tbdf, PciPCR, p->pcr, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
base = p->ioa.bar;
|
||||
limit = base+p->ioa.size-1;
|
||||
v = pcicfgrw32(p->tbdf, PciIBR, 0, 1);
|
||||
v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8);
|
||||
pcicfgrw32(p->tbdf, PciIBR, v, 0);
|
||||
v = (limit & 0xFFFF0000)|(base>>16);
|
||||
pcicfgrw32(p->tbdf, PciIUBR, v, 0);
|
||||
|
||||
base = p->mema.bar;
|
||||
limit = base+p->mema.size-1;
|
||||
v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16);
|
||||
pcicfgrw32(p->tbdf, PciMBR, v, 0);
|
||||
|
||||
/*
|
||||
* Disable memory prefetch
|
||||
*/
|
||||
pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0);
|
||||
pcicfgrw8(p->tbdf, PciLTR, 64, 0);
|
||||
|
||||
/*
|
||||
* Enable the bridge
|
||||
*/
|
||||
v = 0xFFFF0000 | IOen | MEMen | MASen;
|
||||
pcicfgrw32(p->tbdf, PciPCR, v, 0);
|
||||
|
||||
sioa = p->ioa.bar;
|
||||
smema = p->mema.bar;
|
||||
pcibusmap(p->bridge, &smema, &sioa, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pcilscan(int bno, Pcidev** list)
|
||||
{
|
||||
Pcidev *p, *head, *tail;
|
||||
int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
|
||||
|
||||
maxubn = bno;
|
||||
head = nil;
|
||||
tail = nil;
|
||||
for(dno = 0; dno <= pcimaxdno; dno++){
|
||||
maxfno = 0;
|
||||
for(fno = 0; fno <= maxfno; fno++){
|
||||
/*
|
||||
* For this possible device, form the
|
||||
* bus+device+function triplet needed to address it
|
||||
* and try to read the vendor and device ID.
|
||||
* If successful, allocate a device struct and
|
||||
* start to fill it in with some useful information
|
||||
* from the device's configuration space.
|
||||
*/
|
||||
tbdf = MKBUS(BusPCI, bno, dno, fno);
|
||||
l = pcicfgrw32(tbdf, PciVID, 0, 1);
|
||||
if(l == 0xFFFFFFFF || l == 0)
|
||||
continue;
|
||||
p = malloc(sizeof(*p));
|
||||
p->tbdf = tbdf;
|
||||
p->vid = l;
|
||||
p->did = l>>16;
|
||||
|
||||
if(pcilist != nil)
|
||||
pcitail->list = p;
|
||||
else
|
||||
pcilist = p;
|
||||
pcitail = p;
|
||||
|
||||
p->rid = pcicfgr8(p, PciRID);
|
||||
p->ccrp = pcicfgr8(p, PciCCRp);
|
||||
p->ccru = pcicfgr8(p, PciCCRu);
|
||||
p->ccrb = pcicfgr8(p, PciCCRb);
|
||||
p->pcr = pcicfgr32(p, PciPCR);
|
||||
|
||||
p->intl = pcicfgr8(p, PciINTL);
|
||||
|
||||
/*
|
||||
* If the device is a multi-function device adjust the
|
||||
* loop count so all possible functions are checked.
|
||||
*/
|
||||
hdt = pcicfgr8(p, PciHDT);
|
||||
if(hdt & 0x80)
|
||||
maxfno = MaxFNO;
|
||||
|
||||
/*
|
||||
* If appropriate, read the base address registers
|
||||
* and work out the sizes.
|
||||
*/
|
||||
switch(p->ccrb) {
|
||||
case 0x01: /* mass storage controller */
|
||||
case 0x02: /* network controller */
|
||||
case 0x03: /* display controller */
|
||||
case 0x04: /* multimedia device */
|
||||
case 0x06: /* bridge device */
|
||||
case 0x07: /* simple comm. controllers */
|
||||
case 0x08: /* base system peripherals */
|
||||
case 0x09: /* input devices */
|
||||
case 0x0A: /* docking stations */
|
||||
case 0x0B: /* processors */
|
||||
case 0x0C: /* serial bus controllers */
|
||||
if((hdt & 0x7F) != 0)
|
||||
break;
|
||||
rno = PciBAR0 - 4;
|
||||
for(i = 0; i < nelem(p->mem); i++) {
|
||||
rno += 4;
|
||||
p->mem[i].bar = pcicfgr32(p, rno);
|
||||
p->mem[i].size = pcibarsize(p, rno);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
case 0x05: /* memory controller */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(head != nil)
|
||||
tail->link = p;
|
||||
else
|
||||
head = p;
|
||||
tail = p;
|
||||
}
|
||||
}
|
||||
|
||||
*list = head;
|
||||
for(p = head; p != nil; p = p->link){
|
||||
/*
|
||||
* Find PCI-PCI bridges and recursively descend the tree.
|
||||
*/
|
||||
if(p->ccrb != 0x06 || p->ccru != 0x04)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the secondary or subordinate bus number is not
|
||||
* initialised try to do what the PCI BIOS should have
|
||||
* done and fill in the numbers as the tree is descended.
|
||||
* On the way down the subordinate bus number is set to
|
||||
* the maximum as it's not known how many buses are behind
|
||||
* this one; the final value is set on the way back up.
|
||||
*/
|
||||
sbn = pcicfgr8(p, PciSBN);
|
||||
ubn = pcicfgr8(p, PciUBN);
|
||||
|
||||
if(sbn == 0 || ubn == 0) {
|
||||
sbn = maxubn+1;
|
||||
/*
|
||||
* Make sure memory, I/O and master enables are
|
||||
* off, set the primary, secondary and subordinate
|
||||
* bus numbers and clear the secondary status before
|
||||
* attempting to scan the secondary bus.
|
||||
*
|
||||
* Initialisation of the bridge should be done here.
|
||||
*/
|
||||
pcicfgw32(p, PciPCR, 0xFFFF0000);
|
||||
l = (MaxUBN<<16)|(sbn<<8)|bno;
|
||||
pcicfgw32(p, PciPBN, l);
|
||||
pcicfgw16(p, PciSPSR, 0xFFFF);
|
||||
maxubn = pcilscan(sbn, &p->bridge);
|
||||
l = (maxubn<<16)|(sbn<<8)|bno;
|
||||
|
||||
pcicfgw32(p, PciPBN, l);
|
||||
}
|
||||
else {
|
||||
maxubn = ubn;
|
||||
pcilscan(sbn, &p->bridge);
|
||||
}
|
||||
}
|
||||
|
||||
return maxubn;
|
||||
}
|
||||
|
||||
int
|
||||
pciscan(int bno, Pcidev **list)
|
||||
{
|
||||
int ubn;
|
||||
|
||||
qlock(&pcicfginitlock);
|
||||
ubn = pcilscan(bno, list);
|
||||
qunlock(&pcicfginitlock);
|
||||
return ubn;
|
||||
}
|
||||
|
||||
static void
|
||||
pcicfginit(void)
|
||||
{
|
||||
char *p;
|
||||
int bno;
|
||||
Pcidev **list;
|
||||
ulong mema, ioa;
|
||||
|
||||
qlock(&pcicfginitlock);
|
||||
if(pcicfgmode != -1)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Try to determine which PCI configuration mode is implemented.
|
||||
* Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses
|
||||
* a DWORD at 0xCF8 and another at 0xCFC and will pass through
|
||||
* any non-DWORD accesses as normal I/O cycles. There shouldn't be
|
||||
* a device behind these addresses so if Mode2 accesses fail try
|
||||
* for Mode1 (which is preferred, Mode2 is deprecated).
|
||||
*/
|
||||
outb(PciCSE, 0);
|
||||
if(inb(PciCSE) == 0){
|
||||
pcicfgmode = 2;
|
||||
pcimaxdno = 15;
|
||||
}
|
||||
else {
|
||||
outl(PciADDR, 0);
|
||||
if(inl(PciADDR) == 0){
|
||||
pcicfgmode = 1;
|
||||
pcimaxdno = 31;
|
||||
}
|
||||
}
|
||||
|
||||
if(pcicfgmode < 0)
|
||||
goto out;
|
||||
|
||||
fmtinstall('T', tbdffmt);
|
||||
|
||||
if(p = getconf("*pcimaxbno"))
|
||||
pcimaxbno = strtoul(p, 0, 0);
|
||||
if(p = getconf("*pcimaxdno"))
|
||||
pcimaxdno = strtoul(p, 0, 0);
|
||||
|
||||
list = &pciroot;
|
||||
for(bno = 0; bno <= pcimaxbno; bno++) {
|
||||
int sbno = bno;
|
||||
bno = pcilscan(bno, list);
|
||||
|
||||
while(*list)
|
||||
list = &(*list)->link;
|
||||
|
||||
if (sbno == 0) {
|
||||
Pcidev *pci;
|
||||
|
||||
/*
|
||||
* If we have found a PCI-to-Cardbus bridge, make sure
|
||||
* it has no valid mappings anymore.
|
||||
*/
|
||||
pci = pciroot;
|
||||
while (pci) {
|
||||
if (pci->ccrb == 6 && pci->ccru == 7) {
|
||||
ushort bcr;
|
||||
|
||||
/* reset the cardbus */
|
||||
bcr = pcicfgr16(pci, PciBCR);
|
||||
pcicfgw16(pci, PciBCR, 0x40 | bcr);
|
||||
delay(50);
|
||||
}
|
||||
pci = pci->link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pciroot == nil)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Work out how big the top bus is
|
||||
*/
|
||||
mema = 0;
|
||||
ioa = 0;
|
||||
pcibusmap(pciroot, &mema, &ioa, 0);
|
||||
|
||||
DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n",
|
||||
mema, pcimask(mema), ioa);
|
||||
|
||||
/*
|
||||
* Align the windows and map it
|
||||
*/
|
||||
ioa = 0x1000;
|
||||
mema = 0;
|
||||
|
||||
pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa);
|
||||
|
||||
pcibusmap(pciroot, &mema, &ioa, 1);
|
||||
DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa);
|
||||
|
||||
out:
|
||||
qunlock(&pcicfginitlock);
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw8(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type, x;
|
||||
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
x = -1;
|
||||
if(BUSDNO(tbdf) > pcimaxdno)
|
||||
return x;
|
||||
|
||||
lock(&pcicfglock);
|
||||
switch(pcicfgmode){
|
||||
|
||||
case 1:
|
||||
o = rno & 0x03;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
x = inb(PciDATA+o);
|
||||
else
|
||||
outb(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
}
|
||||
unlock(&pcicfglock);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgr8(Pcidev* pcidev, int rno)
|
||||
{
|
||||
return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
pcicfgw8(Pcidev* pcidev, int rno, int data)
|
||||
{
|
||||
pcicfgrw8(pcidev->tbdf, rno, data, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw16(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type, x;
|
||||
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
x = -1;
|
||||
if(BUSDNO(tbdf) > pcimaxdno)
|
||||
return x;
|
||||
|
||||
lock(&pcicfglock);
|
||||
switch(pcicfgmode){
|
||||
|
||||
case 1:
|
||||
o = rno & 0x02;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
x = ins(PciDATA+o);
|
||||
else
|
||||
outs(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
}
|
||||
unlock(&pcicfglock);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgr16(Pcidev* pcidev, int rno)
|
||||
{
|
||||
return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
pcicfgw16(Pcidev* pcidev, int rno, int data)
|
||||
{
|
||||
pcicfgrw16(pcidev->tbdf, rno, data, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw32(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int type, x;
|
||||
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
x = -1;
|
||||
if(BUSDNO(tbdf) > pcimaxdno)
|
||||
return x;
|
||||
|
||||
lock(&pcicfglock);
|
||||
switch(pcicfgmode){
|
||||
|
||||
case 1:
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
x = inl(PciDATA);
|
||||
else
|
||||
outl(PciDATA, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
}
|
||||
unlock(&pcicfglock);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgr32(Pcidev* pcidev, int rno)
|
||||
{
|
||||
return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
pcicfgw32(Pcidev* pcidev, int rno, int data)
|
||||
{
|
||||
pcicfgrw32(pcidev->tbdf, rno, data, 0);
|
||||
}
|
||||
|
||||
Pcidev*
|
||||
pcimatch(Pcidev* prev, int vid, int did)
|
||||
{
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
if(prev == nil)
|
||||
prev = pcilist;
|
||||
else
|
||||
prev = prev->list;
|
||||
|
||||
while(prev != nil){
|
||||
if((vid == 0 || prev->vid == vid)
|
||||
&& (did == 0 || prev->did == did))
|
||||
break;
|
||||
prev = prev->list;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
Pcidev*
|
||||
pcimatchtbdf(int tbdf)
|
||||
{
|
||||
Pcidev *pcidev;
|
||||
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
|
||||
if(pcidev->tbdf == tbdf)
|
||||
break;
|
||||
}
|
||||
return pcidev;
|
||||
}
|
||||
|
||||
uchar
|
||||
pciipin(Pcidev *pci, uchar pin)
|
||||
{
|
||||
if (pci == nil)
|
||||
pci = pcilist;
|
||||
|
||||
while (pci) {
|
||||
uchar intl;
|
||||
|
||||
if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff)
|
||||
return pci->intl;
|
||||
|
||||
if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0)
|
||||
return intl;
|
||||
|
||||
pci = pci->list;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pcilhinv(Pcidev* p)
|
||||
{
|
||||
int i;
|
||||
Pcidev *t;
|
||||
|
||||
if(p == nil) {
|
||||
putstrn(PCICONS.output, PCICONS.ptr);
|
||||
p = pciroot;
|
||||
print("bus dev type vid did intl memory\n");
|
||||
}
|
||||
for(t = p; t != nil; t = t->link) {
|
||||
print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ",
|
||||
BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
|
||||
t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl);
|
||||
|
||||
for(i = 0; i < nelem(p->mem); i++) {
|
||||
if(t->mem[i].size == 0)
|
||||
continue;
|
||||
print("%d:%.8lux %d ", i,
|
||||
t->mem[i].bar, t->mem[i].size);
|
||||
}
|
||||
if(t->ioa.bar || t->ioa.size)
|
||||
print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size);
|
||||
if(t->mema.bar || t->mema.size)
|
||||
print("mema:%.8lux %d ", t->mema.bar, t->mema.size);
|
||||
if(t->bridge)
|
||||
print("->%d", BUSBNO(t->bridge->tbdf));
|
||||
print("\n");
|
||||
}
|
||||
while(p != nil) {
|
||||
if(p->bridge != nil)
|
||||
pcilhinv(p->bridge);
|
||||
p = p->link;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcihinv(Pcidev* p)
|
||||
{
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
qlock(&pcicfginitlock);
|
||||
pcilhinv(p);
|
||||
qunlock(&pcicfginitlock);
|
||||
}
|
||||
|
||||
void
|
||||
pcireset(void)
|
||||
{
|
||||
Pcidev *p;
|
||||
int pcr;
|
||||
|
||||
if(pcicfgmode == -1)
|
||||
pcicfginit();
|
||||
|
||||
for(p = pcilist; p != nil; p = p->list){
|
||||
pcr = pcicfgr16(p, PciPCR);
|
||||
pcr &= ~0x0004;
|
||||
pcicfgw16(p, PciPCR, pcr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcisetbme(Pcidev* p)
|
||||
{
|
||||
int pcr;
|
||||
|
||||
pcr = pcicfgr16(p, PciPCR);
|
||||
pcr |= MASen;
|
||||
pcicfgw16(p, PciPCR, pcr);
|
||||
}
|
||||
|
||||
void
|
||||
pciclrbme(Pcidev* p)
|
||||
{
|
||||
int pcr;
|
||||
|
||||
pcr = pcicfgr16(p, PciPCR);
|
||||
pcr &= ~MASen;
|
||||
pcicfgw16(p, PciPCR, pcr);
|
||||
}
|
224
sys/src/9/mtx/pcimtx.c
Normal file
224
sys/src/9/mtx/pcimtx.c
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* PCI support code.
|
||||
*/
|
||||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
enum {
|
||||
/* configuration mechanism #1 */
|
||||
PciADDR = 0xCF8, /* CONFIG_ADDRESS */
|
||||
PciDATA = 0xCFC, /* CONFIG_DATA */
|
||||
|
||||
/* configuration mechanism #2 */
|
||||
PciCSE = 0xCF8, /* configuration space enable */
|
||||
PciFORWARD = 0xCFA, /* which bus */
|
||||
};
|
||||
|
||||
static int pcicfgmode = -1;
|
||||
static int pcimaxbno = 7;
|
||||
static Pcidev* pciroot;
|
||||
|
||||
static void
|
||||
pcicfginit(void)
|
||||
{
|
||||
char *p;
|
||||
int bno;
|
||||
Pcidev **list;
|
||||
uvlong mema;
|
||||
ulong ioa;
|
||||
|
||||
fmtinstall('T', tbdffmt);
|
||||
|
||||
/*
|
||||
* Try to determine which PCI configuration mode is implemented.
|
||||
* Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses
|
||||
* a DWORD at 0xCF8 and another at 0xCFC and will pass through
|
||||
* any non-DWORD accesses as normal I/O cycles. There shouldn't be
|
||||
* a device behind these addresses so if Mode2 accesses fail try
|
||||
* for Mode1 (which is preferred, Mode2 is deprecated).
|
||||
*/
|
||||
outb(PciCSE, 0);
|
||||
if(inb(PciCSE) == 0){
|
||||
pcicfgmode = 2;
|
||||
pcimaxdno = 15;
|
||||
}
|
||||
else {
|
||||
outl(PciADDR, 0);
|
||||
if(inl(PciADDR) == 0){
|
||||
pcicfgmode = 1;
|
||||
pcimaxdno = 31;
|
||||
}
|
||||
}
|
||||
|
||||
if(pcicfgmode < 0)
|
||||
return;
|
||||
|
||||
if(p = getconf("*pcimaxbno"))
|
||||
pcimaxbno = strtoul(p, 0, 0);
|
||||
if(p = getconf("*pcimaxdno"))
|
||||
pcimaxdno = strtoul(p, 0, 0);
|
||||
|
||||
list = &pciroot;
|
||||
for(bno = 0; bno <= pcimaxbno; bno++) {
|
||||
int sbno = bno;
|
||||
bno = pciscan(bno, list);
|
||||
|
||||
while(*list)
|
||||
list = &(*list)->link;
|
||||
|
||||
if (sbno == 0) {
|
||||
Pcidev *pci;
|
||||
|
||||
/*
|
||||
* If we have found a PCI-to-Cardbus bridge, make sure
|
||||
* it has no valid mappings anymore.
|
||||
*/
|
||||
pci = pciroot;
|
||||
while (pci) {
|
||||
if (pci->ccrb == 6 && pci->ccru == 7) {
|
||||
ushort bcr;
|
||||
|
||||
/* reset the cardbus */
|
||||
bcr = pcicfgr16(pci, PciBCR);
|
||||
pcicfgw16(pci, PciBCR, 0x40 | bcr);
|
||||
delay(50);
|
||||
}
|
||||
pci = pci->link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pciroot == nil)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Work out how big the top bus is
|
||||
*/
|
||||
mema = 0;
|
||||
ioa = 0;
|
||||
pcibusmap(pciroot, &mema, &ioa, 0);
|
||||
|
||||
/*
|
||||
* Align the windows and map it
|
||||
*/
|
||||
ioa = 0x1000;
|
||||
mema = 0;
|
||||
pcibusmap(pciroot, &mema, &ioa, 1);
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw8(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type, x;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
o = rno & 0x03;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = inb(PciDATA+o);
|
||||
else
|
||||
outb(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw16(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
o = rno & 0x02;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = ins(PciDATA+o);
|
||||
else
|
||||
outs(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
pcicfgrw32(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int type;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = inl(PciDATA);
|
||||
else
|
||||
outl(PciDATA, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
pcimtxlink(void)
|
||||
{
|
||||
pcicfginit();
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#include "mp.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
#include "mp.h"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/audioif.h"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/audioif.h"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
static int
|
||||
intelcputempok(void)
|
||||
|
|
|
@ -153,7 +153,6 @@ ioinit(void)
|
|||
ioalloc(io_s, io_e - io_s + 1, 0, "pre-allocated");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
/* this driver doesn't implement the management interrupts. we
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
#include "devlml.h"
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
|
@ -922,7 +923,7 @@ unconfigure(Cardbus *cb)
|
|||
if (pci->mem[i].size == 0)
|
||||
continue;
|
||||
if (pci->mem[i].bar & 1) {
|
||||
iofree(pci->mem[i].bar & ~1);
|
||||
iofree(pci->mem[i].bar & ~3);
|
||||
pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8,
|
||||
(ushort)-1);
|
||||
pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 0);
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
#include "io.h"
|
||||
#include "hcwAMC.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "hcwAMC.h"
|
||||
|
||||
#define max(a, b) (((a) > (b))? (a): (b))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -62,7 +63,7 @@ ne2000match(Ether* edev, int id)
|
|||
p = ctlr->pcidev;
|
||||
if(((p->did<<16)|p->vid) != id)
|
||||
continue;
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(edev->port != 0 && edev->port != port)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1671,7 +1672,7 @@ dec2114xpci(void)
|
|||
print("dec2114x: can't allocate memory\n");
|
||||
continue;
|
||||
}
|
||||
ctlr->port = p->mem[0].bar & ~0x01;
|
||||
ctlr->port = p->mem[0].bar & ~3;
|
||||
ctlr->pcidev = p;
|
||||
ctlr->id = (p->did<<16)|p->vid;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -490,7 +491,7 @@ amd79c970pci(void)
|
|||
|
||||
p = nil;
|
||||
while(p = pcimatch(p, 0x1022, 0x2000)){
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(port, p->mem[0].size, 0, "amd79c970") < 0){
|
||||
print("amd79c970: port 0x%uX in use\n", port);
|
||||
continue;
|
||||
|
@ -501,7 +502,7 @@ amd79c970pci(void)
|
|||
iofree(port);
|
||||
continue;
|
||||
}
|
||||
ctlr->port = p->mem[0].bar & ~0x01;
|
||||
ctlr->port = port;
|
||||
ctlr->pcidev = p;
|
||||
|
||||
if(ctlrhead != nil)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -693,7 +694,7 @@ rtl8139match(Ether* edev, int id)
|
|||
p = ctlr->pcidev;
|
||||
if(((p->did<<16)|p->vid) != id)
|
||||
continue;
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(edev->port != 0 && edev->port != port)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1102,7 +1103,7 @@ rtl8169pci(void)
|
|||
break;
|
||||
}
|
||||
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
|
||||
print("rtl8169: port %#ux in use\n", port);
|
||||
continue;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1282,8 +1283,7 @@ gc82543pci(void)
|
|||
free(ctlr);
|
||||
continue;
|
||||
}
|
||||
cls = pcicfgr8(p, PciCLS);
|
||||
switch(cls){
|
||||
switch(p->cls){
|
||||
case 0x08:
|
||||
case 0x10:
|
||||
break;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -963,7 +964,7 @@ i82557pci(void)
|
|||
* bar[1] is the I/O port register address (32 bytes) and
|
||||
* bar[2] is for the flash ROM (1MB).
|
||||
*/
|
||||
port = p->mem[1].bar & ~0x01;
|
||||
port = p->mem[1].bar & ~3;
|
||||
if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
|
||||
print("i82557: port %#ux in use\n", port);
|
||||
continue;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1089,7 +1090,7 @@ scanpci83815(void)
|
|||
print("ns83815: can't allocate memory\n");
|
||||
continue;
|
||||
}
|
||||
ctlr->port = p->mem[0].bar & ~0x01;
|
||||
ctlr->port = p->mem[0].bar & ~3;
|
||||
ctlr->pcidev = p;
|
||||
ctlr->id = id;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1475,7 +1476,7 @@ tcm59Xpci(void)
|
|||
*/
|
||||
if(!(p->mem[0].bar & 0x01))
|
||||
continue;
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if((port = ioalloc((port == 0)? -1: port, p->mem[0].size,
|
||||
0, "tcm59Xpci")) < 0){
|
||||
print("tcm59Xpci: port 0x%uX in use\n", port);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1085,7 +1086,7 @@ print("ga620shutdown\n");
|
|||
static int
|
||||
ga620reset(Ctlr* ctlr)
|
||||
{
|
||||
int cls, csr, i, r;
|
||||
int csr, i, r;
|
||||
|
||||
if(ga620detach(ctlr) < 0)
|
||||
return -1;
|
||||
|
@ -1108,9 +1109,10 @@ ga620reset(Ctlr* ctlr)
|
|||
csr = csr32r(ctlr, Ps) & (PCI32|PCI66);
|
||||
csr |= PCIwcmd|PCIrcmd|PCImrm;
|
||||
if(ctlr->pcidev->pcr & 0x0010){
|
||||
cls = pcicfgr8(ctlr->pcidev, PciCLS) * 4;
|
||||
if(cls != 32)
|
||||
pcicfgw8(ctlr->pcidev, PciCLS, 32/4);
|
||||
if(ctlr->pcidev->cls != 32/4){
|
||||
ctlr->pcidev->cls = 32/4;
|
||||
pcicfgw8(ctlr->pcidev, PciCLS, ctlr->pcidev->cls);
|
||||
}
|
||||
csr |= PCIwm32;
|
||||
}
|
||||
csr32w(ctlr, Ps, csr);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1910,7 +1911,6 @@ igbereset(Ctlr* ctlr)
|
|||
static void
|
||||
igbepci(void)
|
||||
{
|
||||
int cls;
|
||||
Pcidev *p;
|
||||
Ctlr *ctlr;
|
||||
void *mem;
|
||||
|
@ -1949,8 +1949,7 @@ igbepci(void)
|
|||
print("igbe: can't map %llux\n", p->mem[0].bar & ~0xF);
|
||||
continue;
|
||||
}
|
||||
cls = pcicfgr8(p, PciCLS);
|
||||
switch(cls){
|
||||
switch(p->cls){
|
||||
default:
|
||||
print("igbe: p->cls %#ux, setting to 0x10\n", p->cls);
|
||||
p->cls = 0x10;
|
||||
|
@ -1969,7 +1968,7 @@ igbepci(void)
|
|||
ctlr->pcidev = p;
|
||||
pcienable(p);
|
||||
ctlr->id = (p->did<<16)|p->vid;
|
||||
ctlr->cls = cls*4;
|
||||
ctlr->cls = p->cls*4;
|
||||
ctlr->nic = mem;
|
||||
|
||||
if(igbereset(ctlr)){
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -942,7 +943,7 @@ vgbepci(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
port &= 0xfffe;
|
||||
port &= 0xfffc;
|
||||
|
||||
if(size != 256){
|
||||
print("vgbe: invalid io size: %d\n", size);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -563,6 +564,9 @@ pciprobe(int typ)
|
|||
/* non-transitional devices will have a revision > 0 */
|
||||
if(p->rid != 0)
|
||||
continue;
|
||||
/* first membar needs to be I/O */
|
||||
if((p->mem[0].bar & 1) == 0)
|
||||
continue;
|
||||
/* non-transitional device will have typ+0x40 */
|
||||
if(pcicfgr16(p, 0x2E) != typ)
|
||||
continue;
|
||||
|
@ -570,8 +574,7 @@ pciprobe(int typ)
|
|||
print("ethervirtio: no memory for Ctlr\n");
|
||||
break;
|
||||
}
|
||||
|
||||
c->port = p->mem[0].bar & ~0x1;
|
||||
c->port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(c->port, p->mem[0].size, 0, "ethervirtio") < 0){
|
||||
print("ethervirtio: port %ux in use\n", c->port);
|
||||
free(c);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -947,7 +948,7 @@ vt6102pci(void)
|
|||
{
|
||||
Pcidev *p;
|
||||
Ctlr *ctlr;
|
||||
int cls, port;
|
||||
int port;
|
||||
|
||||
p = nil;
|
||||
while(p = pcimatch(p, 0, 0)){
|
||||
|
@ -962,7 +963,7 @@ vt6102pci(void)
|
|||
break;
|
||||
}
|
||||
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(port, p->mem[0].size, 0, "vt6102") < 0){
|
||||
print("vt6102: port 0x%uX in use\n", port);
|
||||
continue;
|
||||
|
@ -977,9 +978,7 @@ vt6102pci(void)
|
|||
ctlr->pcidev = p;
|
||||
pcienable(p);
|
||||
ctlr->id = (p->did<<16)|p->vid;
|
||||
if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
|
||||
cls = 0x10;
|
||||
ctlr->cls = cls*4;
|
||||
ctlr->cls = p->cls*4;
|
||||
ctlr->tft = Ctft64;
|
||||
|
||||
if(vt6102reset(ctlr)){
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
@ -1112,7 +1113,7 @@ vt6105Mpci(void)
|
|||
{
|
||||
Pcidev *p;
|
||||
Ctlr *ctlr;
|
||||
int cls, port;
|
||||
int port;
|
||||
|
||||
p = nil;
|
||||
while(p = pcimatch(p, 0, 0)){
|
||||
|
@ -1126,7 +1127,7 @@ vt6105Mpci(void)
|
|||
break;
|
||||
}
|
||||
|
||||
port = p->mem[0].bar & ~0x01;
|
||||
port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(port, p->mem[0].size, 0, "vt6105M") < 0){
|
||||
print("vt6105M: port 0x%uX in use\n", port);
|
||||
continue;
|
||||
|
@ -1141,9 +1142,7 @@ vt6105Mpci(void)
|
|||
ctlr->pcidev = p;
|
||||
pcienable(p);
|
||||
ctlr->id = (p->did<<16)|p->vid;
|
||||
if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
|
||||
cls = 0x10;
|
||||
ctlr->cls = cls*4;
|
||||
ctlr->cls = p->cls*4;
|
||||
ctlr->tft = CtftSAF;
|
||||
|
||||
if(vt6105Mreset(ctlr)){
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
|
|
|
@ -125,32 +125,10 @@ void outl(int, ulong);
|
|||
void outsl(int, void*, int);
|
||||
ulong paddr(void*);
|
||||
void patwc(void*, int);
|
||||
ulong pcibarsize(Pcidev*, int);
|
||||
void pcibussize(Pcidev*, uvlong*, ulong*);
|
||||
int pcicfgr8(Pcidev*, int);
|
||||
int pcicfgr16(Pcidev*, int);
|
||||
int pcicfgr32(Pcidev*, int);
|
||||
void pcicfgw8(Pcidev*, int, int);
|
||||
void pcicfgw16(Pcidev*, int, int);
|
||||
void pcicfgw32(Pcidev*, int, int);
|
||||
void pciclrbme(Pcidev*);
|
||||
void pciclrioe(Pcidev*);
|
||||
void pciclrmwi(Pcidev*);
|
||||
int pcigetpms(Pcidev*);
|
||||
void pcihinv(Pcidev*);
|
||||
uchar pciipin(Pcidev*, uchar);
|
||||
Pcidev* pcimatch(Pcidev*, int, int);
|
||||
Pcidev* pcimatchtbdf(int);
|
||||
int pcicap(Pcidev*, int);
|
||||
int pcihtcap(Pcidev*, int);
|
||||
void pcireset(void);
|
||||
int pciscan(int, Pcidev**);
|
||||
void pcisetbme(Pcidev*);
|
||||
void pcisetioe(Pcidev*);
|
||||
void pcisetmwi(Pcidev*);
|
||||
int pcisetpms(Pcidev*, int);
|
||||
void pcienable(Pcidev*);
|
||||
void pcidisable(Pcidev*);
|
||||
void pcicfginit(void);
|
||||
int (*pcicfgrw8)(int, int, int, int);
|
||||
int (*pcicfgrw16)(int, int, int, int);
|
||||
int (*pcicfgrw32)(int, int, int, int);
|
||||
void pcmcisread(PCMslot*);
|
||||
int pcmcistuple(int, int, int, void*, int);
|
||||
PCMmap* pcmmap(int, ulong, int, int);
|
||||
|
@ -193,6 +171,7 @@ uvlong tscticks(uvlong*);
|
|||
ulong umballoc(ulong, ulong, ulong);
|
||||
void umbfree(ulong, ulong);
|
||||
uvlong upaalloc(uvlong, ulong, ulong);
|
||||
uvlong upaallocwin(uvlong, ulong, ulong, ulong);
|
||||
void upafree(uvlong, ulong);
|
||||
void vectortable(void);
|
||||
void* vmap(uvlong, int);
|
||||
|
|
|
@ -59,230 +59,18 @@ typedef struct Vctl {
|
|||
void* a; /* argument to call it with */
|
||||
} Vctl;
|
||||
|
||||
enum {
|
||||
BusCBUS = 0, /* Corollary CBUS */
|
||||
BusCBUSII, /* Corollary CBUS II */
|
||||
BusEISA, /* Extended ISA */
|
||||
BusFUTURE, /* IEEE Futurebus */
|
||||
BusINTERN, /* Internal bus */
|
||||
BusISA, /* Industry Standard Architecture */
|
||||
BusMBI, /* Multibus I */
|
||||
BusMBII, /* Multibus II */
|
||||
BusMCA, /* Micro Channel Architecture */
|
||||
BusMPI, /* MPI */
|
||||
BusMPSA, /* MPSA */
|
||||
BusNUBUS, /* Apple Macintosh NuBus */
|
||||
BusPCI, /* Peripheral Component Interconnect */
|
||||
BusPCMCIA, /* PC Memory Card International Association */
|
||||
BusTC, /* DEC TurboChannel */
|
||||
BusVL, /* VESA Local bus */
|
||||
BusVME, /* VMEbus */
|
||||
BusXPRESS, /* Express System Bus */
|
||||
};
|
||||
|
||||
#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
|
||||
#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
|
||||
#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
|
||||
#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
|
||||
#define BUSTYPE(tbdf) ((tbdf)>>24)
|
||||
#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
|
||||
#define BUSUNKNOWN (-1)
|
||||
|
||||
enum {
|
||||
MaxEISA = 16,
|
||||
CfgEISA = 0xC80,
|
||||
};
|
||||
|
||||
/*
|
||||
* PCI support code.
|
||||
*/
|
||||
enum { /* type 0 & type 1 pre-defined header */
|
||||
PciVID = 0x00, /* vendor ID */
|
||||
PciDID = 0x02, /* device ID */
|
||||
PciPCR = 0x04, /* command */
|
||||
PciPSR = 0x06, /* status */
|
||||
PciRID = 0x08, /* revision ID */
|
||||
PciCCRp = 0x09, /* programming interface class code */
|
||||
PciCCRu = 0x0A, /* sub-class code */
|
||||
PciCCRb = 0x0B, /* base class code */
|
||||
PciCLS = 0x0C, /* cache line size */
|
||||
PciLTR = 0x0D, /* latency timer */
|
||||
PciHDT = 0x0E, /* header type */
|
||||
PciBST = 0x0F, /* BIST */
|
||||
|
||||
PciBAR0 = 0x10, /* base address */
|
||||
PciBAR1 = 0x14,
|
||||
|
||||
PciCAP = 0x34, /* capabilities pointer */
|
||||
PciINTL = 0x3C, /* interrupt line */
|
||||
PciINTP = 0x3D, /* interrupt pin */
|
||||
};
|
||||
|
||||
/* ccrb (base class code) values; controller types */
|
||||
enum {
|
||||
Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
|
||||
Pcibcstore = 1, /* mass storage */
|
||||
Pcibcnet = 2, /* network */
|
||||
Pcibcdisp = 3, /* display */
|
||||
Pcibcmmedia = 4, /* multimedia */
|
||||
Pcibcmem = 5, /* memory */
|
||||
Pcibcbridge = 6, /* bridge */
|
||||
Pcibccomm = 7, /* simple comms (e.g., serial) */
|
||||
Pcibcbasesys = 8, /* base system */
|
||||
Pcibcinput = 9, /* input */
|
||||
Pcibcdock = 0xa, /* docking stations */
|
||||
Pcibcproc = 0xb, /* processors */
|
||||
Pcibcserial = 0xc, /* serial bus (e.g., USB) */
|
||||
Pcibcwireless = 0xd, /* wireless */
|
||||
Pcibcintell = 0xe, /* intelligent i/o */
|
||||
Pcibcsatcom = 0xf, /* satellite comms */
|
||||
Pcibccrypto = 0x10, /* encryption/decryption */
|
||||
Pcibcdacq = 0x11, /* data acquisition & signal proc. */
|
||||
};
|
||||
|
||||
/* ccru (sub-class code) values; common cases only */
|
||||
enum {
|
||||
/* mass storage */
|
||||
Pciscscsi = 0, /* SCSI */
|
||||
Pciscide = 1, /* IDE (ATA) */
|
||||
|
||||
/* network */
|
||||
Pciscether = 0, /* Ethernet */
|
||||
|
||||
/* display */
|
||||
Pciscvga = 0, /* VGA */
|
||||
Pciscxga = 1, /* XGA */
|
||||
Pcisc3d = 2, /* 3D */
|
||||
|
||||
/* bridges */
|
||||
Pcischostpci = 0, /* host/pci */
|
||||
Pciscpcicpci = 1, /* pci/pci */
|
||||
|
||||
/* simple comms */
|
||||
Pciscserial = 0, /* 16450, etc. */
|
||||
Pciscmultiser = 1, /* multiport serial */
|
||||
|
||||
/* serial bus */
|
||||
Pciscusb = 3, /* USB */
|
||||
};
|
||||
|
||||
enum { /* type 0 pre-defined header */
|
||||
PciCIS = 0x28, /* cardbus CIS pointer */
|
||||
PciSVID = 0x2C, /* subsystem vendor ID */
|
||||
PciSID = 0x2E, /* subsystem ID */
|
||||
PciEBAR0 = 0x30, /* expansion ROM base address */
|
||||
PciMGNT = 0x3E, /* burst period length */
|
||||
PciMLT = 0x3F, /* maximum latency between bursts */
|
||||
};
|
||||
|
||||
enum { /* type 1 pre-defined header */
|
||||
PciPBN = 0x18, /* primary bus number */
|
||||
PciSBN = 0x19, /* secondary bus number */
|
||||
PciUBN = 0x1A, /* subordinate bus number */
|
||||
PciSLTR = 0x1B, /* secondary latency timer */
|
||||
PciIBR = 0x1C, /* I/O base */
|
||||
PciILR = 0x1D, /* I/O limit */
|
||||
PciSPSR = 0x1E, /* secondary status */
|
||||
PciMBR = 0x20, /* memory base */
|
||||
PciMLR = 0x22, /* memory limit */
|
||||
PciPMBR = 0x24, /* prefetchable memory base */
|
||||
PciPMLR = 0x26, /* prefetchable memory limit */
|
||||
PciPUBR = 0x28, /* prefetchable base upper 32 bits */
|
||||
PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
|
||||
PciIUBR = 0x30, /* I/O base upper 16 bits */
|
||||
PciIULR = 0x32, /* I/O limit upper 16 bits */
|
||||
PciEBAR1 = 0x28, /* expansion ROM base address */
|
||||
PciBCR = 0x3E, /* bridge control register */
|
||||
};
|
||||
|
||||
enum { /* type 2 pre-defined header */
|
||||
PciCBExCA = 0x10,
|
||||
PciCBSPSR = 0x16,
|
||||
PciCBPBN = 0x18, /* primary bus number */
|
||||
PciCBSBN = 0x19, /* secondary bus number */
|
||||
PciCBUBN = 0x1A, /* subordinate bus number */
|
||||
PciCBSLTR = 0x1B, /* secondary latency timer */
|
||||
PciCBMBR0 = 0x1C,
|
||||
PciCBMLR0 = 0x20,
|
||||
PciCBMBR1 = 0x24,
|
||||
PciCBMLR1 = 0x28,
|
||||
PciCBIBR0 = 0x2C, /* I/O base */
|
||||
PciCBILR0 = 0x30, /* I/O limit */
|
||||
PciCBIBR1 = 0x34, /* I/O base */
|
||||
PciCBILR1 = 0x38, /* I/O limit */
|
||||
PciCBSVID = 0x40, /* subsystem vendor ID */
|
||||
PciCBSID = 0x42, /* subsystem ID */
|
||||
PciCBLMBAR = 0x44, /* legacy mode base address */
|
||||
};
|
||||
|
||||
/* capabilities */
|
||||
enum {
|
||||
PciCapPMG = 0x01, /* power management */
|
||||
PciCapAGP = 0x02,
|
||||
PciCapVPD = 0x03, /* vital product data */
|
||||
PciCapSID = 0x04, /* slot id */
|
||||
PciCapMSI = 0x05,
|
||||
PciCapCHS = 0x06, /* compact pci hot swap */
|
||||
PciCapPCIX = 0x07,
|
||||
PciCapHTC = 0x08, /* hypertransport irq conf */
|
||||
PciCapVND = 0x09, /* vendor specific information */
|
||||
PciCapPCIe = 0x10,
|
||||
PciCapMSIX = 0x11,
|
||||
PciCapSATA = 0x12,
|
||||
PciCapHSW = 0x0c, /* hot swap */
|
||||
};
|
||||
|
||||
typedef struct Pcidev Pcidev;
|
||||
struct Pcidev
|
||||
{
|
||||
int tbdf; /* type+bus+device+function */
|
||||
ushort vid; /* vendor ID */
|
||||
ushort did; /* device ID */
|
||||
|
||||
ushort pcr;
|
||||
|
||||
uchar rid;
|
||||
uchar ccrp;
|
||||
uchar ccru;
|
||||
uchar ccrb;
|
||||
uchar cls;
|
||||
uchar ltr;
|
||||
|
||||
struct {
|
||||
uvlong bar; /* base address */
|
||||
int size;
|
||||
} mem[6];
|
||||
|
||||
struct {
|
||||
uvlong bar;
|
||||
int size;
|
||||
} rom;
|
||||
uchar intl; /* interrupt line */
|
||||
|
||||
Pcidev* list;
|
||||
Pcidev* link; /* next device on this bno */
|
||||
|
||||
Pcidev* parent; /* up a bus */
|
||||
Pcidev* bridge; /* down a bus */
|
||||
struct {
|
||||
uvlong bar;
|
||||
int size;
|
||||
} ioa, mema;
|
||||
|
||||
int pmrb; /* power management register block */
|
||||
};
|
||||
|
||||
enum {
|
||||
/* vendor ids */
|
||||
Vintel = 0x8086,
|
||||
Vmyricom= 0x14c1,
|
||||
};
|
||||
|
||||
#define PCIWINDOW 0
|
||||
#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
|
||||
#define ISAWINDOW 0
|
||||
#define ISAWADDR(va) (PADDR(va)+ISAWINDOW)
|
||||
|
||||
#define BUSUNKNOWN (-1)
|
||||
|
||||
/* SMBus transactions */
|
||||
enum
|
||||
{
|
||||
|
@ -387,6 +175,3 @@ struct PCMslot
|
|||
int time;
|
||||
PCMmap mmap[4]; /* maps, last is always for the kernel */
|
||||
};
|
||||
|
||||
#pragma varargck type "T" int
|
||||
#pragma varargck type "T" uint
|
||||
|
|
|
@ -40,6 +40,7 @@ main(void)
|
|||
ramdiskinit();
|
||||
confinit();
|
||||
xinit();
|
||||
pcicfginit();
|
||||
bootscreeninit();
|
||||
if(i8237alloc != nil)
|
||||
i8237alloc();
|
||||
|
@ -57,7 +58,6 @@ main(void)
|
|||
initseg();
|
||||
if(delaylink){
|
||||
bootlinks();
|
||||
pcimatch(0, 0, 0);
|
||||
}else
|
||||
links();
|
||||
chandevreset();
|
||||
|
|
|
@ -250,6 +250,24 @@ upaalloc(uvlong pa, ulong size, ulong align)
|
|||
return memmapalloc(pa, size, align, MemUPA);
|
||||
}
|
||||
|
||||
uvlong
|
||||
upaallocwin(uvlong pa, ulong win, ulong size, ulong align)
|
||||
{
|
||||
uvlong a, base, top = pa + win;
|
||||
|
||||
for(base = memmapnext(-1, MemUPA); base != -1 && base < top; base = memmapnext(base, MemUPA)){
|
||||
if(base < pa){
|
||||
if(pa >= base + memmapsize(base, 0))
|
||||
continue;
|
||||
base = pa;
|
||||
}
|
||||
a = upaalloc(base, size, align);
|
||||
if(a != -1)
|
||||
return a;
|
||||
}
|
||||
return -1ULL;
|
||||
}
|
||||
|
||||
void
|
||||
upafree(uvlong pa, ulong size)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
|
||||
#include "mp.h"
|
||||
|
|
|
@ -27,7 +27,7 @@ dev
|
|||
draw screen vga vgax vgasoft
|
||||
mouse mouse
|
||||
kbd
|
||||
vga
|
||||
vga pci
|
||||
|
||||
sd
|
||||
floppy dma
|
||||
|
@ -35,7 +35,7 @@ dev
|
|||
lpt
|
||||
|
||||
audio dma
|
||||
pccard
|
||||
pccard pci
|
||||
i82365 cis
|
||||
uart
|
||||
usb
|
||||
|
@ -45,11 +45,11 @@ dev
|
|||
|
||||
link
|
||||
segdesc
|
||||
devpccard
|
||||
devpccard pci
|
||||
devi82365
|
||||
cputemp
|
||||
cputemp pci
|
||||
apm apmjump
|
||||
ether2000 ether8390
|
||||
ether2000 pci ether8390
|
||||
ether2114x pci
|
||||
ether589 etherelnk3
|
||||
ether79c970 pci
|
||||
|
@ -73,7 +73,7 @@ link
|
|||
ethervt6102 pci ethermii
|
||||
ethervt6105m pci ethermii
|
||||
ethersink
|
||||
ethersmc devi82365 cis
|
||||
ethersmc pci devi82365 cis
|
||||
etheryuk pci
|
||||
etherwavelan wavelan devi82365 cis pci
|
||||
etheriwl pci wifi
|
||||
|
@ -84,16 +84,18 @@ link
|
|||
pcmciamodem
|
||||
netdevmedium
|
||||
loopbackmedium
|
||||
usbuhci
|
||||
usbohci
|
||||
usbuhci pci
|
||||
usbohci pci
|
||||
usbehci usbehcipc
|
||||
usbxhci pci
|
||||
|
||||
audiosb16 dma
|
||||
audioac97 audioac97mix
|
||||
audiohda
|
||||
audioac97 pci audioac97mix
|
||||
audiohda pci
|
||||
|
||||
misc
|
||||
pci pcipc
|
||||
|
||||
archacpi mp apic squidboy ec
|
||||
archmp mp apic squidboy
|
||||
mtrr
|
||||
|
|
1647
sys/src/9/pc/pci.c
1647
sys/src/9/pc/pci.c
File diff suppressed because it is too large
Load diff
739
sys/src/9/pc/pcipc.c
Normal file
739
sys/src/9/pc/pcipc.c
Normal file
|
@ -0,0 +1,739 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define DBG if(1) print
|
||||
|
||||
enum
|
||||
{ /* configuration mechanism #1 */
|
||||
PciADDR = 0xCF8, /* CONFIG_ADDRESS */
|
||||
PciDATA = 0xCFC, /* CONFIG_DATA */
|
||||
|
||||
/* configuration mechanism #2 */
|
||||
PciCSE = 0xCF8, /* configuration space enable */
|
||||
PciFORWARD = 0xCFA, /* which bus */
|
||||
};
|
||||
|
||||
static int pcimaxbno = 255;
|
||||
static int pcicfgmode = -1;
|
||||
static Pcidev* pciroot;
|
||||
static int nobios, nopcirouting;
|
||||
static BIOS32si* pcibiossi;
|
||||
|
||||
static int pcicfgrw8raw(int, int, int, int);
|
||||
static int pcicfgrw16raw(int, int, int, int);
|
||||
static int pcicfgrw32raw(int, int, int, int);
|
||||
|
||||
int (*pcicfgrw8)(int, int, int, int) = pcicfgrw8raw;
|
||||
int (*pcicfgrw16)(int, int, int, int) = pcicfgrw16raw;
|
||||
int (*pcicfgrw32)(int, int, int, int) = pcicfgrw32raw;
|
||||
|
||||
static int
|
||||
pcicfgrw8raw(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
o = rno & 0x03;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = inb(PciDATA+o);
|
||||
else
|
||||
outb(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw16raw(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int o, type;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
o = rno & 0x02;
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = ins(PciDATA+o);
|
||||
else
|
||||
outs(PciDATA+o, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw32raw(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
int type;
|
||||
|
||||
if(BUSBNO(tbdf))
|
||||
type = 0x01;
|
||||
else
|
||||
type = 0x00;
|
||||
switch(pcicfgmode){
|
||||
case 1:
|
||||
rno &= ~0x03;
|
||||
outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
|
||||
if(read)
|
||||
data = inl(PciDATA);
|
||||
else
|
||||
outl(PciDATA, data);
|
||||
outl(PciADDR, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
|
||||
outb(PciFORWARD, BUSBNO(tbdf));
|
||||
if(read)
|
||||
data = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
|
||||
else
|
||||
outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
|
||||
outb(PciCSE, 0);
|
||||
break;
|
||||
default:
|
||||
data = -1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw8bios(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
BIOS32ci ci;
|
||||
|
||||
if(pcibiossi == nil)
|
||||
return -1;
|
||||
|
||||
memset(&ci, 0, sizeof(BIOS32ci));
|
||||
ci.ebx = (BUSBNO(tbdf)<<8)|(BUSDNO(tbdf)<<3)|BUSFNO(tbdf);
|
||||
ci.edi = rno;
|
||||
if(read){
|
||||
ci.eax = 0xB108;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return ci.ecx & 0xFF;
|
||||
}
|
||||
else{
|
||||
ci.eax = 0xB10B;
|
||||
ci.ecx = data & 0xFF;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw16bios(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
BIOS32ci ci;
|
||||
|
||||
if(pcibiossi == nil)
|
||||
return -1;
|
||||
|
||||
memset(&ci, 0, sizeof(BIOS32ci));
|
||||
ci.ebx = (BUSBNO(tbdf)<<8)|(BUSDNO(tbdf)<<3)|BUSFNO(tbdf);
|
||||
ci.edi = rno;
|
||||
if(read){
|
||||
ci.eax = 0xB109;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return ci.ecx & 0xFFFF;
|
||||
}
|
||||
else{
|
||||
ci.eax = 0xB10C;
|
||||
ci.ecx = data & 0xFFFF;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
pcicfgrw32bios(int tbdf, int rno, int data, int read)
|
||||
{
|
||||
BIOS32ci ci;
|
||||
|
||||
if(pcibiossi == nil)
|
||||
return -1;
|
||||
|
||||
memset(&ci, 0, sizeof(BIOS32ci));
|
||||
ci.ebx = (BUSBNO(tbdf)<<8)|(BUSDNO(tbdf)<<3)|BUSFNO(tbdf);
|
||||
ci.edi = rno;
|
||||
if(read){
|
||||
ci.eax = 0xB10A;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return ci.ecx;
|
||||
}
|
||||
else{
|
||||
ci.eax = 0xB10D;
|
||||
ci.ecx = data;
|
||||
if(!bios32ci(pcibiossi, &ci)/* && !(ci.eax & 0xFF)*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static BIOS32si*
|
||||
pcibiosinit(void)
|
||||
{
|
||||
BIOS32ci ci;
|
||||
BIOS32si *si;
|
||||
|
||||
if((si = bios32open("$PCI")) == nil)
|
||||
return nil;
|
||||
|
||||
memset(&ci, 0, sizeof(BIOS32ci));
|
||||
ci.eax = 0xB101;
|
||||
if(bios32ci(si, &ci) || ci.edx != ((' '<<24)|('I'<<16)|('C'<<8)|'P')){
|
||||
free(si);
|
||||
return nil;
|
||||
}
|
||||
if(ci.eax & 0x01)
|
||||
pcimaxdno = 31;
|
||||
else
|
||||
pcimaxdno = 15;
|
||||
pcimaxbno = ci.ecx & 0xff;
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
static uchar
|
||||
pIIxget(Pcidev *router, uchar link)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
/* link should be 0x60, 0x61, 0x62, 0x63 */
|
||||
pirq = pcicfgr8(router, link);
|
||||
return (pirq < 16)? pirq: 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pIIxset(Pcidev *router, uchar link, uchar irq)
|
||||
{
|
||||
pcicfgw8(router, link, irq);
|
||||
}
|
||||
|
||||
static uchar
|
||||
viaget(Pcidev *router, uchar link)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
/* link should be 1, 2, 3, 5 */
|
||||
pirq = (link < 6)? pcicfgr8(router, 0x55 + (link>>1)): 0;
|
||||
|
||||
return (link & 1)? (pirq >> 4): (pirq & 15);
|
||||
}
|
||||
|
||||
static void
|
||||
viaset(Pcidev *router, uchar link, uchar irq)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
pirq = pcicfgr8(router, 0x55 + (link >> 1));
|
||||
pirq &= (link & 1)? 0x0f: 0xf0;
|
||||
pirq |= (link & 1)? (irq << 4): (irq & 15);
|
||||
pcicfgw8(router, 0x55 + (link>>1), pirq);
|
||||
}
|
||||
|
||||
static uchar
|
||||
optiget(Pcidev *router, uchar link)
|
||||
{
|
||||
uchar pirq = 0;
|
||||
|
||||
/* link should be 0x02, 0x12, 0x22, 0x32 */
|
||||
if ((link & 0xcf) == 0x02)
|
||||
pirq = pcicfgr8(router, 0xb8 + (link >> 5));
|
||||
return (link & 0x10)? (pirq >> 4): (pirq & 15);
|
||||
}
|
||||
|
||||
static void
|
||||
optiset(Pcidev *router, uchar link, uchar irq)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
pirq = pcicfgr8(router, 0xb8 + (link >> 5));
|
||||
pirq &= (link & 0x10)? 0x0f : 0xf0;
|
||||
pirq |= (link & 0x10)? (irq << 4): (irq & 15);
|
||||
pcicfgw8(router, 0xb8 + (link >> 5), pirq);
|
||||
}
|
||||
|
||||
static uchar
|
||||
aliget(Pcidev *router, uchar link)
|
||||
{
|
||||
/* No, you're not dreaming */
|
||||
static const uchar map[] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
|
||||
uchar pirq;
|
||||
|
||||
/* link should be 0x01..0x08 */
|
||||
pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
|
||||
return (link & 1)? map[pirq&15]: map[pirq>>4];
|
||||
}
|
||||
|
||||
static void
|
||||
aliset(Pcidev *router, uchar link, uchar irq)
|
||||
{
|
||||
/* Inverse of map in aliget */
|
||||
static const uchar map[] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
|
||||
uchar pirq;
|
||||
|
||||
pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
|
||||
pirq &= (link & 1)? 0x0f: 0xf0;
|
||||
pirq |= (link & 1)? (map[irq] << 4): (map[irq] & 15);
|
||||
pcicfgw8(router, 0x48 + ((link-1)>>1), pirq);
|
||||
}
|
||||
|
||||
static uchar
|
||||
cyrixget(Pcidev *router, uchar link)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
/* link should be 1, 2, 3, 4 */
|
||||
pirq = pcicfgr8(router, 0x5c + ((link-1)>>1));
|
||||
return ((link & 1)? pirq >> 4: pirq & 15);
|
||||
}
|
||||
|
||||
static void
|
||||
cyrixset(Pcidev *router, uchar link, uchar irq)
|
||||
{
|
||||
uchar pirq;
|
||||
|
||||
pirq = pcicfgr8(router, 0x5c + (link>>1));
|
||||
pirq &= (link & 1)? 0x0f: 0xf0;
|
||||
pirq |= (link & 1)? (irq << 4): (irq & 15);
|
||||
pcicfgw8(router, 0x5c + (link>>1), pirq);
|
||||
}
|
||||
|
||||
typedef struct Bridge Bridge;
|
||||
struct Bridge
|
||||
{
|
||||
ushort vid;
|
||||
ushort did;
|
||||
uchar (*get)(Pcidev *, uchar);
|
||||
void (*set)(Pcidev *, uchar, uchar);
|
||||
};
|
||||
|
||||
static Bridge southbridges[] = {
|
||||
{ 0x8086, 0x122e, pIIxget, pIIxset }, /* Intel 82371FB */
|
||||
{ 0x8086, 0x1234, pIIxget, pIIxset }, /* Intel 82371MX */
|
||||
{ 0x8086, 0x7000, pIIxget, pIIxset }, /* Intel 82371SB */
|
||||
{ 0x8086, 0x7110, pIIxget, pIIxset }, /* Intel 82371AB */
|
||||
{ 0x8086, 0x7198, pIIxget, pIIxset }, /* Intel 82443MX (fn 1) */
|
||||
{ 0x8086, 0x2410, pIIxget, pIIxset }, /* Intel 82801AA */
|
||||
{ 0x8086, 0x2420, pIIxget, pIIxset }, /* Intel 82801AB */
|
||||
{ 0x8086, 0x2440, pIIxget, pIIxset }, /* Intel 82801BA */
|
||||
{ 0x8086, 0x2448, pIIxget, pIIxset }, /* Intel 82801BAM/CAM/DBM */
|
||||
{ 0x8086, 0x244c, pIIxget, pIIxset }, /* Intel 82801BAM */
|
||||
{ 0x8086, 0x244e, pIIxget, pIIxset }, /* Intel 82801 */
|
||||
{ 0x8086, 0x2480, pIIxget, pIIxset }, /* Intel 82801CA */
|
||||
{ 0x8086, 0x248c, pIIxget, pIIxset }, /* Intel 82801CAM */
|
||||
{ 0x8086, 0x24c0, pIIxget, pIIxset }, /* Intel 82801DBL */
|
||||
{ 0x8086, 0x24cc, pIIxget, pIIxset }, /* Intel 82801DBM */
|
||||
{ 0x8086, 0x24d0, pIIxget, pIIxset }, /* Intel 82801EB */
|
||||
{ 0x8086, 0x25a1, pIIxget, pIIxset }, /* Intel 6300ESB */
|
||||
{ 0x8086, 0x2640, pIIxget, pIIxset }, /* Intel 82801FB */
|
||||
{ 0x8086, 0x2641, pIIxget, pIIxset }, /* Intel 82801FBM */
|
||||
{ 0x8086, 0x2670, pIIxget, pIIxset }, /* Intel 632xesb */
|
||||
{ 0x8086, 0x27b8, pIIxget, pIIxset }, /* Intel 82801GB */
|
||||
{ 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, 0x1c02, pIIxget, pIIxset }, /* Intel 6 Series/C200 */
|
||||
{ 0x8086, 0x1e53, pIIxget, pIIxset }, /* Intel 7 Series/C216 */
|
||||
{ 0x8086, 0x8c56, pIIxget, pIIxset }, /* Intel 8 Series/C226 */
|
||||
{ 0x8086, 0x2810, pIIxget, pIIxset }, /* Intel 82801HB/HR (ich8/r) */
|
||||
{ 0x8086, 0x2812, pIIxget, pIIxset }, /* Intel 82801HH (ich8dh) */
|
||||
{ 0x8086, 0x2912, pIIxget, pIIxset }, /* Intel 82801ih ich9dh */
|
||||
{ 0x8086, 0x2914, pIIxget, pIIxset }, /* Intel 82801io ich9do */
|
||||
{ 0x8086, 0x2916, pIIxget, pIIxset }, /* Intel 82801ibr ich9r */
|
||||
{ 0x8086, 0x2917, pIIxget, pIIxset }, /* Intel 82801iem ich9m-e */
|
||||
{ 0x8086, 0x2918, pIIxget, pIIxset }, /* Intel 82801ib ich9 */
|
||||
{ 0x8086, 0x2919, pIIxget, pIIxset }, /* Intel 82801? ich9m */
|
||||
{ 0x8086, 0x3a16, pIIxget, pIIxset }, /* Intel 82801jir ich10r */
|
||||
{ 0x8086, 0x3a18, pIIxget, pIIxset }, /* Intel 82801jib ich10 */
|
||||
{ 0x8086, 0x3a40, pIIxget, pIIxset }, /* Intel 82801ji */
|
||||
{ 0x8086, 0x3a42, pIIxget, pIIxset }, /* Intel 82801ji */
|
||||
{ 0x8086, 0x3a48, pIIxget, pIIxset }, /* Intel 82801ji */
|
||||
{ 0x8086, 0x3b06, pIIxget, pIIxset }, /* Intel 82801? ibex peak */
|
||||
{ 0x8086, 0x3b14, pIIxget, pIIxset }, /* Intel 82801? 3420 */
|
||||
{ 0x8086, 0x1c49, pIIxget, pIIxset }, /* Intel 82hm65 cougar point pch */
|
||||
{ 0x8086, 0x1c4b, pIIxget, pIIxset }, /* Intel 82hm67 */
|
||||
{ 0x8086, 0x1c4f, pIIxget, pIIxset }, /* Intel 82qm67 cougar point pch */
|
||||
{ 0x8086, 0x1c52, pIIxget, pIIxset }, /* Intel 82q65 cougar point pch */
|
||||
{ 0x8086, 0x1c54, pIIxget, pIIxset }, /* Intel 82q67 cougar point pch */
|
||||
{ 0x8086, 0x1e55, pIIxget, pIIxset }, /* Intel QM77 panter point lpc */
|
||||
|
||||
{ 0x1106, 0x0586, viaget, viaset }, /* Viatech 82C586 */
|
||||
{ 0x1106, 0x0596, viaget, viaset }, /* Viatech 82C596 */
|
||||
{ 0x1106, 0x0686, viaget, viaset }, /* Viatech 82C686 */
|
||||
{ 0x1106, 0x3177, viaget, viaset }, /* Viatech VT8235 */
|
||||
{ 0x1106, 0x3227, viaget, viaset }, /* Viatech VT8237 */
|
||||
{ 0x1106, 0x3287, viaget, viaset }, /* Viatech VT8251 */
|
||||
{ 0x1106, 0x8410, viaget, viaset }, /* Viatech PV530 bridge */
|
||||
{ 0x1045, 0xc700, optiget, optiset }, /* Opti 82C700 */
|
||||
{ 0x10b9, 0x1533, aliget, aliset }, /* Al M1533 */
|
||||
{ 0x1039, 0x0008, pIIxget, pIIxset }, /* SI 503 */
|
||||
{ 0x1039, 0x0496, pIIxget, pIIxset }, /* SI 496 */
|
||||
{ 0x1078, 0x0100, cyrixget, cyrixset }, /* Cyrix 5530 Legacy */
|
||||
|
||||
{ 0x1022, 0x790e, nil, nil }, /* AMD FCH LPC bridge */
|
||||
{ 0x1022, 0x746b, nil, nil }, /* AMD 8111 */
|
||||
{ 0x10de, 0x00d1, nil, nil }, /* NVIDIA nForce 3 */
|
||||
{ 0x10de, 0x00e0, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
||||
{ 0x10de, 0x00e1, nil, nil }, /* NVIDIA nForce 3 250 Series */
|
||||
{ 0x1166, 0x0200, nil, nil }, /* ServerWorks ServerSet III LE */
|
||||
{ 0x1002, 0x4377, nil, nil }, /* ATI Radeon Xpress 200M */
|
||||
{ 0x1002, 0x4372, nil, nil }, /* ATI SB400 */
|
||||
{ 0x1002, 0x9601, nil, nil }, /* AMD SB710 */
|
||||
{ 0x1002, 0x438d, nil, nil }, /* AMD SB600 */
|
||||
{ 0x1002, 0x439d, nil, nil }, /* AMD SB810 */
|
||||
};
|
||||
|
||||
typedef struct Slot Slot;
|
||||
struct Slot {
|
||||
uchar bus; /* Pci bus number */
|
||||
uchar dev; /* Pci device number */
|
||||
uchar maps[12]; /* Avoid structs! Link and mask. */
|
||||
uchar slot; /* Add-in/built-in slot */
|
||||
uchar reserved;
|
||||
};
|
||||
|
||||
typedef struct Router Router;
|
||||
struct Router {
|
||||
uchar signature[4]; /* Routing table signature */
|
||||
uchar version[2]; /* Version number */
|
||||
uchar size[2]; /* Total table size */
|
||||
uchar bus; /* Interrupt router bus number */
|
||||
uchar devfn; /* Router's devfunc */
|
||||
uchar pciirqs[2]; /* Exclusive PCI irqs */
|
||||
uchar compat[4]; /* Compatible PCI interrupt router */
|
||||
uchar miniport[4]; /* Miniport data */
|
||||
uchar reserved[11];
|
||||
uchar checksum;
|
||||
};
|
||||
|
||||
static ushort pciirqs; /* Exclusive PCI irqs */
|
||||
static Bridge *southbridge; /* Which southbridge to use. */
|
||||
|
||||
static void
|
||||
pcirouting(void)
|
||||
{
|
||||
Slot *e;
|
||||
Router *r;
|
||||
int i, size, tbdf;
|
||||
Pcidev *sbpci, *pci;
|
||||
uchar *p, pin, irq, link, *map;
|
||||
|
||||
if((p = sigsearch("$PIR", 0)) == nil)
|
||||
return;
|
||||
|
||||
r = (Router*)p;
|
||||
size = (r->size[1] << 8)|r->size[0];
|
||||
if(size < sizeof(Router) || checksum(r, size))
|
||||
return;
|
||||
|
||||
if(0) print("PCI interrupt routing table version %d.%d at %p\n",
|
||||
r->version[0], r->version[1], r);
|
||||
|
||||
tbdf = MKBUS(BusPCI, r->bus, (r->devfn>>3)&0x1f, r->devfn&7);
|
||||
sbpci = pcimatchtbdf(tbdf);
|
||||
if(sbpci == nil) {
|
||||
print("pcirouting: Cannot find south bridge %T\n", tbdf);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < nelem(southbridges); i++)
|
||||
if(sbpci->vid == southbridges[i].vid && sbpci->did == southbridges[i].did)
|
||||
break;
|
||||
|
||||
if(i == nelem(southbridges)) {
|
||||
print("pcirouting: ignoring south bridge %T %.4uX/%.4uX\n", tbdf, sbpci->vid, sbpci->did);
|
||||
return;
|
||||
}
|
||||
southbridge = &southbridges[i];
|
||||
if(southbridge->get == nil)
|
||||
return;
|
||||
|
||||
pciirqs = (r->pciirqs[1] << 8)|r->pciirqs[0];
|
||||
for(e = (Slot *)&r[1]; (uchar *)e < p + size; e++) {
|
||||
if(0) {
|
||||
print("%.2uX/%.2uX %.2uX: ", e->bus, e->dev, e->slot);
|
||||
for (i = 0; i < 4; i++) {
|
||||
map = &e->maps[i * 3];
|
||||
print("[%d] %.2uX %.4uX ", i, map[0], (map[2] << 8)|map[1]);
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
for(i = 0; i < 8; i++) {
|
||||
tbdf = MKBUS(BusPCI, e->bus, (e->dev>>3)&0x1f, i);
|
||||
pci = pcimatchtbdf(tbdf);
|
||||
if(pci == nil)
|
||||
continue;
|
||||
pin = pcicfgr8(pci, PciINTP);
|
||||
if(pin == 0 || pin == 0xff)
|
||||
continue;
|
||||
|
||||
map = &e->maps[((pin - 1) % 4) * 3];
|
||||
link = map[0];
|
||||
irq = southbridge->get(sbpci, link);
|
||||
if(irq == pci->intl)
|
||||
continue;
|
||||
if(irq == 0 || (irq & 0x80) != 0){
|
||||
irq = pci->intl;
|
||||
if(irq == 0 || irq == 0xff)
|
||||
continue;
|
||||
if(southbridge->set == nil)
|
||||
continue;
|
||||
southbridge->set(sbpci, link, irq);
|
||||
}
|
||||
print("pcirouting: %T at pin %d link %.2uX irq %d -> %d\n", tbdf, pin, link, pci->intl, irq);
|
||||
pcicfgw8(pci, PciINTL, irq);
|
||||
pci->intl = irq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pcireservemem(void)
|
||||
{
|
||||
Pcidev *p;
|
||||
uvlong pa;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* mark all valid physical address space claimed by pci devices
|
||||
* as in use, so that upaalloc doesn't give it out.
|
||||
*/
|
||||
for(p=pciroot; p != nil; p=p->list){
|
||||
for(i=0; i<nelem(p->mem); i++){
|
||||
if(p->mem[i].size == 0)
|
||||
continue;
|
||||
if(p->mem[i].bar & 1)
|
||||
continue;
|
||||
if((p->mem[i].bar & ~0xFULL) == 0)
|
||||
continue;
|
||||
upaalloc(p->mem[i].bar&~0xFULL, p->mem[i].size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate physical address space for unassigned membars.
|
||||
*/
|
||||
for(p=pciroot; p != nil; p=p->list){
|
||||
for(i=0; i<nelem(p->mem); i++){
|
||||
if(p->mem[i].size == 0)
|
||||
continue;
|
||||
if(p->mem[i].bar & ~0xEULL)
|
||||
continue;
|
||||
|
||||
if(p->parent == nil){
|
||||
pa = upaalloc(-1ULL,
|
||||
p->mem[i].size, p->mem[i].size);
|
||||
} else if(p->mem[i].bar & 8){
|
||||
pa = upaallocwin(p->parent->prefa.bar, p->parent->prefa.size,
|
||||
p->mem[i].size, p->mem[i].size);
|
||||
if(pa == -1ULL)
|
||||
goto Mem;
|
||||
} else {
|
||||
Mem:
|
||||
pa = upaallocwin(p->parent->mema.bar, p->parent->mema.size,
|
||||
p->mem[i].size, p->mem[i].size);
|
||||
}
|
||||
if(pa == -1ULL)
|
||||
continue;
|
||||
|
||||
p->mem[i].bar |= pa;
|
||||
pcisetbar(p, PciBAR0 + i*4, p->mem[i].bar);
|
||||
|
||||
DBG("%T: bar%d: fixed %.8lluX %d\n",
|
||||
p->tbdf, i, p->mem[i].bar, p->mem[i].size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcicfginit(void)
|
||||
{
|
||||
char *p;
|
||||
Pcidev **list;
|
||||
int bno, n, pcibios;
|
||||
|
||||
fmtinstall('T', tbdffmt);
|
||||
|
||||
pcibios = 0;
|
||||
if(getconf("*nobios"))
|
||||
nobios = 1;
|
||||
else if(getconf("*pcibios"))
|
||||
pcibios = 1;
|
||||
if(getconf("*nopcirouting"))
|
||||
nopcirouting = 1;
|
||||
|
||||
/*
|
||||
* Try to determine which PCI configuration mode is implemented.
|
||||
* Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses
|
||||
* a DWORD at 0xCF8 and another at 0xCFC and will pass through
|
||||
* any non-DWORD accesses as normal I/O cycles. There shouldn't be
|
||||
* a device behind these addresses so if Mode1 accesses fail try
|
||||
* for Mode2 (Mode2 is deprecated).
|
||||
*/
|
||||
if(!pcibios){
|
||||
/*
|
||||
* Bits [30:24] of PciADDR must be 0,
|
||||
* according to the spec.
|
||||
*/
|
||||
n = inl(PciADDR);
|
||||
if(!(n & 0x7F000000)){
|
||||
outl(PciADDR, 0x80000000);
|
||||
outb(PciADDR+3, 0);
|
||||
if(inl(PciADDR) & 0x80000000){
|
||||
pcicfgmode = 1;
|
||||
pcimaxdno = 31;
|
||||
}
|
||||
}
|
||||
outl(PciADDR, n);
|
||||
|
||||
if(pcicfgmode < 0){
|
||||
/*
|
||||
* The 'key' part of PciCSE should be 0.
|
||||
*/
|
||||
n = inb(PciCSE);
|
||||
if(!(n & 0xF0)){
|
||||
outb(PciCSE, 0x0E);
|
||||
if(inb(PciCSE) == 0x0E){
|
||||
pcicfgmode = 2;
|
||||
pcimaxdno = 15;
|
||||
}
|
||||
}
|
||||
outb(PciCSE, n);
|
||||
}
|
||||
}
|
||||
|
||||
if(pcicfgmode < 0 || pcibios) {
|
||||
if((pcibiossi = pcibiosinit()) == nil)
|
||||
goto out;
|
||||
pcicfgrw8 = pcicfgrw8bios;
|
||||
pcicfgrw16 = pcicfgrw16bios;
|
||||
pcicfgrw32 = pcicfgrw32bios;
|
||||
pcicfgmode = 3;
|
||||
}
|
||||
|
||||
if(p = getconf("*pcimaxbno"))
|
||||
pcimaxbno = strtoul(p, 0, 0);
|
||||
if(p = getconf("*pcimaxdno")){
|
||||
n = strtoul(p, 0, 0);
|
||||
if(n < pcimaxdno)
|
||||
pcimaxdno = n;
|
||||
}
|
||||
|
||||
list = &pciroot;
|
||||
for(bno = 0; bno <= pcimaxbno; bno++) {
|
||||
int sbno = bno;
|
||||
bno = pciscan(bno, list);
|
||||
|
||||
while(*list)
|
||||
list = &(*list)->link;
|
||||
|
||||
if (sbno == 0) {
|
||||
Pcidev *pci;
|
||||
|
||||
/*
|
||||
* If we have found a PCI-to-Cardbus bridge, make sure
|
||||
* it has no valid mappings anymore.
|
||||
*/
|
||||
for(pci = pciroot; pci != nil; pci = pci->link){
|
||||
if (pci->ccrb == 6 && pci->ccru == 7) {
|
||||
ushort bcr;
|
||||
|
||||
/* reset the cardbus */
|
||||
bcr = pcicfgr16(pci, PciBCR);
|
||||
pcicfgw16(pci, PciBCR, 0x40 | bcr);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pciroot == nil)
|
||||
goto out;
|
||||
|
||||
if(nobios) {
|
||||
uvlong mema;
|
||||
ulong ioa;
|
||||
|
||||
/*
|
||||
* Work out how big the top bus is
|
||||
*/
|
||||
pcibussize(pciroot, &mema, &ioa);
|
||||
DBG("Size: mem=%.8llux io=%lux\n", mema, ioa);
|
||||
|
||||
/*
|
||||
* Align the windows and map it
|
||||
*/
|
||||
mema = upaalloc(-1ULL, mema, mema);
|
||||
if(mema == -1ULL)
|
||||
panic("pcicfginit: can't allocate pci window");
|
||||
|
||||
ioa = 0x1000;
|
||||
DBG("Base: mem=%.8llux io=%lux\n", mema, ioa);
|
||||
pcibusmap(pciroot, &mema, &ioa, 1);
|
||||
DBG("Limit: mem=%.8llux io=%lux\n", mema, ioa);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcireservemem();
|
||||
|
||||
if(!nopcirouting)
|
||||
pcirouting();
|
||||
|
||||
out:
|
||||
if(getconf("*pcihinv"))
|
||||
pcihinv(pciroot);
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
/*
|
||||
* SMBus support for the PIIX4
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/sd.h"
|
||||
|
||||
/* registers */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
|
||||
#include "../port/sd.h"
|
||||
extern SDifc sd53c8xxifc;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/sd.h"
|
||||
#include <fis.h>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
@ -352,7 +353,7 @@ pc87415ienable(Ctlr* ctlr)
|
|||
return;
|
||||
|
||||
x = pcicfgr32(p, 0x40);
|
||||
if(ctlr->cmdport == p->mem[0].bar)
|
||||
if(ctlr->cmdport == (p->mem[0].bar & ~3))
|
||||
x &= ~0x00000100;
|
||||
else
|
||||
x &= ~0x00000200;
|
||||
|
@ -2142,8 +2143,8 @@ atapnp(void)
|
|||
if((map & 1<<channel) == 0)
|
||||
continue;
|
||||
if(pi & 1<<2*channel){
|
||||
sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
|
||||
p->mem[1+2*channel].bar & ~0x01,
|
||||
sdev = ataprobe(p->mem[0+2*channel].bar & ~3,
|
||||
p->mem[1+2*channel].bar & ~3,
|
||||
p->intl, 3);
|
||||
tbdf = p->tbdf;
|
||||
}
|
||||
|
@ -2169,7 +2170,7 @@ atapnp(void)
|
|||
ctlr->span = span;
|
||||
ctlr->irqack = irqack;
|
||||
if((pi & 0x80) && (p->mem[4].bar & 0x01))
|
||||
ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
|
||||
ctlr->bmiba = (p->mem[4].bar & ~3) + channel*8;
|
||||
if(head != nil)
|
||||
tail->next = sdev;
|
||||
else
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/sd.h"
|
||||
#include <fis.h>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
@ -1054,7 +1055,7 @@ mylexpnp(void)
|
|||
p = nil;
|
||||
head = tail = nil;
|
||||
while(p = pcimatch(p, 0x104B, 0)){
|
||||
if((sdev = mylexprobe(p->mem[0].bar & ~0x01, p->intl)) == nil)
|
||||
if((sdev = mylexprobe(p->mem[0].bar & ~3, p->intl)) == nil)
|
||||
continue;
|
||||
|
||||
ctlr = sdev->ctlr;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/sd.h"
|
||||
#include <fis.h>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "ureg.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
@ -203,13 +204,15 @@ viopnpdevs(int typ)
|
|||
continue;
|
||||
if(p->rid != 0)
|
||||
continue;
|
||||
if((p->mem[0].bar & 1) == 0)
|
||||
continue;
|
||||
if(pcicfgr16(p, 0x2E) != typ)
|
||||
continue;
|
||||
if((vd = malloc(sizeof(*vd))) == nil){
|
||||
print("virtio: no memory for Vdev\n");
|
||||
break;
|
||||
}
|
||||
vd->port = p->mem[0].bar & ~0x1;
|
||||
vd->port = p->mem[0].bar & ~3;
|
||||
if(ioalloc(vd->port, p->mem[0].size, 0, "virtio") < 0){
|
||||
print("virtio: port %lux in use\n", vd->port);
|
||||
free(vd);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#include "uartaxp.i"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
extern PhysUart i8250physuart;
|
||||
|
@ -21,21 +22,21 @@ uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name,
|
|||
char buf[64];
|
||||
Uart *head, *uart;
|
||||
|
||||
head = malloc(sizeof(Uart)*n);
|
||||
if(head == nil){
|
||||
print("uartpci: no memory for Uarts\n");
|
||||
if((p->mem[barno].bar & 1) == 0)
|
||||
return nil;
|
||||
}
|
||||
|
||||
io = p->mem[barno].bar & ~0x01;
|
||||
io = p->mem[barno].bar & ~3;
|
||||
snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
|
||||
if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
|
||||
print("uartpci: I/O 0x%uX in use\n", io);
|
||||
free(head);
|
||||
return nil;
|
||||
}
|
||||
|
||||
pcienable(p);
|
||||
head = malloc(sizeof(Uart)*n);
|
||||
if(head == nil){
|
||||
print("uartpci: no memory for Uarts\n");
|
||||
iofree(io);
|
||||
return nil;
|
||||
}
|
||||
uart = head;
|
||||
for(i = 0; i < n; i++){
|
||||
ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/usb.h"
|
||||
#include "usbehci.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#include "../port/usb.h"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
#include "../port/usb.h"
|
||||
|
||||
|
@ -2131,7 +2132,7 @@ scanpci(void)
|
|||
case 0:
|
||||
if((p->mem[4].bar & 1) == 0)
|
||||
continue;
|
||||
io = (int)p->mem[4].bar & ~0xF;
|
||||
io = p->mem[4].bar & ~3;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Ureg Ureg386
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#define Image IMAGE
|
||||
|
|
|
@ -124,32 +124,10 @@ void outl(int, ulong);
|
|||
void outsl(int, void*, int);
|
||||
uintptr paddr(void*);
|
||||
void patwc(void*, int);
|
||||
ulong pcibarsize(Pcidev*, int);
|
||||
void pcibussize(Pcidev*, uvlong*, ulong*);
|
||||
int pcicfgr8(Pcidev*, int);
|
||||
int pcicfgr16(Pcidev*, int);
|
||||
int pcicfgr32(Pcidev*, int);
|
||||
void pcicfgw8(Pcidev*, int, int);
|
||||
void pcicfgw16(Pcidev*, int, int);
|
||||
void pcicfgw32(Pcidev*, int, int);
|
||||
void pciclrbme(Pcidev*);
|
||||
void pciclrioe(Pcidev*);
|
||||
void pciclrmwi(Pcidev*);
|
||||
int pcigetpms(Pcidev*);
|
||||
void pcihinv(Pcidev*);
|
||||
uchar pciipin(Pcidev*, uchar);
|
||||
Pcidev* pcimatch(Pcidev*, int, int);
|
||||
Pcidev* pcimatchtbdf(int);
|
||||
int pcicap(Pcidev*, int);
|
||||
int pcihtcap(Pcidev*, int);
|
||||
void pcireset(void);
|
||||
int pciscan(int, Pcidev**);
|
||||
void pcisetbme(Pcidev*);
|
||||
void pcisetioe(Pcidev*);
|
||||
void pcisetmwi(Pcidev*);
|
||||
int pcisetpms(Pcidev*, int);
|
||||
void pcienable(Pcidev*);
|
||||
void pcidisable(Pcidev*);
|
||||
void pcicfginit(void);
|
||||
int (*pcicfgrw8)(int, int, int, int);
|
||||
int (*pcicfgrw16)(int, int, int, int);
|
||||
int (*pcicfgrw32)(int, int, int, int);
|
||||
void pcmcisread(PCMslot*);
|
||||
int pcmcistuple(int, int, int, void*, int);
|
||||
PCMmap* pcmmap(int, ulong, int, int);
|
||||
|
@ -192,6 +170,7 @@ uvlong tscticks(uvlong*);
|
|||
ulong umballoc(ulong, ulong, ulong);
|
||||
void umbfree(ulong, ulong);
|
||||
uvlong upaalloc(uvlong, ulong, ulong);
|
||||
uvlong upaallocwin(uvlong, ulong, ulong, ulong);
|
||||
void upafree(uvlong, ulong);
|
||||
void vectortable(void);
|
||||
void vmxprocrestore(Proc *);
|
||||
|
|
|
@ -190,6 +190,7 @@ main(void)
|
|||
ramdiskinit();
|
||||
confinit();
|
||||
xinit();
|
||||
pcicfginit();
|
||||
bootscreeninit();
|
||||
if(i8237alloc != nil)
|
||||
i8237alloc();
|
||||
|
@ -207,7 +208,6 @@ main(void)
|
|||
initseg();
|
||||
if(delaylink){
|
||||
bootlinks();
|
||||
pcimatch(0, 0, 0);
|
||||
}else
|
||||
links();
|
||||
chandevreset();
|
||||
|
|
|
@ -26,7 +26,7 @@ dev
|
|||
draw screen vga vgax vgasoft
|
||||
mouse mouse
|
||||
kbd
|
||||
vga
|
||||
vga pci
|
||||
|
||||
sd
|
||||
# floppy dma
|
||||
|
@ -44,9 +44,9 @@ dev
|
|||
dtracy
|
||||
|
||||
link
|
||||
# devpccard
|
||||
# devpccard pci
|
||||
# devi82365
|
||||
cputemp
|
||||
cputemp pci
|
||||
# ether2000 ether8390
|
||||
# ether2114x pci
|
||||
# ether589 etherelnk3
|
||||
|
@ -82,16 +82,17 @@ link
|
|||
# pcmciamodem
|
||||
netdevmedium
|
||||
loopbackmedium
|
||||
usbuhci
|
||||
usbohci
|
||||
usbehci usbehcipc
|
||||
usbuhci pci
|
||||
usbohci pci
|
||||
usbehci pci usbehcipc
|
||||
usbxhci pci
|
||||
|
||||
# audiosb16 dma
|
||||
# audioac97 audioac97mix
|
||||
audiohda
|
||||
# audioac97 pci audioac97mix
|
||||
audiohda pci
|
||||
|
||||
misc
|
||||
pci pcipc
|
||||
archacpi mp apic squidboy ec
|
||||
archmp mp apic squidboy
|
||||
mtrr
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "io.h"
|
||||
#include "../port/pci.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
typedef struct Pnp Pnp;
|
||||
|
|
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue