MSI cleanup and IRQ routing
[akaros.git] / kern / arch / x86 / pci.c
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * See LICENSE for details.
3  *
4  * Barret Rhoden <brho@cs.berkeley.edu>
5  * Original by Paul Pearce <pearce@eecs.berkeley.edu> */
6
7 #include <arch/x86.h>
8 #include <arch/pci.h>
9 #include <trap.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <kmalloc.h>
14 #include <arch/pci_defs.h>
15
16 /* List of all discovered devices */
17 struct pcidev_stailq pci_devices = STAILQ_HEAD_INITIALIZER(pci_devices);
18
19 /* PCI accesses are two-stage PIO, which need to complete atomically */
20 spinlock_t pci_lock = SPINLOCK_INITIALIZER_IRQSAVE;
21
22 static char STD_PCI_DEV[] = "Standard PCI Device";
23 static char PCI2PCI[] = "PCI-to-PCI Bridge";
24 static char PCI2CARDBUS[] = "PCI-Cardbus Bridge";
25
26 /* memory bars have a little dance you go through to detect what the size of the
27  * memory region is.  for 64 bit bars, i'm assuming you only need to do this to
28  * the lower part (no device will need > 4GB, right?). */
29 uint32_t pci_membar_get_sz(struct pci_device *pcidev, int bar)
30 {
31         /* save the old value, write all 1s, invert, add 1, restore.
32          * http://wiki.osdev.org/PCI for details. */
33         uint32_t bar_off = PCI_BAR0_STD + bar * PCI_BAR_OFF;
34         uint32_t old_val = pcidev_read32(pcidev, bar_off);
35         uint32_t retval;
36         pcidev_write32(pcidev, bar_off, 0xffffffff);
37         /* Don't forget to mask the lower 3 bits! */
38         retval = pcidev_read32(pcidev, bar_off) & PCI_BAR_MEM_MASK;
39         retval = ~retval + 1;
40         pcidev_write32(pcidev, bar_off, old_val);
41         return retval;
42 }
43
44 /* process the bars.  these will tell us what address space (PIO or memory) and
45  * where the base is.  fills results into pcidev.  i don't know if you can have
46  * multiple bars with conflicting/different regions (like two separate PIO
47  * ranges).  I'm assuming you don't, and will warn if we see one. */
48 static void pci_handle_bars(struct pci_device *pcidev)
49 {
50         /* only handling standards for now */
51         uint32_t bar_val;
52         int max_bars = pcidev->header_type == STD_PCI_DEV ? MAX_PCI_BAR : 0;
53         /* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge) */
54         for (int i = 0; i < max_bars; i++) {
55                 bar_val = pci_getbar(pcidev, i);
56                 pcidev->bar[i].raw_bar = bar_val;
57                 if (!bar_val)   /* (0 denotes no valid data) */
58                         continue;
59                 if (pci_is_iobar(bar_val)) {
60                         pcidev->bar[i].pio_base = pci_getiobar32(bar_val);
61                 } else {
62                         if (pci_is_membar32(bar_val)) {
63                                 pcidev->bar[i].mmio_base32 = bar_val & PCI_BAR_MEM_MASK;
64                                 pcidev->bar[i].mmio_sz = pci_membar_get_sz(pcidev, i);
65                         } else if (pci_is_membar64(bar_val)) {
66                                 /* 64 bit, the lower 32 are in this bar, the upper
67                                  * are in the next bar */
68                                 pcidev->bar[i].mmio_base64 = bar_val & PCI_BAR_MEM_MASK;
69                                 assert(i < max_bars - 1);
70                                 bar_val = pci_getbar(pcidev, i + 1);    /* read next bar */
71                                 /* note we don't check for IO or memsize.  the entire next bar
72                                  * is supposed to be for the upper 32 bits. */
73                                 pcidev->bar[i].mmio_base64 |= (uint64_t)bar_val << 32;
74                                 pcidev->bar[i].mmio_sz = pci_membar_get_sz(pcidev, i);
75                                 i++;
76                         }
77                 }
78                 /* this will track the maximum bar we've had.  it'll include the 64 bit
79                  * uppers, as well as devices that have only higher numbered bars. */
80                 pcidev->nr_bars = i + 1;
81         }
82 }
83
84 static void pci_parse_caps(struct pci_device *pcidev)
85 {
86         uint32_t cap_off;       /* not sure if this can be extended from u8 */
87         uint8_t cap_id;
88         if (!(pcidev_read16(pcidev, PCI_STATUS_REG) & (1 << 4)))
89                 return;
90         switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7f) {
91                 case 0:                         /* etc */
92                 case 1:                         /* pci to pci bridge */
93                         cap_off = 0x34;
94                         break;
95                 case 2:                         /* cardbus bridge */
96                         cap_off = 0x14;
97                         break;
98                 default:
99                         return;
100         }
101         /* initial offset points to the addr of the first cap */
102         cap_off = pcidev_read8(pcidev, cap_off);
103         cap_off &= ~0x3;        /* osdev says the lower 2 bits are reserved */
104         while (cap_off) {
105                 cap_id = pcidev_read8(pcidev, cap_off);
106                 if (cap_id > PCI_CAP_ID_MAX) {
107                         printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus, pcidev->dev,
108                                pcidev->func, cap_id);
109                         return;
110                 }
111                 pcidev->caps[cap_id] = cap_off;
112                 cap_off = pcidev_read8(pcidev, cap_off + 1);
113                 /* not sure if subsequent caps must be aligned or not */
114                 if (cap_off & 0x3)
115                         printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n", pcidev->bus,
116                                pcidev->dev, pcidev->func, cap_off);
117         }
118 }
119
120 /* Scans the PCI bus.  Won't actually work for anything other than bus 0, til we
121  * sort out how to handle bridge devices. */
122 void pci_init(void) {
123         uint32_t result = 0;
124         uint16_t dev_id, ven_id;
125         struct pci_device *pcidev;
126         int max_nr_func;
127         for (int i = 0; i < PCI_MAX_BUS - 1; i++) {     /* phantoms at 0xff */
128                 for (int j = 0; j < PCI_MAX_DEV; j++) {
129                         max_nr_func = 1;
130                         for (int k = 0; k < max_nr_func; k++) {
131                                 result = pci_read32(i, j, k, PCI_DEV_VEND_REG);
132                                 dev_id = result >> 16;
133                                 ven_id = result & 0xffff;
134                                 /* Skip invalid IDs (not a device) */
135                                 if (ven_id == INVALID_VENDOR_ID) 
136                                         break;  /* skip functions too, they won't exist */
137                                 pcidev = kzmalloc(sizeof(struct pci_device), 0);
138                                 pcidev->bus = i;
139                                 pcidev->dev = j;
140                                 pcidev->func = k;
141                                 pcidev->dev_id = dev_id;
142                                 pcidev->ven_id = ven_id;
143                                 /* Get the Class/subclass */
144                                 pcidev->class = pcidev_read8(pcidev, PCI_CLASS_REG);
145                                 pcidev->subclass = pcidev_read8(pcidev, PCI_SUBCLASS_REG);
146                                 pcidev->progif = pcidev_read8(pcidev, PCI_PROGIF_REG);
147                                 /* All device types (0, 1, 2) have the IRQ in the same place */
148                                 /* This is the PIC IRQ the device is wired to */
149                                 pcidev->irqline = pcidev_read8(pcidev, PCI_IRQLINE_STD);
150                                 /* This is the interrupt pin the device uses (INTA# - INTD#) */
151                                 pcidev->irqpin = pcidev_read8(pcidev, PCI_IRQPIN_STD);
152                                 /* bottom 7 bits are header type */
153                                 switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c) {
154                                         case 0x00:
155                                                 pcidev->header_type = STD_PCI_DEV;
156                                                 break;
157                                         case 0x01:
158                                                 pcidev->header_type = PCI2PCI;
159                                                 break;
160                                         case 0x02:
161                                                 pcidev->header_type = PCI2CARDBUS;
162                                                 break;
163                                         default:
164                                                 pcidev->header_type = "Unknown Header Type";
165                                 }
166                                 pci_handle_bars(pcidev);
167                                 pci_parse_caps(pcidev);
168                                 STAILQ_INSERT_TAIL(&pci_devices, pcidev, all_dev);
169                                 #ifdef CONFIG_PCI_VERBOSE
170                                 pcidev_print_info(pcidev, 4);
171                                 #else
172                                 pcidev_print_info(pcidev, 0);
173                                 #endif /* CONFIG_PCI_VERBOSE */
174                                 /* Top bit determines if we have multiple functions on this
175                                  * device.  We can't just check for more functions, since
176                                  * non-multifunction devices exist that respond to different
177                                  * functions with the same underlying device (same bars etc).
178                                  * Note that this style allows for devices that only report
179                                  * multifunction in the first function's header. */
180                                 if (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x80)
181                                         max_nr_func = PCI_MAX_FUNC;
182                         }
183                 }
184         }
185 }
186
187 uint32_t pci_config_addr(uint8_t bus, uint8_t dev, uint8_t func, uint32_t reg)
188 {
189         return (uint32_t)(((uint32_t)bus << 16) |
190                           ((uint32_t)dev << 11) |
191                           ((uint32_t)func << 8) |
192                           (reg & 0xfc) |
193                           ((reg & 0xf00) << 16) |       /* extended PCI CFG space... */
194                                           0x80000000);
195 }
196
197 /* Helper to read 32 bits from the config space of B:D:F.  'Offset' is how far
198  * into the config space we offset before reading, aka: where we are reading. */
199 uint32_t pci_read32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
200 {
201         uint32_t ret;
202         spin_lock_irqsave(&pci_lock);
203         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
204         ret = inl(PCI_CONFIG_DATA);
205         spin_unlock_irqsave(&pci_lock);
206         return ret;
207 }
208
209 /* Same, but writes (doing 32bit at a time).  Never actually tested (not sure if
210  * PCI lets you write back). */
211 void pci_write32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
212                  uint32_t value)
213 {
214         spin_lock_irqsave(&pci_lock);
215         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
216         outl(PCI_CONFIG_DATA, value);
217         spin_unlock_irqsave(&pci_lock);
218 }
219
220 uint16_t pci_read16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
221 {
222         uint16_t ret;
223         spin_lock_irqsave(&pci_lock);
224         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
225         ret = inw(PCI_CONFIG_DATA + (offset & 2));
226         spin_unlock_irqsave(&pci_lock);
227         return ret;
228 }
229
230 void pci_write16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
231                  uint16_t value)
232 {
233         spin_lock_irqsave(&pci_lock);
234         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
235         outw(PCI_CONFIG_DATA + (offset & 2), value);
236         spin_unlock_irqsave(&pci_lock);
237 }
238
239 uint8_t pci_read8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
240 {
241         uint8_t ret;
242         spin_lock_irqsave(&pci_lock);
243         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
244         ret = inb(PCI_CONFIG_DATA + (offset & 3));
245         spin_unlock_irqsave(&pci_lock);
246         return ret;
247 }
248
249 void pci_write8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
250                 uint8_t value)
251 {
252         spin_lock_irqsave(&pci_lock);
253         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
254         outb(PCI_CONFIG_DATA + (offset & 3), value);
255         spin_unlock_irqsave(&pci_lock);
256 }
257
258 uint32_t pcidev_read32(struct pci_device *pcidev, uint32_t offset)
259 {
260         return pci_read32(pcidev->bus, pcidev->dev, pcidev->func, offset);
261 }
262
263 void pcidev_write32(struct pci_device *pcidev, uint32_t offset, uint32_t value)
264 {
265         pci_write32(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
266 }
267
268 uint16_t pcidev_read16(struct pci_device *pcidev, uint32_t offset)
269 {
270         return pci_read16(pcidev->bus, pcidev->dev, pcidev->func, offset);
271 }
272
273 void pcidev_write16(struct pci_device *pcidev, uint32_t offset, uint16_t value)
274 {
275         pci_write16(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
276 }
277
278 uint8_t pcidev_read8(struct pci_device *pcidev, uint32_t offset)
279 {
280         return pci_read8(pcidev->bus, pcidev->dev, pcidev->func, offset);
281 }
282
283 void pcidev_write8(struct pci_device *pcidev, uint32_t offset, uint8_t value)
284 {
285         pci_write8(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
286 }
287
288 /* Gets any old raw bar, with some catches based on type. */
289 uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar)
290 {
291         uint8_t type;
292         if (bar >= MAX_PCI_BAR)
293                 panic("Nonexistant bar requested!");
294         type = pcidev_read8(pcidev, PCI_HEADER_REG);
295         type &= ~0x80;  /* drop the MF bit */
296         /* Only types 0 and 1 have BARS */
297         if ((type != 0x00) && (type != 0x01))
298                 return 0;
299         /* Only type 0 has BAR2 - BAR5 */
300         if ((bar > 1) && (type != 0x00))
301                 return 0;
302         return pcidev_read32(pcidev, PCI_BAR0_STD + bar * PCI_BAR_OFF);
303 }
304
305 /* Determines if a given bar is IO (o/w, it's mem) */
306 bool pci_is_iobar(uint32_t bar)
307 {
308         return bar & PCI_BAR_IO;
309 }
310
311 bool pci_is_membar32(uint32_t bar)
312 {
313         if (pci_is_iobar(bar))
314                 return FALSE;
315         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_32BIT;
316 }
317
318 bool pci_is_membar64(uint32_t bar)
319 {
320         if (pci_is_iobar(bar))
321                 return FALSE;
322         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_64BIT;
323 }
324
325 /* Helper to get the address from a membar.  Check the type beforehand */
326 uint32_t pci_getmembar32(uint32_t bar)
327 {
328         uint8_t type = bar & PCI_MEMBAR_TYPE;
329         if (type != PCI_MEMBAR_32BIT) {
330                 warn("Unhandled PCI membar type: %02p\n", type >> 1);
331                 return 0;
332         }
333         return bar & 0xfffffff0;
334 }
335
336 /* Helper to get the address from an IObar.  Check the type beforehand */
337 uint32_t pci_getiobar32(uint32_t bar)
338 {
339         return bar & 0xfffffffc;
340 }
341
342 /* Helper to get the class description strings.  Adapted from
343  * http://www.pcidatabase.com/reports.php?type=c-header */
344 static void pcidev_get_cldesc(struct pci_device *pcidev, char **class,
345                               char **subclass, char **progif)
346 {
347         int     i ;
348         *class = *subclass = *progif = "";
349
350         for (i = 0; i < PCI_CLASSCODETABLE_LEN; i++) {
351                 if (PciClassCodeTable[i].BaseClass == pcidev->class) {
352                         if (!(**class))
353                                 *class = PciClassCodeTable[i].BaseDesc;
354                         if (PciClassCodeTable[i].SubClass == pcidev->subclass) {
355                                 if (!(**subclass))
356                                         *subclass = PciClassCodeTable[i].SubDesc;
357                                 if (PciClassCodeTable[i].ProgIf == pcidev->progif) {
358                                         *progif = PciClassCodeTable[i].ProgDesc;
359                                         break ;
360                                 }
361                         }
362                 }
363         }
364 }
365
366 /* Helper to get the vendor and device description strings */
367 static void pcidev_get_devdesc(struct pci_device *pcidev, char **vend_short,
368                                char **vend_full, char **chip, char **chip_desc)
369 {
370         int     i ;
371         *vend_short = *vend_full = *chip = *chip_desc = "";
372
373         for (i = 0; i < PCI_VENTABLE_LEN; i++) {
374                 if (PciVenTable[i].VenId == pcidev->ven_id) {
375                         *vend_short = PciVenTable[i].VenShort;
376                         *vend_full = PciVenTable[i].VenFull;
377                         break ;
378                 }
379         }
380         for (i = 0; i < PCI_DEVTABLE_LEN; i++) {
381                 if ((PciDevTable[i].VenId == pcidev->ven_id) &&
382                    (PciDevTable[i].DevId == pcidev->dev_id)) {
383                         *chip = PciDevTable[i].Chip;
384                         *chip_desc = PciDevTable[i].ChipDesc;
385                         break ;
386                 }
387         }
388 }
389
390 /* Prints info (like lspci) for a device */
391 void pcidev_print_info(struct pci_device *pcidev, int verbosity)
392 {
393         char *ven_sht, *ven_fl, *chip, *chip_txt, *class, *subcl, *progif;
394         pcidev_get_cldesc(pcidev, &class, &subcl, &progif);
395         pcidev_get_devdesc(pcidev, &ven_sht, &ven_fl, &chip, &chip_txt);
396
397         printk("%02x:%02x.%x %s: %s %s %s: %s\n",
398                pcidev->bus,
399                pcidev->dev,
400                pcidev->func,
401                subcl,
402                ven_sht,
403                chip,
404                chip_txt,
405                    pcidev->header_type);
406         if (verbosity < 1)      /* whatever */
407                 return;
408         printk("\tIRQ: %02d IRQ pin: 0x%02x\n",
409                pcidev->irqline,
410                pcidev->irqpin);
411         printk("\tVendor Id: 0x%04x Device Id: 0x%04x\n",
412                pcidev->ven_id,
413                pcidev->dev_id);
414         printk("\t%s %s %s\n",
415                class,
416                progif,
417                ven_fl);
418         for (int i = 0; i < pcidev->nr_bars; i++) {
419                 if (pcidev->bar[i].raw_bar == 0)
420                         continue;
421                 printk("\tBAR %d: ", i);
422                 if (pci_is_iobar(pcidev->bar[i].raw_bar)) {
423                         assert(pcidev->bar[i].pio_base);
424                         printk("IO port 0x%04x\n", pcidev->bar[i].pio_base);
425                 } else {
426                         bool bar_is_64 = pci_is_membar64(pcidev->bar[i].raw_bar);
427                         printk("MMIO Base %p, MMIO Size %p\n",
428                                bar_is_64 ? pcidev->bar[i].mmio_base64 :
429                                            pcidev->bar[i].mmio_base32,
430                                pcidev->bar[i].mmio_sz);
431                         /* Takes up two bars */
432                         if (bar_is_64) {
433                                 assert(!pcidev->bar[i].mmio_base32);    /* double-check */
434                                 i++;
435                         }
436                 }
437         }
438         printk("\tCapabilities:");
439         for (int i = 0; i < PCI_CAP_ID_MAX + 1; i++) {
440                 if (pcidev->caps[i])
441                         printk(" 0x%02x", i);
442         }
443         printk("\n");
444 }
445
446 void pci_set_bus_master(struct pci_device *pcidev)
447 {
448         pcidev_write16(pcidev, PCI_CMD_REG, pcidev_read16(pcidev, PCI_CMD_REG) |
449                                             PCI_CMD_BUS_MAS);
450 }
451
452 void pci_clr_bus_master(struct pci_device *pcidev)
453 {
454         uint16_t reg;
455         reg = pcidev_read16(pcidev, PCI_CMD_REG);
456         reg &= ~PCI_CMD_BUS_MAS;
457         pcidev_write16(pcidev, PCI_CMD_REG, reg);
458 }
459
460 /* Find up to 'need' unused bars. Needed for MSI-X */
461 int pci_find_unused_bars(struct pci_device *dev, int *bars, int need)
462 {
463         int i, found;
464         for(i = found = 0; found < need && i < ARRAY_SIZE(dev->bar); i++)
465                 if (!dev->bar[i].raw_bar)
466                         bars[found++] = i;
467         return found;
468
469 }
470
471 struct pci_device *pci_match_tbdf(int tbdf)
472 {
473         struct pci_device *search;
474         int bus, dev, func;
475         bus = BUSBNO(tbdf);
476         dev = BUSDNO(tbdf);
477         func = BUSFNO(tbdf);
478
479         STAILQ_FOREACH(search, &pci_devices, all_dev) {
480                 if ((search->bus == bus) &&
481                     (search->dev == dev) &&
482                     (search->func == func))
483                         return search;
484         }
485         return NULL;
486 }