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,6 +25,21 @@
25 25
26 //#define DEBUG_PCI 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 typedef struct PCIBridge { 43 typedef struct PCIBridge {
29 uint32_t config_reg; 44 uint32_t config_reg;
30 PCIDevice **pci_bus[256]; 45 PCIDevice **pci_bus[256];
@@ -32,6 +47,8 @@ typedef struct PCIBridge { @@ -32,6 +47,8 @@ typedef struct PCIBridge {
32 47
33 static PCIBridge pci_bridge; 48 static PCIBridge pci_bridge;
34 target_phys_addr_t pci_mem_base; 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 /* -1 for devfn means auto assign */ 53 /* -1 for devfn means auto assign */
37 PCIDevice *pci_register_device(const char *name, int instance_size, 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,6 +59,9 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
42 PCIBridge *s = &pci_bridge; 59 PCIBridge *s = &pci_bridge;
43 PCIDevice *pci_dev, **bus; 60 PCIDevice *pci_dev, **bus;
44 61
  62 + if (pci_irq_index >= PCI_DEVICES_MAX)
  63 + return NULL;
  64 +
45 if (!s->pci_bus[bus_num]) { 65 if (!s->pci_bus[bus_num]) {
46 s->pci_bus[bus_num] = qemu_mallocz(256 * sizeof(PCIDevice *)); 66 s->pci_bus[bus_num] = qemu_mallocz(256 * sizeof(PCIDevice *));
47 if (!s->pci_bus[bus_num]) 67 if (!s->pci_bus[bus_num])
@@ -62,8 +82,14 @@ PCIDevice *pci_register_device(const char *name, int instance_size, @@ -62,8 +82,14 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
62 pci_dev->bus_num = bus_num; 82 pci_dev->bus_num = bus_num;
63 pci_dev->devfn = devfn; 83 pci_dev->devfn = devfn;
64 pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); 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 pci_dev->config_read = config_read; 90 pci_dev->config_read = config_read;
66 pci_dev->config_write = config_write; 91 pci_dev->config_write = config_write;
  92 + pci_dev->irq_index = pci_irq_index++;
67 bus[devfn] = pci_dev; 93 bus[devfn] = pci_dev;
68 return pci_dev; 94 return pci_dev;
69 } 95 }
@@ -83,30 +109,160 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num, @@ -83,30 +109,160 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
83 r->map_func = map_func; 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 PCIBridge *s = opaque; 114 PCIBridge *s = opaque;
89 s->config_reg = val; 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 PCIBridge *s = opaque; 120 PCIBridge *s = opaque;
95 return s->config_reg; 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 return; 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,7 +271,7 @@ static void pci_data_write(void *opaque, uint32_t addr,
115 { 271 {
116 PCIBridge *s = opaque; 272 PCIBridge *s = opaque;
117 PCIDevice **bus, *pci_dev; 273 PCIDevice **bus, *pci_dev;
118 - int config_addr, reg; 274 + int config_addr;
119 275
120 #if defined(DEBUG_PCI) && 0 276 #if defined(DEBUG_PCI) && 0
121 printf("pci_data_write: addr=%08x val=%08x len=%d\n", 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,41 +290,11 @@ static void pci_data_write(void *opaque, uint32_t addr,
134 if (!pci_dev) 290 if (!pci_dev)
135 return; 291 return;
136 config_addr = (s->config_reg & 0xfc) | (addr & 3); 292 config_addr = (s->config_reg & 0xfc) | (addr & 3);
137 -  
138 #if defined(DEBUG_PCI) 293 #if defined(DEBUG_PCI)
139 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n", 294 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
140 pci_dev->name, config_addr, val, len); 295 pci_dev->name, config_addr, val, len);
141 #endif 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 static uint32_t pci_data_read(void *opaque, uint32_t addr, 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,28 +364,13 @@ static uint32_t pci_data_readl(void* opaque, uint32_t addr)
238 364
239 /* i440FX PCI bridge */ 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 void i440fx_init(void) 367 void i440fx_init(void)
257 { 368 {
258 PCIBridge *s = &pci_bridge; 369 PCIBridge *s = &pci_bridge;
259 PCIDevice *d; 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 register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s); 375 register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
265 register_ioport_write(0xcfc, 4, 2, pci_data_writew, s); 376 register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
@@ -269,7 +380,7 @@ void i440fx_init(void) @@ -269,7 +380,7 @@ void i440fx_init(void)
269 register_ioport_read(0xcfc, 4, 4, pci_data_readl, s); 380 register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
270 381
271 d = pci_register_device("i440FX", sizeof(PCIDevice), 0, 0, 382 d = pci_register_device("i440FX", sizeof(PCIDevice), 0, 0,
272 - i440_read_config, i440_write_config); 383 + NULL, NULL);
273 384
274 d->config[0x00] = 0x86; // vendor_id 385 d->config[0x00] = 0x86; // vendor_id
275 d->config[0x01] = 0x80; 386 d->config[0x01] = 0x80;
@@ -282,35 +393,295 @@ void i440fx_init(void) @@ -282,35 +393,295 @@ void i440fx_init(void)
282 d->config[0x0e] = 0x01; // header_type 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 static uint32_t pci_bios_io_addr; 657 static uint32_t pci_bios_io_addr;
288 static uint32_t pci_bios_mem_addr; 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 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) 662 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
291 { 663 {
292 - PCIBridge *s = &pci_bridge;  
293 PCIIORegion *r; 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 r = &d->io_regions[region_num]; 668 r = &d->io_regions[region_num];
299 669
300 /* enable memory mappings */ 670 /* enable memory mappings */
  671 + cmd = pci_config_readw(d, PCI_COMMAND);
301 if (r->type & PCI_ADDRESS_SPACE_IO) 672 if (r->type & PCI_ADDRESS_SPACE_IO)
302 - d->config[0x04] |= 1; 673 + cmd |= 1;
303 else 674 else
304 - d->config[0x04] |= 2; 675 + cmd |= 2;
  676 + pci_config_writew(d, PCI_COMMAND, cmd);
305 } 677 }
306 678
307 -  
308 static void pci_bios_init_device(PCIDevice *d) 679 static void pci_bios_init_device(PCIDevice *d)
309 { 680 {
310 int class; 681 int class;
311 PCIIORegion *r; 682 PCIIORegion *r;
312 uint32_t *paddr; 683 uint32_t *paddr;
313 - int i; 684 + int i, pin, pic_irq;
314 685
315 class = d->config[0x0a] | (d->config[0x0b] << 8); 686 class = d->config[0x0a] | (d->config[0x0b] << 8);
316 switch(class) { 687 switch(class) {
@@ -321,6 +692,10 @@ static void pci_bios_init_device(PCIDevice *d) @@ -321,6 +692,10 @@ static void pci_bios_init_device(PCIDevice *d)
321 pci_set_io_region_addr(d, 2, 0x170); 692 pci_set_io_region_addr(d, 2, 0x170);
322 pci_set_io_region_addr(d, 3, 0x374); 693 pci_set_io_region_addr(d, 3, 0x374);
323 break; 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 default: 699 default:
325 /* default memory mappings */ 700 /* default memory mappings */
326 for(i = 0; i < 6; i++) { 701 for(i = 0; i < 6; i++) {
@@ -337,6 +712,14 @@ static void pci_bios_init_device(PCIDevice *d) @@ -337,6 +712,14 @@ static void pci_bios_init_device(PCIDevice *d)
337 } 712 }
338 break; 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,11 +731,25 @@ void pci_bios_init(void)
348 { 731 {
349 PCIBridge *s = &pci_bridge; 732 PCIBridge *s = &pci_bridge;
350 PCIDevice **bus; 733 PCIDevice **bus;
351 - int bus_num, devfn; 734 + int bus_num, devfn, i, irq;
  735 + uint8_t elcr[2];
352 736
353 pci_bios_io_addr = 0xc000; 737 pci_bios_io_addr = 0xc000;
354 pci_bios_mem_addr = 0xf0000000; 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 for(bus_num = 0; bus_num < 256; bus_num++) { 753 for(bus_num = 0; bus_num < 256; bus_num++) {
357 bus = s->pci_bus[bus_num]; 754 bus = s->pci_bus[bus_num];
358 if (bus) { 755 if (bus) {
@@ -363,5 +760,3 @@ void pci_bios_init(void) @@ -363,5 +760,3 @@ void pci_bios_init(void)
363 } 760 }
364 } 761 }
365 } 762 }
366 -  
367 -