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