xref: /openbmc/qemu/hw/pci-host/q35.c (revision a3fb4e93a3a7cf2be355c41cd550bef856f5ffe4)
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.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  
31  #include "qemu/osdep.h"
32  #include "qemu/log.h"
33  #include "hw/i386/pc.h"
34  #include "hw/pci-host/q35.h"
35  #include "hw/qdev-properties.h"
36  #include "migration/vmstate.h"
37  #include "qapi/error.h"
38  #include "qapi/visitor.h"
39  #include "qemu/module.h"
40  
41  /****************************************************************************
42   * Q35 host
43   */
44  
45  #define Q35_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 35)
46  
q35_host_realize(DeviceState * dev,Error ** errp)47  static void q35_host_realize(DeviceState *dev, Error **errp)
48  {
49      PCIHostState *pci = PCI_HOST_BRIDGE(dev);
50      Q35PCIHost *s = Q35_HOST_DEVICE(dev);
51      SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52  
53      memory_region_add_subregion(s->mch.address_space_io,
54                                  MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
55      sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
56  
57      memory_region_add_subregion(s->mch.address_space_io,
58                                  MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
59      sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
60  
61      /* register q35 0xcf8 port as coalesced pio */
62      memory_region_set_flush_coalesced(&pci->data_mem);
63      memory_region_add_coalescing(&pci->conf_mem, 0, 4);
64  
65      pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
66                                  s->mch.pci_address_space,
67                                  s->mch.address_space_io,
68                                  0, TYPE_PCIE_BUS);
69  
70      qdev_realize(DEVICE(&s->mch), BUS(pci->bus), &error_fatal);
71  }
72  
q35_host_root_bus_path(PCIHostState * host_bridge,PCIBus * rootbus)73  static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
74                                            PCIBus *rootbus)
75  {
76      return "0000:00";
77  }
78  
q35_host_get_pci_hole_start(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)79  static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
80                                          const char *name, void *opaque,
81                                          Error **errp)
82  {
83      Q35PCIHost *s = Q35_HOST_DEVICE(obj);
84      uint64_t val64;
85      uint32_t value;
86  
87      val64 = range_is_empty(&s->mch.pci_hole)
88          ? 0 : range_lob(&s->mch.pci_hole);
89      value = val64;
90      assert(value == val64);
91      visit_type_uint32(v, name, &value, errp);
92  }
93  
q35_host_get_pci_hole_end(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)94  static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
95                                        const char *name, void *opaque,
96                                        Error **errp)
97  {
98      Q35PCIHost *s = Q35_HOST_DEVICE(obj);
99      uint64_t val64;
100      uint32_t value;
101  
102      val64 = range_is_empty(&s->mch.pci_hole)
103          ? 0 : range_upb(&s->mch.pci_hole) + 1;
104      value = val64;
105      assert(value == val64);
106      visit_type_uint32(v, name, &value, errp);
107  }
108  
109  /*
110   * The 64bit PCI hole start is set by the Guest firmware
111   * as the address of the first 64bit PCI MEM resource.
112   * If no PCI device has resources on the 64bit area,
113   * the 64bit PCI hole will start after "over 4G RAM" and the
114   * reserved space for memory hotplug if any.
115   */
q35_host_get_pci_hole64_start_value(Object * obj)116  static uint64_t q35_host_get_pci_hole64_start_value(Object *obj)
117  {
118      PCIHostState *h = PCI_HOST_BRIDGE(obj);
119      Q35PCIHost *s = Q35_HOST_DEVICE(obj);
120      Range w64;
121      uint64_t value;
122  
123      pci_bus_get_w64_range(h->bus, &w64);
124      value = range_is_empty(&w64) ? 0 : range_lob(&w64);
125      if (!value && s->pci_hole64_fix) {
126          value = pc_pci_hole64_start();
127      }
128      return value;
129  }
130  
q35_host_get_pci_hole64_start(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)131  static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
132                                            const char *name, void *opaque,
133                                            Error **errp)
134  {
135      uint64_t hole64_start = q35_host_get_pci_hole64_start_value(obj);
136  
137      visit_type_uint64(v, name, &hole64_start, errp);
138  }
139  
140  /*
141   * The 64bit PCI hole end is set by the Guest firmware
142   * as the address of the last 64bit PCI MEM resource.
143   * Then it is expanded to the PCI_HOST_PROP_PCI_HOLE64_SIZE
144   * that can be configured by the user.
145   */
q35_host_get_pci_hole64_end(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)146  static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
147                                          const char *name, void *opaque,
148                                          Error **errp)
149  {
150      PCIHostState *h = PCI_HOST_BRIDGE(obj);
151      Q35PCIHost *s = Q35_HOST_DEVICE(obj);
152      uint64_t hole64_start = q35_host_get_pci_hole64_start_value(obj);
153      Range w64;
154      uint64_t value, hole64_end;
155  
156      pci_bus_get_w64_range(h->bus, &w64);
157      value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
158      hole64_end = ROUND_UP(hole64_start + s->mch.pci_hole64_size, 1ULL << 30);
159      if (s->pci_hole64_fix && value < hole64_end) {
160          value = hole64_end;
161      }
162      visit_type_uint64(v, name, &value, errp);
163  }
164  
165  /*
166   * NOTE: setting defaults for the mch.* fields in this table
167   * doesn't work, because mch is a separate QOM object that is
168   * zeroed by the object_initialize(&s->mch, ...) call inside
169   * q35_host_initfn().  The default values for those
170   * properties need to be initialized manually by
171   * q35_host_initfn() after the object_initialize() call.
172   */
173  static Property q35_host_props[] = {
174      DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
175                          MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
176      DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
177                       mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
178      DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
179                       mch.below_4g_mem_size, 0),
180      DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
181                       mch.above_4g_mem_size, 0),
182      DEFINE_PROP_BOOL(PCI_HOST_PROP_SMM_RANGES, Q35PCIHost,
183                       mch.has_smm_ranges, true),
184      DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
185      DEFINE_PROP_END_OF_LIST(),
186  };
187  
q35_host_class_init(ObjectClass * klass,void * data)188  static void q35_host_class_init(ObjectClass *klass, void *data)
189  {
190      DeviceClass *dc = DEVICE_CLASS(klass);
191      PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
192  
193      hc->root_bus_path = q35_host_root_bus_path;
194      dc->realize = q35_host_realize;
195      device_class_set_props(dc, q35_host_props);
196      /* Reason: needs to be wired up by pc_q35_init */
197      dc->user_creatable = false;
198      set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
199      dc->fw_name = "pci";
200  }
201  
q35_host_initfn(Object * obj)202  static void q35_host_initfn(Object *obj)
203  {
204      Q35PCIHost *s = Q35_HOST_DEVICE(obj);
205      PCIHostState *phb = PCI_HOST_BRIDGE(obj);
206      PCIExpressHost *pehb = PCIE_HOST_BRIDGE(obj);
207  
208      memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
209                            "pci-conf-idx", 4);
210      memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
211                            "pci-conf-data", 4);
212  
213      object_initialize_child(OBJECT(s), "mch", &s->mch, TYPE_MCH_PCI_DEVICE);
214      qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
215      qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
216      /* mch's object_initialize resets the default value, set it again */
217      qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
218                           Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
219  
220      object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
221                          q35_host_get_pci_hole_start,
222                          NULL, NULL, NULL);
223  
224      object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
225                          q35_host_get_pci_hole_end,
226                          NULL, NULL, NULL);
227  
228      object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
229                          q35_host_get_pci_hole64_start,
230                          NULL, NULL, NULL);
231  
232      object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
233                          q35_host_get_pci_hole64_end,
234                          NULL, NULL, NULL);
235  
236      object_property_add_uint64_ptr(obj, PCIE_HOST_MCFG_SIZE,
237                                     &pehb->size, OBJ_PROP_FLAG_READ);
238  
239      object_property_add_link(obj, PCI_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION,
240                               (Object **) &s->mch.ram_memory,
241                               qdev_prop_allow_set_link_before_realize, 0);
242  
243      object_property_add_link(obj, PCI_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION,
244                               (Object **) &s->mch.pci_address_space,
245                               qdev_prop_allow_set_link_before_realize, 0);
246  
247      object_property_add_link(obj, PCI_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION,
248                               (Object **) &s->mch.system_memory,
249                               qdev_prop_allow_set_link_before_realize, 0);
250  
251      object_property_add_link(obj, PCI_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION,
252                               (Object **) &s->mch.address_space_io,
253                               qdev_prop_allow_set_link_before_realize, 0);
254  }
255  
256  static const TypeInfo q35_host_info = {
257      .name       = TYPE_Q35_HOST_DEVICE,
258      .parent     = TYPE_PCIE_HOST_BRIDGE,
259      .instance_size = sizeof(Q35PCIHost),
260      .instance_init = q35_host_initfn,
261      .class_init = q35_host_class_init,
262  };
263  
264  /****************************************************************************
265   * MCH D0:F0
266   */
267  
blackhole_read(void * ptr,hwaddr reg,unsigned size)268  static uint64_t blackhole_read(void *ptr, hwaddr reg, unsigned size)
269  {
270      return 0xffffffff;
271  }
272  
blackhole_write(void * opaque,hwaddr addr,uint64_t val,unsigned width)273  static void blackhole_write(void *opaque, hwaddr addr, uint64_t val,
274                              unsigned width)
275  {
276      /* nothing */
277  }
278  
279  static const MemoryRegionOps blackhole_ops = {
280      .read = blackhole_read,
281      .write = blackhole_write,
282      .valid.min_access_size = 1,
283      .valid.max_access_size = 4,
284      .impl.min_access_size = 4,
285      .impl.max_access_size = 4,
286      .endianness = DEVICE_LITTLE_ENDIAN,
287  };
288  
289  /* PCIe MMCFG */
mch_update_pciexbar(MCHPCIState * mch)290  static void mch_update_pciexbar(MCHPCIState *mch)
291  {
292      PCIDevice *pci_dev = PCI_DEVICE(mch);
293      BusState *bus = qdev_get_parent_bus(DEVICE(mch));
294      PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent);
295  
296      uint64_t pciexbar;
297      int enable;
298      uint64_t addr;
299      uint64_t addr_mask;
300      uint32_t length;
301  
302      pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR);
303      enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN;
304      addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK;
305      switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) {
306      case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M:
307          length = 256 * 1024 * 1024;
308          break;
309      case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:
310          length = 128 * 1024 * 1024;
311          addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |
312              MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
313          break;
314      case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:
315          length = 64 * 1024 * 1024;
316          addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
317          break;
318      case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
319          qemu_log_mask(LOG_GUEST_ERROR, "Q35: Reserved PCIEXBAR LENGTH\n");
320          return;
321      default:
322          abort();
323      }
324      addr = pciexbar & addr_mask;
325      pcie_host_mmcfg_update(pehb, enable, addr, length);
326  }
327  
328  /* PAM */
mch_update_pam(MCHPCIState * mch)329  static void mch_update_pam(MCHPCIState *mch)
330  {
331      PCIDevice *pd = PCI_DEVICE(mch);
332      int i;
333  
334      memory_region_transaction_begin();
335      for (i = 0; i < 13; i++) {
336          pam_update(&mch->pam_regions[i], i,
337                     pd->config[MCH_HOST_BRIDGE_PAM0 + DIV_ROUND_UP(i, 2)]);
338      }
339      memory_region_transaction_commit();
340  }
341  
342  /* SMRAM */
mch_update_smram(MCHPCIState * mch)343  static void mch_update_smram(MCHPCIState *mch)
344  {
345      PCIDevice *pd = PCI_DEVICE(mch);
346      bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
347      uint32_t tseg_size;
348  
349      /* implement SMRAM.D_LCK */
350      if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {
351          pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN;
352          pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK;
353          pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK;
354      }
355  
356      memory_region_transaction_begin();
357  
358      if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {
359          /* Hide (!) low SMRAM if H_SMRAME = 1 */
360          memory_region_set_enabled(&mch->smram_region, h_smrame);
361          /* Show high SMRAM if H_SMRAME = 1 */
362          memory_region_set_enabled(&mch->open_high_smram, h_smrame);
363      } else {
364          /* Hide high SMRAM and low SMRAM */
365          memory_region_set_enabled(&mch->smram_region, true);
366          memory_region_set_enabled(&mch->open_high_smram, false);
367      }
368  
369      if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {
370          memory_region_set_enabled(&mch->low_smram, !h_smrame);
371          memory_region_set_enabled(&mch->high_smram, h_smrame);
372      } else {
373          memory_region_set_enabled(&mch->low_smram, false);
374          memory_region_set_enabled(&mch->high_smram, false);
375      }
376  
377      if ((pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) &&
378          (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME)) {
379          switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] &
380                  MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) {
381          case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB:
382              tseg_size = 1024 * 1024;
383              break;
384          case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB:
385              tseg_size = 1024 * 1024 * 2;
386              break;
387          case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB:
388              tseg_size = 1024 * 1024 * 8;
389              break;
390          default:
391              tseg_size = 1024 * 1024 * (uint32_t)mch->ext_tseg_mbytes;
392              break;
393          }
394      } else {
395          tseg_size = 0;
396      }
397      memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole);
398      memory_region_set_enabled(&mch->tseg_blackhole, tseg_size);
399      memory_region_set_size(&mch->tseg_blackhole, tseg_size);
400      memory_region_add_subregion_overlap(mch->system_memory,
401                                          mch->below_4g_mem_size - tseg_size,
402                                          &mch->tseg_blackhole, 1);
403  
404      memory_region_set_enabled(&mch->tseg_window, tseg_size);
405      memory_region_set_size(&mch->tseg_window, tseg_size);
406      memory_region_set_address(&mch->tseg_window,
407                                mch->below_4g_mem_size - tseg_size);
408      memory_region_set_alias_offset(&mch->tseg_window,
409                                     mch->below_4g_mem_size - tseg_size);
410  
411      memory_region_transaction_commit();
412  }
413  
mch_update_ext_tseg_mbytes(MCHPCIState * mch)414  static void mch_update_ext_tseg_mbytes(MCHPCIState *mch)
415  {
416      PCIDevice *pd = PCI_DEVICE(mch);
417      uint8_t *reg = pd->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES;
418  
419      if (mch->ext_tseg_mbytes > 0 &&
420          pci_get_word(reg) == MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY) {
421          pci_set_word(reg, mch->ext_tseg_mbytes);
422      }
423  }
424  
mch_update_smbase_smram(MCHPCIState * mch)425  static void mch_update_smbase_smram(MCHPCIState *mch)
426  {
427      PCIDevice *pd = PCI_DEVICE(mch);
428      uint8_t *reg = pd->config + MCH_HOST_BRIDGE_F_SMBASE;
429      bool lck;
430  
431      if (!mch->has_smram_at_smbase) {
432          return;
433      }
434  
435      if (*reg == MCH_HOST_BRIDGE_F_SMBASE_QUERY) {
436          pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] =
437              MCH_HOST_BRIDGE_F_SMBASE_LCK;
438          *reg = MCH_HOST_BRIDGE_F_SMBASE_IN_RAM;
439          return;
440      }
441  
442      /*
443       * default/reset state, discard written value
444       * which will disable SMRAM balackhole at SMBASE
445       */
446      if (pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] == 0xff) {
447          *reg = 0x00;
448      }
449  
450      memory_region_transaction_begin();
451      if (*reg & MCH_HOST_BRIDGE_F_SMBASE_LCK) {
452          /* disable all writes */
453          pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] &=
454              ~MCH_HOST_BRIDGE_F_SMBASE_LCK;
455          *reg = MCH_HOST_BRIDGE_F_SMBASE_LCK;
456          lck = true;
457      } else {
458          lck = false;
459      }
460      memory_region_set_enabled(&mch->smbase_blackhole, lck);
461      memory_region_set_enabled(&mch->smbase_window, lck);
462      memory_region_transaction_commit();
463  }
464  
mch_write_config(PCIDevice * d,uint32_t address,uint32_t val,int len)465  static void mch_write_config(PCIDevice *d,
466                                uint32_t address, uint32_t val, int len)
467  {
468      MCHPCIState *mch = MCH_PCI_DEVICE(d);
469  
470      pci_default_write_config(d, address, val, len);
471  
472      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PAM0,
473                         MCH_HOST_BRIDGE_PAM_SIZE)) {
474          mch_update_pam(mch);
475      }
476  
477      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PCIEXBAR,
478                         MCH_HOST_BRIDGE_PCIEXBAR_SIZE)) {
479          mch_update_pciexbar(mch);
480      }
481  
482      if (!mch->has_smm_ranges) {
483          return;
484      }
485  
486      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
487                         MCH_HOST_BRIDGE_SMRAM_SIZE)) {
488          mch_update_smram(mch);
489      }
490  
491      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
492                         MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_SIZE)) {
493          mch_update_ext_tseg_mbytes(mch);
494      }
495  
496      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_F_SMBASE, 1)) {
497          mch_update_smbase_smram(mch);
498      }
499  }
500  
mch_update(MCHPCIState * mch)501  static void mch_update(MCHPCIState *mch)
502  {
503      mch_update_pciexbar(mch);
504  
505      mch_update_pam(mch);
506      if (mch->has_smm_ranges) {
507          mch_update_smram(mch);
508          mch_update_ext_tseg_mbytes(mch);
509          mch_update_smbase_smram(mch);
510      }
511  
512      /*
513       * pci hole goes from end-of-low-ram to io-apic.
514       * mmconfig will be excluded by the dsdt builder.
515       */
516      range_set_bounds(&mch->pci_hole,
517                       mch->below_4g_mem_size,
518                       IO_APIC_DEFAULT_ADDRESS - 1);
519  }
520  
mch_post_load(void * opaque,int version_id)521  static int mch_post_load(void *opaque, int version_id)
522  {
523      MCHPCIState *mch = opaque;
524      mch_update(mch);
525      return 0;
526  }
527  
528  static const VMStateDescription vmstate_mch = {
529      .name = "mch",
530      .version_id = 1,
531      .minimum_version_id = 1,
532      .post_load = mch_post_load,
533      .fields = (const VMStateField[]) {
534          VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
535          /* Used to be smm_enabled, which was basically always zero because
536           * SeaBIOS hardly uses SMM.  SMRAM is now handled by CPU code.
537           */
538          VMSTATE_UNUSED(1),
539          VMSTATE_END_OF_LIST()
540      }
541  };
542  
mch_reset(DeviceState * qdev)543  static void mch_reset(DeviceState *qdev)
544  {
545      PCIDevice *d = PCI_DEVICE(qdev);
546      MCHPCIState *mch = MCH_PCI_DEVICE(d);
547  
548      pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
549                   MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
550  
551      if (mch->has_smm_ranges) {
552          d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
553          d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
554          d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
555          d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
556  
557          if (mch->ext_tseg_mbytes > 0) {
558              pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
559                          MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY);
560          }
561  
562          d->config[MCH_HOST_BRIDGE_F_SMBASE] = 0;
563          d->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0xff;
564      }
565  
566      mch_update(mch);
567  }
568  
mch_realize(PCIDevice * d,Error ** errp)569  static void mch_realize(PCIDevice *d, Error **errp)
570  {
571      int i;
572      MCHPCIState *mch = MCH_PCI_DEVICE(d);
573  
574      if (mch->ext_tseg_mbytes > MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_MAX) {
575          error_setg(errp, "invalid extended-tseg-mbytes value: %" PRIu16,
576                     mch->ext_tseg_mbytes);
577          return;
578      }
579  
580      /* setup pci memory mapping */
581      pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space);
582  
583      /* PAM */
584      init_pam(&mch->pam_regions[0], OBJECT(mch), mch->ram_memory,
585               mch->system_memory, mch->pci_address_space,
586               PAM_BIOS_BASE, PAM_BIOS_SIZE);
587      for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) {
588          init_pam(&mch->pam_regions[i + 1], OBJECT(mch), mch->ram_memory,
589                   mch->system_memory, mch->pci_address_space,
590                   PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
591      }
592  
593      if (!mch->has_smm_ranges) {
594          return;
595      }
596  
597      /* if *disabled* show SMRAM to all CPUs */
598      memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
599                               mch->pci_address_space, MCH_HOST_BRIDGE_SMRAM_C_BASE,
600                               MCH_HOST_BRIDGE_SMRAM_C_SIZE);
601      memory_region_add_subregion_overlap(mch->system_memory, MCH_HOST_BRIDGE_SMRAM_C_BASE,
602                                          &mch->smram_region, 1);
603      memory_region_set_enabled(&mch->smram_region, true);
604  
605      memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high",
606                               mch->ram_memory, MCH_HOST_BRIDGE_SMRAM_C_BASE,
607                               MCH_HOST_BRIDGE_SMRAM_C_SIZE);
608      memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000,
609                                          &mch->open_high_smram, 1);
610      memory_region_set_enabled(&mch->open_high_smram, false);
611  
612      /* smram, as seen by SMM CPUs */
613      memory_region_init(&mch->smram, OBJECT(mch), "smram", 4 * GiB);
614      memory_region_set_enabled(&mch->smram, true);
615      memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
616                               mch->ram_memory, MCH_HOST_BRIDGE_SMRAM_C_BASE,
617                               MCH_HOST_BRIDGE_SMRAM_C_SIZE);
618      memory_region_set_enabled(&mch->low_smram, true);
619      memory_region_add_subregion(&mch->smram, MCH_HOST_BRIDGE_SMRAM_C_BASE,
620                                  &mch->low_smram);
621      memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
622                               mch->ram_memory, MCH_HOST_BRIDGE_SMRAM_C_BASE,
623                               MCH_HOST_BRIDGE_SMRAM_C_SIZE);
624      memory_region_set_enabled(&mch->high_smram, true);
625      memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
626  
627      memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
628                            &blackhole_ops, NULL,
629                            "tseg-blackhole", 0);
630      memory_region_set_enabled(&mch->tseg_blackhole, false);
631      memory_region_add_subregion_overlap(mch->system_memory,
632                                          mch->below_4g_mem_size,
633                                          &mch->tseg_blackhole, 1);
634  
635      memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window",
636                               mch->ram_memory, mch->below_4g_mem_size, 0);
637      memory_region_set_enabled(&mch->tseg_window, false);
638      memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
639                                  &mch->tseg_window);
640  
641      /*
642       * This is not what hardware does, so it's QEMU specific hack.
643       * See commit message for details.
644       */
645      memory_region_init_io(&mch->smbase_blackhole, OBJECT(mch), &blackhole_ops,
646                            NULL, "smbase-blackhole",
647                            MCH_HOST_BRIDGE_SMBASE_SIZE);
648      memory_region_set_enabled(&mch->smbase_blackhole, false);
649      memory_region_add_subregion_overlap(mch->system_memory,
650                                          MCH_HOST_BRIDGE_SMBASE_ADDR,
651                                          &mch->smbase_blackhole, 1);
652  
653      memory_region_init_alias(&mch->smbase_window, OBJECT(mch),
654                               "smbase-window", mch->ram_memory,
655                               MCH_HOST_BRIDGE_SMBASE_ADDR,
656                               MCH_HOST_BRIDGE_SMBASE_SIZE);
657      memory_region_set_enabled(&mch->smbase_window, false);
658      memory_region_add_subregion(&mch->smram, MCH_HOST_BRIDGE_SMBASE_ADDR,
659                                  &mch->smbase_window);
660  
661      object_property_add_const_link(qdev_get_machine(), "smram",
662                                     OBJECT(&mch->smram));
663  }
664  
665  static Property mch_props[] = {
666      DEFINE_PROP_UINT16("extended-tseg-mbytes", MCHPCIState, ext_tseg_mbytes,
667                         16),
668      DEFINE_PROP_BOOL("smbase-smram", MCHPCIState, has_smram_at_smbase, true),
669      DEFINE_PROP_END_OF_LIST(),
670  };
671  
mch_class_init(ObjectClass * klass,void * data)672  static void mch_class_init(ObjectClass *klass, void *data)
673  {
674      PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
675      DeviceClass *dc = DEVICE_CLASS(klass);
676  
677      k->realize = mch_realize;
678      k->config_write = mch_write_config;
679      device_class_set_legacy_reset(dc, mch_reset);
680      device_class_set_props(dc, mch_props);
681      set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
682      dc->desc = "Host bridge";
683      dc->vmsd = &vmstate_mch;
684      k->vendor_id = PCI_VENDOR_ID_INTEL;
685      /*
686       * The 'q35' machine type implements an Intel Series 3 chipset,
687       * of which there are several variants. The key difference between
688       * the 82P35 MCH ('p35') and 82Q35 GMCH ('q35') variants is that
689       * the latter has an integrated graphics adapter. QEMU does not
690       * implement integrated graphics, so uses the PCI ID for the 82P35
691       * chipset.
692       */
693      k->device_id = PCI_DEVICE_ID_INTEL_P35_MCH;
694      k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT;
695      k->class_id = PCI_CLASS_BRIDGE_HOST;
696      /*
697       * PCI-facing part of the host bridge, not usable without the
698       * host-facing part, which can't be device_add'ed, yet.
699       */
700      dc->user_creatable = false;
701  }
702  
703  static const TypeInfo mch_info = {
704      .name = TYPE_MCH_PCI_DEVICE,
705      .parent = TYPE_PCI_DEVICE,
706      .instance_size = sizeof(MCHPCIState),
707      .class_init = mch_class_init,
708      .interfaces = (InterfaceInfo[]) {
709          { INTERFACE_CONVENTIONAL_PCI_DEVICE },
710          { },
711      },
712  };
713  
q35_register(void)714  static void q35_register(void)
715  {
716      type_register_static(&mch_info);
717      type_register_static(&q35_host_info);
718  }
719  
720  type_init(q35_register);
721