Revision 7cd9eee0
b/hw/piix_pci.c | ||
---|---|---|
36 | 36 |
typedef struct PIIX3State { |
37 | 37 |
PCIDevice dev; |
38 | 38 |
int pci_irq_levels[4]; |
39 |
} PIIX3State; |
|
40 |
|
|
41 |
typedef struct PIIX3IrqState { |
|
42 |
PIIX3State *piix3; |
|
43 | 39 |
qemu_irq *pic; |
44 |
} PIIX3IrqState;
|
|
40 |
} PIIX3State; |
|
45 | 41 |
|
46 | 42 |
struct PCII440FXState { |
47 | 43 |
PCIDevice dev; |
48 | 44 |
target_phys_addr_t isa_page_descs[384 / 4]; |
49 | 45 |
uint8_t smm_enabled; |
50 |
PIIX3IrqState *irq_state;
|
|
46 |
PIIX3State *piix3;
|
|
51 | 47 |
}; |
52 | 48 |
|
53 | 49 |
static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val) |
... | ... | |
167 | 163 |
|
168 | 164 |
if (version_id == 2) |
169 | 165 |
for (i = 0; i < 4; i++) |
170 |
d->irq_state->piix3->pci_irq_levels[i] = qemu_get_be32(f);
|
|
166 |
d->piix3->pci_irq_levels[i] = qemu_get_be32(f); |
|
171 | 167 |
|
172 | 168 |
return 0; |
173 | 169 |
} |
... | ... | |
232 | 228 |
PCIBus *b; |
233 | 229 |
PCIDevice *d; |
234 | 230 |
I440FXState *s; |
235 |
PIIX3IrqState *irq_state = qemu_malloc(sizeof(*irq_state));
|
|
231 |
PIIX3State *piix3;
|
|
236 | 232 |
|
237 |
irq_state->pic = pic; |
|
238 | 233 |
dev = qdev_create(NULL, "i440FX-pcihost"); |
239 | 234 |
s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev)); |
240 |
b = pci_register_bus(&s->busdev.qdev, "pci.0", |
|
241 |
piix3_set_irq, pci_slot_get_pirq, irq_state, 0, 4); |
|
235 |
b = pci_bus_new(&s->busdev.qdev, NULL, 0); |
|
242 | 236 |
s->bus = b; |
243 | 237 |
qdev_init(dev); |
244 | 238 |
|
245 | 239 |
d = pci_create_simple(b, 0, "i440FX"); |
246 | 240 |
*pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); |
247 |
(*pi440fx_state)->irq_state = irq_state; |
|
248 | 241 |
|
249 |
irq_state->piix3 = DO_UPCAST(PIIX3State, dev,
|
|
242 |
piix3 = DO_UPCAST(PIIX3State, dev, |
|
250 | 243 |
pci_create_simple(b, -1, "PIIX3")); |
251 |
*piix3_devfn = irq_state->piix3->dev.devfn; |
|
244 |
piix3->pic = pic; |
|
245 |
pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); |
|
246 |
(*pi440fx_state)->piix3 = piix3; |
|
247 |
|
|
248 |
*piix3_devfn = piix3->dev.devfn; |
|
252 | 249 |
|
253 | 250 |
return b; |
254 | 251 |
} |
... | ... | |
258 | 255 |
static void piix3_set_irq(void *opaque, int irq_num, int level) |
259 | 256 |
{ |
260 | 257 |
int i, pic_irq, pic_level; |
261 |
PIIX3IrqState *irq_state = opaque;
|
|
258 |
PIIX3State *piix3 = opaque;
|
|
262 | 259 |
|
263 |
irq_state->piix3->pci_irq_levels[irq_num] = level;
|
|
260 |
piix3->pci_irq_levels[irq_num] = level; |
|
264 | 261 |
|
265 | 262 |
/* now we change the pic irq level according to the piix irq mappings */ |
266 | 263 |
/* XXX: optimize */ |
267 |
pic_irq = irq_state->piix3->dev.config[0x60 + irq_num];
|
|
264 |
pic_irq = piix3->dev.config[0x60 + irq_num]; |
|
268 | 265 |
if (pic_irq < 16) { |
269 | 266 |
/* The pic level is the logical OR of all the PCI irqs mapped |
270 | 267 |
to it */ |
271 | 268 |
pic_level = 0; |
272 | 269 |
for (i = 0; i < 4; i++) { |
273 |
if (pic_irq == irq_state->piix3->dev.config[0x60 + i])
|
|
274 |
pic_level |= irq_state->piix3->pci_irq_levels[i];
|
|
270 |
if (pic_irq == piix3->dev.config[0x60 + i]) |
|
271 |
pic_level |= piix3->pci_irq_levels[i]; |
|
275 | 272 |
} |
276 |
qemu_set_irq(irq_state->pic[pic_irq], pic_level);
|
|
273 |
qemu_set_irq(piix3->pic[pic_irq], pic_level);
|
|
277 | 274 |
} |
278 | 275 |
} |
279 | 276 |
|
Also available in: Unified diff