1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include "qemu/osdep.h"
31#include "hw/hw.h"
32#include "hw/pci-host/q35.h"
33#include "qapi/error.h"
34#include "qapi/visitor.h"
35
36
37
38
39
40#define Q35_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 35)
41
42static void q35_host_realize(DeviceState *dev, Error **errp)
43{
44 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
45 Q35PCIHost *s = Q35_HOST_DEVICE(dev);
46 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
47
48 sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
49 sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
50
51 sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
52 sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
53
54 pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
55 s->mch.pci_address_space,
56 s->mch.address_space_io,
57 0, TYPE_PCIE_BUS);
58 PC_MACHINE(qdev_get_machine())->bus = pci->bus;
59 qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
60 qdev_init_nofail(DEVICE(&s->mch));
61}
62
63static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
64 PCIBus *rootbus)
65{
66 Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge);
67
68
69 if (s->mch.short_root_bus) {
70 return "0000";
71 }
72 return "0000:00";
73}
74
75static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
76 const char *name, void *opaque,
77 Error **errp)
78{
79 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
80 uint64_t val64;
81 uint32_t value;
82
83 val64 = range_is_empty(&s->mch.pci_hole)
84 ? 0 : range_lob(&s->mch.pci_hole);
85 value = val64;
86 assert(value == val64);
87 visit_type_uint32(v, name, &value, errp);
88}
89
90static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
91 const char *name, void *opaque,
92 Error **errp)
93{
94 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
95 uint64_t val64;
96 uint32_t value;
97
98 val64 = range_is_empty(&s->mch.pci_hole)
99 ? 0 : range_upb(&s->mch.pci_hole) + 1;
100 value = val64;
101 assert(value == val64);
102 visit_type_uint32(v, name, &value, errp);
103}
104
105
106
107
108
109
110
111
112static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
113 const char *name, void *opaque,
114 Error **errp)
115{
116 PCIHostState *h = PCI_HOST_BRIDGE(obj);
117 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
118 Range w64;
119 uint64_t value;
120
121 pci_bus_get_w64_range(h->bus, &w64);
122 value = range_is_empty(&w64) ? 0 : range_lob(&w64);
123 if (!value && s->pci_hole64_fix) {
124 value = pc_pci_hole64_start();
125 }
126 visit_type_uint64(v, name, &value, errp);
127}
128
129
130
131
132
133
134
135static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
136 const char *name, void *opaque,
137 Error **errp)
138{
139 PCIHostState *h = PCI_HOST_BRIDGE(obj);
140 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
141 uint64_t hole64_start = pc_pci_hole64_start();
142 Range w64;
143 uint64_t value, hole64_end;
144
145 pci_bus_get_w64_range(h->bus, &w64);
146 value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
147 hole64_end = ROUND_UP(hole64_start + s->mch.pci_hole64_size, 1ULL << 30);
148 if (s->pci_hole64_fix && value < hole64_end) {
149 value = hole64_end;
150 }
151 visit_type_uint64(v, name, &value, errp);
152}
153
154static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
155 void *opaque, Error **errp)
156{
157 PCIExpressHost *e = PCIE_HOST_BRIDGE(obj);
158
159 visit_type_uint64(v, name, &e->size, errp);
160}
161
162
163
164
165
166
167
168
169
170static Property q35_host_props[] = {
171 DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
172 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
173 DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
174 mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
175 DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
176 DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
177 mch.below_4g_mem_size, 0),
178 DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
179 mch.above_4g_mem_size, 0),
180 DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
181 DEFINE_PROP_END_OF_LIST(),
182};
183
184static void q35_host_class_init(ObjectClass *klass, void *data)
185{
186 DeviceClass *dc = DEVICE_CLASS(klass);
187 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
188
189 hc->root_bus_path = q35_host_root_bus_path;
190 dc->realize = q35_host_realize;
191 dc->props = q35_host_props;
192
193 dc->user_creatable = false;
194 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
195 dc->fw_name = "pci";
196}
197
198static void q35_host_initfn(Object *obj)
199{
200 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
201 PCIHostState *phb = PCI_HOST_BRIDGE(obj);
202
203 memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
204 "pci-conf-idx", 4);
205 memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
206 "pci-conf-data", 4);
207
208 object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
209 object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
210 qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
211 qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
212
213 qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
214 Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
215 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
216 q35_host_get_pci_hole_start,
217 NULL, NULL, NULL, NULL);
218
219 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
220 q35_host_get_pci_hole_end,
221 NULL, NULL, NULL, NULL);
222
223 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
224 q35_host_get_pci_hole64_start,
225 NULL, NULL, NULL, NULL);
226
227 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
228 q35_host_get_pci_hole64_end,
229 NULL, NULL, NULL, NULL);
230
231 object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64",
232 q35_host_get_mmcfg_size,
233 NULL, NULL, NULL, NULL);
234
235 object_property_add_link(obj, MCH_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION,
236 (Object **) &s->mch.ram_memory,
237 qdev_prop_allow_set_link_before_realize, 0, NULL);
238
239 object_property_add_link(obj, MCH_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION,
240 (Object **) &s->mch.pci_address_space,
241 qdev_prop_allow_set_link_before_realize, 0, NULL);
242
243 object_property_add_link(obj, MCH_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION,
244 (Object **) &s->mch.system_memory,
245 qdev_prop_allow_set_link_before_realize, 0, NULL);
246
247 object_property_add_link(obj, MCH_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION,
248 (Object **) &s->mch.address_space_io,
249 qdev_prop_allow_set_link_before_realize, 0, NULL);
250
251
252
253
254
255
256 range_set_bounds(&s->mch.pci_hole,
257 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT + MCH_HOST_BRIDGE_PCIEXBAR_MAX,
258 IO_APIC_DEFAULT_ADDRESS - 1);
259}
260
261static const TypeInfo q35_host_info = {
262 .name = TYPE_Q35_HOST_DEVICE,
263 .parent = TYPE_PCIE_HOST_BRIDGE,
264 .instance_size = sizeof(Q35PCIHost),
265 .instance_init = q35_host_initfn,
266 .class_init = q35_host_class_init,
267};
268
269
270
271
272
273static uint64_t tseg_blackhole_read(void *ptr, hwaddr reg, unsigned size)
274{
275 return 0xffffffff;
276}
277
278static void tseg_blackhole_write(void *opaque, hwaddr addr, uint64_t val,
279 unsigned width)
280{
281
282}
283
284static const MemoryRegionOps tseg_blackhole_ops = {
285 .read = tseg_blackhole_read,
286 .write = tseg_blackhole_write,
287 .endianness = DEVICE_NATIVE_ENDIAN,
288 .valid.min_access_size = 1,
289 .valid.max_access_size = 4,
290 .impl.min_access_size = 4,
291 .impl.max_access_size = 4,
292 .endianness = DEVICE_LITTLE_ENDIAN,
293};
294
295
296static void mch_update_pciexbar(MCHPCIState *mch)
297{
298 PCIDevice *pci_dev = PCI_DEVICE(mch);
299 BusState *bus = qdev_get_parent_bus(DEVICE(mch));
300 PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent);
301
302 uint64_t pciexbar;
303 int enable;
304 uint64_t addr;
305 uint64_t addr_mask;
306 uint32_t length;
307
308 pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR);
309 enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN;
310 addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK;
311 switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) {
312 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M:
313 length = 256 * 1024 * 1024;
314 break;
315 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:
316 length = 128 * 1024 * 1024;
317 addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |
318 MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
319 break;
320 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:
321 length = 64 * 1024 * 1024;
322 addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
323 break;
324 case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
325 default:
326 abort();
327 }
328 addr = pciexbar & addr_mask;
329 pcie_host_mmcfg_update(pehb, enable, addr, length);
330
331
332
333
334
335 if (enable) {
336 range_set_bounds(&mch->pci_hole,
337 addr + length,
338 IO_APIC_DEFAULT_ADDRESS - 1);
339 } else {
340 range_set_bounds(&mch->pci_hole,
341 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT,
342 IO_APIC_DEFAULT_ADDRESS - 1);
343 }
344}
345
346
347static void mch_update_pam(MCHPCIState *mch)
348{
349 PCIDevice *pd = PCI_DEVICE(mch);
350 int i;
351
352 memory_region_transaction_begin();
353 for (i = 0; i < 13; i++) {
354 pam_update(&mch->pam_regions[i], i,
355 pd->config[MCH_HOST_BRIDGE_PAM0 + (DIV_ROUND_UP(i, 2))]);
356 }
357 memory_region_transaction_commit();
358}
359
360
361static void mch_update_smram(MCHPCIState *mch)
362{
363 PCIDevice *pd = PCI_DEVICE(mch);
364 bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
365 uint32_t tseg_size;
366
367
368 if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {
369 pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN;
370 pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK;
371 pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK;
372 }
373
374 memory_region_transaction_begin();
375
376 if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {
377
378 memory_region_set_enabled(&mch->smram_region, h_smrame);
379
380 memory_region_set_enabled(&mch->open_high_smram, h_smrame);
381 } else {
382
383 memory_region_set_enabled(&mch->smram_region, true);
384 memory_region_set_enabled(&mch->open_high_smram, false);
385 }
386
387 if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {
388 memory_region_set_enabled(&mch->low_smram, !h_smrame);
389 memory_region_set_enabled(&mch->high_smram, h_smrame);
390 } else {
391 memory_region_set_enabled(&mch->low_smram, false);
392 memory_region_set_enabled(&mch->high_smram, false);
393 }
394
395 if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) {
396 switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] &
397 MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) {
398 case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB:
399 tseg_size = 1024 * 1024;
400 break;
401 case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB:
402 tseg_size = 1024 * 1024 * 2;
403 break;
404 case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB:
405 tseg_size = 1024 * 1024 * 8;
406 break;
407 default:
408 tseg_size = 1024 * 1024 * (uint32_t)mch->ext_tseg_mbytes;
409 break;
410 }
411 } else {
412 tseg_size = 0;
413 }
414 memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole);
415 memory_region_set_enabled(&mch->tseg_blackhole, tseg_size);
416 memory_region_set_size(&mch->tseg_blackhole, tseg_size);
417 memory_region_add_subregion_overlap(mch->system_memory,
418 mch->below_4g_mem_size - tseg_size,
419 &mch->tseg_blackhole, 1);
420
421 memory_region_set_enabled(&mch->tseg_window, tseg_size);
422 memory_region_set_size(&mch->tseg_window, tseg_size);
423 memory_region_set_address(&mch->tseg_window,
424 mch->below_4g_mem_size - tseg_size);
425 memory_region_set_alias_offset(&mch->tseg_window,
426 mch->below_4g_mem_size - tseg_size);
427
428 memory_region_transaction_commit();
429}
430
431static void mch_update_ext_tseg_mbytes(MCHPCIState *mch)
432{
433 PCIDevice *pd = PCI_DEVICE(mch);
434 uint8_t *reg = pd->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES;
435
436 if (mch->ext_tseg_mbytes > 0 &&
437 pci_get_word(reg) == MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY) {
438 pci_set_word(reg, mch->ext_tseg_mbytes);
439 }
440}
441
442static void mch_write_config(PCIDevice *d,
443 uint32_t address, uint32_t val, int len)
444{
445 MCHPCIState *mch = MCH_PCI_DEVICE(d);
446
447 pci_default_write_config(d, address, val, len);
448
449 if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PAM0,
450 MCH_HOST_BRIDGE_PAM_SIZE)) {
451 mch_update_pam(mch);
452 }
453
454 if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PCIEXBAR,
455 MCH_HOST_BRIDGE_PCIEXBAR_SIZE)) {
456 mch_update_pciexbar(mch);
457 }
458
459 if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
460 MCH_HOST_BRIDGE_SMRAM_SIZE)) {
461 mch_update_smram(mch);
462 }
463
464 if (ranges_overlap(address, len, MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
465 MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_SIZE)) {
466 mch_update_ext_tseg_mbytes(mch);
467 }
468}
469
470static void mch_update(MCHPCIState *mch)
471{
472 mch_update_pciexbar(mch);
473 mch_update_pam(mch);
474 mch_update_smram(mch);
475 mch_update_ext_tseg_mbytes(mch);
476}
477
478static int mch_post_load(void *opaque, int version_id)
479{
480 MCHPCIState *mch = opaque;
481 mch_update(mch);
482 return 0;
483}
484
485static const VMStateDescription vmstate_mch = {
486 .name = "mch",
487 .version_id = 1,
488 .minimum_version_id = 1,
489 .post_load = mch_post_load,
490 .fields = (VMStateField[]) {
491 VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
492
493
494
495 VMSTATE_UNUSED(1),
496 VMSTATE_END_OF_LIST()
497 }
498};
499
500static void mch_reset(DeviceState *qdev)
501{
502 PCIDevice *d = PCI_DEVICE(qdev);
503 MCHPCIState *mch = MCH_PCI_DEVICE(d);
504
505 pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
506 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
507
508 d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
509 d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
510 d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
511 d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
512
513 if (mch->ext_tseg_mbytes > 0) {
514 pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
515 MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY);
516 }
517
518 mch_update(mch);
519}
520
521static void mch_realize(PCIDevice *d, Error **errp)
522{
523 int i;
524 MCHPCIState *mch = MCH_PCI_DEVICE(d);
525
526 if (mch->ext_tseg_mbytes > MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_MAX) {
527 error_setg(errp, "invalid extended-tseg-mbytes value: %" PRIu16,
528 mch->ext_tseg_mbytes);
529 return;
530 }
531
532
533 pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
534 mch->pci_address_space);
535
536
537 memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
538 mch->pci_address_space, 0xa0000, 0x20000);
539 memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
540 &mch->smram_region, 1);
541 memory_region_set_enabled(&mch->smram_region, true);
542
543 memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high",
544 mch->ram_memory, 0xa0000, 0x20000);
545 memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000,
546 &mch->open_high_smram, 1);
547 memory_region_set_enabled(&mch->open_high_smram, false);
548
549
550 memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
551 memory_region_set_enabled(&mch->smram, true);
552 memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
553 mch->ram_memory, 0xa0000, 0x20000);
554 memory_region_set_enabled(&mch->low_smram, true);
555 memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
556 memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
557 mch->ram_memory, 0xa0000, 0x20000);
558 memory_region_set_enabled(&mch->high_smram, true);
559 memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
560
561 memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
562 &tseg_blackhole_ops, NULL,
563 "tseg-blackhole", 0);
564 memory_region_set_enabled(&mch->tseg_blackhole, false);
565 memory_region_add_subregion_overlap(mch->system_memory,
566 mch->below_4g_mem_size,
567 &mch->tseg_blackhole, 1);
568
569 memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window",
570 mch->ram_memory, mch->below_4g_mem_size, 0);
571 memory_region_set_enabled(&mch->tseg_window, false);
572 memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
573 &mch->tseg_window);
574 object_property_add_const_link(qdev_get_machine(), "smram",
575 OBJECT(&mch->smram), &error_abort);
576
577 init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
578 mch->pci_address_space, &mch->pam_regions[0],
579 PAM_BIOS_BASE, PAM_BIOS_SIZE);
580 for (i = 0; i < 12; ++i) {
581 init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
582 mch->pci_address_space, &mch->pam_regions[i+1],
583 PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
584 }
585}
586
587uint64_t mch_mcfg_base(void)
588{
589 bool ambiguous;
590 Object *o = object_resolve_path_type("", TYPE_MCH_PCI_DEVICE, &ambiguous);
591 if (!o) {
592 return 0;
593 }
594 return MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT;
595}
596
597static Property mch_props[] = {
598 DEFINE_PROP_UINT16("extended-tseg-mbytes", MCHPCIState, ext_tseg_mbytes,
599 16),
600 DEFINE_PROP_END_OF_LIST(),
601};
602
603static void mch_class_init(ObjectClass *klass, void *data)
604{
605 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
606 DeviceClass *dc = DEVICE_CLASS(klass);
607
608 k->realize = mch_realize;
609 k->config_write = mch_write_config;
610 dc->reset = mch_reset;
611 dc->props = mch_props;
612 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
613 dc->desc = "Host bridge";
614 dc->vmsd = &vmstate_mch;
615 k->vendor_id = PCI_VENDOR_ID_INTEL;
616 k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH;
617 k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT;
618 k->class_id = PCI_CLASS_BRIDGE_HOST;
619
620
621
622
623 dc->user_creatable = false;
624}
625
626static const TypeInfo mch_info = {
627 .name = TYPE_MCH_PCI_DEVICE,
628 .parent = TYPE_PCI_DEVICE,
629 .instance_size = sizeof(MCHPCIState),
630 .class_init = mch_class_init,
631 .interfaces = (InterfaceInfo[]) {
632 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
633 { },
634 },
635};
636
637static void q35_register(void)
638{
639 type_register_static(&mch_info);
640 type_register_static(&q35_host_info);
641}
642
643type_init(q35_register);
644