121
132
static void i440fx_update_memory_mappings(PCII440FXState *d)
135
PCIDevice *pd = PCI_DEVICE(d);
125
137
memory_region_transaction_begin();
126
138
for (i = 0; i < 13; i++) {
127
139
pam_update(&d->pam_regions[i], i,
128
d->dev.config[I440FX_PAM + ((i + 1) / 2)]);
140
pd->config[I440FX_PAM + ((i + 1) / 2)]);
130
smram_update(&d->smram_region, d->dev.config[I440FX_SMRAM], d->smm_enabled);
142
smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
131
143
memory_region_transaction_commit();
134
146
static void i440fx_set_smm(int val, void *arg)
136
148
PCII440FXState *d = arg;
149
PCIDevice *pd = PCI_DEVICE(d);
138
151
memory_region_transaction_begin();
139
smram_set_smm(&d->smm_enabled, val, d->dev.config[I440FX_SMRAM],
152
smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
140
153
&d->smram_region);
141
154
memory_region_transaction_commit();
191
205
.load_state_old = i440fx_load_old,
192
206
.post_load = i440fx_post_load,
193
207
.fields = (VMStateField []) {
194
VMSTATE_PCI_DEVICE(dev, PCII440FXState),
208
VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
195
209
VMSTATE_UINT8(smm_enabled, PCII440FXState),
196
210
VMSTATE_END_OF_LIST()
200
static int i440fx_pcihost_initfn(SysBusDevice *dev)
202
PCIHostState *s = PCI_HOST_BRIDGE(dev);
204
memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
214
static void i440fx_pcihost_get_pci_hole_start(Object *obj, Visitor *v,
215
void *opaque, const char *name,
218
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
219
uint32_t value = s->pci_info.w32.begin;
221
visit_type_uint32(v, &value, name, errp);
224
static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
225
void *opaque, const char *name,
228
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
229
uint32_t value = s->pci_info.w32.end;
231
visit_type_uint32(v, &value, name, errp);
234
static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
235
void *opaque, const char *name,
238
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
240
visit_type_uint64(v, &s->pci_info.w64.begin, name, errp);
243
static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
244
void *opaque, const char *name,
247
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
249
visit_type_uint64(v, &s->pci_info.w64.end, name, errp);
252
static void i440fx_pcihost_initfn(Object *obj)
254
PCIHostState *s = PCI_HOST_BRIDGE(obj);
255
I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
257
memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
205
258
"pci-conf-idx", 4);
206
sysbus_add_io(dev, 0xcf8, &s->conf_mem);
207
sysbus_init_ioports(&s->busdev, 0xcf8, 4);
209
memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
259
memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
210
260
"pci-conf-data", 4);
211
sysbus_add_io(dev, 0xcfc, &s->data_mem);
212
sysbus_init_ioports(&s->busdev, 0xcfc, 4);
262
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
263
i440fx_pcihost_get_pci_hole_start,
264
NULL, NULL, NULL, NULL);
266
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
267
i440fx_pcihost_get_pci_hole_end,
268
NULL, NULL, NULL, NULL);
270
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
271
i440fx_pcihost_get_pci_hole64_start,
272
NULL, NULL, NULL, NULL);
274
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
275
i440fx_pcihost_get_pci_hole64_end,
276
NULL, NULL, NULL, NULL);
278
d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
281
static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
283
PCIHostState *s = PCI_HOST_BRIDGE(dev);
284
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
286
sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
287
sysbus_init_ioports(sbd, 0xcf8, 4);
289
sysbus_add_io(sbd, 0xcfc, &s->data_mem);
290
sysbus_init_ioports(sbd, 0xcfc, 4);
217
293
static int i440fx_initfn(PCIDevice *dev)
219
295
PCII440FXState *d = I440FX_PCI_DEVICE(dev);
221
d->dev.config[I440FX_SMRAM] = 0x02;
297
dev->config[I440FX_SMRAM] = 0x02;
223
299
cpu_smm_register(&i440fx_set_smm, d);
227
static PCIBus *i440fx_common_init(const char *device_name,
228
PCII440FXState **pi440fx_state,
230
ISABus **isa_bus, qemu_irq *pic,
231
MemoryRegion *address_space_mem,
232
MemoryRegion *address_space_io,
234
hwaddr pci_hole_start,
235
hwaddr pci_hole_size,
236
hwaddr pci_hole64_start,
237
hwaddr pci_hole64_size,
238
MemoryRegion *pci_address_space,
239
MemoryRegion *ram_memory)
303
PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
305
ISABus **isa_bus, qemu_irq *pic,
306
MemoryRegion *address_space_mem,
307
MemoryRegion *address_space_io,
309
hwaddr pci_hole_start,
310
hwaddr pci_hole_size,
311
ram_addr_t above_4g_mem_size,
312
MemoryRegion *pci_address_space,
313
MemoryRegion *ram_memory)
241
315
DeviceState *dev;
254
330
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
255
331
qdev_init_nofail(dev);
257
d = pci_create_simple(b, 0, device_name);
333
d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
258
334
*pi440fx_state = I440FX_PCI_DEVICE(d);
259
335
f = *pi440fx_state;
260
336
f->system_memory = address_space_mem;
261
337
f->pci_address_space = pci_address_space;
262
338
f->ram_memory = ram_memory;
263
memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space,
340
i440fx = I440FX_PCI_HOST_BRIDGE(dev);
341
/* Set PCI window size the way seabios has always done it. */
342
/* Power of 2 so bios can cover it with a single MTRR */
343
if (ram_size <= 0x80000000) {
344
i440fx->pci_info.w32.begin = 0x80000000;
345
} else if (ram_size <= 0xc0000000) {
346
i440fx->pci_info.w32.begin = 0xc0000000;
348
i440fx->pci_info.w32.begin = 0xe0000000;
351
memory_region_init_alias(&f->pci_hole, OBJECT(d), "pci-hole", f->pci_address_space,
264
352
pci_hole_start, pci_hole_size);
265
353
memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
266
memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64",
355
pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
357
pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
359
memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
267
360
f->pci_address_space,
268
pci_hole64_start, pci_hole64_size);
361
i440fx->pci_info.w64.begin,
269
363
if (pci_hole64_size) {
270
memory_region_add_subregion(f->system_memory, pci_hole64_start,
364
memory_region_add_subregion(f->system_memory,
365
i440fx->pci_info.w64.begin,
271
366
&f->pci_hole_64bit);
273
memory_region_init_alias(&f->smram_region, "smram-region",
368
memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
274
369
f->pci_address_space, 0xa0000, 0x20000);
275
370
memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
276
371
&f->smram_region, 1);
277
372
memory_region_set_enabled(&f->smram_region, false);
278
init_pam(f->ram_memory, f->system_memory, f->pci_address_space,
373
init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
279
374
&f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
280
375
for (i = 0; i < 12; ++i) {
281
init_pam(f->ram_memory, f->system_memory, f->pci_address_space,
376
init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
282
377
&f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
305
400
*piix3_devfn = piix3->dev.devfn;
307
402
ram_size = ram_size / 8 / 1024 / 1024;
403
if (ram_size > 255) {
310
(*pi440fx_state)->dev.config[0x57]=ram_size;
406
d->config[0x57] = ram_size;
312
408
i440fx_update_memory_mappings(f);
317
PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
318
ISABus **isa_bus, qemu_irq *pic,
319
MemoryRegion *address_space_mem,
320
MemoryRegion *address_space_io,
322
hwaddr pci_hole_start,
323
hwaddr pci_hole_size,
324
hwaddr pci_hole64_start,
325
hwaddr pci_hole64_size,
326
MemoryRegion *pci_memory, MemoryRegion *ram_memory)
331
b = i440fx_common_init(TYPE_I440FX_PCI_DEVICE, pi440fx_state,
332
piix3_devfn, isa_bus, pic,
333
address_space_mem, address_space_io, ram_size,
334
pci_hole_start, pci_hole_size,
335
pci_hole64_start, pci_hole64_size,
336
pci_memory, ram_memory);
340
413
/* PIIX3 PCI to ISA bridge */
341
414
static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
629
703
.class_init = i440fx_class_init,
706
static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
709
/* For backwards compat with old device paths */
713
static Property i440fx_props[] = {
714
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
715
pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
716
DEFINE_PROP_END_OF_LIST(),
632
719
static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
634
721
DeviceClass *dc = DEVICE_CLASS(klass);
635
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
722
PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
637
k->init = i440fx_pcihost_initfn;
724
hc->root_bus_path = i440fx_pcihost_root_bus_path;
725
dc->realize = i440fx_pcihost_realize;
638
726
dc->fw_name = "pci";
728
dc->props = i440fx_props;
642
731
static const TypeInfo i440fx_pcihost_info = {
643
.name = "i440FX-pcihost",
732
.name = TYPE_I440FX_PCI_HOST_BRIDGE,
644
733
.parent = TYPE_PCI_HOST_BRIDGE,
645
734
.instance_size = sizeof(I440FXState),
735
.instance_init = i440fx_pcihost_initfn,
646
736
.class_init = i440fx_pcihost_class_init,