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