xref: /plan9-contrib/sys/src/9/pc/io.h (revision ee52d9b2f0fe10bb66599f9f2443840e1d58c7f0)
1 #define X86STEPPING(x)	((x) & 0x0F)
2 /* incorporates extended-model and -family bits */
3 #define X86MODEL(x)	((((x)>>4) & 0x0F) | (((x)>>16) & 0x0F)<<4)
4 #define X86FAMILY(x)	((((x)>>8) & 0x0F) | (((x)>>20) & 0xFF)<<4)
5 
6 enum {
7 	VectorNMI	= 2,		/* non-maskable interrupt */
8 	VectorBPT	= 3,		/* breakpoint */
9 	VectorUD	= 6,		/* invalid opcode exception */
10 	VectorCNA	= 7,		/* coprocessor not available */
11 	Vector2F	= 8,		/* double fault */
12 	VectorCSO	= 9,		/* coprocessor segment overrun */
13 	VectorPF	= 14,		/* page fault */
14 	Vector15	= 15,		/* reserved */
15 	VectorCERR	= 16,		/* coprocessor error */
16 
17 	VectorPIC	= 32,		/* external i8259 interrupts */
18 	IrqCLOCK	= 0,
19 	IrqKBD		= 1,
20 	IrqUART1	= 3,
21 	IrqUART0	= 4,
22 	IrqPCMCIA	= 5,
23 	IrqFLOPPY	= 6,
24 	IrqLPT		= 7,
25 	IrqIRQ7		= 7,
26 	IrqAUX		= 12,		/* PS/2 port */
27 	IrqIRQ13	= 13,		/* coprocessor on 386 */
28 	IrqATA0		= 14,
29 	IrqATA1		= 15,
30 	MaxIrqPIC	= 15,
31 
32 	VectorLAPIC	= VectorPIC+16,	/* local APIC interrupts */
33 	IrqLINT0	= 16,		/* LINT[01] must be offsets 0 and 1 */
34 	IrqLINT1	= 17,
35 	IrqTIMER	= 18,
36 	IrqERROR	= 19,
37 	IrqPCINT	= 20,
38 	IrqSPURIOUS	= 31,		/* must have bits [3-0] == 0x0F */
39 	MaxIrqLAPIC	= 31,
40 
41 	VectorSYSCALL	= 64,
42 
43 	VectorAPIC	= 65,		/* external APIC interrupts */
44 	MaxVectorAPIC	= 255,
45 };
46 
47 typedef struct Vctl {
48 	Vctl*	next;			/* handlers on this vector */
49 
50 	char	name[KNAMELEN];		/* of driver */
51 	int	isintr;			/* interrupt or fault/trap */
52 	int	irq;
53 	int	tbdf;
54 	int	(*isr)(int);		/* get isr bit for this irq */
55 	int	(*eoi)(int);		/* eoi */
56 
57 	void	(*f)(Ureg*, void*);	/* handler to call */
58 	void*	a;			/* argument to call it with */
59 } Vctl;
60 
61 enum {
62 	BusCBUS		= 0,		/* Corollary CBUS */
63 	BusCBUSII,			/* Corollary CBUS II */
64 	BusEISA,			/* Extended ISA */
65 	BusFUTURE,			/* IEEE Futurebus */
66 	BusINTERN,			/* Internal bus */
67 	BusISA,				/* Industry Standard Architecture */
68 	BusMBI,				/* Multibus I */
69 	BusMBII,			/* Multibus II */
70 	BusMCA,				/* Micro Channel Architecture */
71 	BusMPI,				/* MPI */
72 	BusMPSA,			/* MPSA */
73 	BusNUBUS,			/* Apple Macintosh NuBus */
74 	BusPCI,				/* Peripheral Component Interconnect */
75 	BusPCMCIA,			/* PC Memory Card International Association */
76 	BusTC,				/* DEC TurboChannel */
77 	BusVL,				/* VESA Local bus */
78 	BusVME,				/* VMEbus */
79 	BusXPRESS,			/* Express System Bus */
80 };
81 
82 #define MKBUS(t,b,d,f)	(((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
83 #define BUSFNO(tbdf)	(((tbdf)>>8)&0x07)
84 #define BUSDNO(tbdf)	(((tbdf)>>11)&0x1F)
85 #define BUSBNO(tbdf)	(((tbdf)>>16)&0xFF)
86 #define BUSTYPE(tbdf)	((tbdf)>>24)
87 #define BUSBDF(tbdf)	((tbdf)&0x00FFFF00)
88 #define BUSUNKNOWN	(-1)
89 
90 enum {
91 	MaxEISA		= 16,
92 	CfgEISA		= 0xC80,
93 };
94 
95 /*
96  * PCI support code.
97  */
98 enum {					/* type 0 & type 1 pre-defined header */
99 	PciVID		= 0x00,		/* vendor ID */
100 	PciDID		= 0x02,		/* device ID */
101 	PciPCR		= 0x04,		/* command */
102 	PciPSR		= 0x06,		/* status */
103 	PciRID		= 0x08,		/* revision ID */
104 	PciCCRp		= 0x09,		/* programming interface class code */
105 	PciCCRu		= 0x0A,		/* sub-class code */
106 	PciCCRb		= 0x0B,		/* base class code */
107 	PciCLS		= 0x0C,		/* cache line size */
108 	PciLTR		= 0x0D,		/* latency timer */
109 	PciHDT		= 0x0E,		/* header type */
110 	PciBST		= 0x0F,		/* BIST */
111 
112 	PciBAR0		= 0x10,		/* base address */
113 	PciBAR1		= 0x14,
114 
115 	PciINTL		= 0x3C,		/* interrupt line */
116 	PciINTP		= 0x3D,		/* interrupt pin */
117 };
118 
119 /* ccrb (base class code) values; controller types */
120 enum {
121 	Pcibcpci1	= 0,		/* pci 1.0; no class codes defined */
122 	Pcibcstore	= 1,		/* mass storage */
123 	Pcibcnet	= 2,		/* network */
124 	Pcibcdisp	= 3,		/* display */
125 	Pcibcmmedia	= 4,		/* multimedia */
126 	Pcibcmem	= 5,		/* memory */
127 	Pcibcbridge	= 6,		/* bridge */
128 	Pcibccomm	= 7,		/* simple comms (e.g., serial) */
129 	Pcibcbasesys	= 8,		/* base system */
130 	Pcibcinput	= 9,		/* input */
131 	Pcibcdock	= 0xa,		/* docking stations */
132 	Pcibcproc	= 0xb,		/* processors */
133 	Pcibcserial	= 0xc,		/* serial bus (e.g., USB) */
134 	Pcibcwireless	= 0xd,		/* wireless */
135 	Pcibcintell	= 0xe,		/* intelligent i/o */
136 	Pcibcsatcom	= 0xf,		/* satellite comms */
137 	Pcibccrypto	= 0x10,		/* encryption/decryption */
138 	Pcibcdacq	= 0x11,		/* data acquisition & signal proc. */
139 };
140 
141 /* ccru (sub-class code) values; common cases only */
142 enum {
143 	/* mass storage */
144 	Pciscscsi	= 0,		/* SCSI */
145 	Pciscide	= 1,		/* IDE (ATA) */
146 	Pciscsata	= 6,		/* SATA */
147 
148 	/* network */
149 	Pciscether	= 0,		/* Ethernet */
150 
151 	/* display */
152 	Pciscvga	= 0,		/* VGA */
153 	Pciscxga	= 1,		/* XGA */
154 	Pcisc3d		= 2,		/* 3D */
155 
156 	/* bridges */
157 	Pcischostpci	= 0,		/* host/pci */
158 	Pciscpcicpci	= 1,		/* pci/pci */
159 
160 	/* simple comms */
161 	Pciscserial	= 0,		/* 16450, etc. */
162 	Pciscmultiser	= 1,		/* multiport serial */
163 
164 	/* serial bus */
165 	Pciscusb	= 3,		/* USB */
166 };
167 
168 enum {					/* type 0 pre-defined header */
169 	PciCIS		= 0x28,		/* cardbus CIS pointer */
170 	PciSVID		= 0x2C,		/* subsystem vendor ID */
171 	PciSID		= 0x2E,		/* cardbus CIS pointer */
172 	PciEBAR0	= 0x30,		/* expansion ROM base address */
173 	PciMGNT		= 0x3E,		/* burst period length */
174 	PciMLT		= 0x3F,		/* maximum latency between bursts */
175 };
176 
177 enum {					/* type 1 pre-defined header */
178 	PciPBN		= 0x18,		/* primary bus number */
179 	PciSBN		= 0x19,		/* secondary bus number */
180 	PciUBN		= 0x1A,		/* subordinate bus number */
181 	PciSLTR		= 0x1B,		/* secondary latency timer */
182 	PciIBR		= 0x1C,		/* I/O base */
183 	PciILR		= 0x1D,		/* I/O limit */
184 	PciSPSR		= 0x1E,		/* secondary status */
185 	PciMBR		= 0x20,		/* memory base */
186 	PciMLR		= 0x22,		/* memory limit */
187 	PciPMBR		= 0x24,		/* prefetchable memory base */
188 	PciPMLR		= 0x26,		/* prefetchable memory limit */
189 	PciPUBR		= 0x28,		/* prefetchable base upper 32 bits */
190 	PciPULR		= 0x2C,		/* prefetchable limit upper 32 bits */
191 	PciIUBR		= 0x30,		/* I/O base upper 16 bits */
192 	PciIULR		= 0x32,		/* I/O limit upper 16 bits */
193 	PciEBAR1	= 0x28,		/* expansion ROM base address */
194 	PciBCR		= 0x3E,		/* bridge control register */
195 };
196 
197 enum {					/* type 2 pre-defined header */
198 	PciCBExCA	= 0x10,
199 	PciCBSPSR	= 0x16,
200 	PciCBPBN	= 0x18,		/* primary bus number */
201 	PciCBSBN	= 0x19,		/* secondary bus number */
202 	PciCBUBN	= 0x1A,		/* subordinate bus number */
203 	PciCBSLTR	= 0x1B,		/* secondary latency timer */
204 	PciCBMBR0	= 0x1C,
205 	PciCBMLR0	= 0x20,
206 	PciCBMBR1	= 0x24,
207 	PciCBMLR1	= 0x28,
208 	PciCBIBR0	= 0x2C,		/* I/O base */
209 	PciCBILR0	= 0x30,		/* I/O limit */
210 	PciCBIBR1	= 0x34,		/* I/O base */
211 	PciCBILR1	= 0x38,		/* I/O limit */
212 	PciCBSVID	= 0x40,		/* subsystem vendor ID */
213 	PciCBSID	= 0x42,		/* subsystem ID */
214 	PciCBLMBAR	= 0x44,		/* legacy mode base address */
215 };
216 
217 /* capabilities */
218 enum {
219 	PciCapPMG	= 0x01,		/* power management */
220 	PciCapAGP	= 0x02,
221 	PciCapVPD	= 0x03,		/* vital product data */
222 	PciCapSID	= 0x04,		/* slot id */
223 	PciCapMSI	= 0x05,
224 	PciCapCHS	= 0x06,		/* compact pci hot swap */
225 	PciCapPCIX	= 0x07,
226 	PciCapHTC	= 0x08,		/* hypertransport irq conf */
227 	PciCapVND	= 0x09,		/* vendor specific information */
228 	PciCapPCIe	= 0x10,
229 	PciCapMSIX	= 0x11,
230 	PciCapSATA	= 0x12,
231 	PciCapHSW	= 0x0c,		/* hot swap */
232 };
233 
234 typedef struct Pcisiz Pcisiz;
235 struct Pcisiz
236 {
237 	Pcidev*	dev;
238 	int	siz;
239 	int	bar;
240 };
241 
242 typedef struct Pcidev Pcidev;
243 struct Pcidev
244 {
245 	int	tbdf;			/* type+bus+device+function */
246 	ushort	vid;			/* vendor ID */
247 	ushort	did;			/* device ID */
248 
249 	ushort	pcr;
250 
251 	uchar	rid;
252 	uchar	ccrp;
253 	uchar	ccru;
254 	uchar	ccrb;
255 	uchar	cls;
256 	uchar	ltr;
257 
258 	struct {
259 		ulong	bar;		/* base address */
260 		int	size;
261 	} mem[6];
262 
263 	struct {
264 		ulong	bar;
265 		int	size;
266 	} rom;
267 	uchar	intl;			/* interrupt line */
268 
269 	Pcidev*	list;
270 	Pcidev*	link;			/* next device on this bno */
271 
272 	Pcidev*	bridge;			/* down a bus */
273 	struct {
274 		ulong	bar;
275 		int	size;
276 	} ioa, mema;
277 
278 	int	pmrb;			/* power management register block */
279 };
280 
281 enum {
282 	/* vendor ids */
283 	Vatiamd	= 0x1002,
284 	Vintel	= 0x8086,
285 	Vjmicron= 0x197b,
286 	Vmarvell= 0x1b4b,
287 	Vmyricom= 0x14c1,
288 };
289 
290 #define PCIWINDOW	0
291 #define PCIWADDR(va)	(PADDR(va)+PCIWINDOW)
292 #define ISAWINDOW	0
293 #define ISAWADDR(va)	(PADDR(va)+ISAWINDOW)
294 
295 /* SMBus transactions */
296 enum
297 {
298 	SMBquick,		/* sends address only */
299 
300 	/* write */
301 	SMBsend,		/* sends address and cmd */
302 	SMBbytewrite,		/* sends address and cmd and 1 byte */
303 	SMBwordwrite,		/* sends address and cmd and 2 bytes */
304 
305 	/* read */
306 	SMBrecv,		/* sends address, recvs 1 byte */
307 	SMBbyteread,		/* sends address and cmd, recv's byte */
308 	SMBwordread,		/* sends address and cmd, recv's 2 bytes */
309 };
310 
311 typedef struct SMBus SMBus;
312 struct SMBus {
313 	QLock;		/* mutex */
314 	Rendez	r;	/* rendezvous point for completion interrupts */
315 	void	*arg;	/* implementation dependent */
316 	ulong	base;	/* port or memory base of smbus */
317 	int	busy;
318 	void	(*transact)(SMBus*, int, int, int, uchar*);
319 };
320 
321 /*
322  * PCMCIA support code.
323  */
324 
325 typedef struct PCMslot		PCMslot;
326 typedef struct PCMconftab	PCMconftab;
327 
328 /*
329  * Map between ISA memory space and PCMCIA card memory space.
330  */
331 struct PCMmap {
332 	ulong	ca;			/* card address */
333 	ulong	cea;			/* card end address */
334 	ulong	isa;			/* ISA address */
335 	int	len;			/* length of the ISA area */
336 	int	attr;			/* attribute memory */
337 	int	ref;
338 };
339 
340 /* configuration table entry */
341 struct PCMconftab
342 {
343 	int	index;
344 	ushort	irqs;		/* legal irqs */
345 	uchar	irqtype;
346 	uchar	bit16;		/* true for 16 bit access */
347 	struct {
348 		ulong	start;
349 		ulong	len;
350 	} io[16];
351 	int	nio;
352 	uchar	vpp1;
353 	uchar	vpp2;
354 	uchar	memwait;
355 	ulong	maxwait;
356 	ulong	readywait;
357 	ulong	otherwait;
358 };
359 
360 /* a card slot */
361 struct PCMslot
362 {
363 	Lock;
364 	int	ref;
365 
366 	void	*cp;		/* controller for this slot */
367 	long	memlen;		/* memory length */
368 	uchar	base;		/* index register base */
369 	uchar	slotno;		/* slot number */
370 
371 	/* status */
372 	uchar	special;	/* in use for a special device */
373 	uchar	already;	/* already inited */
374 	uchar	occupied;
375 	uchar	battery;
376 	uchar	wrprot;
377 	uchar	powered;
378 	uchar	configed;
379 	uchar	enabled;
380 	uchar	busy;
381 
382 	/* cis info */
383 	ulong	msec;		/* time of last slotinfo call */
384 	char	verstr[512];	/* version string */
385 	int	ncfg;		/* number of configurations */
386 	struct {
387 		ushort	cpresent;	/* config registers present */
388 		ulong	caddr;		/* relative address of config registers */
389 	} cfg[8];
390 	int	nctab;		/* number of config table entries */
391 	PCMconftab	ctab[8];
392 	PCMconftab	*def;	/* default conftab */
393 
394 	/* memory maps */
395 	Lock	mlock;		/* lock down the maps */
396 	int	time;
397 	PCMmap	mmap[4];	/* maps, last is always for the kernel */
398 };
399 
400 #pragma varargck	type	"T"	int
401 #pragma varargck	type	"T"	uint
402