Commit 0ac32c837507260009d170af15f4ae9652a9ea97

Authored by bellard
1 parent 4a9c9687

PCI interrupt support - PCI BIOS interrupt remapping - more accurate memory mapp…

…ing - 'info pci' monitor command


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@823 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 469 additions and 74 deletions
hw/pci.c
... ... @@ -25,6 +25,21 @@
25 25  
26 26 //#define DEBUG_PCI
27 27  
  28 +#define PCI_VENDOR_ID 0x00 /* 16 bits */
  29 +#define PCI_DEVICE_ID 0x02 /* 16 bits */
  30 +#define PCI_COMMAND 0x04 /* 16 bits */
  31 +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
  32 +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
  33 +#define PCI_CLASS_DEVICE 0x0a /* Device class */
  34 +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
  35 +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
  36 +#define PCI_MIN_GNT 0x3e /* 8 bits */
  37 +#define PCI_MAX_LAT 0x3f /* 8 bits */
  38 +
  39 +/* just used for simpler irq handling. */
  40 +#define PCI_DEVICES_MAX 64
  41 +#define PCI_IRQ_WORDS ((PCI_DEVICES_MAX + 31) / 32)
  42 +
28 43 typedef struct PCIBridge {
29 44 uint32_t config_reg;
30 45 PCIDevice **pci_bus[256];
... ... @@ -32,6 +47,8 @@ typedef struct PCIBridge {
32 47  
33 48 static PCIBridge pci_bridge;
34 49 target_phys_addr_t pci_mem_base;
  50 +static int pci_irq_index;
  51 +static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
35 52  
36 53 /* -1 for devfn means auto assign */
37 54 PCIDevice *pci_register_device(const char *name, int instance_size,
... ... @@ -42,6 +59,9 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
42 59 PCIBridge *s = &pci_bridge;
43 60 PCIDevice *pci_dev, **bus;
44 61  
  62 + if (pci_irq_index >= PCI_DEVICES_MAX)
  63 + return NULL;
  64 +
45 65 if (!s->pci_bus[bus_num]) {
46 66 s->pci_bus[bus_num] = qemu_mallocz(256 * sizeof(PCIDevice *));
47 67 if (!s->pci_bus[bus_num])
... ... @@ -62,8 +82,14 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
62 82 pci_dev->bus_num = bus_num;
63 83 pci_dev->devfn = devfn;
64 84 pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
  85 +
  86 + if (!config_read)
  87 + config_read = pci_default_read_config;
  88 + if (!config_write)
  89 + config_write = pci_default_write_config;
65 90 pci_dev->config_read = config_read;
66 91 pci_dev->config_write = config_write;
  92 + pci_dev->irq_index = pci_irq_index++;
67 93 bus[devfn] = pci_dev;
68 94 return pci_dev;
69 95 }
... ... @@ -83,30 +109,160 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
83 109 r->map_func = map_func;
84 110 }
85 111  
86   -static void pci_config_writel(void* opaque, uint32_t addr, uint32_t val)
  112 +static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
87 113 {
88 114 PCIBridge *s = opaque;
89 115 s->config_reg = val;
90 116 }
91 117  
92   -static uint32_t pci_config_readl(void* opaque, uint32_t addr)
  118 +static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
93 119 {
94 120 PCIBridge *s = opaque;
95 121 return s->config_reg;
96 122 }
97 123  
98   -static void unmap_region(PCIIORegion *r)
  124 +static void pci_update_mappings(PCIDevice *d)
  125 +{
  126 + PCIIORegion *r;
  127 + int cmd, i;
  128 + uint32_t last_addr, new_addr;
  129 +
  130 + cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
  131 + for(i = 0; i < 6; i++) {
  132 + r = &d->io_regions[i];
  133 + if (r->size != 0) {
  134 + if (r->type & PCI_ADDRESS_SPACE_IO) {
  135 + if (cmd & PCI_COMMAND_IO) {
  136 + new_addr = le32_to_cpu(*(uint32_t *)(d->config +
  137 + 0x10 + i * 4));
  138 + new_addr = new_addr & ~(r->size - 1);
  139 + last_addr = new_addr + r->size - 1;
  140 + /* NOTE: we have only 64K ioports on PC */
  141 + if (last_addr <= new_addr || new_addr == 0 ||
  142 + last_addr >= 0x10000) {
  143 + new_addr = -1;
  144 + }
  145 + } else {
  146 + new_addr = -1;
  147 + }
  148 + } else {
  149 + if (cmd & PCI_COMMAND_MEMORY) {
  150 + new_addr = le32_to_cpu(*(uint32_t *)(d->config +
  151 + 0x10 + i * 4));
  152 + new_addr = new_addr & ~(r->size - 1);
  153 + last_addr = new_addr + r->size - 1;
  154 + /* NOTE: we do not support wrapping */
  155 + /* XXX: as we cannot support really dynamic
  156 + mappings, we handle specific values as invalid
  157 + mappings. */
  158 + if (last_addr <= new_addr || new_addr == 0 ||
  159 + last_addr == -1) {
  160 + new_addr = -1;
  161 + }
  162 + } else {
  163 + new_addr = -1;
  164 + }
  165 + }
  166 + /* now do the real mapping */
  167 + if (new_addr != r->addr) {
  168 + if (r->addr != -1) {
  169 + if (r->type & PCI_ADDRESS_SPACE_IO) {
  170 + int class;
  171 + /* NOTE: specific hack for IDE in PC case:
  172 + only one byte must be mapped. */
  173 + class = d->config[0x0a] | (d->config[0x0b] << 8);
  174 + if (class == 0x0101 && r->size == 4) {
  175 + isa_unassign_ioport(r->addr + 2, 1);
  176 + } else {
  177 + isa_unassign_ioport(r->addr, r->size);
  178 + }
  179 + } else {
  180 + cpu_register_physical_memory(r->addr + pci_mem_base,
  181 + r->size,
  182 + IO_MEM_UNASSIGNED);
  183 + }
  184 + }
  185 + r->addr = new_addr;
  186 + if (r->addr != -1) {
  187 + r->map_func(d, i, r->addr, r->size, r->type);
  188 + }
  189 + }
  190 + }
  191 + }
  192 +}
  193 +
  194 +uint32_t pci_default_read_config(PCIDevice *d,
  195 + uint32_t address, int len)
99 196 {
100   - if (r->addr == -1)
  197 + uint32_t val;
  198 + switch(len) {
  199 + case 1:
  200 + val = d->config[address];
  201 + break;
  202 + case 2:
  203 + val = le16_to_cpu(*(uint16_t *)(d->config + address));
  204 + break;
  205 + default:
  206 + case 4:
  207 + val = le32_to_cpu(*(uint32_t *)(d->config + address));
  208 + break;
  209 + }
  210 + return val;
  211 +}
  212 +
  213 +void pci_default_write_config(PCIDevice *d,
  214 + uint32_t address, uint32_t val, int len)
  215 +{
  216 + int can_write, i;
  217 + uint32_t end;
  218 +
  219 + if (len == 4 && (address >= 0x10 && address < 0x10 + 4 * 6)) {
  220 + PCIIORegion *r;
  221 + int reg;
  222 +
  223 + reg = (address - 0x10) >> 2;
  224 + r = &d->io_regions[reg];
  225 + if (r->size == 0)
  226 + goto default_config;
  227 + /* compute the stored value */
  228 + val &= ~(r->size - 1);
  229 + val |= r->type;
  230 + *(uint32_t *)(d->config + 0x10 + reg * 4) = cpu_to_le32(val);
  231 + pci_update_mappings(d);
101 232 return;
102   -#ifdef DEBUG_PCI
103   - printf("unmap addr=%08x size=%08x\n", r->addr, r->size);
104   -#endif
105   - if (r->type & PCI_ADDRESS_SPACE_IO) {
106   - isa_unassign_ioport(r->addr, r->size);
107   - } else {
108   - cpu_register_physical_memory(r->addr + pci_mem_base, r->size,
109   - IO_MEM_UNASSIGNED);
  233 + }
  234 + default_config:
  235 + /* not efficient, but simple */
  236 + for(i = 0; i < len; i++) {
  237 + /* default read/write accesses */
  238 + switch(address) {
  239 + case 0x00:
  240 + case 0x01:
  241 + case 0x02:
  242 + case 0x03:
  243 + case 0x08:
  244 + case 0x09:
  245 + case 0x0a:
  246 + case 0x0b:
  247 + case 0x0e:
  248 + case 0x3d:
  249 + can_write = 0;
  250 + break;
  251 + default:
  252 + can_write = 1;
  253 + break;
  254 + }
  255 + if (can_write) {
  256 + d->config[address] = val;
  257 + }
  258 + address++;
  259 + val >>= 8;
  260 + }
  261 +
  262 + end = address + len;
  263 + if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
  264 + /* if the command register is modified, we must modify the mappings */
  265 + pci_update_mappings(d);
110 266 }
111 267 }
112 268  
... ... @@ -115,7 +271,7 @@ static void pci_data_write(void *opaque, uint32_t addr,
115 271 {
116 272 PCIBridge *s = opaque;
117 273 PCIDevice **bus, *pci_dev;
118   - int config_addr, reg;
  274 + int config_addr;
119 275  
120 276 #if defined(DEBUG_PCI) && 0
121 277 printf("pci_data_write: addr=%08x val=%08x len=%d\n",
... ... @@ -134,41 +290,11 @@ static void pci_data_write(void *opaque, uint32_t addr,
134 290 if (!pci_dev)
135 291 return;
136 292 config_addr = (s->config_reg & 0xfc) | (addr & 3);
137   -
138 293 #if defined(DEBUG_PCI)
139 294 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
140 295 pci_dev->name, config_addr, val, len);
141 296 #endif
142   - if (len == 4 && (config_addr >= 0x10 && config_addr < 0x10 + 4 * 6)) {
143   - PCIIORegion *r;
144   - reg = (config_addr - 0x10) >> 2;
145   - r = &pci_dev->io_regions[reg];
146   - if (r->size == 0)
147   - goto default_config;
148   - if (val != 0xffffffff && val != 0) {
149   - /* XXX: the memory assignment should be global to handle
150   - overlaps, but it is not needed at this stage */
151   - /* first unmap the old region */
152   - unmap_region(r);
153   - /* change the address */
154   - if (r->type & PCI_ADDRESS_SPACE_IO)
155   - r->addr = val & ~0x3;
156   - else
157   - r->addr = val & ~0xf;
158   -#ifdef DEBUG_PCI
159   - printf("map addr=%08x size=%08x type=%d\n",
160   - r->addr, r->size, r->type);
161   -#endif
162   - r->map_func(pci_dev, reg, r->addr, r->size, r->type);
163   - }
164   - /* now compute the stored value */
165   - val &= ~(r->size - 1);
166   - val |= r->type;
167   - *(uint32_t *)(pci_dev->config + 0x10 + reg * 4) = cpu_to_le32(val);
168   - } else {
169   - default_config:
170   - pci_dev->config_write(pci_dev, config_addr, val, len);
171   - }
  297 + pci_dev->config_write(pci_dev, config_addr, val, len);
172 298 }
173 299  
174 300 static uint32_t pci_data_read(void *opaque, uint32_t addr,
... ... @@ -238,28 +364,13 @@ static uint32_t pci_data_readl(void* opaque, uint32_t addr)
238 364  
239 365 /* i440FX PCI bridge */
240 366  
241   -static uint32_t i440_read_config(PCIDevice *d,
242   - uint32_t address, int len)
243   -{
244   - uint32_t val;
245   - val = 0;
246   - memcpy(&val, d->config + address, len);
247   - return val;
248   -}
249   -
250   -static void i440_write_config(PCIDevice *d,
251   - uint32_t address, uint32_t val, int len)
252   -{
253   - memcpy(d->config + address, &val, len);
254   -}
255   -
256 367 void i440fx_init(void)
257 368 {
258 369 PCIBridge *s = &pci_bridge;
259 370 PCIDevice *d;
260 371  
261   - register_ioport_write(0xcf8, 4, 4, pci_config_writel, s);
262   - register_ioport_read(0xcf8, 4, 4, pci_config_readl, s);
  372 + register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
  373 + register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
263 374  
264 375 register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
265 376 register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
... ... @@ -269,7 +380,7 @@ void i440fx_init(void)
269 380 register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
270 381  
271 382 d = pci_register_device("i440FX", sizeof(PCIDevice), 0, 0,
272   - i440_read_config, i440_write_config);
  383 + NULL, NULL);
273 384  
274 385 d->config[0x00] = 0x86; // vendor_id
275 386 d->config[0x01] = 0x80;
... ... @@ -282,35 +393,295 @@ void i440fx_init(void)
282 393 d->config[0x0e] = 0x01; // header_type
283 394 }
284 395  
285   -/* NOTE: the following should be done by the BIOS */
  396 +/* PIIX3 PCI to ISA bridge */
  397 +
  398 +typedef struct PIIX3State {
  399 + PCIDevice dev;
  400 +} PIIX3State;
  401 +
  402 +PIIX3State *piix3_state;
  403 +
  404 +static void piix3_reset(PIIX3State *d)
  405 +{
  406 + uint8_t *pci_conf = d->dev.config;
  407 +
  408 + pci_conf[0x04] = 0x07; // master, memory and I/O
  409 + pci_conf[0x05] = 0x00;
  410 + pci_conf[0x06] = 0x00;
  411 + pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
  412 + pci_conf[0x4c] = 0x4d;
  413 + pci_conf[0x4e] = 0x03;
  414 + pci_conf[0x4f] = 0x00;
  415 + pci_conf[0x60] = 0x80;
  416 + pci_conf[0x69] = 0x02;
  417 + pci_conf[0x70] = 0x80;
  418 + pci_conf[0x76] = 0x0c;
  419 + pci_conf[0x77] = 0x0c;
  420 + pci_conf[0x78] = 0x02;
  421 + pci_conf[0x79] = 0x00;
  422 + pci_conf[0x80] = 0x00;
  423 + pci_conf[0x82] = 0x00;
  424 + pci_conf[0xa0] = 0x08;
  425 + pci_conf[0xa0] = 0x08;
  426 + pci_conf[0xa2] = 0x00;
  427 + pci_conf[0xa3] = 0x00;
  428 + pci_conf[0xa4] = 0x00;
  429 + pci_conf[0xa5] = 0x00;
  430 + pci_conf[0xa6] = 0x00;
  431 + pci_conf[0xa7] = 0x00;
  432 + pci_conf[0xa8] = 0x0f;
  433 + pci_conf[0xaa] = 0x00;
  434 + pci_conf[0xab] = 0x00;
  435 + pci_conf[0xac] = 0x00;
  436 + pci_conf[0xae] = 0x00;
  437 +}
  438 +
  439 +void piix3_init(void)
  440 +{
  441 + PIIX3State *d;
  442 + uint8_t *pci_conf;
  443 +
  444 + d = (PIIX3State *)pci_register_device("PIIX3", sizeof(PIIX3State),
  445 + 0, -1,
  446 + NULL, NULL);
  447 + piix3_state = d;
  448 + pci_conf = d->dev.config;
  449 +
  450 + pci_conf[0x00] = 0x86; // Intel
  451 + pci_conf[0x01] = 0x80;
  452 + pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
  453 + pci_conf[0x03] = 0x70;
  454 + pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
  455 + pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
  456 + pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
  457 +
  458 + piix3_reset(d);
  459 +}
  460 +
  461 +/***********************************************************/
  462 +/* generic PCI irq support */
  463 +
  464 +/* return the global irq number corresponding to a given device irq
  465 + pin. We could also use the bus number to have a more precise
  466 + mapping. */
  467 +static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  468 +{
  469 + int slot_addend;
  470 + slot_addend = (pci_dev->devfn >> 3);
  471 + return (irq_num + slot_addend) & 3;
  472 +}
  473 +
  474 +/* 0 <= irq_num <= 3. level must be 0 or 1 */
  475 +void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
  476 +{
  477 + int irq_index, shift, pic_irq, pic_level;
  478 + uint32_t *p;
  479 +
  480 + irq_num = pci_slot_get_pirq(pci_dev, irq_num);
  481 + irq_index = pci_dev->irq_index;
  482 + p = &pci_irq_levels[irq_num][irq_index >> 5];
  483 + shift = (irq_index & 0x1f);
  484 + *p = (*p & ~(1 << shift)) | (level << shift);
  485 +
  486 + /* now we change the pic irq level according to the piix irq mappings */
  487 + pic_irq = piix3_state->dev.config[0x60 + irq_num];
  488 + if (pic_irq < 16) {
  489 + /* the pic level is the logical OR of all the PCI irqs mapped
  490 + to it */
  491 + pic_level = 0;
  492 +#if (PCI_IRQ_WORDS == 2)
  493 + pic_level = ((pci_irq_levels[irq_num][0] |
  494 + pci_irq_levels[irq_num][1]) != 0);
  495 +#else
  496 + {
  497 + int i;
  498 + pic_level = 0;
  499 + for(i = 0; i < PCI_IRQ_WORDS; i++) {
  500 + if (pci_irq_levels[irq_num][i]) {
  501 + pic_level = 1;
  502 + break;
  503 + }
  504 + }
  505 + }
  506 +#endif
  507 + pic_set_irq(pic_irq, pic_level);
  508 + }
  509 +}
  510 +
  511 +/***********************************************************/
  512 +/* monitor info on PCI */
  513 +
  514 +static void pci_info_device(PCIDevice *d)
  515 +{
  516 + int i, class;
  517 + PCIIORegion *r;
  518 +
  519 + printf(" Bus %2d, device %3d, function %d:\n",
  520 + d->bus_num, d->devfn >> 3, d->devfn & 7);
  521 + class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
  522 + printf(" ");
  523 + switch(class) {
  524 + case 0x0101:
  525 + printf("IDE controller");
  526 + break;
  527 + case 0x0200:
  528 + printf("Ethernet controller");
  529 + break;
  530 + case 0x0300:
  531 + printf("VGA controller");
  532 + break;
  533 + default:
  534 + printf("Class %04x", class);
  535 + break;
  536 + }
  537 + printf(": PCI device %04x:%04x\n",
  538 + le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
  539 + le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
  540 +
  541 + if (d->config[PCI_INTERRUPT_PIN] != 0) {
  542 + printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
  543 + }
  544 + for(i = 0;i < 6; i++) {
  545 + r = &d->io_regions[i];
  546 + if (r->size != 0) {
  547 + printf(" BAR%d: ", i);
  548 + if (r->type & PCI_ADDRESS_SPACE_IO) {
  549 + printf("I/O at 0x%04x [0x%04x].\n",
  550 + r->addr, r->addr + r->size - 1);
  551 + } else {
  552 + printf("32 bit memory at 0x%08x [0x%08x].\n",
  553 + r->addr, r->addr + r->size - 1);
  554 + }
  555 + }
  556 + }
  557 +}
  558 +
  559 +void pci_info(void)
  560 +{
  561 + PCIBridge *s = &pci_bridge;
  562 + PCIDevice **bus;
  563 + int bus_num, devfn;
  564 +
  565 + for(bus_num = 0; bus_num < 256; bus_num++) {
  566 + bus = s->pci_bus[bus_num];
  567 + if (bus) {
  568 + for(devfn = 0; devfn < 256; devfn++) {
  569 + if (bus[devfn])
  570 + pci_info_device(bus[devfn]);
  571 + }
  572 + }
  573 + }
  574 +}
  575 +
  576 +/***********************************************************/
  577 +/* XXX: the following should be moved to the PC BIOS */
  578 +
  579 +static uint32_t isa_inb(uint32_t addr)
  580 +{
  581 + return cpu_inb(cpu_single_env, addr);
  582 +}
  583 +
  584 +static void isa_outb(uint32_t val, uint32_t addr)
  585 +{
  586 + cpu_outb(cpu_single_env, addr, val);
  587 +}
  588 +
  589 +static uint32_t isa_inw(uint32_t addr)
  590 +{
  591 + return cpu_inw(cpu_single_env, addr);
  592 +}
  593 +
  594 +static void isa_outw(uint32_t val, uint32_t addr)
  595 +{
  596 + cpu_outw(cpu_single_env, addr, val);
  597 +}
  598 +
  599 +static uint32_t isa_inl(uint32_t addr)
  600 +{
  601 + return cpu_inl(cpu_single_env, addr);
  602 +}
  603 +
  604 +static void isa_outl(uint32_t val, uint32_t addr)
  605 +{
  606 + cpu_outl(cpu_single_env, addr, val);
  607 +}
  608 +
  609 +static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
  610 +{
  611 + PCIBridge *s = &pci_bridge;
  612 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  613 + (d->devfn << 8) | addr;
  614 + pci_data_write(s, 0, val, 4);
  615 +}
  616 +
  617 +static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
  618 +{
  619 + PCIBridge *s = &pci_bridge;
  620 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  621 + (d->devfn << 8) | (addr & ~3);
  622 + pci_data_write(s, addr & 3, val, 2);
  623 +}
  624 +
  625 +static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
  626 +{
  627 + PCIBridge *s = &pci_bridge;
  628 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  629 + (d->devfn << 8) | (addr & ~3);
  630 + pci_data_write(s, addr & 3, val, 1);
  631 +}
  632 +
  633 +static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
  634 +{
  635 + PCIBridge *s = &pci_bridge;
  636 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  637 + (d->devfn << 8) | addr;
  638 + return pci_data_read(s, 0, 4);
  639 +}
  640 +
  641 +static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
  642 +{
  643 + PCIBridge *s = &pci_bridge;
  644 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  645 + (d->devfn << 8) | (addr & ~3);
  646 + return pci_data_read(s, addr & 3, 2);
  647 +}
  648 +
  649 +static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
  650 +{
  651 + PCIBridge *s = &pci_bridge;
  652 + s->config_reg = 0x80000000 | (d->bus_num << 16) |
  653 + (d->devfn << 8) | (addr & ~3);
  654 + return pci_data_read(s, addr & 3, 1);
  655 +}
286 656  
287 657 static uint32_t pci_bios_io_addr;
288 658 static uint32_t pci_bios_mem_addr;
  659 +/* host irqs corresponding to PCI irqs A-D */
  660 +static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
289 661  
290 662 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
291 663 {
292   - PCIBridge *s = &pci_bridge;
293 664 PCIIORegion *r;
  665 + uint16_t cmd;
294 666  
295   - s->config_reg = 0x80000000 | (d->bus_num << 16) |
296   - (d->devfn << 8) | (0x10 + region_num * 4);
297   - pci_data_write(s, 0, addr, 4);
  667 + pci_config_writel(d, 0x10 + region_num * 4, addr);
298 668 r = &d->io_regions[region_num];
299 669  
300 670 /* enable memory mappings */
  671 + cmd = pci_config_readw(d, PCI_COMMAND);
301 672 if (r->type & PCI_ADDRESS_SPACE_IO)
302   - d->config[0x04] |= 1;
  673 + cmd |= 1;
303 674 else
304   - d->config[0x04] |= 2;
  675 + cmd |= 2;
  676 + pci_config_writew(d, PCI_COMMAND, cmd);
305 677 }
306 678  
307   -
308 679 static void pci_bios_init_device(PCIDevice *d)
309 680 {
310 681 int class;
311 682 PCIIORegion *r;
312 683 uint32_t *paddr;
313   - int i;
  684 + int i, pin, pic_irq;
314 685  
315 686 class = d->config[0x0a] | (d->config[0x0b] << 8);
316 687 switch(class) {
... ... @@ -321,6 +692,10 @@ static void pci_bios_init_device(PCIDevice *d)
321 692 pci_set_io_region_addr(d, 2, 0x170);
322 693 pci_set_io_region_addr(d, 3, 0x374);
323 694 break;
  695 + case 0x0300:
  696 + /* VGA: map frame buffer to default Bochs VBE address */
  697 + pci_set_io_region_addr(d, 0, 0xE0000000);
  698 + break;
324 699 default:
325 700 /* default memory mappings */
326 701 for(i = 0; i < 6; i++) {
... ... @@ -337,6 +712,14 @@ static void pci_bios_init_device(PCIDevice *d)
337 712 }
338 713 break;
339 714 }
  715 +
  716 + /* map the interrupt */
  717 + pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
  718 + if (pin != 0) {
  719 + pin = pci_slot_get_pirq(d, pin - 1);
  720 + pic_irq = pci_irqs[pin];
  721 + pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
  722 + }
340 723 }
341 724  
342 725 /*
... ... @@ -348,11 +731,25 @@ void pci_bios_init(void)
348 731 {
349 732 PCIBridge *s = &pci_bridge;
350 733 PCIDevice **bus;
351   - int bus_num, devfn;
  734 + int bus_num, devfn, i, irq;
  735 + uint8_t elcr[2];
352 736  
353 737 pci_bios_io_addr = 0xc000;
354 738 pci_bios_mem_addr = 0xf0000000;
355 739  
  740 + /* activate IRQ mappings */
  741 + elcr[0] = 0x00;
  742 + elcr[1] = 0x00;
  743 + for(i = 0; i < 4; i++) {
  744 + irq = pci_irqs[i];
  745 + /* set to trigger level */
  746 + elcr[irq >> 3] |= (1 << (irq & 7));
  747 + /* activate irq remapping in PIIX */
  748 + pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
  749 + }
  750 + isa_outb(elcr[0], 0x4d0);
  751 + isa_outb(elcr[1], 0x4d1);
  752 +
356 753 for(bus_num = 0; bus_num < 256; bus_num++) {
357 754 bus = s->pci_bus[bus_num];
358 755 if (bus) {
... ... @@ -363,5 +760,3 @@ void pci_bios_init(void)
363 760 }
364 761 }
365 762 }
366   -
367   -
... ...