qemu/hw/isa/lpc_ich9.c
<<
>>
Prefs
   1/*
   2 * QEMU ICH9 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#include "qemu-common.h"
  31#include "hw/hw.h"
  32#include "qapi/visitor.h"
  33#include "qemu/range.h"
  34#include "hw/isa/isa.h"
  35#include "hw/sysbus.h"
  36#include "hw/i386/pc.h"
  37#include "hw/isa/apm.h"
  38#include "hw/i386/ioapic.h"
  39#include "hw/pci/pci.h"
  40#include "hw/pci/pcie_host.h"
  41#include "hw/pci/pci_bridge.h"
  42#include "hw/i386/ich9.h"
  43#include "hw/acpi/acpi.h"
  44#include "hw/acpi/ich9.h"
  45#include "hw/pci/pci_bus.h"
  46#include "exec/address-spaces.h"
  47#include "sysemu/sysemu.h"
  48
  49static int ich9_lpc_sci_irq(ICH9LPCState *lpc);
  50
  51/*****************************************************************************/
  52/* ICH9 LPC PCI to ISA bridge */
  53
  54static void ich9_lpc_reset(DeviceState *qdev);
  55
  56/* chipset configuration register
  57 * to access chipset configuration registers, pci_[sg]et_{byte, word, long}
  58 * are used.
  59 * Although it's not pci configuration space, it's little endian as Intel.
  60 */
  61
  62static void ich9_cc_update_ir(uint8_t irr[PCI_NUM_PINS], uint16_t ir)
  63{
  64    int intx;
  65    for (intx = 0; intx < PCI_NUM_PINS; intx++) {
  66        irr[intx] = (ir >> (intx * ICH9_CC_DIR_SHIFT)) & ICH9_CC_DIR_MASK;
  67    }
  68}
  69
  70static void ich9_cc_update(ICH9LPCState *lpc)
  71{
  72    int slot;
  73    int pci_intx;
  74
  75    const int reg_offsets[] = {
  76        ICH9_CC_D25IR,
  77        ICH9_CC_D26IR,
  78        ICH9_CC_D27IR,
  79        ICH9_CC_D28IR,
  80        ICH9_CC_D29IR,
  81        ICH9_CC_D30IR,
  82        ICH9_CC_D31IR,
  83    };
  84    const int *offset;
  85
  86    /* D{25 - 31}IR, but D30IR is read only to 0. */
  87    for (slot = 25, offset = reg_offsets; slot < 32; slot++, offset++) {
  88        if (slot == 30) {
  89            continue;
  90        }
  91        ich9_cc_update_ir(lpc->irr[slot],
  92                          pci_get_word(lpc->chip_config + *offset));
  93    }
  94
  95    /*
  96     * D30: DMI2PCI bridge
  97     * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge
  98     * are connected to pirq lines. Our choice is PIRQ[E-H].
  99     * INT[A-D] are connected to PIRQ[E-H]
 100     */
 101    for (pci_intx = 0; pci_intx < PCI_NUM_PINS; pci_intx++) {
 102        lpc->irr[30][pci_intx] = pci_intx + 4;
 103    }
 104}
 105
 106static void ich9_cc_init(ICH9LPCState *lpc)
 107{
 108    int slot;
 109    int intx;
 110
 111    /* the default irq routing is arbitrary as long as it matches with
 112     * acpi irq routing table.
 113     * The one that is incompatible with piix_pci(= bochs) one is
 114     * intentionally chosen to let the users know that the different
 115     * board is used.
 116     *
 117     * int[A-D] -> pirq[E-F]
 118     * avoid pirq A-D because they are used for pci express port
 119     */
 120    for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
 121        for (intx = 0; intx < PCI_NUM_PINS; intx++) {
 122            lpc->irr[slot][intx] = (slot + intx) % 4 + 4;
 123        }
 124    }
 125    ich9_cc_update(lpc);
 126}
 127
 128static void ich9_cc_reset(ICH9LPCState *lpc)
 129{
 130    uint8_t *c = lpc->chip_config;
 131
 132    memset(lpc->chip_config, 0, sizeof(lpc->chip_config));
 133
 134    pci_set_long(c + ICH9_CC_D31IR, ICH9_CC_DIR_DEFAULT);
 135    pci_set_long(c + ICH9_CC_D30IR, ICH9_CC_D30IR_DEFAULT);
 136    pci_set_long(c + ICH9_CC_D29IR, ICH9_CC_DIR_DEFAULT);
 137    pci_set_long(c + ICH9_CC_D28IR, ICH9_CC_DIR_DEFAULT);
 138    pci_set_long(c + ICH9_CC_D27IR, ICH9_CC_DIR_DEFAULT);
 139    pci_set_long(c + ICH9_CC_D26IR, ICH9_CC_DIR_DEFAULT);
 140    pci_set_long(c + ICH9_CC_D25IR, ICH9_CC_DIR_DEFAULT);
 141
 142    ich9_cc_update(lpc);
 143}
 144
 145static void ich9_cc_addr_len(uint64_t *addr, unsigned *len)
 146{
 147    *addr &= ICH9_CC_ADDR_MASK;
 148    if (*addr + *len >= ICH9_CC_SIZE) {
 149        *len = ICH9_CC_SIZE - *addr;
 150    }
 151}
 152
 153/* val: little endian */
 154static void ich9_cc_write(void *opaque, hwaddr addr,
 155                          uint64_t val, unsigned len)
 156{
 157    ICH9LPCState *lpc = (ICH9LPCState *)opaque;
 158
 159    ich9_cc_addr_len(&addr, &len);
 160    memcpy(lpc->chip_config + addr, &val, len);
 161    pci_bus_fire_intx_routing_notifier(lpc->d.bus);
 162    ich9_cc_update(lpc);
 163}
 164
 165/* return value: little endian */
 166static uint64_t ich9_cc_read(void *opaque, hwaddr addr,
 167                              unsigned len)
 168{
 169    ICH9LPCState *lpc = (ICH9LPCState *)opaque;
 170
 171    uint32_t val = 0;
 172    ich9_cc_addr_len(&addr, &len);
 173    memcpy(&val, lpc->chip_config + addr, len);
 174    return val;
 175}
 176
 177/* IRQ routing */
 178/* */
 179static void ich9_lpc_rout(uint8_t pirq_rout, int *pic_irq, int *pic_dis)
 180{
 181    *pic_irq = pirq_rout & ICH9_LPC_PIRQ_ROUT_MASK;
 182    *pic_dis = pirq_rout & ICH9_LPC_PIRQ_ROUT_IRQEN;
 183}
 184
 185static void ich9_lpc_pic_irq(ICH9LPCState *lpc, int pirq_num,
 186                             int *pic_irq, int *pic_dis)
 187{
 188    switch (pirq_num) {
 189    case 0 ... 3: /* A-D */
 190        ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQA_ROUT + pirq_num],
 191                      pic_irq, pic_dis);
 192        return;
 193    case 4 ... 7: /* E-H */
 194        ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQE_ROUT + (pirq_num - 4)],
 195                      pic_irq, pic_dis);
 196        return;
 197    default:
 198        break;
 199    }
 200    abort();
 201}
 202
 203/* pic_irq: i8254 irq 0-15 */
 204static void ich9_lpc_update_pic(ICH9LPCState *lpc, int pic_irq)
 205{
 206    int i, pic_level;
 207
 208    /* The pic level is the logical OR of all the PCI irqs mapped to it */
 209    pic_level = 0;
 210    for (i = 0; i < ICH9_LPC_NB_PIRQS; i++) {
 211        int tmp_irq;
 212        int tmp_dis;
 213        ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
 214        if (!tmp_dis && pic_irq == tmp_irq) {
 215            pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
 216        }
 217    }
 218    if (pic_irq == ich9_lpc_sci_irq(lpc)) {
 219        pic_level |= lpc->sci_level;
 220    }
 221
 222    qemu_set_irq(lpc->pic[pic_irq], pic_level);
 223}
 224
 225/* pirq: pirq[A-H] 0-7*/
 226static void ich9_lpc_update_by_pirq(ICH9LPCState *lpc, int pirq)
 227{
 228    int pic_irq;
 229    int pic_dis;
 230
 231    ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis);
 232    assert(pic_irq < ICH9_LPC_PIC_NUM_PINS);
 233    if (pic_dis) {
 234        return;
 235    }
 236
 237    ich9_lpc_update_pic(lpc, pic_irq);
 238}
 239
 240/* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */
 241static int ich9_pirq_to_gsi(int pirq)
 242{
 243    return pirq + ICH9_LPC_PIC_NUM_PINS;
 244}
 245
 246static int ich9_gsi_to_pirq(int gsi)
 247{
 248    return gsi - ICH9_LPC_PIC_NUM_PINS;
 249}
 250
 251static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
 252{
 253    int level = 0;
 254
 255    if (gsi >= ICH9_LPC_PIC_NUM_PINS) {
 256        level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
 257    }
 258    if (gsi == ich9_lpc_sci_irq(lpc)) {
 259        level |= lpc->sci_level;
 260    }
 261
 262    qemu_set_irq(lpc->ioapic[gsi], level);
 263}
 264
 265void ich9_lpc_set_irq(void *opaque, int pirq, int level)
 266{
 267    ICH9LPCState *lpc = opaque;
 268
 269    assert(0 <= pirq);
 270    assert(pirq < ICH9_LPC_NB_PIRQS);
 271
 272    ich9_lpc_update_apic(lpc, ich9_pirq_to_gsi(pirq));
 273    ich9_lpc_update_by_pirq(lpc, pirq);
 274}
 275
 276/* return the pirq number (PIRQ[A-H]:0-7) corresponding to
 277 * a given device irq pin.
 278 */
 279int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx)
 280{
 281    BusState *bus = qdev_get_parent_bus(&pci_dev->qdev);
 282    PCIBus *pci_bus = PCI_BUS(bus);
 283    PCIDevice *lpc_pdev =
 284            pci_bus->devices[PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC)];
 285    ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pdev);
 286
 287    return lpc->irr[PCI_SLOT(pci_dev->devfn)][intx];
 288}
 289
 290PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin)
 291{
 292    ICH9LPCState *lpc = opaque;
 293    PCIINTxRoute route;
 294    int pic_irq;
 295    int pic_dis;
 296
 297    assert(0 <= pirq_pin);
 298    assert(pirq_pin < ICH9_LPC_NB_PIRQS);
 299
 300    route.mode = PCI_INTX_ENABLED;
 301    ich9_lpc_pic_irq(lpc, pirq_pin, &pic_irq, &pic_dis);
 302    if (!pic_dis) {
 303        if (pic_irq < ICH9_LPC_PIC_NUM_PINS) {
 304            route.irq = pic_irq;
 305        } else {
 306            route.mode = PCI_INTX_DISABLED;
 307            route.irq = -1;
 308        }
 309    } else {
 310        route.irq = ich9_pirq_to_gsi(pirq_pin);
 311    }
 312
 313    return route;
 314}
 315
 316static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
 317{
 318    switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] &
 319            ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK) {
 320    case ICH9_LPC_ACPI_CTRL_9:
 321        return 9;
 322    case ICH9_LPC_ACPI_CTRL_10:
 323        return 10;
 324    case ICH9_LPC_ACPI_CTRL_11:
 325        return 11;
 326    case ICH9_LPC_ACPI_CTRL_20:
 327        return 20;
 328    case ICH9_LPC_ACPI_CTRL_21:
 329        return 21;
 330    default:
 331        /* reserved */
 332        break;
 333    }
 334    return -1;
 335}
 336
 337static void ich9_set_sci(void *opaque, int irq_num, int level)
 338{
 339    ICH9LPCState *lpc = opaque;
 340    int irq;
 341
 342    assert(irq_num == 0);
 343    level = !!level;
 344    if (level == lpc->sci_level) {
 345        return;
 346    }
 347    lpc->sci_level = level;
 348
 349    irq = ich9_lpc_sci_irq(lpc);
 350    if (irq < 0) {
 351        return;
 352    }
 353
 354    ich9_lpc_update_apic(lpc, irq);
 355    if (irq < ICH9_LPC_PIC_NUM_PINS) {
 356        ich9_lpc_update_pic(lpc, irq);
 357    }
 358}
 359
 360void ich9_lpc_pm_init(PCIDevice *lpc_pci)
 361{
 362    ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
 363    qemu_irq *sci_irq;
 364
 365    sci_irq = qemu_allocate_irqs(ich9_set_sci, lpc, 1);
 366    ich9_pm_init(lpc_pci, &lpc->pm, sci_irq[0]);
 367
 368    ich9_lpc_reset(&lpc->d.qdev);
 369}
 370
 371/* APM */
 372
 373static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 374{
 375    ICH9LPCState *lpc = arg;
 376
 377    /* ACPI specs 3.0, 4.7.2.5 */
 378    acpi_pm1_cnt_update(&lpc->pm.acpi_regs,
 379                        val == ICH9_APM_ACPI_ENABLE,
 380                        val == ICH9_APM_ACPI_DISABLE);
 381
 382    /* SMI_EN = PMBASE + 30. SMI control and enable register */
 383    if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
 384        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
 385    }
 386}
 387
 388/* config:PMBASE */
 389static void
 390ich9_lpc_pmbase_update(ICH9LPCState *lpc)
 391{
 392    uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE);
 393    pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK;
 394
 395    ich9_pm_iospace_update(&lpc->pm, pm_io_base);
 396}
 397
 398/* config:RBCA */
 399static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
 400{
 401    uint32_t rbca = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
 402
 403    if (rbca_old & ICH9_LPC_RCBA_EN) {
 404            memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem);
 405    }
 406    if (rbca & ICH9_LPC_RCBA_EN) {
 407            memory_region_add_subregion_overlap(get_system_memory(),
 408                                                rbca & ICH9_LPC_RCBA_BA_MASK,
 409                                                &lpc->rbca_mem, 1);
 410    }
 411}
 412
 413static int ich9_lpc_post_load(void *opaque, int version_id)
 414{
 415    ICH9LPCState *lpc = opaque;
 416
 417    ich9_lpc_pmbase_update(lpc);
 418    ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
 419    return 0;
 420}
 421
 422static void ich9_lpc_config_write(PCIDevice *d,
 423                                  uint32_t addr, uint32_t val, int len)
 424{
 425    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
 426    uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
 427
 428    pci_default_write_config(d, addr, val, len);
 429    if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4)) {
 430        ich9_lpc_pmbase_update(lpc);
 431    }
 432    if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) {
 433        ich9_lpc_rcba_update(lpc, rbca_old);
 434    }
 435    if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
 436        pci_bus_fire_intx_routing_notifier(lpc->d.bus);
 437    }
 438    if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
 439        pci_bus_fire_intx_routing_notifier(lpc->d.bus);
 440    }
 441}
 442
 443static void ich9_lpc_reset(DeviceState *qdev)
 444{
 445    PCIDevice *d = PCI_DEVICE(qdev);
 446    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
 447    uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
 448    int i;
 449
 450    for (i = 0; i < 4; i++) {
 451        pci_set_byte(d->config + ICH9_LPC_PIRQA_ROUT + i,
 452                     ICH9_LPC_PIRQ_ROUT_DEFAULT);
 453    }
 454    for (i = 0; i < 4; i++) {
 455        pci_set_byte(d->config + ICH9_LPC_PIRQE_ROUT + i,
 456                     ICH9_LPC_PIRQ_ROUT_DEFAULT);
 457    }
 458    pci_set_byte(d->config + ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_DEFAULT);
 459
 460    pci_set_long(d->config + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_DEFAULT);
 461    pci_set_long(d->config + ICH9_LPC_RCBA, ICH9_LPC_RCBA_DEFAULT);
 462
 463    ich9_cc_reset(lpc);
 464
 465    ich9_lpc_pmbase_update(lpc);
 466    ich9_lpc_rcba_update(lpc, rbca_old);
 467
 468    lpc->sci_level = 0;
 469    lpc->rst_cnt = 0;
 470}
 471
 472static const MemoryRegionOps rbca_mmio_ops = {
 473    .read = ich9_cc_read,
 474    .write = ich9_cc_write,
 475    .endianness = DEVICE_LITTLE_ENDIAN,
 476};
 477
 478static void ich9_lpc_machine_ready(Notifier *n, void *opaque)
 479{
 480    ICH9LPCState *s = container_of(n, ICH9LPCState, machine_ready);
 481    MemoryRegion *io_as = pci_address_space_io(&s->d);
 482    uint8_t *pci_conf;
 483
 484    pci_conf = s->d.config;
 485    if (memory_region_present(io_as, 0x3f8)) {
 486        /* com1 */
 487        pci_conf[0x82] |= 0x01;
 488    }
 489    if (memory_region_present(io_as, 0x2f8)) {
 490        /* com2 */
 491        pci_conf[0x82] |= 0x02;
 492    }
 493    if (memory_region_present(io_as, 0x378)) {
 494        /* lpt */
 495        pci_conf[0x82] |= 0x04;
 496    }
 497    if (memory_region_present(io_as, 0x3f0)) {
 498        /* floppy */
 499        pci_conf[0x82] |= 0x08;
 500    }
 501}
 502
 503/* reset control */
 504static void ich9_rst_cnt_write(void *opaque, hwaddr addr, uint64_t val,
 505                               unsigned len)
 506{
 507    ICH9LPCState *lpc = opaque;
 508
 509    if (val & 4) {
 510        qemu_system_reset_request();
 511        return;
 512    }
 513    lpc->rst_cnt = val & 0xA; /* keep FULL_RST (bit 3) and SYS_RST (bit 1) */
 514}
 515
 516static uint64_t ich9_rst_cnt_read(void *opaque, hwaddr addr, unsigned len)
 517{
 518    ICH9LPCState *lpc = opaque;
 519
 520    return lpc->rst_cnt;
 521}
 522
 523static const MemoryRegionOps ich9_rst_cnt_ops = {
 524    .read = ich9_rst_cnt_read,
 525    .write = ich9_rst_cnt_write,
 526    .endianness = DEVICE_LITTLE_ENDIAN
 527};
 528
 529Object *ich9_lpc_find(void)
 530{
 531    bool ambig;
 532    Object *o = object_resolve_path_type("", TYPE_ICH9_LPC_DEVICE, &ambig);
 533
 534    if (ambig) {
 535        return NULL;
 536    }
 537    return o;
 538}
 539
 540static void ich9_lpc_get_sci_int(Object *obj, Visitor *v,
 541                                 void *opaque, const char *name,
 542                                 Error **errp)
 543{
 544    ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj);
 545    uint32_t value = ich9_lpc_sci_irq(lpc);
 546
 547    visit_type_uint32(v, &value, name, errp);
 548}
 549
 550static void ich9_lpc_add_properties(ICH9LPCState *lpc)
 551{
 552    static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE;
 553    static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE;
 554
 555    object_property_add(OBJECT(lpc), ACPI_PM_PROP_SCI_INT, "uint32",
 556                        ich9_lpc_get_sci_int,
 557                        NULL, NULL, NULL, NULL);
 558    object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD,
 559                                  &acpi_enable_cmd, NULL);
 560    object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD,
 561                                  &acpi_disable_cmd, NULL);
 562
 563    ich9_pm_add_properties(OBJECT(lpc), &lpc->pm, NULL);
 564}
 565
 566static void ich9_lpc_initfn(Object *obj)
 567{
 568    ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj);
 569
 570    ich9_lpc_add_properties(lpc);
 571}
 572
 573static int ich9_lpc_init(PCIDevice *d)
 574{
 575    ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
 576    ISABus *isa_bus;
 577
 578    isa_bus = isa_bus_new(&d->qdev, get_system_io());
 579
 580    pci_set_long(d->wmask + ICH9_LPC_PMBASE,
 581                 ICH9_LPC_PMBASE_BASE_ADDRESS_MASK);
 582
 583    memory_region_init_io(&lpc->rbca_mem, OBJECT(d), &rbca_mmio_ops, lpc,
 584                            "lpc-rbca-mmio", ICH9_CC_SIZE);
 585
 586    lpc->isa_bus = isa_bus;
 587
 588    ich9_cc_init(lpc);
 589    apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc);
 590
 591    lpc->machine_ready.notify = ich9_lpc_machine_ready;
 592    qemu_add_machine_init_done_notifier(&lpc->machine_ready);
 593
 594    memory_region_init_io(&lpc->rst_cnt_mem, OBJECT(d), &ich9_rst_cnt_ops, lpc,
 595                          "lpc-reset-control", 1);
 596    memory_region_add_subregion_overlap(pci_address_space_io(d),
 597                                        ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
 598                                        1);
 599    return 0;
 600}
 601
 602static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
 603                                DeviceState *dev, Error **errp)
 604{
 605    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
 606
 607    ich9_pm_device_plug_cb(&lpc->pm, dev, errp);
 608}
 609
 610static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev,
 611                                          DeviceState *dev, Error **errp)
 612{
 613    error_setg(errp, "acpi: device unplug request for not supported device"
 614               " type: %s", object_get_typename(OBJECT(dev)));
 615}
 616
 617static bool ich9_rst_cnt_needed(void *opaque)
 618{
 619    ICH9LPCState *lpc = opaque;
 620
 621    return (lpc->rst_cnt != 0);
 622}
 623
 624static const VMStateDescription vmstate_ich9_rst_cnt = {
 625    .name = "ICH9LPC/rst_cnt",
 626    .version_id = 1,
 627    .minimum_version_id = 1,
 628    .fields = (VMStateField[]) {
 629        VMSTATE_UINT8(rst_cnt, ICH9LPCState),
 630        VMSTATE_END_OF_LIST()
 631    }
 632};
 633
 634static const VMStateDescription vmstate_ich9_lpc = {
 635    .name = "ICH9LPC",
 636    .version_id = 1,
 637    .minimum_version_id = 1,
 638    .post_load = ich9_lpc_post_load,
 639    .fields = (VMStateField[]) {
 640        VMSTATE_PCI_DEVICE(d, ICH9LPCState),
 641        VMSTATE_STRUCT(apm, ICH9LPCState, 0, vmstate_apm, APMState),
 642        VMSTATE_STRUCT(pm, ICH9LPCState, 0, vmstate_ich9_pm, ICH9LPCPMRegs),
 643        VMSTATE_UINT8_ARRAY(chip_config, ICH9LPCState, ICH9_CC_SIZE),
 644        VMSTATE_UINT32(sci_level, ICH9LPCState),
 645        VMSTATE_END_OF_LIST()
 646    },
 647    .subsections = (VMStateSubsection[]) {
 648        {
 649            .vmsd = &vmstate_ich9_rst_cnt,
 650            .needed = ich9_rst_cnt_needed
 651        },
 652        { 0 }
 653    }
 654};
 655
 656static void ich9_lpc_class_init(ObjectClass *klass, void *data)
 657{
 658    DeviceClass *dc = DEVICE_CLASS(klass);
 659    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 660    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 661    AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass);
 662
 663    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 664    dc->reset = ich9_lpc_reset;
 665    k->init = ich9_lpc_init;
 666    dc->vmsd = &vmstate_ich9_lpc;
 667    k->config_write = ich9_lpc_config_write;
 668    dc->desc = "ICH9 LPC bridge";
 669    k->vendor_id = PCI_VENDOR_ID_INTEL;
 670    k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8;
 671    k->revision = ICH9_A2_LPC_REVISION;
 672    k->class_id = PCI_CLASS_BRIDGE_ISA;
 673    /*
 674     * Reason: part of ICH9 southbridge, needs to be wired up by
 675     * pc_q35_init()
 676     */
 677    dc->cannot_instantiate_with_device_add_yet = true;
 678    hc->plug = ich9_device_plug_cb;
 679    hc->unplug_request = ich9_device_unplug_request_cb;
 680    adevc->ospm_status = ich9_pm_ospm_status;
 681}
 682
 683static const TypeInfo ich9_lpc_info = {
 684    .name       = TYPE_ICH9_LPC_DEVICE,
 685    .parent     = TYPE_PCI_DEVICE,
 686    .instance_size = sizeof(struct ICH9LPCState),
 687    .instance_init = ich9_lpc_initfn,
 688    .class_init  = ich9_lpc_class_init,
 689    .interfaces = (InterfaceInfo[]) {
 690        { TYPE_HOTPLUG_HANDLER },
 691        { TYPE_ACPI_DEVICE_IF },
 692        { }
 693    }
 694};
 695
 696static void ich9_lpc_register(void)
 697{
 698    type_register_static(&ich9_lpc_info);
 699}
 700
 701type_init(ich9_lpc_register);
 702