Revision e735b55a hw/piix_pci.c
b/hw/piix_pci.c | ||
---|---|---|
37 | 37 |
|
38 | 38 |
typedef PCIHostState I440FXState; |
39 | 39 |
|
40 |
#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ |
|
41 |
|
|
40 | 42 |
typedef struct PIIX3State { |
41 | 43 |
PCIDevice dev; |
42 |
int pci_irq_levels[4]; |
|
43 | 44 |
qemu_irq *pic; |
45 |
|
|
46 |
/* This member isn't used. Just for save/load compatibility */ |
|
47 |
int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS]; |
|
44 | 48 |
} PIIX3State; |
45 | 49 |
|
46 | 50 |
struct PCII440FXState { |
... | ... | |
162 | 166 |
i440fx_update_memory_mappings(d); |
163 | 167 |
qemu_get_8s(f, &d->smm_enabled); |
164 | 168 |
|
165 |
if (version_id == 2) |
|
166 |
for (i = 0; i < 4; i++) |
|
167 |
d->piix3->pci_irq_levels[i] = qemu_get_be32(f); |
|
169 |
if (version_id == 2) { |
|
170 |
for (i = 0; i < PIIX_NUM_PIRQS; i++) { |
|
171 |
qemu_get_be32(f); /* dummy load for compatibility */ |
|
172 |
} |
|
173 |
} |
|
168 | 174 |
|
169 | 175 |
return 0; |
170 | 176 |
} |
... | ... | |
236 | 242 |
piix3 = DO_UPCAST(PIIX3State, dev, |
237 | 243 |
pci_create_simple_multifunction(b, -1, true, "PIIX3")); |
238 | 244 |
piix3->pic = pic; |
239 |
pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
|
|
245 |
pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS);
|
|
240 | 246 |
(*pi440fx_state)->piix3 = piix3; |
241 | 247 |
|
242 | 248 |
*piix3_devfn = piix3->dev.devfn; |
... | ... | |
256 | 262 |
int i, pic_irq, pic_level; |
257 | 263 |
PIIX3State *piix3 = opaque; |
258 | 264 |
|
259 |
piix3->pci_irq_levels[irq_num] = level; |
|
260 |
|
|
261 | 265 |
/* now we change the pic irq level according to the piix irq mappings */ |
262 | 266 |
/* XXX: optimize */ |
263 | 267 |
pic_irq = piix3->dev.config[0x60 + irq_num]; |
... | ... | |
266 | 270 |
to it */ |
267 | 271 |
pic_level = 0; |
268 | 272 |
for (i = 0; i < 4; i++) { |
269 |
if (pic_irq == piix3->dev.config[0x60 + i]) |
|
270 |
pic_level |= piix3->pci_irq_levels[i]; |
|
273 |
if (pic_irq == piix3->dev.config[0x60 + i]) { |
|
274 |
pic_level |= pci_bus_get_irq_level(piix3->dev.bus, i); |
|
275 |
} |
|
271 | 276 |
} |
272 | 277 |
qemu_set_irq(piix3->pic[pic_irq], pic_level); |
273 | 278 |
} |
... | ... | |
309 | 314 |
pci_conf[0xab] = 0x00; |
310 | 315 |
pci_conf[0xac] = 0x00; |
311 | 316 |
pci_conf[0xae] = 0x00; |
317 |
} |
|
312 | 318 |
|
313 |
memset(d->pci_irq_levels, 0, sizeof(d->pci_irq_levels)); |
|
319 |
static void piix3_pre_save(void *opaque) |
|
320 |
{ |
|
321 |
int i; |
|
322 |
PIIX3State *piix3 = opaque; |
|
323 |
|
|
324 |
for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) { |
|
325 |
piix3->pci_irq_levels_vmstate[i] = |
|
326 |
pci_bus_get_irq_level(piix3->dev.bus, i); |
|
327 |
} |
|
314 | 328 |
} |
315 | 329 |
|
316 | 330 |
static const VMStateDescription vmstate_piix3 = { |
... | ... | |
318 | 332 |
.version_id = 3, |
319 | 333 |
.minimum_version_id = 2, |
320 | 334 |
.minimum_version_id_old = 2, |
335 |
.pre_save = piix3_pre_save, |
|
321 | 336 |
.fields = (VMStateField []) { |
322 | 337 |
VMSTATE_PCI_DEVICE(dev, PIIX3State), |
323 |
VMSTATE_INT32_ARRAY_V(pci_irq_levels, PIIX3State, 4, 3), |
|
338 |
VMSTATE_INT32_ARRAY_V(pci_irq_levels_vmstate, PIIX3State, |
|
339 |
PIIX_NUM_PIRQS, 3), |
|
324 | 340 |
VMSTATE_END_OF_LIST() |
325 | 341 |
} |
326 | 342 |
}; |
Also available in: Unified diff