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