merge
commit
d3ebd02bef
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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 New Issue