/** * Read a VGA ROM * */ static int pci_device_openbsd_read_rom(struct pci_device *device, void *buffer) { struct pci_device_private *priv = (struct pci_device_private *)device; unsigned char *bios; pciaddr_t rom_base; pciaddr_t rom_size; u_int32_t csr, rom; int pci_rom, domain, bus, dev, func; domain = device->domain; if (domain < 0 || domain >= ndomains) return ENXIO; bus = device->bus; dev = device->dev; func = device->func; if (aperturefd == -1) return ENOSYS; if (priv->base.rom_size == 0) { #if defined(__alpha__) || defined(__amd64__) || defined(__i386__) if ((device->device_class & 0x00ffff00) == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8))) { rom_base = 0xc0000; rom_size = 0x10000; pci_rom = 0; } else #endif return ENOSYS; } else { rom_base = priv->rom_base; rom_size = priv->base.rom_size; pci_rom = 1; pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, &csr); pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MEM_ENABLE); pci_read(domain, bus, dev, func, PCI_ROM_REG, &rom); pci_write(domain, bus, dev, func, PCI_ROM_REG, rom | PCI_ROM_ENABLE); } bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED, aperturefd, (off_t)rom_base); if (bios == MAP_FAILED) return errno; memcpy(buffer, bios, rom_size); munmap(bios, rom_size); if (pci_rom) { /* Restore PCI config space */ pci_write(domain, bus, dev, func, PCI_ROM_REG, rom); pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, csr); } return 0; }
int pci_probe(int bus, int dev, int func, pci_cfg *cfg) { uint32 *word = (uint32 *) cfg; uint32 v; int i; for(i=0;i<4;i++){ word[i] = pci_read(bus,dev,func,4*i,4); } if(cfg->vendor_id == 0xffff) return 1; cfg->bus = bus; cfg->dev = dev; cfg->func = func; #if 0 printf("Device Info: /bus/pci/%d/%d/%d\n",bus,dev,func); printf(" * Vendor: %S Device: %S Class/SubClass/Interface %X/%X/%X\n", cfg->vendor_id,cfg->device_id,cfg->base_class,cfg->sub_class,cfg->interface); printf(" * Status: %S Command: %S BIST/Type/Lat/CLS: %X/%X/%X/%X\n", cfg->status, cfg->command, cfg->bist, cfg->header_type, cfg->latency_timer, cfg->cache_line_size); #endif switch(cfg->header_type & 0x7F){ case 0: /* normal device */ for(i=0;i<6;i++){ v = pci_read(bus,dev,func,i*4 + 0x10, 4); if(v) { int v2; pci_write(bus,dev,func,i*4 + 0x10, 0xffffffff, 4); v2 = pci_read(bus,dev,func,i*4+0x10, 4) & 0xfffffff0; pci_write(bus,dev,func,i*4 + 0x10, v, 4); v2 = 1 + ~v2; if(v & 1) { // printf(" * Base Register %d IO: %x (%x)\n",i,v&0xfff0,v2&0xffff); cfg->base[i] = v & 0xffff; cfg->size[i] = v2 & 0xffff; } else { // printf(" * Base Register %d MM: %x (%x)\n",i,v&0xfffffff0,v2); cfg->base[i] = v; cfg->size[i] = v2; } } else { cfg->base[i] = 0; cfg->size[i] = 0; } } v = pci_read(bus,dev,func,0x3c,1); cfg->irq = (v == 0xff ? 0 : v); // printf(" * Interrupt Line: %X\n",cfg->irq); break; case 1: // printf(" * PCI <-> PCI Bridge\n"); break; default: // printf(" * Unknown Header Type\n"); } return 0; }
int pci_read_msi(pci_addr_t *addr, pci_dev_header_t *pci_hdr,pci_bar_t *bars, uint32_t bars_total, struct pcicfg_msix *msix) { uint32_t ret; uint16_t buf; uint32_t val; uint32_t bar_offset; uint8_t pos=pci_hdr->capabilities_pointer; ret = pci_read(addr, pos, 2, &buf); ret = pci_read(addr, pos + PCIR_MSIX_CTRL, 2, &msix->msix_ctrl); msix->msix_msgnum = (msix->msix_ctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1; if (msix->msix_msgnum > 0) { msix->isr_vector = msi_start_vector; msi_start_vector = msi_start_vector + msix->msix_msgnum; ut_log(" msi vector start :%d num:%d \n",msix->isr_vector,msix->msix_msgnum); } else { msix->isr_vector = 0; } ret = pci_read(addr, pos + PCIR_MSIX_TABLE, 4, &bar_offset); msix->msix_table_bar = PCIR_BAR(bar_offset & PCIM_MSIX_BIR_MASK); if (bar_offset >= bars_total) return 0; msix->msix_table_res = bars[bar_offset].addr; msix->msix_table = vm_create_kmap("msix",0x1000,PROT_WRITE,MAP_FIXED,msix->msix_table_res); ut_log(" msix table :%x bar addr:%x baroffset:%d msix tableres:%x\n",msix->msix_table,bars[bar_offset].addr,bar_offset,msix->msix_table_res); ret = pci_read(addr, pos + PCIR_MSIX_PBA, 4, &val); msix->msix_pba_bar = PCIR_BAR(val & PCIM_MSIX_BIR_MASK); return msix->isr_vector; }
/* **************************************************************** * Inicialização * **************************************************************** */ int ata_sis_chipinit (PCIDATA *pci) { ATA_PCI_CTLR *ctlrp = pci->pci_dev_info_ptr; const ATA_CHIP_ID *idp = ctlrp->ac_idp; switch (idp->ch_cfg1) { case SIS33: break; case SIS66: case SIS100OLD: pci_write (pci, 0x52, pci_read (pci, 0x52, 1) & ~0x04, 1); break; case SIS100NEW: case SIS133OLD: pci_write (pci, 0x49, pci_read (pci, 0x49, 1) & ~0x01, 1); break; case SIS133NEW: pci_write (pci, 0x50, pci_read (pci, 0x50, 2) | 0x0008, 2); pci_write (pci, 0x52, pci_read (pci, 0x52, 2) | 0x0008, 2); break; case SISSATA: #if (0) /*******************************************************/ ctlr->r_type2 = SYS_RES_IOPORT; ctlr->r_rid2 = PCIR_BAR(5); if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))) { ctlrp->ac_allocate = ata_sis_allocate; ctlrp->ac_reset = ata_sis_reset; /* enable PCI interrupt */ pci_write (pci, PCIR_COMMAND, pci_read (pci, PCIR_COMMAND, 2) & ~0x0400,2); } ctlrp->ac_setmode = ata_sata_setmode; return (0); #endif /*******************************************************/ default: return (-1); } #ifndef BOOT ctlrp->ac_setmode = ata_sis_pata_setmode; #endif return (0); } /* end ata_sis_chipinit */
int pci_generic_read(pci_addr_t *d, uint16_t pos, uint16_t len, void *buf) { int c; int step; while(len > 0) { if((pos & 1) && len >= 1) { step = 1; } else if((pos & 3) && len >= 2) { step = 2; } else if(len < 2) { step = 1; } else if(len < 4) { step = 2; } else { step = 4; } c = pci_read(d, pos, step, buf); if( c != 0) { return c; } buf += step; pos += step; len -= step; } return 0; }
static PCI_Device_t* pci_readdevice(int bus, int dev, int func) { int place, total = sizeof(PCI_Device_t) / sizeof(unsigned long); for (place = 0; place < total; place++) ((u32int*)ret)[place] = pci_read(bus, dev, func, (place * sizeof (unsigned long))); return ret; }
static int pci_nfuncs(int domain, int bus, int dev) { uint32_t hdr; if (domain < 0 || domain >= ndomains) return ENXIO; if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0) return -1; return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1); }
static int pci_rcba_mask_get(union pci_addr_reg pci_ctrl_addr, u32_t *mask) { u32_t old_value; /* save the current setting */ pci_read(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(old_value), &old_value); /* write to the RCBA to see how large it is */ pci_write(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(u32_t), 0xffffffff); pci_read(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(*mask), mask); /* put back the old configuration */ pci_write(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(old_value), old_value); /* check if this RCBA is implemented */ if (*mask != 0xffffffff && *mask != 0) { /* clear the least address unrelated bit */ *mask &= ~0x01; return 0; } /* RCBA not supported */ return -1; }
static int get_bar(pci_addr_t *addr, int barno, uint32_t *start, uint32_t *len) { int res; uint16_t offset; uint32_t mask = ~0U; // We write all ones to the register and read it. offset = PCI_BAR_0 + 4 * barno; res = pci_read(addr, offset, 4, start); if(res != 0) { return -1; } res = pci_write(addr, offset, 4, &mask); if(res != 0) { return -1; } res = pci_read(addr, offset, 4, len); if(res != 0) { return -1; } res = pci_write(addr, offset, 4, start); if(res != 0) { return -1; } if (*start == 0 ) return 0; DEBUG(" barno:%d start :%i len:%i \n",barno,*start,*len); return 0; }
struct PCI_DEVICEINFO * pci_probeDevice( int bus, int dev, int func ) { struct PCI_DEVICEINFO * info; DWORD data; int index; // read in the vendor id data = pci_read( bus, dev, func, PCI_VENDORID, SIZE_WORD ); // if we dont have one we return fail if( data == 0xFFFF || data == VENDOR_UNKNOWN ) return NULL; // if we have a vendor then we have a device. create a device info structure and fill it in info = (struct PCI_DEVICEINFO *)mm_kmalloc( sizeof(struct PCI_DEVICEINFO) ); // fill in the vendor id info->vendor_id = data; // fill in the device id info->device_id = pci_read( bus, dev, func, PCI_DEVICEID, SIZE_WORD ); // linear search for the vendor and device name based on the id's we just read in for( index=0 ; pci_devices[index].vendor_id != VENDOR_UNKNOWN ; index++ ) { // if we have a match we break out of the loop if( pci_devices[index].vendor_id == info->vendor_id && pci_devices[index].device_id == info->device_id ) break; } // fill in the vendor/device name into our device info structure info->vendor_name = pci_devices[index].vendor_name; info->device_name = pci_devices[index].device_name; // fill in the header type info->header_type = pci_read( bus, dev, func, PCI_HEADERTYPE, SIZE_BYTE ); // fill in the sub sys info info->subsys_vendor = pci_read( bus, dev, func, PCI_SUBSYSVENDOR, SIZE_WORD ); info->subsys = pci_read( bus, dev, func, PCI_SUBSYS, SIZE_WORD ); // fill in the device class info->sub_class = pci_read( bus, dev, func, PCI_SUBCLASS, SIZE_BYTE ); info->base_class = pci_read( bus, dev, func, PCI_BASECLASS, SIZE_BYTE ); // linear search for the base class name for( index=0 ; pci_baseclassnames[index].base_class != 0xFF ; index++ ) { if( pci_baseclassnames[index].base_class == info->base_class ) break; } info->class_name = pci_baseclassnames[index].name; // fill in an irq value if their is one data = pci_read( bus, dev, func, PCI_IRQ, SIZE_BYTE ); info->irq = ( data == 0xFF ? 0 : data ); // return our new info structure return info; }
uint8_t pci_read_byte(struct pci_address* addr, uint8_t reg_offset) { return (uint8_t)pci_read(addr->bus, addr->device, addr->func, reg_offset, sizeof(uint8_t)); }
/* **************************************************************** * Reconhecimento * **************************************************************** */ const ATA_CHIP_ID * ata_sis_ident (PCIDATA *pci, ulong chipset_id) { ATA_CHIP_ID *idp; int found = 0; uchar rev = pci->pci_revid; ATA_PCI_CTLR *ctlrp = pci->pci_dev_info_ptr; ctlrp->ac_chip_nm = "SiS"; ctlrp->ac_chipinit = ata_sis_chipinit; #if (0) /*******************************************************/ PCIDATA *parent = pci->pci_parent; chipset_id = (parent->pci_device << 16) | parent->pci_vendor; #endif /*******************************************************/ for (idp = sis_ids; /* abaixo */; idp++) { if (idp->ch_id == 0) return (ctlrp->ac_idp = NULL); if (chipset_id == idp->ch_id && rev >= idp->ch_rev) break; } if (idp->ch_cfg2 /*** && !found ***/) { uchar reg57 = pci_read (pci, 0x57, 1); pci_write (pci, 0x57, (reg57 & 0x7F), 1); if (pci_read (pci, PCIR_DEVVENDOR, 4) == ATA_SIS5518) { found = 1; idp = &sis_quirk1; } pci_write (pci, 0x57, reg57, 1); } if (idp->ch_cfg2 && !found) { uchar reg4a = pci_read (pci, 0x4A, 1); pci_write (pci, 0x4A, (reg4a | 0x10), 1); if (pci_read (pci, PCIR_DEVVENDOR, 4) == ATA_SIS5517) { memmove (&sis_quirk2, idp, sizeof (ATA_CHIP_ID)); found = 1; idp = &sis_quirk2; idp->ch_nm = "961"; if (chipset_id == ATA_SISSOUTH) { idp->ch_cfg1 = SIS133OLD; idp->ch_max_dma = ATA_UDMA6; } else { idp->ch_cfg1 = SIS100NEW; idp->ch_max_dma = ATA_UDMA5; } } pci_write (pci, 0x4A, reg4a, 1); } return (ctlrp->ac_idp = idp); } /* end ata_sis_ident */
/* **************************************************************** * Inicializa o DMA para os Controladores PATA * **************************************************************** */ void ata_sis_pata_setmode (PCIDATA *pci, ATA_DEVICE *adp, int mode) { ATA_PCI_CTLR *ctlrp = pci->pci_dev_info_ptr; const ATA_CHIP_ID *idp = ctlrp->ac_idp; int devno; devno = (adp->ad_channel->ch_unit << 1) + adp->ad_devno; mode = ata_limit_mode (adp, mode, idp->ch_max_dma); if (idp->ch_cfg1 == SIS133NEW) { if (mode > ATA_UDMA2 && pci_read (pci, adp->ad_channel->ch_unit ? 0x52 : 0x50, 2) & 0x8000) { mode = ATA_UDMA2; printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode)); } } else { if (mode > ATA_UDMA2 && pci_read (pci, 0x48, 1) & (adp->ad_channel->ch_unit ? 0x20 : 0x10)) { mode = ATA_UDMA2; printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode)); } } if (ata_command (adp, ATA_C_SETFEATURES, 0, mode, ATA_C_F_SETXFER, 0)) return; switch (idp->ch_cfg1) { case SIS133NEW: { ulong timings[] = { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008, 0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac, 0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c }; ulong reg; reg = (pci_read (pci, 0x57, 1) & 0x40?0x70 : 0x40) + (devno << 2); pci_write (pci, reg, timings[ata_mode2idx (mode)], 4); break; } case SIS133OLD: { ushort timings[] = { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131 }; ushort reg = 0x40 + (devno << 1); pci_write (pci, reg, timings[ata_mode2idx (mode)], 2); break; } case SIS100NEW: { ushort timings[] = { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 }; ushort reg = 0x40 + (devno << 1); pci_write (pci, reg, timings[ata_mode2idx (mode)], 2); break; } case SIS100OLD: case SIS66: case SIS33: { ushort timings[] = { 0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303, 0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 }; ushort reg = 0x40 + (devno << 1); pci_write (pci, reg, timings[ata_mode2idx (mode)], 2); break; } } adp->ad_transfer_mode = mode; } /* end ata_sis_pata_setmode */
int pci_legacy_bridge_detect(struct pci_dev_info *dev_info) { union pci_addr_reg pci_ctrl_addr; static union pci_dev pci_dev_header; u32_t pci_data; /* temporary data to read */ u32_t rcba; /* root complex base address */ u32_t rcba_mask; /* bits set for RCBA */ /* initialise the PCI controller address register value */ pci_ctrl_addr.value = 0; pci_ctrl_addr.field.bus = CONFIG_PCI_LEGACY_BRIDGE_BUS; pci_ctrl_addr.field.device = CONFIG_PCI_LEGACY_BRIDGE_DEV; /* verify first if there is a valid device at this point */ pci_ctrl_addr.field.func = 0; pci_read(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(pci_data), &pci_data); if (pci_data == 0xffffffff) { return -1; } /* get the PCI header from the device */ pci_header_get(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, &pci_dev_header); if (pci_dev_header.field.vendor_id != CONFIG_PCI_LEGACY_BRIDGE_VENDOR_ID || pci_dev_header.field.device_id != CONFIG_PCI_LEGACY_BRIDGE_DEVICE_ID) { return -1; } pci_ctrl_addr.field.reg = PCI_LEGACY_BRIDGE_REG; /* read RCBA PCI register */ pci_read(DEFAULT_PCI_CONTROLLER, pci_ctrl_addr, sizeof(rcba), &rcba); if (pci_rcba_mask_get(pci_ctrl_addr, &rcba_mask) != 0) { return -1; } dev_info->addr = rcba & rcba_mask; if (dev_info->addr != 0) { /* calculate the size of the root complex memory required */ dev_info->size = 1 << (find_lsb_set(rcba_mask) - 1); } dev_info->irq = -1; dev_info->bus = CONFIG_PCI_LEGACY_BRIDGE_BUS; dev_info->dev = CONFIG_PCI_LEGACY_BRIDGE_DEV; dev_info->function = 0; dev_info->mem_type = BAR_SPACE_MEM; dev_info->class_type = pci_dev_header.field.class; dev_info->bar = 0; dev_info->vendor_id = pci_dev_header.field.vendor_id; dev_info->device_id = pci_dev_header.field.device_id; return 0; }
static int pci_device_openbsd_probe(struct pci_device *device) { struct pci_device_private *priv = (struct pci_device_private *)device; struct pci_mem_region *region; uint64_t reg64, size64; uint32_t bar, reg, size; int domain, bus, dev, func, err; domain = device->domain; bus = device->bus; dev = device->dev; func = device->func; err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, ®); if (err) return err; priv->header_type = PCI_HDRTYPE_TYPE(reg); if (priv->header_type != 0) return 0; region = device->regions; for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; bar += sizeof(uint32_t), region++) { err = pci_read(domain, bus, dev, func, bar, ®); if (err) return err; /* Probe the size of the region. */ err = pci_readmask(domain, bus, dev, func, bar, &size); if (err) return err; if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) { region->is_IO = 1; region->base_addr = PCI_MAPREG_IO_ADDR(reg); region->size = PCI_MAPREG_IO_SIZE(size); } else { if (PCI_MAPREG_MEM_PREFETCHABLE(reg)) region->is_prefetchable = 1; switch(PCI_MAPREG_MEM_TYPE(reg)) { case PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_MEM_TYPE_32BIT_1M: region->base_addr = PCI_MAPREG_MEM_ADDR(reg); region->size = PCI_MAPREG_MEM_SIZE(size); break; case PCI_MAPREG_MEM_TYPE_64BIT: region->is_64 = 1; reg64 = reg; size64 = size; bar += sizeof(uint32_t); err = pci_read(domain, bus, dev, func, bar, ®); if (err) return err; reg64 |= (uint64_t)reg << 32; err = pci_readmask(domain, bus, dev, func, bar, &size); if (err) return err; size64 |= (uint64_t)size << 32; region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64); region->size = PCI_MAPREG_MEM64_SIZE(size64); region++; break; } } } /* Probe expansion ROM if present */ err = pci_read(domain, bus, dev, func, PCI_ROM_REG, ®); if (err) return err; if (reg != 0) { err = pci_write(domain, bus, dev, func, PCI_ROM_REG, ~PCI_ROM_ENABLE); if (err) return err; pci_read(domain, bus, dev, func, PCI_ROM_REG, &size); pci_write(domain, bus, dev, func, PCI_ROM_REG, reg); if (PCI_ROM_ADDR(reg) != 0) { priv->rom_base = PCI_ROM_ADDR(reg); device->rom_size = PCI_ROM_SIZE(size); } } return 0; }
int pci_system_openbsd_create(void) { struct pci_device_private *device; int domain, bus, dev, func, ndevs, nfuncs; char path[MAXPATHLEN]; uint32_t reg; if (ndomains > 0) return 0; pci_sys = calloc(1, sizeof(struct pci_system)); if (pci_sys == NULL) return ENOMEM; pci_sys->methods = &openbsd_pci_methods; for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) { snprintf(path, sizeof(path), "/dev/pci%d", domain); pcifd[domain] = open(path, O_RDWR | O_CLOEXEC); if (pcifd[domain] == -1) { pcifd[domain] = open(path, O_RDONLY | O_CLOEXEC); if (pcifd[domain] == -1) break; } ndomains++; } if (ndomains == 0) return ENXIO; ndevs = 0; for (domain = 0; domain < ndomains; domain++) { for (bus = 0; bus < 256; bus++) { for (dev = 0; dev < 32; dev++) { nfuncs = pci_nfuncs(domain, bus, dev); for (func = 0; func < nfuncs; func++) { if (pci_read(domain, bus, dev, func, PCI_ID_REG, ®) != 0) continue; if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || PCI_VENDOR(reg) == 0) continue; ndevs++; } } } } pci_sys->num_devices = ndevs; pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private)); if (pci_sys->devices == NULL) { free(pci_sys); pci_sys = NULL; for (domain = 0; domain < ndomains; domain++) close(pcifd[domain]); ndomains = 0; return ENOMEM; } device = pci_sys->devices; for (domain = 0; domain < ndomains; domain++) { for (bus = 0; bus < 256; bus++) { for (dev = 0; dev < 32; dev++) { nfuncs = pci_nfuncs(domain, bus, dev); for (func = 0; func < nfuncs; func++) { if (pci_read(domain, bus, dev, func, PCI_ID_REG, ®) != 0) continue; if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || PCI_VENDOR(reg) == 0) continue; device->base.domain = domain; device->base.bus = bus; device->base.dev = dev; device->base.func = func; device->base.vendor_id = PCI_VENDOR(reg); device->base.device_id = PCI_PRODUCT(reg); if (pci_read(domain, bus, dev, func, PCI_CLASS_REG, ®) != 0) continue; device->base.device_class = PCI_INTERFACE(reg) | PCI_CLASS(reg) << 16 | PCI_SUBCLASS(reg) << 8; device->base.revision = PCI_REVISION(reg); if (pci_read(domain, bus, dev, func, PCI_SUBVEND_0, ®) != 0) continue; device->base.subvendor_id = PCI_VENDOR(reg); device->base.subdevice_id = PCI_PRODUCT(reg); device++; } } } } return 0; }
uint32_t pci_read_dword(struct pci_address* addr, uint8_t reg_offset) { return pci_read(addr->bus, addr->device, addr->func, reg_offset, sizeof(uint32_t)); }