1 /* 2 * The PCI Library -- Generic Direct Access Functions 3 * 4 * Copyright (c) 1997--2022 Martin Mares <[email protected]> 5 * 6 * Can be freely distributed and used under the terms of the GNU GPL v2+. 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #include <string.h> 12 13 #include "internal.h" 14 15 void 16 pci_generic_scan_bus(struct pci_access *a, byte *busmap, int domain, int bus) 17 { 18 int dev, multi, ht; 19 struct pci_dev *t; 20 21 a->debug("Scanning bus %02x for devices...\n", bus); 22 if (busmap[bus]) 23 { 24 a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus); 25 return; 26 } 27 busmap[bus] = 1; 28 t = pci_alloc_dev(a); 29 t->domain = domain; 30 t->bus = bus; 31 for (dev=0; dev<32; dev++) 32 { 33 t->dev = dev; 34 multi = 0; 35 for (t->func=0; !t->func || multi && t->func<8; t->func++) 36 { 37 u32 vd = pci_read_long(t, PCI_VENDOR_ID); 38 struct pci_dev *d; 39 40 if (!vd || vd == 0xffffffff) 41 continue; 42 ht = pci_read_byte(t, PCI_HEADER_TYPE); 43 if (!t->func) 44 multi = ht & 0x80; 45 ht &= 0x7f; 46 d = pci_alloc_dev(a); 47 d->domain = t->domain; 48 d->bus = t->bus; 49 d->dev = t->dev; 50 d->func = t->func; 51 d->vendor_id = vd & 0xffff; 52 d->device_id = vd >> 16U; 53 d->known_fields = PCI_FILL_IDENT; 54 d->hdrtype = ht; 55 pci_link_dev(a, d); 56 switch (ht) 57 { 58 case PCI_HEADER_TYPE_NORMAL: 59 break; 60 case PCI_HEADER_TYPE_BRIDGE: 61 case PCI_HEADER_TYPE_CARDBUS: 62 pci_generic_scan_bus(a, busmap, domain, pci_read_byte(t, PCI_SECONDARY_BUS)); 63 break; 64 default: 65 a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht); 66 } 67 } 68 } 69 pci_free_dev(t); 70 } 71 72 void 73 pci_generic_scan_domain(struct pci_access *a, int domain) 74 { 75 byte busmap[256]; 76 77 memset(busmap, 0, sizeof(busmap)); 78 pci_generic_scan_bus(a, busmap, domain, 0); 79 } 80 81 void 82 pci_generic_scan(struct pci_access *a) 83 { 84 pci_generic_scan_domain(a, 0); 85 } 86 87 static int 88 get_hdr_type(struct pci_dev *d) 89 { 90 if (d->hdrtype < 0) 91 d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f; 92 return d->hdrtype; 93 } 94 95 void 96 pci_generic_fill_info(struct pci_dev *d, unsigned int flags) 97 { 98 struct pci_access *a = d->access; 99 struct pci_cap *cap; 100 101 if (want_fill(d, flags, PCI_FILL_IDENT)) 102 { 103 d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); 104 d->device_id = pci_read_word(d, PCI_DEVICE_ID); 105 } 106 107 if (want_fill(d, flags, PCI_FILL_CLASS)) 108 d->device_class = pci_read_word(d, PCI_CLASS_DEVICE); 109 110 if (want_fill(d, flags, PCI_FILL_CLASS_EXT)) 111 { 112 d->prog_if = pci_read_byte(d, PCI_CLASS_PROG); 113 d->rev_id = pci_read_byte(d, PCI_REVISION_ID); 114 } 115 116 if (want_fill(d, flags, PCI_FILL_SUBSYS)) 117 { 118 switch (get_hdr_type(d)) 119 { 120 case PCI_HEADER_TYPE_NORMAL: 121 d->subsys_vendor_id = pci_read_word(d, PCI_SUBSYSTEM_VENDOR_ID); 122 d->subsys_id = pci_read_word(d, PCI_SUBSYSTEM_ID); 123 break; 124 case PCI_HEADER_TYPE_BRIDGE: 125 cap = pci_find_cap(d, PCI_CAP_ID_SSVID, PCI_CAP_NORMAL); 126 if (cap) 127 { 128 d->subsys_vendor_id = pci_read_word(d, cap->addr + PCI_SSVID_VENDOR); 129 d->subsys_id = pci_read_word(d, cap->addr + PCI_SSVID_DEVICE); 130 } 131 break; 132 case PCI_HEADER_TYPE_CARDBUS: 133 d->subsys_vendor_id = pci_read_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID); 134 d->subsys_id = pci_read_word(d, PCI_CB_SUBSYSTEM_ID); 135 break; 136 default: 137 clear_fill(d, PCI_FILL_SUBSYS); 138 } 139 } 140 141 if (want_fill(d, flags, PCI_FILL_IRQ)) 142 d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE); 143 144 if (want_fill(d, flags, PCI_FILL_BASES)) 145 { 146 int cnt = 0, i; 147 memset(d->base_addr, 0, sizeof(d->base_addr)); 148 switch (get_hdr_type(d)) 149 { 150 case PCI_HEADER_TYPE_NORMAL: 151 cnt = 6; 152 break; 153 case PCI_HEADER_TYPE_BRIDGE: 154 cnt = 2; 155 break; 156 case PCI_HEADER_TYPE_CARDBUS: 157 cnt = 1; 158 break; 159 } 160 if (cnt) 161 { 162 for (i=0; i<cnt; i++) 163 { 164 u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4); 165 if (!x || x == (u32) ~0) 166 continue; 167 if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) 168 d->base_addr[i] = x; 169 else 170 { 171 if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64) 172 d->base_addr[i] = x; 173 else if (i >= cnt-1) 174 a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i); 175 else 176 { 177 u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4); 178 #ifdef PCI_HAVE_64BIT_ADDRESS 179 d->base_addr[i-1] = x | (((pciaddr_t) y) << 32); 180 #else 181 if (y) 182 a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func); 183 else 184 d->base_addr[i-1] = x; 185 #endif 186 } 187 } 188 } 189 } 190 } 191 192 if (want_fill(d, flags, PCI_FILL_ROM_BASE)) 193 { 194 int reg = 0; 195 d->rom_base_addr = 0; 196 switch (get_hdr_type(d)) 197 { 198 case PCI_HEADER_TYPE_NORMAL: 199 reg = PCI_ROM_ADDRESS; 200 break; 201 case PCI_HEADER_TYPE_BRIDGE: 202 reg = PCI_ROM_ADDRESS1; 203 break; 204 } 205 if (reg) 206 { 207 u32 u = pci_read_long(d, reg); 208 if (u != 0xffffffff) 209 d->rom_base_addr = u; 210 } 211 } 212 213 pci_scan_caps(d, flags); 214 } 215 216 static int 217 pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len, 218 int (*r)(struct pci_dev *d, int pos, byte *buf, int len)) 219 { 220 if ((pos & 1) && len >= 1) 221 { 222 if (!r(d, pos, buf, 1)) 223 return 0; 224 pos++; buf++; len--; 225 } 226 if ((pos & 3) && len >= 2) 227 { 228 if (!r(d, pos, buf, 2)) 229 return 0; 230 pos += 2; buf += 2; len -= 2; 231 } 232 while (len >= 4) 233 { 234 if (!r(d, pos, buf, 4)) 235 return 0; 236 pos += 4; buf += 4; len -= 4; 237 } 238 if (len >= 2) 239 { 240 if (!r(d, pos, buf, 2)) 241 return 0; 242 pos += 2; buf += 2; len -= 2; 243 } 244 if (len && !r(d, pos, buf, 1)) 245 return 0; 246 return 1; 247 } 248 249 int 250 pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len) 251 { 252 return pci_generic_block_op(d, pos, buf, len, d->access->methods->read); 253 } 254 255 int 256 pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len) 257 { 258 return pci_generic_block_op(d, pos, buf, len, d->access->methods->write); 259 } 260