~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/pci-host/piix.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "hw/xen/xen.h"
33
33
#include "hw/pci-host/pam.h"
34
34
#include "sysemu/sysemu.h"
 
35
#include "hw/i386/ioapic.h"
 
36
#include "qapi/visitor.h"
35
37
 
36
38
/*
37
39
 * I440FX chipset data sheet.
38
40
 * http://download.intel.com/design/chipsets/datashts/29054901.pdf
39
41
 */
40
42
 
 
43
#define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost"
 
44
#define I440FX_PCI_HOST_BRIDGE(obj) \
 
45
    OBJECT_CHECK(I440FXState, (obj), TYPE_I440FX_PCI_HOST_BRIDGE)
 
46
 
41
47
typedef struct I440FXState {
42
48
    PCIHostState parent_obj;
 
49
    PcPciInfo pci_info;
 
50
    uint64_t pci_hole64_size;
43
51
} I440FXState;
44
52
 
45
53
#define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
87
95
    OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
88
96
 
89
97
struct PCII440FXState {
90
 
    PCIDevice dev;
 
98
    /*< private >*/
 
99
    PCIDevice parent_obj;
 
100
    /*< public >*/
 
101
 
91
102
    MemoryRegion *system_memory;
92
103
    MemoryRegion *pci_address_space;
93
104
    MemoryRegion *ram_memory;
121
132
static void i440fx_update_memory_mappings(PCII440FXState *d)
122
133
{
123
134
    int i;
 
135
    PCIDevice *pd = PCI_DEVICE(d);
124
136
 
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)]);
129
141
    }
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();
132
144
}
133
145
 
134
146
static void i440fx_set_smm(int val, void *arg)
135
147
{
136
148
    PCII440FXState *d = arg;
 
149
    PCIDevice *pd = PCI_DEVICE(d);
137
150
 
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();
142
155
}
158
171
static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
159
172
{
160
173
    PCII440FXState *d = opaque;
 
174
    PCIDevice *pd = PCI_DEVICE(d);
161
175
    int ret, i;
162
176
 
163
 
    ret = pci_device_load(&d->dev, f);
 
177
    ret = pci_device_load(pd, f);
164
178
    if (ret < 0)
165
179
        return ret;
166
180
    i440fx_update_memory_mappings(d);
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()
197
211
    }
198
212
};
199
213
 
200
 
static int i440fx_pcihost_initfn(SysBusDevice *dev)
201
 
{
202
 
    PCIHostState *s = PCI_HOST_BRIDGE(dev);
203
 
 
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,
 
216
                                              Error **errp)
 
217
{
 
218
    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
 
219
    uint32_t value = s->pci_info.w32.begin;
 
220
 
 
221
    visit_type_uint32(v, &value, name, errp);
 
222
}
 
223
 
 
224
static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
 
225
                                            void *opaque, const char *name,
 
226
                                            Error **errp)
 
227
{
 
228
    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
 
229
    uint32_t value = s->pci_info.w32.end;
 
230
 
 
231
    visit_type_uint32(v, &value, name, errp);
 
232
}
 
233
 
 
234
static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
 
235
                                                void *opaque, const char *name,
 
236
                                                Error **errp)
 
237
{
 
238
    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
 
239
 
 
240
    visit_type_uint64(v, &s->pci_info.w64.begin, name, errp);
 
241
}
 
242
 
 
243
static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
 
244
                                              void *opaque, const char *name,
 
245
                                              Error **errp)
 
246
{
 
247
    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
 
248
 
 
249
    visit_type_uint64(v, &s->pci_info.w64.end, name, errp);
 
250
}
 
251
 
 
252
static void i440fx_pcihost_initfn(Object *obj)
 
253
{
 
254
    PCIHostState *s = PCI_HOST_BRIDGE(obj);
 
255
    I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
 
256
 
 
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);
208
 
 
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);
213
 
 
214
 
    return 0;
 
261
 
 
262
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
 
263
                        i440fx_pcihost_get_pci_hole_start,
 
264
                        NULL, NULL, NULL, NULL);
 
265
 
 
266
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
 
267
                        i440fx_pcihost_get_pci_hole_end,
 
268
                        NULL, NULL, NULL, NULL);
 
269
 
 
270
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
 
271
                        i440fx_pcihost_get_pci_hole64_start,
 
272
                        NULL, NULL, NULL, NULL);
 
273
 
 
274
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
 
275
                        i440fx_pcihost_get_pci_hole64_end,
 
276
                        NULL, NULL, NULL, NULL);
 
277
 
 
278
    d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
 
279
}
 
280
 
 
281
static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
 
282
{
 
283
    PCIHostState *s = PCI_HOST_BRIDGE(dev);
 
284
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
285
 
 
286
    sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
 
287
    sysbus_init_ioports(sbd, 0xcf8, 4);
 
288
 
 
289
    sysbus_add_io(sbd, 0xcfc, &s->data_mem);
 
290
    sysbus_init_ioports(sbd, 0xcfc, 4);
215
291
}
216
292
 
217
293
static int i440fx_initfn(PCIDevice *dev)
218
294
{
219
295
    PCII440FXState *d = I440FX_PCI_DEVICE(dev);
220
296
 
221
 
    d->dev.config[I440FX_SMRAM] = 0x02;
 
297
    dev->config[I440FX_SMRAM] = 0x02;
222
298
 
223
299
    cpu_smm_register(&i440fx_set_smm, d);
224
300
    return 0;
225
301
}
226
302
 
227
 
static PCIBus *i440fx_common_init(const char *device_name,
228
 
                                  PCII440FXState **pi440fx_state,
229
 
                                  int *piix3_devfn,
230
 
                                  ISABus **isa_bus, qemu_irq *pic,
231
 
                                  MemoryRegion *address_space_mem,
232
 
                                  MemoryRegion *address_space_io,
233
 
                                  ram_addr_t ram_size,
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,
 
304
                    int *piix3_devfn,
 
305
                    ISABus **isa_bus, qemu_irq *pic,
 
306
                    MemoryRegion *address_space_mem,
 
307
                    MemoryRegion *address_space_io,
 
308
                    ram_addr_t ram_size,
 
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)
240
314
{
241
315
    DeviceState *dev;
242
316
    PCIBus *b;
245
319
    PIIX3State *piix3;
246
320
    PCII440FXState *f;
247
321
    unsigned i;
 
322
    I440FXState *i440fx;
 
323
    uint64_t pci_hole64_size;
248
324
 
249
 
    dev = qdev_create(NULL, "i440FX-pcihost");
 
325
    dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
250
326
    s = PCI_HOST_BRIDGE(dev);
251
327
    b = pci_bus_new(dev, NULL, pci_address_space,
252
328
                    address_space_io, 0, TYPE_PCI_BUS);
254
330
    object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
255
331
    qdev_init_nofail(dev);
256
332
 
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,
 
339
 
 
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;
 
347
    } else {
 
348
        i440fx->pci_info.w32.begin = 0xe0000000;
 
349
    }
 
350
 
 
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",
 
354
 
 
355
    pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
 
356
 
 
357
    pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
 
358
                       pci_hole64_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,
 
362
                             pci_hole64_size);
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);
272
367
    }
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,
283
378
                 PAM_EXPAN_SIZE);
284
379
    }
305
400
    *piix3_devfn = piix3->dev.devfn;
306
401
 
307
402
    ram_size = ram_size / 8 / 1024 / 1024;
308
 
    if (ram_size > 255)
 
403
    if (ram_size > 255) {
309
404
        ram_size = 255;
310
 
    (*pi440fx_state)->dev.config[0x57]=ram_size;
 
405
    }
 
406
    d->config[0x57] = ram_size;
311
407
 
312
408
    i440fx_update_memory_mappings(f);
313
409
 
314
410
    return b;
315
411
}
316
412
 
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,
321
 
                    ram_addr_t ram_size,
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)
327
 
 
328
 
{
329
 
    PCIBus *b;
330
 
 
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);
337
 
    return b;
338
 
}
339
 
 
340
413
/* PIIX3 PCI to ISA bridge */
341
414
static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
342
415
{
549
622
 
550
623
    isa_bus_new(DEVICE(d), pci_address_space_io(dev));
551
624
 
552
 
    memory_region_init_io(&d->rcr_mem, &rcr_ops, d, "piix3-reset-control", 1);
 
625
    memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d,
 
626
                          "piix3-reset-control", 1);
553
627
    memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT,
554
628
                                        &d->rcr_mem, 1);
555
629
 
629
703
    .class_init    = i440fx_class_init,
630
704
};
631
705
 
 
706
static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
 
707
                                                PCIBus *rootbus)
 
708
{
 
709
    /* For backwards compat with old device paths */
 
710
    return "0000";
 
711
}
 
712
 
 
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(),
 
717
};
 
718
 
632
719
static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
633
720
{
634
721
    DeviceClass *dc = DEVICE_CLASS(klass);
635
 
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
722
    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
636
723
 
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";
639
727
    dc->no_user = 1;
 
728
    dc->props = i440fx_props;
640
729
}
641
730
 
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,
647
737
};
648
738