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