iommu: add essential functionality
[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 <arch/intel-iommu.h>
10 #include <trap.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <kmalloc.h>
15 #include <mm.h>
16 #include <arch/pci_defs.h>
17 #include <ros/errno.h>
18 #include <acpi.h>
19
20 /* List of all discovered devices */
21 struct pcidev_stailq pci_devices = STAILQ_HEAD_INITIALIZER(pci_devices);
22
23 /* PCI accesses are two-stage PIO, which need to complete atomically */
24 spinlock_t pci_lock = SPINLOCK_INITIALIZER_IRQSAVE;
25
26 static char STD_PCI_DEV[] = "Standard PCI Device";
27 static char PCI2PCI[] = "PCI-to-PCI Bridge";
28 static char PCI2CARDBUS[] = "PCI-Cardbus Bridge";
29
30 static uint32_t pci_cfg_pio_read32(uint8_t bus, uint8_t dev, uint8_t func,
31                                    uint32_t offset);
32
33 /* Gets any old raw bar, with some catches based on type. */
34 static uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar)
35 {
36         uint8_t type;
37
38         if (bar >= MAX_PCI_BAR)
39                 panic("Nonexistant bar requested!");
40         type = pcidev_read8(pcidev, PCI_HEADER_REG);
41         type &= ~0x80;  /* drop the MF bit */
42         /* Only types 0 and 1 have BARS */
43         if ((type != 0x00) && (type != 0x01))
44                 return 0;
45         /* Only type 0 has BAR2 - BAR5 */
46         if ((bar > 1) && (type != 0x00))
47                 return 0;
48         return pcidev_read32(pcidev, PCI_BAR0_STD + bar * PCI_BAR_OFF);
49 }
50
51 /* Determines if a given bar is IO (o/w, it's mem) */
52 static bool pci_is_iobar(uint32_t bar)
53 {
54         return bar & PCI_BAR_IO;
55 }
56
57 static bool pci_is_membar32(uint32_t bar)
58 {
59         if (pci_is_iobar(bar))
60                 return FALSE;
61         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_32BIT;
62 }
63
64 static bool pci_is_membar64(uint32_t bar)
65 {
66         if (pci_is_iobar(bar))
67                 return FALSE;
68         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_64BIT;
69 }
70
71 /* Helper to get the address from a membar.  Check the type beforehand */
72 static uint32_t pci_getmembar32(uint32_t bar)
73 {
74         uint8_t type = bar & PCI_MEMBAR_TYPE;
75
76         if (type != PCI_MEMBAR_32BIT) {
77                 warn("Unhandled PCI membar type: %02p\n", type >> 1);
78                 return 0;
79         }
80         return bar & 0xfffffff0;
81 }
82
83 /* Helper to get the address from an IObar.  Check the type beforehand */
84 static uint32_t pci_getiobar32(uint32_t bar)
85 {
86         return bar & 0xfffffffc;
87 }
88
89 /* memory bars have a little dance you go through to detect what the size of the
90  * memory region is.  for 64 bit bars, i'm assuming you only need to do this to
91  * the lower part (no device will need > 4GB, right?).
92  *
93  * Hold the dev's lock, or o/w avoid sync issues. */
94 static uint32_t __pci_membar_get_sz(struct pci_device *pcidev, int bar)
95 {
96         /* save the old value, write all 1s, invert, add 1, restore.
97          * http://wiki.osdev.org/PCI for details. */
98         uint32_t bar_off = PCI_BAR0_STD + bar * PCI_BAR_OFF;
99         uint32_t old_val = pcidev_read32(pcidev, bar_off);
100         uint32_t retval;
101
102         pcidev_write32(pcidev, bar_off, 0xffffffff);
103         /* Don't forget to mask the lower 3 bits! */
104         retval = pcidev_read32(pcidev, bar_off) & PCI_BAR_MEM_MASK;
105         retval = ~retval + 1;
106         pcidev_write32(pcidev, bar_off, old_val);
107         return retval;
108 }
109
110 /* process the bars.  these will tell us what address space (PIO or memory) and
111  * where the base is.  fills results into pcidev.  i don't know if you can have
112  * multiple bars with conflicting/different regions (like two separate PIO
113  * ranges).  I'm assuming you don't, and will warn if we see one. */
114 static void __pci_handle_bars(struct pci_device *pcidev)
115 {
116         uint32_t bar_val;
117         int max_bars;
118
119         if (pcidev->header_type == STD_PCI_DEV)
120                 max_bars = MAX_PCI_BAR;
121         else if (pcidev->header_type == PCI2PCI)
122                 max_bars = 2;
123         else
124                 max_bars = 0;
125         /* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge)
126          */
127         for (int i = 0; i < max_bars; i++) {
128                 bar_val = pci_getbar(pcidev, i);
129                 pcidev->bar[i].raw_bar = bar_val;
130                 if (!bar_val)   /* (0 denotes no valid data) */
131                         continue;
132                 if (pci_is_iobar(bar_val)) {
133                         pcidev->bar[i].pio_base = pci_getiobar32(bar_val);
134                 } else {
135                         if (pci_is_membar32(bar_val)) {
136                                 pcidev->bar[i].mmio_base32 =
137                                         bar_val & PCI_BAR_MEM_MASK;
138                                 pcidev->bar[i].mmio_sz =
139                                         __pci_membar_get_sz(pcidev, i);
140                         } else if (pci_is_membar64(bar_val)) {
141                                 /* 64 bit, the lower 32 are in this bar, the
142                                  * upper are in the next bar */
143                                 pcidev->bar[i].mmio_base64 =
144                                         bar_val & PCI_BAR_MEM_MASK;
145                                 assert(i < max_bars - 1);
146                                 /* read next bar */
147                                 bar_val = pci_getbar(pcidev, i + 1);
148                                 /* note we don't check for IO or memsize.  the
149                                  * entire next bar is supposed to be for the
150                                  * upper 32 bits. */
151                                 pcidev->bar[i].mmio_base64 |=
152                                         (uint64_t)bar_val << 32;
153                                 pcidev->bar[i].mmio_sz =
154                                         __pci_membar_get_sz(pcidev, i);
155                                 i++;
156                         }
157                 }
158                 /* this will track the maximum bar we've had.  it'll include the
159                  * 64 bit uppers, as well as devices that have only higher
160                  * numbered bars. */
161                 pcidev->nr_bars = i + 1;
162         }
163 }
164
165 static void __pci_parse_caps(struct pci_device *pcidev)
166 {
167         uint32_t cap_off;       /* not sure if this can be extended from u8 */
168         uint8_t cap_id;
169
170         if (!(pcidev_read16(pcidev, PCI_STATUS_REG) & (1 << 4)))
171                 return;
172         switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7f) {
173         case 0:                         /* etc */
174         case 1:                         /* pci to pci bridge */
175                 cap_off = 0x34;
176                 break;
177         case 2:                         /* cardbus bridge */
178                 cap_off = 0x14;
179                 break;
180         default:
181                 return;
182         }
183         /* initial offset points to the addr of the first cap */
184         cap_off = pcidev_read8(pcidev, cap_off);
185         cap_off &= ~0x3;        /* osdev says the lower 2 bits are reserved */
186         while (cap_off) {
187                 cap_id = pcidev_read8(pcidev, cap_off);
188                 if (cap_id > PCI_CAP_ID_MAX) {
189                         printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus,
190                                pcidev->dev, pcidev->func, cap_id);
191                         return;
192                 }
193                 pcidev->caps[cap_id] = cap_off;
194                 cap_off = pcidev_read8(pcidev, cap_off + 1);
195                 /* not sure if subsequent caps must be aligned or not */
196                 if (cap_off & 0x3)
197                         printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n",
198                                pcidev->bus, pcidev->dev, pcidev->func, cap_off);
199         }
200 }
201
202 static uintptr_t pci_get_mmio_cfg(struct pci_device *pcidev)
203 {
204         physaddr_t paddr;
205
206         paddr = acpi_pci_get_mmio_cfg_addr(pcidev->domain,
207                                           pcidev->bus, pcidev->dev,
208                                           pcidev->func);
209         if (!paddr)
210                 return 0;
211         return vmap_pmem_nocache(paddr, 4096);
212 }
213
214 /* Scans the PCI bus.  Won't actually work for anything other than bus 0, til we
215  * sort out how to handle bridge devices. */
216 void pci_init(void)
217 {
218         uint32_t result = 0;
219         uint16_t dev_id, ven_id;
220         struct pci_device *pcidev;
221         int max_nr_func;
222         /* In earlier days bus address 0xff caused problems so we only iterated
223          * to PCI_MAX_BUS - 1, but this should no longer be an issue.  Old
224          * comment: phantoms at 0xff */
225         for (int i = 0; i < PCI_MAX_BUS; i++) {
226                 for (int j = 0; j < PCI_MAX_DEV; j++) {
227                         max_nr_func = 1;
228                         for (int k = 0; k < max_nr_func; k++) {
229                                 result = pci_cfg_pio_read32(i, j, k,
230                                                             PCI_DEV_VEND_REG);
231                                 dev_id = result >> 16;
232                                 ven_id = result & 0xffff;
233                                 /* Skip invalid IDs (not a device)
234                                  * If the first function doesn't exist then no
235                                  * device is connected, but there can be gaps in
236                                  * the other function numbers. Eg. 0,2,3 is ok.
237                                  * */
238                                 if (ven_id == INVALID_VENDOR_ID) {
239                                         if (k == 0)
240                                                 break;
241                                         continue;
242                                 }
243                                 pcidev = kzmalloc(sizeof(struct pci_device), 0);
244                                 /* we don't need to lock it til we post the
245                                  * pcidev to the list*/
246                                 spinlock_init_irqsave(&pcidev->lock);
247                                 /* we only discover domain 0 during legacy
248                                  * PCI enumeration */
249                                 pcidev->domain = 0;
250                                 pcidev->bus = i;
251                                 pcidev->dev = j;
252                                 pcidev->func = k;
253                                 snprintf(pcidev->name, sizeof(pcidev->name),
254                                          "%02x:%02x.%x", pcidev->bus,
255                                          pcidev->dev, pcidev->func);
256                                 pcidev->dev_id = dev_id;
257                                 pcidev->ven_id = ven_id;
258                                 /* Set up the MMIO CFG before using accessors */
259                                 pcidev->mmio_cfg = pci_get_mmio_cfg(pcidev);
260                                 /* Get the Class/subclass */
261                                 pcidev->class =
262                                         pcidev_read8(pcidev, PCI_CLASS_REG);
263                                 pcidev->subclass =
264                                         pcidev_read8(pcidev, PCI_SUBCLASS_REG);
265                                 pcidev->progif =
266                                         pcidev_read8(pcidev, PCI_PROGIF_REG);
267                                 /* All device types (0, 1, 2) have the IRQ in
268                                  * the same place */
269                                 /* This is the PIC IRQ the device is wired to */
270                                 pcidev->irqline =
271                                         pcidev_read8(pcidev, PCI_IRQLINE_STD);
272                                 /* This is the interrupt pin the device uses
273                                  * (INTA# - INTD#) */
274                                 pcidev->irqpin =
275                                         pcidev_read8(pcidev, PCI_IRQPIN_STD);
276                                 /* bottom 7 bits are header type */
277                                 switch (pcidev_read8(pcidev, PCI_HEADER_REG)
278                                         & 0x7c) {
279                                 case 0x00:
280                                         pcidev->header_type = STD_PCI_DEV;
281                                         break;
282                                 case 0x01:
283                                         pcidev->header_type = PCI2PCI;
284                                         break;
285                                 case 0x02:
286                                         pcidev->header_type = PCI2CARDBUS;
287                                         break;
288                                 default:
289                                         pcidev->header_type =
290                                                 "Unknown Header Type";
291                                 }
292                                 
293                                 __pci_handle_bars(pcidev);
294                                 __pci_parse_caps(pcidev);
295                                 /* we're the only writer at this point in the
296                                  * boot process */
297                                 STAILQ_INSERT_TAIL(&pci_devices, pcidev,
298                                                    all_dev);
299                                 #ifdef CONFIG_PCI_VERBOSE
300                                 pcidev_print_info(pcidev, 4);
301                                 #else
302                                 pcidev_print_info(pcidev, 0);
303                                 #endif /* CONFIG_PCI_VERBOSE */
304                                 /* Top bit determines if we have multiple
305                                  * functions on this device.  We can't just
306                                  * check for more functions, since
307                                  * non-multifunction devices exist that respond
308                                  * to different functions with the same
309                                  * underlying device (same bars etc).  Note that
310                                  * this style allows for devices that only
311                                  * report multifunction in the first function's
312                                  * header. */
313                                 if (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x80)
314                                         max_nr_func = PCI_MAX_FUNC;
315                                 pcidev->proc_owner = NULL;
316                         }
317                 }
318         }
319         iommu_map_pci_devices();
320 }
321
322 uint32_t pci_config_addr(uint8_t bus, uint8_t dev, uint8_t func, uint32_t reg)
323 {
324         return (uint32_t)(((uint32_t)bus << 16) |
325                           ((uint32_t)dev << 11) |
326                           ((uint32_t)func << 8) |
327                           (reg & 0xfc) |
328                           ((reg & 0xf00) << 16) |/* extended PCI CFG space... */
329                           0x80000000);
330 }
331
332 /* Helper to read 32 bits from the config space of B:D:F.  'Offset' is how far
333  * into the config space we offset before reading, aka: where we are reading. */
334 static uint32_t pci_cfg_pio_read32(uint8_t bus, uint8_t dev, uint8_t func,
335                                    uint32_t offset)
336 {
337         uint32_t ret;
338
339         spin_lock_irqsave(&pci_lock);
340         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
341         ret = inl(PCI_CONFIG_DATA);
342         spin_unlock_irqsave(&pci_lock);
343         return ret;
344 }
345
346 /* Same, but writes (doing 32bit at a time).  Never actually tested (not sure if
347  * PCI lets you write back). */
348 static void pci_cfg_pio_write32(uint8_t bus, uint8_t dev, uint8_t func,
349                                 uint32_t offset, uint32_t value)
350 {
351         spin_lock_irqsave(&pci_lock);
352         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
353         outl(PCI_CONFIG_DATA, value);
354         spin_unlock_irqsave(&pci_lock);
355 }
356
357 static uint16_t pci_cfg_pio_read16(uint8_t bus, uint8_t dev, uint8_t func,
358                                    uint32_t offset)
359 {
360         uint16_t ret;
361
362         spin_lock_irqsave(&pci_lock);
363         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
364         ret = inw(PCI_CONFIG_DATA + (offset & 2));
365         spin_unlock_irqsave(&pci_lock);
366         return ret;
367 }
368
369 static void pci_cfg_pio_write16(uint8_t bus, uint8_t dev, uint8_t func,
370                                 uint32_t offset, uint16_t value)
371 {
372         spin_lock_irqsave(&pci_lock);
373         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
374         outw(PCI_CONFIG_DATA + (offset & 2), value);
375         spin_unlock_irqsave(&pci_lock);
376 }
377
378 static uint8_t pci_cfg_pio_read8(uint8_t bus, uint8_t dev, uint8_t func,
379                                  uint32_t offset)
380 {
381         uint8_t ret;
382
383         spin_lock_irqsave(&pci_lock);
384         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
385         ret = inb(PCI_CONFIG_DATA + (offset & 3));
386         spin_unlock_irqsave(&pci_lock);
387         return ret;
388 }
389
390 static void pci_cfg_pio_write8(uint8_t bus, uint8_t dev, uint8_t func,
391                                uint32_t offset, uint8_t value)
392 {
393         spin_lock_irqsave(&pci_lock);
394         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
395         outb(PCI_CONFIG_DATA + (offset & 3), value);
396         spin_unlock_irqsave(&pci_lock);
397 }
398
399 /* Some AMD processors require using eax for MMIO config ops. */
400 static uint32_t pci_cfg_mmio_read32(uintptr_t mmio_cfg, uint32_t offset)
401 {
402         uint32_t val;
403
404         asm volatile("movl (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
405         return val;
406 }
407
408 static void pci_cfg_mmio_write32(uintptr_t mmio_cfg, uint32_t offset,
409                                  uint32_t val)
410 {
411         asm volatile("movl %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
412 }
413
414 static uint16_t pci_cfg_mmio_read16(uintptr_t mmio_cfg, uint32_t offset)
415 {
416         uint16_t val;
417
418         asm volatile("movw (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
419         return val;
420 }
421
422 static void pci_cfg_mmio_write16(uintptr_t mmio_cfg, uint32_t offset,
423                                  uint16_t val)
424 {
425         asm volatile("movw %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
426 }
427
428 static uint8_t pci_cfg_mmio_read8(uintptr_t mmio_cfg, uint32_t offset)
429 {
430         uint8_t val;
431
432         asm volatile("movb (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
433         return val;
434 }
435
436 static void pci_cfg_mmio_write8(uintptr_t mmio_cfg, uint32_t offset,
437                                 uint8_t val)
438 {
439         asm volatile("movb %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
440 }
441
442 uint32_t pcidev_read32(struct pci_device *pcidev, uint32_t offset)
443 {
444         if (pcidev->mmio_cfg)
445                 return pci_cfg_mmio_read32(pcidev->mmio_cfg, offset);
446         else
447                 return pci_cfg_pio_read32(pcidev->bus, pcidev->dev,
448                                           pcidev->func, offset);
449 }
450
451 void pcidev_write32(struct pci_device *pcidev, uint32_t offset, uint32_t value)
452 {
453         if (pcidev->mmio_cfg)
454                 pci_cfg_mmio_write32(pcidev->mmio_cfg, offset, value);
455         else
456                 pci_cfg_pio_write32(pcidev->bus, pcidev->dev, pcidev->func,
457                                     offset, value);
458 }
459
460 uint16_t pcidev_read16(struct pci_device *pcidev, uint32_t offset)
461 {
462         if (pcidev->mmio_cfg)
463                 return pci_cfg_mmio_read16(pcidev->mmio_cfg, offset);
464         else
465                 return pci_cfg_pio_read16(pcidev->bus, pcidev->dev,
466                                           pcidev->func, offset);
467 }
468
469 void pcidev_write16(struct pci_device *pcidev, uint32_t offset, uint16_t value)
470 {
471         if (pcidev->mmio_cfg)
472                 pci_cfg_mmio_write16(pcidev->mmio_cfg, offset, value);
473         else
474                 pci_cfg_pio_write16(pcidev->bus, pcidev->dev, pcidev->func,
475                                     offset, value);
476 }
477
478 uint8_t pcidev_read8(struct pci_device *pcidev, uint32_t offset)
479 {
480         if (pcidev->mmio_cfg)
481                 return pci_cfg_mmio_read8(pcidev->mmio_cfg, offset);
482         else
483                 return pci_cfg_pio_read8(pcidev->bus, pcidev->dev, pcidev->func,
484                                          offset);
485 }
486
487 void pcidev_write8(struct pci_device *pcidev, uint32_t offset, uint8_t value)
488 {
489         if (pcidev->mmio_cfg)
490                 pci_cfg_mmio_write8(pcidev->mmio_cfg, offset, value);
491         else
492                 pci_cfg_pio_write8(pcidev->bus, pcidev->dev, pcidev->func,
493                                    offset, value);
494 }
495
496 /* Helper to get the class description strings.  Adapted from
497  * http://www.pcidatabase.com/reports.php?type=c-header */
498 static void pcidev_get_cldesc(struct pci_device *pcidev, char **class,
499                               char **subclass, char **progif)
500 {
501         int i;
502         *class = *subclass = *progif = "";
503
504         for (i = 0; i < PCI_CLASSCODETABLE_LEN; i++) {
505                 if (PciClassCodeTable[i].BaseClass == pcidev->class) {
506                         if (!(**class))
507                                 *class = PciClassCodeTable[i].BaseDesc;
508                         if (PciClassCodeTable[i].SubClass == pcidev->subclass) {
509                                 if (!(**subclass))
510                                         *subclass =
511                                                 PciClassCodeTable[i].SubDesc;
512                                 if (PciClassCodeTable[i].ProgIf ==
513                                     pcidev->progif) {
514                                         *progif = PciClassCodeTable[i].ProgDesc;
515                                         break ;
516                                 }
517                         }
518                 }
519         }
520 }
521
522 /* Helper to get the vendor and device description strings */
523 static void pcidev_get_devdesc(struct pci_device *pcidev, char **vend_short,
524                                char **vend_full, char **chip, char **chip_desc)
525 {
526         int i;
527         *vend_short = *vend_full = *chip = *chip_desc = "";
528
529         for (i = 0; i < PCI_VENTABLE_LEN; i++) {
530                 if (PciVenTable[i].VenId == pcidev->ven_id) {
531                         *vend_short = PciVenTable[i].VenShort;
532                         *vend_full = PciVenTable[i].VenFull;
533                         break ;
534                 }
535         }
536         for (i = 0; i < PCI_DEVTABLE_LEN; i++) {
537                 if ((PciDevTable[i].VenId == pcidev->ven_id) &&
538                    (PciDevTable[i].DevId == pcidev->dev_id)) {
539                         *chip = PciDevTable[i].Chip;
540                         *chip_desc = PciDevTable[i].ChipDesc;
541                         break ;
542                 }
543         }
544 }
545
546 /* Prints info (like lspci) for a device */
547 void pcidev_print_info(struct pci_device *pcidev, int verbosity)
548 {
549         char *ven_sht, *ven_fl, *chip, *chip_txt, *class, *subcl, *progif;
550
551         pcidev_get_cldesc(pcidev, &class, &subcl, &progif);
552         pcidev_get_devdesc(pcidev, &ven_sht, &ven_fl, &chip, &chip_txt);
553
554         printk("%02x:%02x.%x %s: %s %s %s: %s\n",
555                pcidev->bus,
556                pcidev->dev,
557                pcidev->func,
558                subcl,
559                ven_sht,
560                chip,
561                chip_txt,
562                    pcidev->header_type);
563         if (verbosity < 1)      /* whatever */
564                 return;
565         printk("\tIRQ: %02d IRQ pin: 0x%02x\n",
566                pcidev->irqline,
567                pcidev->irqpin);
568         printk("\tVendor Id: 0x%04x Device Id: 0x%04x\n",
569                pcidev->ven_id,
570                pcidev->dev_id);
571         printk("\t%s %s %s\n",
572                class,
573                progif,
574                ven_fl);
575         for (int i = 0; i < pcidev->nr_bars; i++) {
576                 if (pcidev->bar[i].raw_bar == 0)
577                         continue;
578                 printk("\tBAR %d: ", i);
579                 if (pci_is_iobar(pcidev->bar[i].raw_bar)) {
580                         assert(pcidev->bar[i].pio_base);
581                         printk("IO port 0x%04x\n", pcidev->bar[i].pio_base);
582                 } else {
583                         bool bar_is_64 =
584                                 pci_is_membar64(pcidev->bar[i].raw_bar);
585                         printk("MMIO Base%s %p, MMIO Size %p\n",
586                                bar_is_64 ? "64" : "32",
587                                bar_is_64 ? pcidev->bar[i].mmio_base64 :
588                                            pcidev->bar[i].mmio_base32,
589                                pcidev->bar[i].mmio_sz);
590                         /* Takes up two bars */
591                         if (bar_is_64) {
592                                 assert(!pcidev->bar[i].mmio_base32);
593                                 i++;
594                         }
595                 }
596         }
597         printk("\tCapabilities:");
598         for (int i = 0; i < PCI_CAP_ID_MAX + 1; i++) {
599                 if (pcidev->caps[i])
600                         printk(" 0x%02x", i);
601         }
602         printk("\n");
603 }
604
605 void pci_set_bus_master(struct pci_device *pcidev)
606 {
607         spin_lock_irqsave(&pcidev->lock);
608         pcidev_write16(pcidev, PCI_CMD_REG, pcidev_read16(pcidev, PCI_CMD_REG) |
609                                             PCI_CMD_BUS_MAS);
610         spin_unlock_irqsave(&pcidev->lock);
611 }
612
613 void pci_clr_bus_master(struct pci_device *pcidev)
614 {
615         uint16_t reg;
616
617         spin_lock_irqsave(&pcidev->lock);
618         reg = pcidev_read16(pcidev, PCI_CMD_REG);
619         reg &= ~PCI_CMD_BUS_MAS;
620         pcidev_write16(pcidev, PCI_CMD_REG, reg);
621         spin_unlock_irqsave(&pcidev->lock);
622 }
623
624 struct pci_device *pci_match_tbdf(int tbdf)
625 {
626         struct pci_device *search;
627         int bus, dev, func;
628
629         bus = BUSBNO(tbdf);
630         dev = BUSDNO(tbdf);
631         func = BUSFNO(tbdf);
632
633         STAILQ_FOREACH(search, &pci_devices, all_dev) {
634                 if ((search->bus == bus) &&
635                     (search->dev == dev) &&
636                     (search->func == func))
637                         return search;
638         }
639         return NULL;
640 }
641
642 /* Helper to get the membar value for BAR index bir */
643 uintptr_t pci_get_membar(struct pci_device *pcidev, int bir)
644 {
645         if (bir >= pcidev->nr_bars)
646                 return 0;
647         if (pcidev->bar[bir].mmio_base64) {
648                 assert(pci_is_membar64(pcidev->bar[bir].raw_bar));
649                 return pcidev->bar[bir].mmio_base64;
650         }
651         /* we can just return mmio_base32, even if it's 0.  but i'd like to do
652          * the assert too. */
653         if (pcidev->bar[bir].mmio_base32) {
654                 assert(pci_is_membar32(pcidev->bar[bir].raw_bar));
655                 return pcidev->bar[bir].mmio_base32;
656         }
657         return 0;
658 }
659
660 uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir)
661 {
662         if (bir >= pcidev->nr_bars)
663                 return 0;
664         /* we can just return pio_base, even if it's 0.  but i'd like to do the
665          * assert too. */
666         if (pcidev->bar[bir].pio_base) {
667                 assert(pci_is_iobar(pcidev->bar[bir].raw_bar));
668                 return pcidev->bar[bir].pio_base;
669         }
670         return 0;
671 }
672
673 uint32_t pci_get_membar_sz(struct pci_device *pcidev, int bir)
674 {
675         if (bir >= pcidev->nr_bars)
676                 return 0;
677         return pcidev->bar[bir].mmio_sz;
678 }
679
680 uint16_t pci_get_vendor(struct pci_device *pcidev)
681 {
682         return pcidev->ven_id;
683 }
684
685 uint16_t pci_get_device(struct pci_device *pcidev)
686 {
687         return pcidev->dev_id;
688 }
689
690 uint16_t pci_get_subvendor(struct pci_device *pcidev)
691 {
692         uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
693
694         switch (header_type) {
695         case 0x00: /* STD_PCI_DEV */
696                 return pcidev_read16(pcidev, PCI_SUBSYSVEN_STD);
697         case 0x01: /* PCI2PCI */
698                 return -1;
699         case 0x02: /* PCI2CARDBUS */
700                 return pcidev_read16(pcidev, PCI_SUBVENID_CB);
701         default:
702                 warn("Unknown Header Type, %d", header_type);
703         }
704         return -1;
705 }
706
707 uint16_t pci_get_subdevice(struct pci_device *pcidev)
708 {
709         uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
710
711         switch (header_type) {
712         case 0x00: /* STD_PCI_DEV */
713                 return pcidev_read16(pcidev, PCI_SUBSYSID_STD);
714         case 0x01: /* PCI2PCI */
715                 return -1;
716         case 0x02: /* PCI2CARDBUS */
717                 return pcidev_read16(pcidev, PCI_SUBDEVID_CB);
718         default:
719                 warn("Unknown Header Type, %d", header_type);
720         }
721         return -1;
722 }
723
724 void pci_dump_config(struct pci_device *pcidev, size_t len)
725 {
726         if (len > 256)
727                 printk("FYI, printing more than 256 bytes of PCI space\n");
728         printk("PCI Config space for %02x:%02x:%02x\n---------------------\n",
729                pcidev->bus, pcidev->dev, pcidev->func);
730         for (int i = 0; i < len; i += 4)
731                 printk("0x%03x | %08x\n", i, pcidev_read32(pcidev, i));
732 }
733
734 int pci_find_cap(struct pci_device *pcidev, uint8_t cap_id, uint32_t *cap_reg)
735 {
736         if (cap_id > PCI_CAP_ID_MAX)
737                 return -EINVAL;
738         if (!pcidev->caps[cap_id])
739                 return -ENOENT;
740         /* The actual value at caps[id] is the offset in the PCI config space
741          * where that ID was stored.  That's needed for accessing the
742          * capability. */
743         if (cap_reg)
744                 *cap_reg = pcidev->caps[cap_id];
745         return 0;
746 }
747
748 unsigned int pci_to_tbdf(struct pci_device *pcidev)
749 {
750         return MKBUS(BusPCI, pcidev->bus, pcidev->dev, pcidev->func);
751 }
752
753 uintptr_t pci_map_membar(struct pci_device *dev, int bir)
754 {
755         uintptr_t paddr = pci_get_membar(dev, bir);
756         size_t sz = pci_get_membar_sz(dev, bir);
757         
758         if (!paddr || !sz)
759                 return 0;
760         return vmap_pmem_nocache(paddr, sz);
761 }
762
763 /* The following were ported from Linux:
764  *
765  * pci_set_cacheline_size
766  * pci_set_mwi
767  * pci_clear_mwi
768  */
769 int pci_set_cacheline_size(struct pci_device *dev)
770 {
771         uint8_t cl_sz;
772         uint8_t pci_cache_line_size = ARCH_CL_SIZE >> 2;
773
774         cl_sz = pcidev_read8(dev, PCI_CACHE_LINE_SIZE);
775         /* Validate current setting: the PCI_CACHE_LINE_SIZE must be equal to or
776          * multiple of the right value. */
777         if (cl_sz >= pci_cache_line_size && (cl_sz % pci_cache_line_size) == 0)
778                 return 0;
779         pcidev_write8(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
780         cl_sz = pcidev_read8(dev, PCI_CACHE_LINE_SIZE);
781         if (cl_sz == pci_cache_line_size)
782                 return 0;
783         printk("PCI device %s does not support cache line size of %d\n",
784                dev->name, pci_cache_line_size << 2);
785         return -EINVAL;
786 }
787
788 int pci_set_mwi(struct pci_device *dev)
789 {
790         int rc;
791         uint16_t cmd;
792
793         rc = pci_set_cacheline_size(dev);
794         if (rc)
795                 return rc;
796         cmd = pcidev_read16(dev, PCI_COMMAND);
797         if (!(cmd & PCI_COMMAND_INVALIDATE)) {
798                 cmd |= PCI_COMMAND_INVALIDATE;
799                 pcidev_write16(dev, PCI_COMMAND, cmd);
800         }
801         return 0;
802 }
803
804 void pci_clear_mwi(struct pci_device *dev)
805 {
806         uint16_t cmd;
807
808         cmd = pcidev_read16(dev, PCI_COMMAND);
809         if (cmd & PCI_COMMAND_INVALIDATE) {
810                 cmd &= ~PCI_COMMAND_INVALIDATE;
811                 pcidev_write16(dev, PCI_COMMAND, cmd);
812         }
813 }