1 /* 2 * The PCI Library -- Virtual Emulated Config Space Access Functions 3 * 4 * Copyright (c) 2022 Pali Rohár 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 "internal.h" 12 13 static u32 14 ioflg_to_pciflg(pciaddr_t ioflg) 15 { 16 u32 flg = 0; 17 18 if ((ioflg & PCI_IORESOURCE_TYPE_BITS) == PCI_IORESOURCE_IO) 19 flg = PCI_BASE_ADDRESS_SPACE_IO; 20 else if ((ioflg & PCI_IORESOURCE_TYPE_BITS) == PCI_IORESOURCE_MEM) 21 { 22 flg = PCI_BASE_ADDRESS_SPACE_MEMORY; 23 if (ioflg & PCI_IORESOURCE_MEM_64) 24 flg |= PCI_BASE_ADDRESS_MEM_TYPE_64; 25 else 26 flg |= PCI_BASE_ADDRESS_MEM_TYPE_32; 27 if (ioflg & PCI_IORESOURCE_PREFETCH) 28 flg |= PCI_BASE_ADDRESS_MEM_PREFETCH; 29 } 30 31 return flg; 32 } 33 34 static u32 35 baseres_to_pcires(pciaddr_t addr, pciaddr_t ioflg, int *have_sec, u32 *sec_val) 36 { 37 u32 val = ioflg_to_pciflg(ioflg); 38 39 if (have_sec) 40 *have_sec = 0; 41 42 if ((val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO && addr <= 0xffffffff) 43 val |= addr & PCI_BASE_ADDRESS_IO_MASK; 44 else if ((val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) 45 { 46 val |= addr & PCI_BASE_ADDRESS_MEM_MASK; 47 if ((val & PCI_BASE_ADDRESS_MEM_TYPE_64) && have_sec) 48 { 49 *have_sec = 1; 50 *sec_val = addr >> 32; 51 } 52 } 53 54 return val; 55 } 56 57 static inline u32 58 even_baseres_to_pcires(pciaddr_t addr, pciaddr_t ioflg) 59 { 60 return baseres_to_pcires(addr, ioflg, NULL, NULL); 61 } 62 63 static inline u32 64 odd_baseres_to_pcires(pciaddr_t addr0, pciaddr_t ioflg0, pciaddr_t addr, pciaddr_t ioflg) 65 { 66 int have_sec; 67 u32 val; 68 baseres_to_pcires(addr0, ioflg0, &have_sec, &val); 69 if (!have_sec) 70 val = baseres_to_pcires(addr, ioflg, NULL, NULL); 71 return val; 72 } 73 74 int 75 pci_emulated_read(struct pci_dev *d, int pos, byte *buf, int len) 76 { 77 u32 ht = PCI_HEADER_TYPE_NORMAL; 78 u32 val = 0; 79 int i; 80 81 if (pos >= 64) 82 return 0; 83 84 if (len > 4) 85 return pci_generic_block_read(d, pos, buf, len); 86 87 if (d->device_class == PCI_CLASS_BRIDGE_PCI) 88 ht = PCI_HEADER_TYPE_BRIDGE; 89 else if (d->device_class == PCI_CLASS_BRIDGE_CARDBUS) 90 ht = PCI_HEADER_TYPE_CARDBUS; 91 92 switch (pos & ~3) 93 { 94 case PCI_COMMAND: 95 for (i = 0; i < 6; i++) 96 { 97 if (!d->size[i]) 98 continue; 99 if ((d->flags[i] & PCI_IORESOURCE_TYPE_BITS) == PCI_IORESOURCE_IO) 100 val |= PCI_COMMAND_IO; 101 else if ((d->flags[i] & PCI_IORESOURCE_TYPE_BITS) == PCI_IORESOURCE_MEM) 102 val |= PCI_COMMAND_MEMORY; 103 } 104 break; 105 case PCI_VENDOR_ID: 106 val = (d->device_id << 16) | d->vendor_id; 107 break; 108 case PCI_CLASS_REVISION: 109 val = (d->device_class << 16) | (d->prog_if << 8) | d->rev_id; 110 break; 111 case PCI_CACHE_LINE_SIZE: 112 val = ht << 16; 113 break; 114 case PCI_BASE_ADDRESS_0: 115 val = even_baseres_to_pcires(d->base_addr[0], d->flags[0]); 116 break; 117 case PCI_INTERRUPT_LINE: 118 val = (d->irq >= 0 && d->irq <= 0xff) ? d->irq : 0; 119 break; 120 } 121 122 if ((pos & ~3) == PCI_BASE_ADDRESS_1 && (ht == PCI_HEADER_TYPE_NORMAL || ht == PCI_HEADER_TYPE_BRIDGE)) 123 val = odd_baseres_to_pcires(d->base_addr[0], d->flags[0], d->base_addr[1], d->flags[1]); 124 125 if (ht == PCI_HEADER_TYPE_NORMAL) 126 switch (pos & ~3) 127 { 128 case PCI_BASE_ADDRESS_2: 129 val = even_baseres_to_pcires(d->base_addr[2], d->flags[2]); 130 break; 131 case PCI_BASE_ADDRESS_3: 132 val = odd_baseres_to_pcires(d->base_addr[2], d->flags[2], d->base_addr[3], d->flags[3]); 133 break; 134 case PCI_BASE_ADDRESS_4: 135 val = even_baseres_to_pcires(d->base_addr[4], d->flags[4]); 136 break; 137 case PCI_BASE_ADDRESS_5: 138 val = odd_baseres_to_pcires(d->base_addr[4], d->flags[4], d->base_addr[5], d->flags[5]); 139 break; 140 case PCI_SUBSYSTEM_VENDOR_ID: 141 val = (d->subsys_id << 16) | d->subsys_vendor_id; 142 break; 143 case PCI_ROM_ADDRESS: 144 val = d->rom_base_addr & PCI_ROM_ADDRESS_MASK; 145 if (val) 146 val |= PCI_ROM_ADDRESS_ENABLE; 147 break; 148 } 149 else if (ht == PCI_HEADER_TYPE_BRIDGE) 150 switch (pos & ~3) 151 { 152 case PCI_COMMAND: 153 if (d->bridge_size[0]) 154 val |= PCI_COMMAND_IO; 155 if (d->bridge_size[1] || d->bridge_size[2]) 156 val |= PCI_COMMAND_MEMORY; 157 break; 158 case PCI_PRIMARY_BUS: 159 val = d->bus; 160 break; 161 case PCI_IO_BASE: 162 if (d->bridge_size[0]) 163 { 164 val = (((((d->bridge_base_addr[0] + d->bridge_size[0] - 1) >> 8) & PCI_IO_RANGE_MASK) << 8) & 0xff00) | 165 (((d->bridge_base_addr[0] >> 8) & PCI_IO_RANGE_MASK) & 0x00ff); 166 if ((d->bridge_flags[0] & PCI_IORESOURCE_IO_16BIT_ADDR) && 167 d->bridge_base_addr[0] + d->bridge_size[0] - 1 <= 0xffff) 168 val |= (PCI_IO_RANGE_TYPE_16 << 8) | PCI_IO_RANGE_TYPE_16; 169 else 170 val |= (PCI_IO_RANGE_TYPE_32 << 8) | PCI_IO_RANGE_TYPE_32; 171 } 172 else 173 val = 0xff & PCI_IO_RANGE_MASK; 174 break; 175 case PCI_MEMORY_BASE: 176 if (d->bridge_size[1]) 177 val = (((((d->bridge_base_addr[1] + d->bridge_size[1] - 1) >> 16) & PCI_MEMORY_RANGE_MASK) << 16) & 0xffff0000) | 178 (((d->bridge_base_addr[1] >> 16) & PCI_MEMORY_RANGE_MASK) & 0x0000ffff); 179 else 180 val = 0xffff & PCI_MEMORY_RANGE_MASK; 181 break; 182 case PCI_PREF_MEMORY_BASE: 183 if (d->bridge_size[2]) 184 { 185 val = (((((d->bridge_base_addr[2] + d->bridge_size[2] - 1) >> 16) & PCI_PREF_RANGE_MASK) << 16) & 0xffff0000) | 186 (((d->bridge_base_addr[2] >> 16) & PCI_PREF_RANGE_MASK) & 0x0000ffff); 187 if ((d->bridge_flags[2] & PCI_IORESOURCE_MEM_64) || 188 d->bridge_base_addr[2] + d->bridge_size[2] - 1 > 0xffffffff) 189 val |= (PCI_PREF_RANGE_TYPE_64 << 16) | PCI_PREF_RANGE_TYPE_64; 190 else 191 val |= (PCI_PREF_RANGE_TYPE_32 << 16) | PCI_PREF_RANGE_TYPE_32; 192 } 193 else 194 val = 0xffff & PCI_PREF_RANGE_MASK; 195 break; 196 case PCI_PREF_BASE_UPPER32: 197 if (d->bridge_size[2]) 198 val = d->bridge_base_addr[2] >> 32; 199 break; 200 case PCI_PREF_LIMIT_UPPER32: 201 if (d->bridge_size[2]) 202 val = (d->bridge_base_addr[2] + d->bridge_size[2] - 1) >> 32; 203 break; 204 case PCI_IO_BASE_UPPER16: 205 if (d->bridge_size[0]) 206 val = ((((d->bridge_base_addr[0] + d->bridge_size[0] - 1) >> 16) << 16) & 0xffff0000) | 207 ((d->bridge_base_addr[0] >> 16) & 0x0000ffff); 208 break; 209 case PCI_ROM_ADDRESS1: 210 val = d->rom_base_addr & PCI_ROM_ADDRESS_MASK; 211 if (val) 212 val |= PCI_ROM_ADDRESS_ENABLE; 213 break; 214 } 215 else if (ht == PCI_HEADER_TYPE_CARDBUS) 216 switch (pos & ~3) 217 { 218 case PCI_COMMAND: 219 if (d->bridge_size[0] || d->bridge_size[1]) 220 val |= PCI_COMMAND_MEMORY; 221 if (d->bridge_size[2] || d->bridge_size[3]) 222 val |= PCI_COMMAND_IO; 223 break; 224 case PCI_CB_PRIMARY_BUS: 225 val = d->bus; 226 break; 227 case PCI_CB_MEMORY_BASE_0: 228 if (d->bridge_size[0]) 229 val = d->bridge_base_addr[0] & ~0xfff; 230 else 231 val = 0xffffffff & ~0xfff; 232 break; 233 case PCI_CB_MEMORY_LIMIT_0: 234 if (d->bridge_size[0]) 235 val = (d->bridge_base_addr[0] + d->bridge_size[0] - 1) & ~0xfff; 236 break; 237 case PCI_CB_MEMORY_BASE_1: 238 if (d->bridge_size[1]) 239 val = d->bridge_base_addr[1] & ~0xfff; 240 else 241 val = 0xffffffff & ~0xfff; 242 break; 243 case PCI_CB_MEMORY_LIMIT_1: 244 if (d->bridge_size[1]) 245 val = (d->bridge_base_addr[1] + d->bridge_size[1] - 1) & ~0xfff; 246 break; 247 case PCI_CB_IO_BASE_0: 248 if (d->bridge_size[2]) 249 { 250 val = d->bridge_base_addr[2] & PCI_CB_IO_RANGE_MASK; 251 if ((d->bridge_flags[2] & PCI_IORESOURCE_IO_16BIT_ADDR) || 252 d->bridge_base_addr[2] + d->bridge_size[2] - 1 <= 0xffff) 253 val |= PCI_IO_RANGE_TYPE_16; 254 else 255 val |= PCI_IO_RANGE_TYPE_32; 256 } 257 else 258 val = 0x0000ffff & PCI_CB_IO_RANGE_MASK; 259 break; 260 case PCI_CB_IO_LIMIT_0: 261 if (d->bridge_size[2]) 262 val = (d->bridge_base_addr[2] + d->bridge_size[2] - 1) & PCI_CB_IO_RANGE_MASK; 263 break; 264 case PCI_CB_IO_BASE_1: 265 if (d->bridge_size[3]) 266 { 267 val = d->bridge_base_addr[3] & PCI_CB_IO_RANGE_MASK; 268 if ((d->bridge_flags[3] & PCI_IORESOURCE_IO_16BIT_ADDR) || 269 d->bridge_base_addr[3] + d->bridge_size[3] - 1 <= 0xffff) 270 val |= PCI_IO_RANGE_TYPE_16; 271 else 272 val |= PCI_IO_RANGE_TYPE_32; 273 } 274 else 275 val = 0x0000ffff & PCI_CB_IO_RANGE_MASK; 276 break; 277 case PCI_CB_IO_LIMIT_1: 278 if (d->bridge_size[3]) 279 val = (d->bridge_base_addr[3] + d->bridge_size[3] - 1) & PCI_CB_IO_RANGE_MASK; 280 break; 281 case PCI_CB_BRIDGE_CONTROL: 282 if (d->bridge_flags[0] & PCI_IORESOURCE_PREFETCH) 283 val |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; 284 if (d->bridge_flags[1] & PCI_IORESOURCE_PREFETCH) 285 val |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; 286 break; 287 case PCI_CB_SUBSYSTEM_VENDOR_ID: 288 val = (d->subsys_id << 16) | d->subsys_vendor_id; 289 break; 290 } 291 292 if (len <= 2) 293 val = (val >> (8 * (pos & 3))) & ((1 << (len * 8)) - 1); 294 295 while (len-- > 0) 296 { 297 *(buf++) = val & 0xff; 298 val >>= 8; 299 } 300 return 1; 301 } 302