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

« back to all changes in this revision

Viewing changes to .pc/1.6.1.patch/hw/pci-host/q35.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:
 
1
/*
 
2
 * QEMU MCH/ICH9 PCI Bridge Emulation
 
3
 *
 
4
 * Copyright (c) 2006 Fabrice Bellard
 
5
 * Copyright (c) 2009, 2010, 2011
 
6
 *               Isaku Yamahata <yamahata at valinux co jp>
 
7
 *               VA Linux Systems Japan K.K.
 
8
 * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
 
9
 *
 
10
 * This is based on piix_pci.c, but heavily modified.
 
11
 *
 
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
13
 * of this software and associated documentation files (the "Software"), to deal
 
14
 * in the Software without restriction, including without limitation the rights
 
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
16
 * copies of the Software, and to permit persons to whom the Software is
 
17
 * furnished to do so, subject to the following conditions:
 
18
 *
 
19
 * The above copyright notice and this permission notice shall be included in
 
20
 * all copies or substantial portions of the Software.
 
21
 *
 
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
25
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
28
 * THE SOFTWARE.
 
29
 */
 
30
#include "hw/hw.h"
 
31
#include "hw/pci-host/q35.h"
 
32
#include "qapi/visitor.h"
 
33
 
 
34
/****************************************************************************
 
35
 * Q35 host
 
36
 */
 
37
 
 
38
static void q35_host_realize(DeviceState *dev, Error **errp)
 
39
{
 
40
    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
 
41
    Q35PCIHost *s = Q35_HOST_DEVICE(dev);
 
42
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
43
 
 
44
    sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
 
45
    sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
 
46
 
 
47
    sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
 
48
    sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
 
49
 
 
50
    if (pcie_host_init(PCIE_HOST_BRIDGE(s)) < 0) {
 
51
        error_setg(errp, "failed to initialize pcie host");
 
52
        return;
 
53
    }
 
54
    pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
 
55
                           s->mch.pci_address_space, s->mch.address_space_io,
 
56
                           0, TYPE_PCIE_BUS);
 
57
    qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
 
58
    qdev_init_nofail(DEVICE(&s->mch));
 
59
}
 
60
 
 
61
static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
 
62
                                          PCIBus *rootbus)
 
63
{
 
64
    /* For backwards compat with old device paths */
 
65
    return "0000";
 
66
}
 
67
 
 
68
static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
 
69
                                        void *opaque, const char *name,
 
70
                                        Error **errp)
 
71
{
 
72
    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
 
73
    uint32_t value = s->mch.pci_info.w32.begin;
 
74
 
 
75
    visit_type_uint32(v, &value, name, errp);
 
76
}
 
77
 
 
78
static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
 
79
                                      void *opaque, const char *name,
 
80
                                      Error **errp)
 
81
{
 
82
    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
 
83
    uint32_t value = s->mch.pci_info.w32.end;
 
84
 
 
85
    visit_type_uint32(v, &value, name, errp);
 
86
}
 
87
 
 
88
static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
 
89
                                          void *opaque, const char *name,
 
90
                                          Error **errp)
 
91
{
 
92
    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
 
93
 
 
94
    visit_type_uint64(v, &s->mch.pci_info.w64.begin, name, errp);
 
95
}
 
96
 
 
97
static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
 
98
                                        void *opaque, const char *name,
 
99
                                        Error **errp)
 
100
{
 
101
    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
 
102
 
 
103
    visit_type_uint64(v, &s->mch.pci_info.w64.end, name, errp);
 
104
}
 
105
 
 
106
static Property mch_props[] = {
 
107
    DEFINE_PROP_UINT64("MCFG", Q35PCIHost, parent_obj.base_addr,
 
108
                        MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
 
109
    DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
 
110
                     mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
 
111
    DEFINE_PROP_END_OF_LIST(),
 
112
};
 
113
 
 
114
static void q35_host_class_init(ObjectClass *klass, void *data)
 
115
{
 
116
    DeviceClass *dc = DEVICE_CLASS(klass);
 
117
    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
 
118
 
 
119
    hc->root_bus_path = q35_host_root_bus_path;
 
120
    dc->realize = q35_host_realize;
 
121
    dc->props = mch_props;
 
122
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 
123
    dc->fw_name = "pci";
 
124
}
 
125
 
 
126
static void q35_host_initfn(Object *obj)
 
127
{
 
128
    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
 
129
    PCIHostState *phb = PCI_HOST_BRIDGE(obj);
 
130
 
 
131
    memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
 
132
                          "pci-conf-idx", 4);
 
133
    memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
 
134
                          "pci-conf-data", 4);
 
135
 
 
136
    object_initialize(&s->mch, TYPE_MCH_PCI_DEVICE);
 
137
    object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
 
138
    qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
 
139
    qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
 
140
 
 
141
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
 
142
                        q35_host_get_pci_hole_start,
 
143
                        NULL, NULL, NULL, NULL);
 
144
 
 
145
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
 
146
                        q35_host_get_pci_hole_end,
 
147
                        NULL, NULL, NULL, NULL);
 
148
 
 
149
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
 
150
                        q35_host_get_pci_hole64_start,
 
151
                        NULL, NULL, NULL, NULL);
 
152
 
 
153
    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
 
154
                        q35_host_get_pci_hole64_end,
 
155
                        NULL, NULL, NULL, NULL);
 
156
 
 
157
    /* Leave enough space for the biggest MCFG BAR */
 
158
    /* TODO: this matches current bios behaviour, but
 
159
     * it's not a power of two, which means an MTRR
 
160
     * can't cover it exactly.
 
161
     */
 
162
    s->mch.pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT +
 
163
        MCH_HOST_BRIDGE_PCIEXBAR_MAX;
 
164
    s->mch.pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
 
165
}
 
166
 
 
167
static const TypeInfo q35_host_info = {
 
168
    .name       = TYPE_Q35_HOST_DEVICE,
 
169
    .parent     = TYPE_PCIE_HOST_BRIDGE,
 
170
    .instance_size = sizeof(Q35PCIHost),
 
171
    .instance_init = q35_host_initfn,
 
172
    .class_init = q35_host_class_init,
 
173
};
 
174
 
 
175
/****************************************************************************
 
176
 * MCH D0:F0
 
177
 */
 
178
 
 
179
/* PCIe MMCFG */
 
180
static void mch_update_pciexbar(MCHPCIState *mch)
 
181
{
 
182
    PCIDevice *pci_dev = PCI_DEVICE(mch);
 
183
    BusState *bus = qdev_get_parent_bus(DEVICE(mch));
 
184
    PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent);
 
185
 
 
186
    uint64_t pciexbar;
 
187
    int enable;
 
188
    uint64_t addr;
 
189
    uint64_t addr_mask;
 
190
    uint32_t length;
 
191
 
 
192
    pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR);
 
193
    enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN;
 
194
    addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK;
 
195
    switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) {
 
196
    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M:
 
197
        length = 256 * 1024 * 1024;
 
198
        break;
 
199
    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:
 
200
        length = 128 * 1024 * 1024;
 
201
        addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |
 
202
            MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
 
203
        break;
 
204
    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:
 
205
        length = 64 * 1024 * 1024;
 
206
        addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
 
207
        break;
 
208
    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
 
209
    default:
 
210
        enable = 0;
 
211
        length = 0;
 
212
        abort();
 
213
        break;
 
214
    }
 
215
    addr = pciexbar & addr_mask;
 
216
    pcie_host_mmcfg_update(pehb, enable, addr, length);
 
217
}
 
218
 
 
219
/* PAM */
 
220
static void mch_update_pam(MCHPCIState *mch)
 
221
{
 
222
    PCIDevice *pd = PCI_DEVICE(mch);
 
223
    int i;
 
224
 
 
225
    memory_region_transaction_begin();
 
226
    for (i = 0; i < 13; i++) {
 
227
        pam_update(&mch->pam_regions[i], i,
 
228
                   pd->config[MCH_HOST_BRIDGE_PAM0 + ((i + 1) / 2)]);
 
229
    }
 
230
    memory_region_transaction_commit();
 
231
}
 
232
 
 
233
/* SMRAM */
 
234
static void mch_update_smram(MCHPCIState *mch)
 
235
{
 
236
    PCIDevice *pd = PCI_DEVICE(mch);
 
237
 
 
238
    memory_region_transaction_begin();
 
239
    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRDIGE_SMRAM],
 
240
                    mch->smm_enabled);
 
241
    memory_region_transaction_commit();
 
242
}
 
243
 
 
244
static void mch_set_smm(int smm, void *arg)
 
245
{
 
246
    MCHPCIState *mch = arg;
 
247
    PCIDevice *pd = PCI_DEVICE(mch);
 
248
 
 
249
    memory_region_transaction_begin();
 
250
    smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRDIGE_SMRAM],
 
251
                    &mch->smram_region);
 
252
    memory_region_transaction_commit();
 
253
}
 
254
 
 
255
static void mch_write_config(PCIDevice *d,
 
256
                              uint32_t address, uint32_t val, int len)
 
257
{
 
258
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
 
259
 
 
260
    /* XXX: implement SMRAM.D_LOCK */
 
261
    pci_default_write_config(d, address, val, len);
 
262
 
 
263
    if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PAM0,
 
264
                       MCH_HOST_BRIDGE_PAM_SIZE)) {
 
265
        mch_update_pam(mch);
 
266
    }
 
267
 
 
268
    if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PCIEXBAR,
 
269
                       MCH_HOST_BRIDGE_PCIEXBAR_SIZE)) {
 
270
        mch_update_pciexbar(mch);
 
271
    }
 
272
 
 
273
    if (ranges_overlap(address, len, MCH_HOST_BRDIGE_SMRAM,
 
274
                       MCH_HOST_BRDIGE_SMRAM_SIZE)) {
 
275
        mch_update_smram(mch);
 
276
    }
 
277
}
 
278
 
 
279
static void mch_update(MCHPCIState *mch)
 
280
{
 
281
    mch_update_pciexbar(mch);
 
282
    mch_update_pam(mch);
 
283
    mch_update_smram(mch);
 
284
}
 
285
 
 
286
static int mch_post_load(void *opaque, int version_id)
 
287
{
 
288
    MCHPCIState *mch = opaque;
 
289
    mch_update(mch);
 
290
    return 0;
 
291
}
 
292
 
 
293
static const VMStateDescription vmstate_mch = {
 
294
    .name = "mch",
 
295
    .version_id = 1,
 
296
    .minimum_version_id = 1,
 
297
    .minimum_version_id_old = 1,
 
298
    .post_load = mch_post_load,
 
299
    .fields = (VMStateField []) {
 
300
        VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
 
301
        VMSTATE_UINT8(smm_enabled, MCHPCIState),
 
302
        VMSTATE_END_OF_LIST()
 
303
    }
 
304
};
 
305
 
 
306
static void mch_reset(DeviceState *qdev)
 
307
{
 
308
    PCIDevice *d = PCI_DEVICE(qdev);
 
309
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
 
310
 
 
311
    pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
 
312
                 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
 
313
 
 
314
    d->config[MCH_HOST_BRDIGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
 
315
 
 
316
    mch_update(mch);
 
317
}
 
318
 
 
319
static int mch_init(PCIDevice *d)
 
320
{
 
321
    int i;
 
322
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
 
323
 
 
324
    /* setup pci memory regions */
 
325
    memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
 
326
                             mch->pci_address_space,
 
327
                             mch->below_4g_mem_size,
 
328
                             0x100000000ULL - mch->below_4g_mem_size);
 
329
    memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
 
330
                                &mch->pci_hole);
 
331
 
 
332
    pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
 
333
                       mch->pci_hole64_size);
 
334
    memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
 
335
                             mch->pci_address_space,
 
336
                             mch->pci_info.w64.begin,
 
337
                             mch->pci_hole64_size);
 
338
    if (mch->pci_hole64_size) {
 
339
        memory_region_add_subregion(mch->system_memory,
 
340
                                    mch->pci_info.w64.begin,
 
341
                                    &mch->pci_hole_64bit);
 
342
    }
 
343
    /* smram */
 
344
    cpu_smm_register(&mch_set_smm, mch);
 
345
    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
 
346
                             mch->pci_address_space, 0xa0000, 0x20000);
 
347
    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
 
348
                                        &mch->smram_region, 1);
 
349
    memory_region_set_enabled(&mch->smram_region, false);
 
350
    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
 
351
             &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
 
352
    for (i = 0; i < 12; ++i) {
 
353
        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
 
354
                 &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
 
355
                 PAM_EXPAN_SIZE);
 
356
    }
 
357
    return 0;
 
358
}
 
359
 
 
360
static void mch_class_init(ObjectClass *klass, void *data)
 
361
{
 
362
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
363
    DeviceClass *dc = DEVICE_CLASS(klass);
 
364
 
 
365
    k->init = mch_init;
 
366
    k->config_write = mch_write_config;
 
367
    dc->reset = mch_reset;
 
368
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 
369
    dc->desc = "Host bridge";
 
370
    dc->vmsd = &vmstate_mch;
 
371
    k->vendor_id = PCI_VENDOR_ID_INTEL;
 
372
    k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH;
 
373
    k->revision = MCH_HOST_BRIDGE_REVISION_DEFUALT;
 
374
    k->class_id = PCI_CLASS_BRIDGE_HOST;
 
375
}
 
376
 
 
377
static const TypeInfo mch_info = {
 
378
    .name = TYPE_MCH_PCI_DEVICE,
 
379
    .parent = TYPE_PCI_DEVICE,
 
380
    .instance_size = sizeof(MCHPCIState),
 
381
    .class_init = mch_class_init,
 
382
};
 
383
 
 
384
static void q35_register(void)
 
385
{
 
386
    type_register_static(&mch_info);
 
387
    type_register_static(&q35_host_info);
 
388
}
 
389
 
 
390
type_init(q35_register);