]>
Commit | Line | Data |
---|---|---|
69b91039 FB |
1 | /* |
2 | * QEMU PCI bus manager | |
3 | * | |
4 | * Copyright (c) 2004 Fabrice Bellard | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | * of this software and associated documentation files (the "Software"), to deal | |
8 | * in the Software without restriction, including without limitation the rights | |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | * copies of the Software, and to permit persons to whom the Software is | |
11 | * furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in | |
14 | * all copies or substantial portions of the Software. | |
15 | * | |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | * THE SOFTWARE. | |
23 | */ | |
24 | #include "vl.h" | |
25 | ||
26 | //#define DEBUG_PCI | |
27 | ||
30468f78 FB |
28 | struct PCIBus { |
29 | int bus_num; | |
30 | int devfn_min; | |
502a5395 | 31 | pci_set_irq_fn set_irq; |
30468f78 | 32 | uint32_t config_reg; /* XXX: suppress */ |
384d8876 FB |
33 | /* low level pic */ |
34 | SetIRQFunc *low_set_irq; | |
35 | void *irq_opaque; | |
30468f78 FB |
36 | PCIDevice *devices[256]; |
37 | }; | |
69b91039 | 38 | |
69b91039 | 39 | target_phys_addr_t pci_mem_base; |
0ac32c83 | 40 | static int pci_irq_index; |
30468f78 FB |
41 | static PCIBus *first_bus; |
42 | ||
502a5395 | 43 | PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min) |
30468f78 FB |
44 | { |
45 | PCIBus *bus; | |
46 | bus = qemu_mallocz(sizeof(PCIBus)); | |
502a5395 PB |
47 | bus->set_irq = set_irq; |
48 | bus->irq_opaque = pic; | |
49 | bus->devfn_min = devfn_min; | |
30468f78 FB |
50 | first_bus = bus; |
51 | return bus; | |
52 | } | |
69b91039 | 53 | |
502a5395 PB |
54 | int pci_bus_num(PCIBus *s) |
55 | { | |
56 | return s->bus_num; | |
57 | } | |
58 | ||
30ca2aab FB |
59 | void generic_pci_save(QEMUFile* f, void *opaque) |
60 | { | |
61 | PCIDevice* s=(PCIDevice*)opaque; | |
62 | ||
63 | qemu_put_buffer(f, s->config, 256); | |
64 | } | |
65 | ||
66 | int generic_pci_load(QEMUFile* f, void *opaque, int version_id) | |
67 | { | |
68 | PCIDevice* s=(PCIDevice*)opaque; | |
69 | ||
70 | if (version_id != 1) | |
71 | return -EINVAL; | |
72 | ||
73 | qemu_get_buffer(f, s->config, 256); | |
74 | return 0; | |
75 | } | |
76 | ||
69b91039 | 77 | /* -1 for devfn means auto assign */ |
30468f78 FB |
78 | PCIDevice *pci_register_device(PCIBus *bus, const char *name, |
79 | int instance_size, int devfn, | |
69b91039 FB |
80 | PCIConfigReadFunc *config_read, |
81 | PCIConfigWriteFunc *config_write) | |
82 | { | |
30468f78 | 83 | PCIDevice *pci_dev; |
69b91039 | 84 | |
0ac32c83 FB |
85 | if (pci_irq_index >= PCI_DEVICES_MAX) |
86 | return NULL; | |
87 | ||
69b91039 | 88 | if (devfn < 0) { |
30468f78 FB |
89 | for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) { |
90 | if (!bus->devices[devfn]) | |
69b91039 FB |
91 | goto found; |
92 | } | |
93 | return NULL; | |
94 | found: ; | |
95 | } | |
96 | pci_dev = qemu_mallocz(instance_size); | |
97 | if (!pci_dev) | |
98 | return NULL; | |
30468f78 | 99 | pci_dev->bus = bus; |
69b91039 FB |
100 | pci_dev->devfn = devfn; |
101 | pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); | |
0ac32c83 FB |
102 | |
103 | if (!config_read) | |
104 | config_read = pci_default_read_config; | |
105 | if (!config_write) | |
106 | config_write = pci_default_write_config; | |
69b91039 FB |
107 | pci_dev->config_read = config_read; |
108 | pci_dev->config_write = config_write; | |
0ac32c83 | 109 | pci_dev->irq_index = pci_irq_index++; |
30468f78 | 110 | bus->devices[devfn] = pci_dev; |
69b91039 FB |
111 | return pci_dev; |
112 | } | |
113 | ||
114 | void pci_register_io_region(PCIDevice *pci_dev, int region_num, | |
115 | uint32_t size, int type, | |
116 | PCIMapIORegionFunc *map_func) | |
117 | { | |
118 | PCIIORegion *r; | |
d7ce493a | 119 | uint32_t addr; |
69b91039 | 120 | |
8a8696a3 | 121 | if ((unsigned int)region_num >= PCI_NUM_REGIONS) |
69b91039 FB |
122 | return; |
123 | r = &pci_dev->io_regions[region_num]; | |
124 | r->addr = -1; | |
125 | r->size = size; | |
126 | r->type = type; | |
127 | r->map_func = map_func; | |
d7ce493a PB |
128 | if (region_num == PCI_ROM_SLOT) { |
129 | addr = 0x30; | |
130 | } else { | |
131 | addr = 0x10 + region_num * 4; | |
132 | } | |
133 | *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type); | |
69b91039 FB |
134 | } |
135 | ||
502a5395 | 136 | target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr) |
69b91039 | 137 | { |
502a5395 | 138 | return addr + pci_mem_base; |
69b91039 FB |
139 | } |
140 | ||
0ac32c83 FB |
141 | static void pci_update_mappings(PCIDevice *d) |
142 | { | |
143 | PCIIORegion *r; | |
144 | int cmd, i; | |
8a8696a3 | 145 | uint32_t last_addr, new_addr, config_ofs; |
0ac32c83 FB |
146 | |
147 | cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND)); | |
8a8696a3 | 148 | for(i = 0; i < PCI_NUM_REGIONS; i++) { |
0ac32c83 | 149 | r = &d->io_regions[i]; |
8a8696a3 FB |
150 | if (i == PCI_ROM_SLOT) { |
151 | config_ofs = 0x30; | |
152 | } else { | |
153 | config_ofs = 0x10 + i * 4; | |
154 | } | |
0ac32c83 FB |
155 | if (r->size != 0) { |
156 | if (r->type & PCI_ADDRESS_SPACE_IO) { | |
157 | if (cmd & PCI_COMMAND_IO) { | |
158 | new_addr = le32_to_cpu(*(uint32_t *)(d->config + | |
8a8696a3 | 159 | config_ofs)); |
0ac32c83 FB |
160 | new_addr = new_addr & ~(r->size - 1); |
161 | last_addr = new_addr + r->size - 1; | |
162 | /* NOTE: we have only 64K ioports on PC */ | |
163 | if (last_addr <= new_addr || new_addr == 0 || | |
164 | last_addr >= 0x10000) { | |
165 | new_addr = -1; | |
166 | } | |
167 | } else { | |
168 | new_addr = -1; | |
169 | } | |
170 | } else { | |
171 | if (cmd & PCI_COMMAND_MEMORY) { | |
172 | new_addr = le32_to_cpu(*(uint32_t *)(d->config + | |
8a8696a3 FB |
173 | config_ofs)); |
174 | /* the ROM slot has a specific enable bit */ | |
175 | if (i == PCI_ROM_SLOT && !(new_addr & 1)) | |
176 | goto no_mem_map; | |
0ac32c83 FB |
177 | new_addr = new_addr & ~(r->size - 1); |
178 | last_addr = new_addr + r->size - 1; | |
179 | /* NOTE: we do not support wrapping */ | |
180 | /* XXX: as we cannot support really dynamic | |
181 | mappings, we handle specific values as invalid | |
182 | mappings. */ | |
183 | if (last_addr <= new_addr || new_addr == 0 || | |
184 | last_addr == -1) { | |
185 | new_addr = -1; | |
186 | } | |
187 | } else { | |
8a8696a3 | 188 | no_mem_map: |
0ac32c83 FB |
189 | new_addr = -1; |
190 | } | |
191 | } | |
192 | /* now do the real mapping */ | |
193 | if (new_addr != r->addr) { | |
194 | if (r->addr != -1) { | |
195 | if (r->type & PCI_ADDRESS_SPACE_IO) { | |
196 | int class; | |
197 | /* NOTE: specific hack for IDE in PC case: | |
198 | only one byte must be mapped. */ | |
199 | class = d->config[0x0a] | (d->config[0x0b] << 8); | |
200 | if (class == 0x0101 && r->size == 4) { | |
201 | isa_unassign_ioport(r->addr + 2, 1); | |
202 | } else { | |
203 | isa_unassign_ioport(r->addr, r->size); | |
204 | } | |
205 | } else { | |
502a5395 | 206 | cpu_register_physical_memory(pci_to_cpu_addr(r->addr), |
0ac32c83 FB |
207 | r->size, |
208 | IO_MEM_UNASSIGNED); | |
209 | } | |
210 | } | |
211 | r->addr = new_addr; | |
212 | if (r->addr != -1) { | |
213 | r->map_func(d, i, r->addr, r->size, r->type); | |
214 | } | |
215 | } | |
216 | } | |
217 | } | |
218 | } | |
219 | ||
220 | uint32_t pci_default_read_config(PCIDevice *d, | |
221 | uint32_t address, int len) | |
69b91039 | 222 | { |
0ac32c83 FB |
223 | uint32_t val; |
224 | switch(len) { | |
225 | case 1: | |
226 | val = d->config[address]; | |
227 | break; | |
228 | case 2: | |
229 | val = le16_to_cpu(*(uint16_t *)(d->config + address)); | |
230 | break; | |
231 | default: | |
232 | case 4: | |
233 | val = le32_to_cpu(*(uint32_t *)(d->config + address)); | |
234 | break; | |
235 | } | |
236 | return val; | |
237 | } | |
238 | ||
239 | void pci_default_write_config(PCIDevice *d, | |
240 | uint32_t address, uint32_t val, int len) | |
241 | { | |
242 | int can_write, i; | |
7bf5be70 | 243 | uint32_t end, addr; |
0ac32c83 | 244 | |
8a8696a3 FB |
245 | if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || |
246 | (address >= 0x30 && address < 0x34))) { | |
0ac32c83 FB |
247 | PCIIORegion *r; |
248 | int reg; | |
249 | ||
8a8696a3 FB |
250 | if ( address >= 0x30 ) { |
251 | reg = PCI_ROM_SLOT; | |
252 | }else{ | |
253 | reg = (address - 0x10) >> 2; | |
254 | } | |
0ac32c83 FB |
255 | r = &d->io_regions[reg]; |
256 | if (r->size == 0) | |
257 | goto default_config; | |
258 | /* compute the stored value */ | |
8a8696a3 FB |
259 | if (reg == PCI_ROM_SLOT) { |
260 | /* keep ROM enable bit */ | |
261 | val &= (~(r->size - 1)) | 1; | |
262 | } else { | |
263 | val &= ~(r->size - 1); | |
264 | val |= r->type; | |
265 | } | |
266 | *(uint32_t *)(d->config + address) = cpu_to_le32(val); | |
0ac32c83 | 267 | pci_update_mappings(d); |
69b91039 | 268 | return; |
0ac32c83 FB |
269 | } |
270 | default_config: | |
271 | /* not efficient, but simple */ | |
7bf5be70 | 272 | addr = address; |
0ac32c83 FB |
273 | for(i = 0; i < len; i++) { |
274 | /* default read/write accesses */ | |
1f62d938 | 275 | switch(d->config[0x0e]) { |
0ac32c83 | 276 | case 0x00: |
1f62d938 FB |
277 | case 0x80: |
278 | switch(addr) { | |
279 | case 0x00: | |
280 | case 0x01: | |
281 | case 0x02: | |
282 | case 0x03: | |
283 | case 0x08: | |
284 | case 0x09: | |
285 | case 0x0a: | |
286 | case 0x0b: | |
287 | case 0x0e: | |
288 | case 0x10 ... 0x27: /* base */ | |
289 | case 0x30 ... 0x33: /* rom */ | |
290 | case 0x3d: | |
291 | can_write = 0; | |
292 | break; | |
293 | default: | |
294 | can_write = 1; | |
295 | break; | |
296 | } | |
0ac32c83 FB |
297 | break; |
298 | default: | |
1f62d938 FB |
299 | case 0x01: |
300 | switch(addr) { | |
301 | case 0x00: | |
302 | case 0x01: | |
303 | case 0x02: | |
304 | case 0x03: | |
305 | case 0x08: | |
306 | case 0x09: | |
307 | case 0x0a: | |
308 | case 0x0b: | |
309 | case 0x0e: | |
310 | case 0x38 ... 0x3b: /* rom */ | |
311 | case 0x3d: | |
312 | can_write = 0; | |
313 | break; | |
314 | default: | |
315 | can_write = 1; | |
316 | break; | |
317 | } | |
0ac32c83 FB |
318 | break; |
319 | } | |
320 | if (can_write) { | |
7bf5be70 | 321 | d->config[addr] = val; |
0ac32c83 | 322 | } |
7bf5be70 | 323 | addr++; |
0ac32c83 FB |
324 | val >>= 8; |
325 | } | |
326 | ||
327 | end = address + len; | |
328 | if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) { | |
329 | /* if the command register is modified, we must modify the mappings */ | |
330 | pci_update_mappings(d); | |
69b91039 FB |
331 | } |
332 | } | |
333 | ||
502a5395 | 334 | void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len) |
69b91039 | 335 | { |
30468f78 FB |
336 | PCIBus *s = opaque; |
337 | PCIDevice *pci_dev; | |
338 | int config_addr, bus_num; | |
69b91039 FB |
339 | |
340 | #if defined(DEBUG_PCI) && 0 | |
341 | printf("pci_data_write: addr=%08x val=%08x len=%d\n", | |
502a5395 | 342 | addr, val, len); |
69b91039 | 343 | #endif |
502a5395 | 344 | bus_num = (addr >> 16) & 0xff; |
30468f78 | 345 | if (bus_num != 0) |
69b91039 | 346 | return; |
502a5395 | 347 | pci_dev = s->devices[(addr >> 8) & 0xff]; |
69b91039 FB |
348 | if (!pci_dev) |
349 | return; | |
502a5395 | 350 | config_addr = addr & 0xff; |
69b91039 FB |
351 | #if defined(DEBUG_PCI) |
352 | printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n", | |
353 | pci_dev->name, config_addr, val, len); | |
354 | #endif | |
0ac32c83 | 355 | pci_dev->config_write(pci_dev, config_addr, val, len); |
69b91039 FB |
356 | } |
357 | ||
502a5395 | 358 | uint32_t pci_data_read(void *opaque, uint32_t addr, int len) |
69b91039 | 359 | { |
30468f78 FB |
360 | PCIBus *s = opaque; |
361 | PCIDevice *pci_dev; | |
362 | int config_addr, bus_num; | |
69b91039 FB |
363 | uint32_t val; |
364 | ||
502a5395 | 365 | bus_num = (addr >> 16) & 0xff; |
30468f78 | 366 | if (bus_num != 0) |
69b91039 | 367 | goto fail; |
502a5395 | 368 | pci_dev = s->devices[(addr >> 8) & 0xff]; |
69b91039 FB |
369 | if (!pci_dev) { |
370 | fail: | |
63ce9e0a FB |
371 | switch(len) { |
372 | case 1: | |
373 | val = 0xff; | |
374 | break; | |
375 | case 2: | |
376 | val = 0xffff; | |
377 | break; | |
378 | default: | |
379 | case 4: | |
380 | val = 0xffffffff; | |
381 | break; | |
382 | } | |
69b91039 FB |
383 | goto the_end; |
384 | } | |
502a5395 | 385 | config_addr = addr & 0xff; |
69b91039 FB |
386 | val = pci_dev->config_read(pci_dev, config_addr, len); |
387 | #if defined(DEBUG_PCI) | |
388 | printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n", | |
389 | pci_dev->name, config_addr, val, len); | |
390 | #endif | |
391 | the_end: | |
392 | #if defined(DEBUG_PCI) && 0 | |
393 | printf("pci_data_read: addr=%08x val=%08x len=%d\n", | |
502a5395 | 394 | addr, val, len); |
69b91039 FB |
395 | #endif |
396 | return val; | |
397 | } | |
398 | ||
502a5395 PB |
399 | /***********************************************************/ |
400 | /* generic PCI irq support */ | |
30468f78 | 401 | |
502a5395 PB |
402 | /* 0 <= irq_num <= 3. level must be 0 or 1 */ |
403 | void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level) | |
69b91039 | 404 | { |
502a5395 PB |
405 | PCIBus *bus = pci_dev->bus; |
406 | bus->set_irq(pci_dev, bus->irq_opaque, irq_num, level); | |
69b91039 FB |
407 | } |
408 | ||
502a5395 PB |
409 | /***********************************************************/ |
410 | /* monitor info on PCI */ | |
0ac32c83 | 411 | |
6650ee6d PB |
412 | typedef struct { |
413 | uint16_t class; | |
414 | const char *desc; | |
415 | } pci_class_desc; | |
416 | ||
417 | static pci_class_desc pci_class_descriptions[] = | |
418 | { | |
419 | { 0x0101, "IDE controller"}, | |
420 | { 0x0200, "Ethernet controller"}, | |
421 | { 0x0300, "VGA controller"}, | |
422 | { 0x0600, "Host bridge"}, | |
423 | { 0x0601, "ISA bridge"}, | |
424 | { 0x0604, "PCI bridge"}, | |
425 | { 0x0c03, "USB controller"}, | |
426 | { 0, NULL} | |
427 | }; | |
428 | ||
502a5395 | 429 | static void pci_info_device(PCIDevice *d) |
30468f78 | 430 | { |
502a5395 PB |
431 | int i, class; |
432 | PCIIORegion *r; | |
6650ee6d | 433 | pci_class_desc *desc; |
30468f78 | 434 | |
502a5395 PB |
435 | term_printf(" Bus %2d, device %3d, function %d:\n", |
436 | d->bus->bus_num, d->devfn >> 3, d->devfn & 7); | |
437 | class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE))); | |
438 | term_printf(" "); | |
6650ee6d PB |
439 | desc = pci_class_descriptions; |
440 | while (desc->desc && class != desc->class) | |
441 | desc++; | |
442 | if (desc->desc) { | |
443 | term_printf("%s", desc->desc); | |
444 | } else { | |
502a5395 | 445 | term_printf("Class %04x", class); |
72cc6cfe | 446 | } |
502a5395 PB |
447 | term_printf(": PCI device %04x:%04x\n", |
448 | le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))), | |
449 | le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID)))); | |
30468f78 | 450 | |
502a5395 PB |
451 | if (d->config[PCI_INTERRUPT_PIN] != 0) { |
452 | term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]); | |
30468f78 | 453 | } |
502a5395 PB |
454 | for(i = 0;i < PCI_NUM_REGIONS; i++) { |
455 | r = &d->io_regions[i]; | |
456 | if (r->size != 0) { | |
457 | term_printf(" BAR%d: ", i); | |
458 | if (r->type & PCI_ADDRESS_SPACE_IO) { | |
459 | term_printf("I/O at 0x%04x [0x%04x].\n", | |
460 | r->addr, r->addr + r->size - 1); | |
461 | } else { | |
462 | term_printf("32 bit memory at 0x%08x [0x%08x].\n", | |
463 | r->addr, r->addr + r->size - 1); | |
464 | } | |
465 | } | |
77d4bc34 | 466 | } |
384d8876 FB |
467 | } |
468 | ||
502a5395 | 469 | void pci_for_each_device(void (*fn)(PCIDevice *d)) |
384d8876 | 470 | { |
502a5395 | 471 | PCIBus *bus = first_bus; |
384d8876 | 472 | PCIDevice *d; |
502a5395 | 473 | int devfn; |
384d8876 | 474 | |
502a5395 PB |
475 | if (bus) { |
476 | for(devfn = 0; devfn < 256; devfn++) { | |
477 | d = bus->devices[devfn]; | |
478 | if (d) | |
479 | fn(d); | |
480 | } | |
f2aa58c6 | 481 | } |
f2aa58c6 FB |
482 | } |
483 | ||
502a5395 | 484 | void pci_info(void) |
f2aa58c6 | 485 | { |
502a5395 | 486 | pci_for_each_device(pci_info_device); |
77d4bc34 | 487 | } |
a41b2ff2 PB |
488 | |
489 | /* Initialize a PCI NIC. */ | |
490 | void pci_nic_init(PCIBus *bus, NICInfo *nd) | |
491 | { | |
492 | if (strcmp(nd->model, "ne2k_pci") == 0) { | |
493 | pci_ne2000_init(bus, nd); | |
494 | } else if (strcmp(nd->model, "rtl8139") == 0) { | |
495 | pci_rtl8139_init(bus, nd); | |
496 | } else { | |
497 | fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model); | |
498 | exit (1); | |
499 | } | |
500 | } | |
501 |