xref: /plan9-contrib/sys/src/9/bcm/pci.h (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
1*5c47fe09SDavid du Colombier /*
2*5c47fe09SDavid du Colombier  * PCI
3*5c47fe09SDavid du Colombier  */
4*5c47fe09SDavid du Colombier typedef unsigned long long uintpci;
5*5c47fe09SDavid du Colombier 
6*5c47fe09SDavid du Colombier #define BUSUNKNOWN	(-1)
7*5c47fe09SDavid du Colombier 
8*5c47fe09SDavid du Colombier enum {
9*5c47fe09SDavid du Colombier 	BusCBUS		= 0,		/* Corollary CBUS */
10*5c47fe09SDavid du Colombier 	BusCBUSII,			/* Corollary CBUS II */
11*5c47fe09SDavid du Colombier 	BusEISA,			/* Extended ISA */
12*5c47fe09SDavid du Colombier 	BusFUTURE,			/* IEEE Futurebus */
13*5c47fe09SDavid du Colombier 	BusINTERN,			/* Internal bus */
14*5c47fe09SDavid du Colombier 	BusISA,				/* Industry Standard Architecture */
15*5c47fe09SDavid du Colombier 	BusMBI,				/* Multibus I */
16*5c47fe09SDavid du Colombier 	BusMBII,			/* Multibus II */
17*5c47fe09SDavid du Colombier 	BusMCA,				/* Micro Channel Architecture */
18*5c47fe09SDavid du Colombier 	BusMPI,				/* MPI */
19*5c47fe09SDavid du Colombier 	BusMPSA,			/* MPSA */
20*5c47fe09SDavid du Colombier 	BusNUBUS,			/* Apple Macintosh NuBus */
21*5c47fe09SDavid du Colombier 	BusPCI,				/* Peripheral Component Interconnect */
22*5c47fe09SDavid du Colombier 	BusPCMCIA,			/* PC Memory Card International Association */
23*5c47fe09SDavid du Colombier 	BusTC,				/* DEC TurboChannel */
24*5c47fe09SDavid du Colombier 	BusVL,				/* VESA Local bus */
25*5c47fe09SDavid du Colombier 	BusVME,				/* VMEbus */
26*5c47fe09SDavid du Colombier 	BusXPRESS,			/* Express System Bus */
27*5c47fe09SDavid du Colombier };
28*5c47fe09SDavid du Colombier 
29*5c47fe09SDavid du Colombier #define MKBUS(t,b,d,f)	(((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
30*5c47fe09SDavid du Colombier #define BUSFNO(tbdf)	(((tbdf)>>8)&0x07)
31*5c47fe09SDavid du Colombier #define BUSDNO(tbdf)	(((tbdf)>>11)&0x1F)
32*5c47fe09SDavid du Colombier #define BUSBNO(tbdf)	(((tbdf)>>16)&0xFF)
33*5c47fe09SDavid du Colombier #define BUSTYPE(tbdf)	((tbdf)>>24)
34*5c47fe09SDavid du Colombier #define BUSBDF(tbdf)	((tbdf)&0x00FFFF00)
35*5c47fe09SDavid du Colombier 
36*5c47fe09SDavid du Colombier enum {					/* type 0 & type 1 pre-defined header */
37*5c47fe09SDavid du Colombier 	PciVID		= 0x00,		/* vendor ID */
38*5c47fe09SDavid du Colombier 	PciDID		= 0x02,		/* device ID */
39*5c47fe09SDavid du Colombier 	PciPCR		= 0x04,		/* command */
40*5c47fe09SDavid du Colombier 	PciPSR		= 0x06,		/* status */
41*5c47fe09SDavid du Colombier 	PciRID		= 0x08,		/* revision ID */
42*5c47fe09SDavid du Colombier 	PciCCRp		= 0x09,		/* programming interface class code */
43*5c47fe09SDavid du Colombier 	PciCCRu		= 0x0A,		/* sub-class code */
44*5c47fe09SDavid du Colombier 	PciCCRb		= 0x0B,		/* base class code */
45*5c47fe09SDavid du Colombier 	PciCLS		= 0x0C,		/* cache line size */
46*5c47fe09SDavid du Colombier 	PciLTR		= 0x0D,		/* latency timer */
47*5c47fe09SDavid du Colombier 	PciHDT		= 0x0E,		/* header type */
48*5c47fe09SDavid du Colombier 	PciBST		= 0x0F,		/* BIST */
49*5c47fe09SDavid du Colombier 
50*5c47fe09SDavid du Colombier 	PciBAR0		= 0x10,		/* base address */
51*5c47fe09SDavid du Colombier 	PciBAR1		= 0x14,
52*5c47fe09SDavid du Colombier 
53*5c47fe09SDavid du Colombier 	PciCAP		= 0x34,		/* capabilities pointer */
54*5c47fe09SDavid du Colombier 	PciINTL		= 0x3C,		/* interrupt line */
55*5c47fe09SDavid du Colombier 	PciINTP		= 0x3D,		/* interrupt pin */
56*5c47fe09SDavid du Colombier };
57*5c47fe09SDavid du Colombier 
58*5c47fe09SDavid du Colombier /* ccrb (base class code) values; controller types */
59*5c47fe09SDavid du Colombier enum {
60*5c47fe09SDavid du Colombier 	Pcibcpci1	= 0,		/* pci 1.0; no class codes defined */
61*5c47fe09SDavid du Colombier 	Pcibcstore	= 1,		/* mass storage */
62*5c47fe09SDavid du Colombier 	Pcibcnet	= 2,		/* network */
63*5c47fe09SDavid du Colombier 	Pcibcdisp	= 3,		/* display */
64*5c47fe09SDavid du Colombier 	Pcibcmmedia	= 4,		/* multimedia */
65*5c47fe09SDavid du Colombier 	Pcibcmem	= 5,		/* memory */
66*5c47fe09SDavid du Colombier 	Pcibcbridge	= 6,		/* bridge */
67*5c47fe09SDavid du Colombier 	Pcibccomm	= 7,		/* simple comms (e.g., serial) */
68*5c47fe09SDavid du Colombier 	Pcibcbasesys	= 8,		/* base system */
69*5c47fe09SDavid du Colombier 	Pcibcinput	= 9,		/* input */
70*5c47fe09SDavid du Colombier 	Pcibcdock	= 0xa,		/* docking stations */
71*5c47fe09SDavid du Colombier 	Pcibcproc	= 0xb,		/* processors */
72*5c47fe09SDavid du Colombier 	Pcibcserial	= 0xc,		/* serial bus (e.g., USB) */
73*5c47fe09SDavid du Colombier 	Pcibcwireless	= 0xd,		/* wireless */
74*5c47fe09SDavid du Colombier 	Pcibcintell	= 0xe,		/* intelligent i/o */
75*5c47fe09SDavid du Colombier 	Pcibcsatcom	= 0xf,		/* satellite comms */
76*5c47fe09SDavid du Colombier 	Pcibccrypto	= 0x10,		/* encryption/decryption */
77*5c47fe09SDavid du Colombier 	Pcibcdacq	= 0x11,		/* data acquisition & signal proc. */
78*5c47fe09SDavid du Colombier };
79*5c47fe09SDavid du Colombier 
80*5c47fe09SDavid du Colombier /* ccru (sub-class code) values; common cases only */
81*5c47fe09SDavid du Colombier enum {
82*5c47fe09SDavid du Colombier 	/* mass storage */
83*5c47fe09SDavid du Colombier 	Pciscscsi	= 0,		/* SCSI */
84*5c47fe09SDavid du Colombier 	Pciscide	= 1,		/* IDE (ATA) */
85*5c47fe09SDavid du Colombier 	Pciscsata	= 6,		/* SATA */
86*5c47fe09SDavid du Colombier 
87*5c47fe09SDavid du Colombier 	/* network */
88*5c47fe09SDavid du Colombier 	Pciscether	= 0,		/* Ethernet */
89*5c47fe09SDavid du Colombier 
90*5c47fe09SDavid du Colombier 	/* display */
91*5c47fe09SDavid du Colombier 	Pciscvga	= 0,		/* VGA */
92*5c47fe09SDavid du Colombier 	Pciscxga	= 1,		/* XGA */
93*5c47fe09SDavid du Colombier 	Pcisc3d		= 2,		/* 3D */
94*5c47fe09SDavid du Colombier 
95*5c47fe09SDavid du Colombier 	/* bridges */
96*5c47fe09SDavid du Colombier 	Pcischostpci	= 0,		/* host/pci */
97*5c47fe09SDavid du Colombier 	Pciscpcicpci	= 1,		/* pci/pci */
98*5c47fe09SDavid du Colombier 
99*5c47fe09SDavid du Colombier 	/* simple comms */
100*5c47fe09SDavid du Colombier 	Pciscserial	= 0,		/* 16450, etc. */
101*5c47fe09SDavid du Colombier 	Pciscmultiser	= 1,		/* multiport serial */
102*5c47fe09SDavid du Colombier 
103*5c47fe09SDavid du Colombier 	/* serial bus */
104*5c47fe09SDavid du Colombier 	Pciscusb	= 3,		/* USB */
105*5c47fe09SDavid du Colombier };
106*5c47fe09SDavid du Colombier 
107*5c47fe09SDavid du Colombier enum {					/* type 0 pre-defined header */
108*5c47fe09SDavid du Colombier 	PciCIS		= 0x28,		/* cardbus CIS pointer */
109*5c47fe09SDavid du Colombier 	PciSVID		= 0x2C,		/* subsystem vendor ID */
110*5c47fe09SDavid du Colombier 	PciSID		= 0x2E,		/* subsystem ID */
111*5c47fe09SDavid du Colombier 	PciEBAR0	= 0x30,		/* expansion ROM base address */
112*5c47fe09SDavid du Colombier 	PciMGNT		= 0x3E,		/* burst period length */
113*5c47fe09SDavid du Colombier 	PciMLT		= 0x3F,		/* maximum latency between bursts */
114*5c47fe09SDavid du Colombier };
115*5c47fe09SDavid du Colombier 
116*5c47fe09SDavid du Colombier enum {					/* type 1 pre-defined header */
117*5c47fe09SDavid du Colombier 	PciPBN		= 0x18,		/* primary bus number */
118*5c47fe09SDavid du Colombier 	PciSBN		= 0x19,		/* secondary bus number */
119*5c47fe09SDavid du Colombier 	PciUBN		= 0x1A,		/* subordinate bus number */
120*5c47fe09SDavid du Colombier 	PciSLTR		= 0x1B,		/* secondary latency timer */
121*5c47fe09SDavid du Colombier 	PciIBR		= 0x1C,		/* I/O base */
122*5c47fe09SDavid du Colombier 	PciILR		= 0x1D,		/* I/O limit */
123*5c47fe09SDavid du Colombier 	PciSPSR		= 0x1E,		/* secondary status */
124*5c47fe09SDavid du Colombier 	PciMBR		= 0x20,		/* memory base */
125*5c47fe09SDavid du Colombier 	PciMLR		= 0x22,		/* memory limit */
126*5c47fe09SDavid du Colombier 	PciPMBR		= 0x24,		/* prefetchable memory base */
127*5c47fe09SDavid du Colombier 	PciPMLR		= 0x26,		/* prefetchable memory limit */
128*5c47fe09SDavid du Colombier 	PciPUBR		= 0x28,		/* prefetchable base upper 32 bits */
129*5c47fe09SDavid du Colombier 	PciPULR		= 0x2C,		/* prefetchable limit upper 32 bits */
130*5c47fe09SDavid du Colombier 	PciIUBR		= 0x30,		/* I/O base upper 16 bits */
131*5c47fe09SDavid du Colombier 	PciIULR		= 0x32,		/* I/O limit upper 16 bits */
132*5c47fe09SDavid du Colombier 	PciEBAR1	= 0x28,		/* expansion ROM base address */
133*5c47fe09SDavid du Colombier 	PciBCR		= 0x3E,		/* bridge control register */
134*5c47fe09SDavid du Colombier };
135*5c47fe09SDavid du Colombier 
136*5c47fe09SDavid du Colombier enum {					/* type 2 pre-defined header */
137*5c47fe09SDavid du Colombier 	PciCBExCA	= 0x10,
138*5c47fe09SDavid du Colombier 	PciCBSPSR	= 0x16,
139*5c47fe09SDavid du Colombier 	PciCBPBN	= 0x18,		/* primary bus number */
140*5c47fe09SDavid du Colombier 	PciCBSBN	= 0x19,		/* secondary bus number */
141*5c47fe09SDavid du Colombier 	PciCBUBN	= 0x1A,		/* subordinate bus number */
142*5c47fe09SDavid du Colombier 	PciCBSLTR	= 0x1B,		/* secondary latency timer */
143*5c47fe09SDavid du Colombier 	PciCBMBR0	= 0x1C,
144*5c47fe09SDavid du Colombier 	PciCBMLR0	= 0x20,
145*5c47fe09SDavid du Colombier 	PciCBMBR1	= 0x24,
146*5c47fe09SDavid du Colombier 	PciCBMLR1	= 0x28,
147*5c47fe09SDavid du Colombier 	PciCBIBR0	= 0x2C,		/* I/O base */
148*5c47fe09SDavid du Colombier 	PciCBILR0	= 0x30,		/* I/O limit */
149*5c47fe09SDavid du Colombier 	PciCBIBR1	= 0x34,		/* I/O base */
150*5c47fe09SDavid du Colombier 	PciCBILR1	= 0x38,		/* I/O limit */
151*5c47fe09SDavid du Colombier 	PciCBSVID	= 0x40,		/* subsystem vendor ID */
152*5c47fe09SDavid du Colombier 	PciCBSID	= 0x42,		/* subsystem ID */
153*5c47fe09SDavid du Colombier 	PciCBLMBAR	= 0x44,		/* legacy mode base address */
154*5c47fe09SDavid du Colombier };
155*5c47fe09SDavid du Colombier 
156*5c47fe09SDavid du Colombier enum {
157*5c47fe09SDavid du Colombier 	/* bar bits */
158*5c47fe09SDavid du Colombier 	Barioaddr	= 1<<0,		/* vs. memory addr */
159*5c47fe09SDavid du Colombier 	Barwidthshift	= 1,
160*5c47fe09SDavid du Colombier 	Barwidthmask	= 3,
161*5c47fe09SDavid du Colombier 	Barwidth32	= 0,
162*5c47fe09SDavid du Colombier 	Barwidth64	= 2,
163*5c47fe09SDavid du Colombier 	Barprefetch	= 1<<3,
164*5c47fe09SDavid du Colombier };
165*5c47fe09SDavid du Colombier 
166*5c47fe09SDavid du Colombier enum
167*5c47fe09SDavid du Colombier {					/* command register */
168*5c47fe09SDavid du Colombier 	IOen		= (1<<0),
169*5c47fe09SDavid du Colombier 	MEMen		= (1<<1),
170*5c47fe09SDavid du Colombier 	MASen		= (1<<2),
171*5c47fe09SDavid du Colombier 	MemWrInv	= (1<<4),
172*5c47fe09SDavid du Colombier 	PErrEn		= (1<<6),
173*5c47fe09SDavid du Colombier 	SErrEn		= (1<<8),
174*5c47fe09SDavid du Colombier };
175*5c47fe09SDavid du Colombier 
176*5c47fe09SDavid du Colombier /* capabilities */
177*5c47fe09SDavid du Colombier enum {
178*5c47fe09SDavid du Colombier 	PciCapPMG       = 0x01,         /* power management */
179*5c47fe09SDavid du Colombier 	PciCapAGP       = 0x02,
180*5c47fe09SDavid du Colombier 	PciCapVPD       = 0x03,         /* vital product data */
181*5c47fe09SDavid du Colombier 	PciCapSID       = 0x04,         /* slot id */
182*5c47fe09SDavid du Colombier 	PciCapMSI       = 0x05,
183*5c47fe09SDavid du Colombier 	PciCapCHS       = 0x06,         /* compact pci hot swap */
184*5c47fe09SDavid du Colombier 	PciCapPCIX      = 0x07,
185*5c47fe09SDavid du Colombier 	PciCapHTC       = 0x08,         /* hypertransport irq conf */
186*5c47fe09SDavid du Colombier 	PciCapVND       = 0x09,         /* vendor specific information */
187*5c47fe09SDavid du Colombier 	PciCapPCIe      = 0x10,
188*5c47fe09SDavid du Colombier 	PciCapMSIX      = 0x11,
189*5c47fe09SDavid du Colombier 	PciCapSATA      = 0x12,
190*5c47fe09SDavid du Colombier 	PciCapHSW       = 0x0c,         /* hot swap */
191*5c47fe09SDavid du Colombier };
192*5c47fe09SDavid du Colombier 
193*5c47fe09SDavid du Colombier typedef struct Pcidev Pcidev;
194*5c47fe09SDavid du Colombier struct Pcidev
195*5c47fe09SDavid du Colombier {
196*5c47fe09SDavid du Colombier 	int	tbdf;			/* type+bus+device+function */
197*5c47fe09SDavid du Colombier 	ushort	vid;			/* vendor ID */
198*5c47fe09SDavid du Colombier 	ushort	did;			/* device ID */
199*5c47fe09SDavid du Colombier 
200*5c47fe09SDavid du Colombier 	ushort	pcr;
201*5c47fe09SDavid du Colombier 
202*5c47fe09SDavid du Colombier 	uchar	rid;
203*5c47fe09SDavid du Colombier 	uchar	ccrp;
204*5c47fe09SDavid du Colombier 	uchar	ccru;
205*5c47fe09SDavid du Colombier 	uchar	ccrb;
206*5c47fe09SDavid du Colombier 	uchar	cls;
207*5c47fe09SDavid du Colombier 	uchar	ltr;
208*5c47fe09SDavid du Colombier 
209*5c47fe09SDavid du Colombier 	struct {
210*5c47fe09SDavid du Colombier 		uintpci	bar;		/* base address */
211*5c47fe09SDavid du Colombier 		int	size;
212*5c47fe09SDavid du Colombier 	} mem[6];
213*5c47fe09SDavid du Colombier 
214*5c47fe09SDavid du Colombier 	uchar	intl;			/* interrupt line */
215*5c47fe09SDavid du Colombier 
216*5c47fe09SDavid du Colombier 	Pcidev*	list;
217*5c47fe09SDavid du Colombier 	Pcidev*	link;			/* next device on this bno */
218*5c47fe09SDavid du Colombier 
219*5c47fe09SDavid du Colombier 	Pcidev*	parent;			/* up a bus */
220*5c47fe09SDavid du Colombier 	Pcidev*	bridge;			/* down a bus */
221*5c47fe09SDavid du Colombier 
222*5c47fe09SDavid du Colombier 	int	pmrb;			/* power management register block */
223*5c47fe09SDavid du Colombier 
224*5c47fe09SDavid du Colombier 	struct {
225*5c47fe09SDavid du Colombier 		uintpci	bar;
226*5c47fe09SDavid du Colombier 		int	size;
227*5c47fe09SDavid du Colombier 	} ioa, mema;
228*5c47fe09SDavid du Colombier };
229*5c47fe09SDavid du Colombier 
230*5c47fe09SDavid du Colombier #define PCIWINDOW	0
231*5c47fe09SDavid du Colombier #define PCIWADDR(va)	(PADDR(va)+PCIWINDOW)
232*5c47fe09SDavid du Colombier 
233*5c47fe09SDavid du Colombier #pragma varargck	type	"T"	int
234*5c47fe09SDavid du Colombier #pragma varargck	type	"T"	uint
235*5c47fe09SDavid du Colombier 
236*5c47fe09SDavid du Colombier void pcienable(Pcidev *);
237*5c47fe09SDavid du Colombier void pcidisable(Pcidev *);
238*5c47fe09SDavid du Colombier void pcisetbme(Pcidev* );
239*5c47fe09SDavid du Colombier Pcidev* pcimatch(Pcidev* prev, int vid, int did);
240*5c47fe09SDavid du Colombier void pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a);
241*5c47fe09SDavid du Colombier void pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a);
242