akaros/kern/arch/x86/pci.c
<<
>>
Prefs
   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 */
  21struct pcidev_stailq pci_devices = STAILQ_HEAD_INITIALIZER(pci_devices);
  22
  23/* PCI accesses are two-stage PIO, which need to complete atomically */
  24spinlock_t pci_lock = SPINLOCK_INITIALIZER_IRQSAVE;
  25
  26static char STD_PCI_DEV[] = "Standard PCI Device";
  27static char PCI2PCI[] = "PCI-to-PCI Bridge";
  28static char PCI2CARDBUS[] = "PCI-Cardbus Bridge";
  29
  30static 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. */
  34static 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) */
  52static bool pci_is_iobar(uint32_t bar)
  53{
  54        return bar & PCI_BAR_IO;
  55}
  56
  57static 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
  64static 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 */
  72static 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 */
  84static 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. */
  94static 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. */
 114static 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
 165static 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
 202static 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. */
 216void 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
 322uint32_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. */
 334static 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). */
 348static 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
 357static 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
 369static 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
 378static 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
 390static 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. */
 400static 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
 408static 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
 414static 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
 422static 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
 428static 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
 436static 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
 442uint32_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
 451void 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
 460uint16_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
 469void 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
 478uint8_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
 487void 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 */
 498static 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 */
 523static 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 */
 547void 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
 605void 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
 613void 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
 624struct 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 */
 643uintptr_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
 660uintptr_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
 673uint32_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
 680uint16_t pci_get_vendor(struct pci_device *pcidev)
 681{
 682        return pcidev->ven_id;
 683}
 684
 685uint16_t pci_get_device(struct pci_device *pcidev)
 686{
 687        return pcidev->dev_id;
 688}
 689
 690uint16_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
 707uint16_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
 724void 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
 734int 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
 748unsigned int pci_to_tbdf(struct pci_device *pcidev)
 749{
 750        return MKBUS(BusPCI, pcidev->bus, pcidev->dev, pcidev->func);
 751}
 752
 753uintptr_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 */
 769int 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
 788int 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
 804void 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}
 814