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