1 /* 2 * ACPI implementation 3 * 4 * Copyright (c) 2006 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License version 2 as published by the Free Software Foundation. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, see <http://www.gnu.org/licenses/> 17 * 18 * Contributions after 2012-01-13 are licensed under the terms of the 19 * GNU GPL, version 2 or (at your option) any later version. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "hw/i386/pc.h" 24 #include "hw/southbridge/piix.h" 25 #include "hw/irq.h" 26 #include "hw/isa/apm.h" 27 #include "hw/i2c/pm_smbus.h" 28 #include "hw/pci/pci.h" 29 #include "hw/qdev-properties.h" 30 #include "hw/acpi/acpi.h" 31 #include "sysemu/runstate.h" 32 #include "sysemu/sysemu.h" 33 #include "qapi/error.h" 34 #include "qemu/range.h" 35 #include "exec/address-spaces.h" 36 #include "hw/acpi/pcihp.h" 37 #include "hw/acpi/cpu_hotplug.h" 38 #include "hw/acpi/cpu.h" 39 #include "hw/hotplug.h" 40 #include "hw/mem/pc-dimm.h" 41 #include "hw/acpi/memory_hotplug.h" 42 #include "hw/acpi/acpi_dev_interface.h" 43 #include "hw/xen/xen.h" 44 #include "migration/vmstate.h" 45 #include "hw/core/cpu.h" 46 #include "trace.h" 47 48 #define GPE_BASE 0xafe0 49 #define GPE_LEN 4 50 51 struct pci_status { 52 uint32_t up; /* deprecated, maintained for migration compatibility */ 53 uint32_t down; 54 }; 55 56 typedef struct PIIX4PMState { 57 /*< private >*/ 58 PCIDevice parent_obj; 59 /*< public >*/ 60 61 MemoryRegion io; 62 uint32_t io_base; 63 64 MemoryRegion io_gpe; 65 ACPIREGS ar; 66 67 APMState apm; 68 69 PMSMBus smb; 70 uint32_t smb_io_base; 71 72 qemu_irq irq; 73 qemu_irq smi_irq; 74 int smm_enabled; 75 Notifier machine_ready; 76 Notifier powerdown_notifier; 77 78 AcpiPciHpState acpi_pci_hotplug; 79 bool use_acpi_pci_hotplug; 80 81 uint8_t disable_s3; 82 uint8_t disable_s4; 83 uint8_t s4_val; 84 85 bool cpu_hotplug_legacy; 86 AcpiCpuHotplug gpe_cpu; 87 CPUHotplugState cpuhp_state; 88 89 MemHotplugState acpi_memory_hotplug; 90 } PIIX4PMState; 91 92 #define PIIX4_PM(obj) \ 93 OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM) 94 95 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, 96 PCIBus *bus, PIIX4PMState *s); 97 98 #define ACPI_ENABLE 0xf1 99 #define ACPI_DISABLE 0xf0 100 101 static void pm_tmr_timer(ACPIREGS *ar) 102 { 103 PIIX4PMState *s = container_of(ar, PIIX4PMState, ar); 104 acpi_update_sci(&s->ar, s->irq); 105 } 106 107 static void apm_ctrl_changed(uint32_t val, void *arg) 108 { 109 PIIX4PMState *s = arg; 110 PCIDevice *d = PCI_DEVICE(s); 111 112 /* ACPI specs 3.0, 4.7.2.5 */ 113 acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE); 114 if (val == ACPI_ENABLE || val == ACPI_DISABLE) { 115 return; 116 } 117 118 if (d->config[0x5b] & (1 << 1)) { 119 if (s->smi_irq) { 120 qemu_irq_raise(s->smi_irq); 121 } 122 } 123 } 124 125 static void pm_io_space_update(PIIX4PMState *s) 126 { 127 PCIDevice *d = PCI_DEVICE(s); 128 129 s->io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40)); 130 s->io_base &= 0xffc0; 131 132 memory_region_transaction_begin(); 133 memory_region_set_enabled(&s->io, d->config[0x80] & 1); 134 memory_region_set_address(&s->io, s->io_base); 135 memory_region_transaction_commit(); 136 } 137 138 static void smbus_io_space_update(PIIX4PMState *s) 139 { 140 PCIDevice *d = PCI_DEVICE(s); 141 142 s->smb_io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x90)); 143 s->smb_io_base &= 0xffc0; 144 145 memory_region_transaction_begin(); 146 memory_region_set_enabled(&s->smb.io, d->config[0xd2] & 1); 147 memory_region_set_address(&s->smb.io, s->smb_io_base); 148 memory_region_transaction_commit(); 149 } 150 151 static void pm_write_config(PCIDevice *d, 152 uint32_t address, uint32_t val, int len) 153 { 154 pci_default_write_config(d, address, val, len); 155 if (range_covers_byte(address, len, 0x80) || 156 ranges_overlap(address, len, 0x40, 4)) { 157 pm_io_space_update((PIIX4PMState *)d); 158 } 159 if (range_covers_byte(address, len, 0xd2) || 160 ranges_overlap(address, len, 0x90, 4)) { 161 smbus_io_space_update((PIIX4PMState *)d); 162 } 163 } 164 165 static int vmstate_acpi_post_load(void *opaque, int version_id) 166 { 167 PIIX4PMState *s = opaque; 168 169 pm_io_space_update(s); 170 smbus_io_space_update(s); 171 return 0; 172 } 173 174 #define VMSTATE_GPE_ARRAY(_field, _state) \ 175 { \ 176 .name = (stringify(_field)), \ 177 .version_id = 0, \ 178 .info = &vmstate_info_uint16, \ 179 .size = sizeof(uint16_t), \ 180 .flags = VMS_SINGLE | VMS_POINTER, \ 181 .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ 182 } 183 184 static const VMStateDescription vmstate_gpe = { 185 .name = "gpe", 186 .version_id = 1, 187 .minimum_version_id = 1, 188 .fields = (VMStateField[]) { 189 VMSTATE_GPE_ARRAY(sts, ACPIGPE), 190 VMSTATE_GPE_ARRAY(en, ACPIGPE), 191 VMSTATE_END_OF_LIST() 192 } 193 }; 194 195 static const VMStateDescription vmstate_pci_status = { 196 .name = "pci_status", 197 .version_id = 1, 198 .minimum_version_id = 1, 199 .fields = (VMStateField[]) { 200 VMSTATE_UINT32(up, struct AcpiPciHpPciStatus), 201 VMSTATE_UINT32(down, struct AcpiPciHpPciStatus), 202 VMSTATE_END_OF_LIST() 203 } 204 }; 205 206 static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) 207 { 208 PIIX4PMState *s = opaque; 209 return s->use_acpi_pci_hotplug; 210 } 211 212 static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) 213 { 214 PIIX4PMState *s = opaque; 215 return !s->use_acpi_pci_hotplug; 216 } 217 218 static bool vmstate_test_use_memhp(void *opaque) 219 { 220 PIIX4PMState *s = opaque; 221 return s->acpi_memory_hotplug.is_enabled; 222 } 223 224 static const VMStateDescription vmstate_memhp_state = { 225 .name = "piix4_pm/memhp", 226 .version_id = 1, 227 .minimum_version_id = 1, 228 .minimum_version_id_old = 1, 229 .needed = vmstate_test_use_memhp, 230 .fields = (VMStateField[]) { 231 VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState), 232 VMSTATE_END_OF_LIST() 233 } 234 }; 235 236 static bool vmstate_test_use_cpuhp(void *opaque) 237 { 238 PIIX4PMState *s = opaque; 239 return !s->cpu_hotplug_legacy; 240 } 241 242 static int vmstate_cpuhp_pre_load(void *opaque) 243 { 244 Object *obj = OBJECT(opaque); 245 object_property_set_bool(obj, false, "cpu-hotplug-legacy", &error_abort); 246 return 0; 247 } 248 249 static const VMStateDescription vmstate_cpuhp_state = { 250 .name = "piix4_pm/cpuhp", 251 .version_id = 1, 252 .minimum_version_id = 1, 253 .minimum_version_id_old = 1, 254 .needed = vmstate_test_use_cpuhp, 255 .pre_load = vmstate_cpuhp_pre_load, 256 .fields = (VMStateField[]) { 257 VMSTATE_CPU_HOTPLUG(cpuhp_state, PIIX4PMState), 258 VMSTATE_END_OF_LIST() 259 } 260 }; 261 262 static bool piix4_vmstate_need_smbus(void *opaque, int version_id) 263 { 264 return pm_smbus_vmstate_needed(); 265 } 266 267 /* qemu-kvm 1.2 uses version 3 but advertised as 2 268 * To support incoming qemu-kvm 1.2 migration, change version_id 269 * and minimum_version_id to 2 below (which breaks migration from 270 * qemu 1.2). 271 * 272 */ 273 static const VMStateDescription vmstate_acpi = { 274 .name = "piix4_pm", 275 .version_id = 3, 276 .minimum_version_id = 3, 277 .post_load = vmstate_acpi_post_load, 278 .fields = (VMStateField[]) { 279 VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), 280 VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState), 281 VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState), 282 VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState), 283 VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState), 284 VMSTATE_STRUCT_TEST(smb, PIIX4PMState, piix4_vmstate_need_smbus, 3, 285 pmsmb_vmstate, PMSMBus), 286 VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState), 287 VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), 288 VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), 289 VMSTATE_STRUCT_TEST( 290 acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], 291 PIIX4PMState, 292 vmstate_test_no_use_acpi_pci_hotplug, 293 2, vmstate_pci_status, 294 struct AcpiPciHpPciStatus), 295 VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, 296 vmstate_test_use_acpi_pci_hotplug), 297 VMSTATE_END_OF_LIST() 298 }, 299 .subsections = (const VMStateDescription*[]) { 300 &vmstate_memhp_state, 301 &vmstate_cpuhp_state, 302 NULL 303 } 304 }; 305 306 static void piix4_pm_reset(DeviceState *dev) 307 { 308 PIIX4PMState *s = PIIX4_PM(dev); 309 PCIDevice *d = PCI_DEVICE(s); 310 uint8_t *pci_conf = d->config; 311 312 pci_conf[0x58] = 0; 313 pci_conf[0x59] = 0; 314 pci_conf[0x5a] = 0; 315 pci_conf[0x5b] = 0; 316 317 pci_conf[0x40] = 0x01; /* PM io base read only bit */ 318 pci_conf[0x80] = 0; 319 320 if (!s->smm_enabled) { 321 /* Mark SMM as already inited (until KVM supports SMM). */ 322 pci_conf[0x5B] = 0x02; 323 } 324 pm_io_space_update(s); 325 acpi_pcihp_reset(&s->acpi_pci_hotplug); 326 } 327 328 static void piix4_pm_powerdown_req(Notifier *n, void *opaque) 329 { 330 PIIX4PMState *s = container_of(n, PIIX4PMState, powerdown_notifier); 331 332 assert(s != NULL); 333 acpi_pm1_evt_power_down(&s->ar); 334 } 335 336 static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev, 337 DeviceState *dev, Error **errp) 338 { 339 PIIX4PMState *s = PIIX4_PM(hotplug_dev); 340 341 if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 342 acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp); 343 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 344 if (!s->acpi_memory_hotplug.is_enabled) { 345 error_setg(errp, 346 "memory hotplug is not enabled: %s.memory-hotplug-support " 347 "is not set", object_get_typename(OBJECT(s))); 348 } 349 } else if ( 350 !object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { 351 error_setg(errp, "acpi: device pre plug request for not supported" 352 " device type: %s", object_get_typename(OBJECT(dev))); 353 } 354 } 355 356 static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, 357 DeviceState *dev, Error **errp) 358 { 359 PIIX4PMState *s = PIIX4_PM(hotplug_dev); 360 361 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 362 if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { 363 nvdimm_acpi_plug_cb(hotplug_dev, dev); 364 } else { 365 acpi_memory_plug_cb(hotplug_dev, &s->acpi_memory_hotplug, 366 dev, errp); 367 } 368 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 369 acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp); 370 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { 371 if (s->cpu_hotplug_legacy) { 372 legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp); 373 } else { 374 acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp); 375 } 376 } else { 377 g_assert_not_reached(); 378 } 379 } 380 381 static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, 382 DeviceState *dev, Error **errp) 383 { 384 PIIX4PMState *s = PIIX4_PM(hotplug_dev); 385 386 if (s->acpi_memory_hotplug.is_enabled && 387 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 388 acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug, 389 dev, errp); 390 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 391 acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->acpi_pci_hotplug, 392 dev, errp); 393 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) && 394 !s->cpu_hotplug_legacy) { 395 acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp); 396 } else { 397 error_setg(errp, "acpi: device unplug request for not supported device" 398 " type: %s", object_get_typename(OBJECT(dev))); 399 } 400 } 401 402 static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev, 403 DeviceState *dev, Error **errp) 404 { 405 PIIX4PMState *s = PIIX4_PM(hotplug_dev); 406 407 if (s->acpi_memory_hotplug.is_enabled && 408 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 409 acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp); 410 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 411 acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, 412 errp); 413 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) && 414 !s->cpu_hotplug_legacy) { 415 acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp); 416 } else { 417 error_setg(errp, "acpi: device unplug for not supported device" 418 " type: %s", object_get_typename(OBJECT(dev))); 419 } 420 } 421 422 static void piix4_pm_machine_ready(Notifier *n, void *opaque) 423 { 424 PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); 425 PCIDevice *d = PCI_DEVICE(s); 426 MemoryRegion *io_as = pci_address_space_io(d); 427 uint8_t *pci_conf; 428 429 pci_conf = d->config; 430 pci_conf[0x5f] = 0x10 | 431 (memory_region_present(io_as, 0x378) ? 0x80 : 0); 432 pci_conf[0x63] = 0x60; 433 pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | 434 (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); 435 } 436 437 static void piix4_pm_add_propeties(PIIX4PMState *s) 438 { 439 static const uint8_t acpi_enable_cmd = ACPI_ENABLE; 440 static const uint8_t acpi_disable_cmd = ACPI_DISABLE; 441 static const uint32_t gpe0_blk = GPE_BASE; 442 static const uint32_t gpe0_blk_len = GPE_LEN; 443 static const uint16_t sci_int = 9; 444 445 object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD, 446 &acpi_enable_cmd, NULL); 447 object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD, 448 &acpi_disable_cmd, NULL); 449 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK, 450 &gpe0_blk, NULL); 451 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN, 452 &gpe0_blk_len, NULL); 453 object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT, 454 &sci_int, NULL); 455 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE, 456 &s->io_base, NULL); 457 } 458 459 static void piix4_pm_realize(PCIDevice *dev, Error **errp) 460 { 461 PIIX4PMState *s = PIIX4_PM(dev); 462 uint8_t *pci_conf; 463 464 pci_conf = dev->config; 465 pci_conf[0x06] = 0x80; 466 pci_conf[0x07] = 0x02; 467 pci_conf[0x09] = 0x00; 468 pci_conf[0x3d] = 0x01; // interrupt pin 1 469 470 /* APM */ 471 apm_init(dev, &s->apm, apm_ctrl_changed, s); 472 473 if (!s->smm_enabled) { 474 /* Mark SMM as already inited to prevent SMM from running. KVM does not 475 * support SMM mode. */ 476 pci_conf[0x5B] = 0x02; 477 } 478 479 /* XXX: which specification is used ? The i82731AB has different 480 mappings */ 481 pci_conf[0x90] = s->smb_io_base | 1; 482 pci_conf[0x91] = s->smb_io_base >> 8; 483 pci_conf[0xd2] = 0x09; 484 pm_smbus_init(DEVICE(dev), &s->smb, true); 485 memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1); 486 memory_region_add_subregion(pci_address_space_io(dev), 487 s->smb_io_base, &s->smb.io); 488 489 memory_region_init(&s->io, OBJECT(s), "piix4-pm", 64); 490 memory_region_set_enabled(&s->io, false); 491 memory_region_add_subregion(pci_address_space_io(dev), 492 0, &s->io); 493 494 acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); 495 acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); 496 acpi_pm1_cnt_init(&s->ar, &s->io, s->disable_s3, s->disable_s4, s->s4_val); 497 acpi_gpe_init(&s->ar, GPE_LEN); 498 499 s->powerdown_notifier.notify = piix4_pm_powerdown_req; 500 qemu_register_powerdown_notifier(&s->powerdown_notifier); 501 502 s->machine_ready.notify = piix4_pm_machine_ready; 503 qemu_add_machine_init_done_notifier(&s->machine_ready); 504 505 piix4_acpi_system_hot_add_init(pci_address_space_io(dev), 506 pci_get_bus(dev), s); 507 qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), OBJECT(s), &error_abort); 508 509 piix4_pm_add_propeties(s); 510 } 511 512 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, 513 qemu_irq sci_irq, qemu_irq smi_irq, 514 int smm_enabled, DeviceState **piix4_pm) 515 { 516 DeviceState *dev; 517 PIIX4PMState *s; 518 519 dev = DEVICE(pci_create(bus, devfn, TYPE_PIIX4_PM)); 520 qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base); 521 if (piix4_pm) { 522 *piix4_pm = dev; 523 } 524 525 s = PIIX4_PM(dev); 526 s->irq = sci_irq; 527 s->smi_irq = smi_irq; 528 s->smm_enabled = smm_enabled; 529 if (xen_enabled()) { 530 s->use_acpi_pci_hotplug = false; 531 } 532 533 qdev_init_nofail(dev); 534 535 return s->smb.smbus; 536 } 537 538 static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width) 539 { 540 PIIX4PMState *s = opaque; 541 uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr); 542 543 trace_piix4_gpe_readb(addr, width, val); 544 return val; 545 } 546 547 static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val, 548 unsigned width) 549 { 550 PIIX4PMState *s = opaque; 551 552 trace_piix4_gpe_writeb(addr, width, val); 553 acpi_gpe_ioport_writeb(&s->ar, addr, val); 554 acpi_update_sci(&s->ar, s->irq); 555 } 556 557 static const MemoryRegionOps piix4_gpe_ops = { 558 .read = gpe_readb, 559 .write = gpe_writeb, 560 .valid.min_access_size = 1, 561 .valid.max_access_size = 4, 562 .impl.min_access_size = 1, 563 .impl.max_access_size = 1, 564 .endianness = DEVICE_LITTLE_ENDIAN, 565 }; 566 567 568 static bool piix4_get_cpu_hotplug_legacy(Object *obj, Error **errp) 569 { 570 PIIX4PMState *s = PIIX4_PM(obj); 571 572 return s->cpu_hotplug_legacy; 573 } 574 575 static void piix4_set_cpu_hotplug_legacy(Object *obj, bool value, Error **errp) 576 { 577 PIIX4PMState *s = PIIX4_PM(obj); 578 579 assert(!value); 580 if (s->cpu_hotplug_legacy && value == false) { 581 acpi_switch_to_modern_cphp(&s->gpe_cpu, &s->cpuhp_state, 582 PIIX4_CPU_HOTPLUG_IO_BASE); 583 } 584 s->cpu_hotplug_legacy = value; 585 } 586 587 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, 588 PCIBus *bus, PIIX4PMState *s) 589 { 590 memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s, 591 "acpi-gpe0", GPE_LEN); 592 memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); 593 594 acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent, 595 s->use_acpi_pci_hotplug); 596 597 s->cpu_hotplug_legacy = true; 598 object_property_add_bool(OBJECT(s), "cpu-hotplug-legacy", 599 piix4_get_cpu_hotplug_legacy, 600 piix4_set_cpu_hotplug_legacy, 601 NULL); 602 legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, 603 PIIX4_CPU_HOTPLUG_IO_BASE); 604 605 if (s->acpi_memory_hotplug.is_enabled) { 606 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug, 607 ACPI_MEMORY_HOTPLUG_BASE); 608 } 609 } 610 611 static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) 612 { 613 PIIX4PMState *s = PIIX4_PM(adev); 614 615 acpi_memory_ospm_status(&s->acpi_memory_hotplug, list); 616 if (!s->cpu_hotplug_legacy) { 617 acpi_cpu_ospm_status(&s->cpuhp_state, list); 618 } 619 } 620 621 static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) 622 { 623 PIIX4PMState *s = PIIX4_PM(adev); 624 625 acpi_send_gpe_event(&s->ar, s->irq, ev); 626 } 627 628 static Property piix4_pm_properties[] = { 629 DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), 630 DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), 631 DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), 632 DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), 633 DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, 634 use_acpi_pci_hotplug, true), 635 DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState, 636 acpi_memory_hotplug.is_enabled, true), 637 DEFINE_PROP_END_OF_LIST(), 638 }; 639 640 static void piix4_pm_class_init(ObjectClass *klass, void *data) 641 { 642 DeviceClass *dc = DEVICE_CLASS(klass); 643 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 644 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); 645 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass); 646 647 k->realize = piix4_pm_realize; 648 k->config_write = pm_write_config; 649 k->vendor_id = PCI_VENDOR_ID_INTEL; 650 k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3; 651 k->revision = 0x03; 652 k->class_id = PCI_CLASS_BRIDGE_OTHER; 653 dc->reset = piix4_pm_reset; 654 dc->desc = "PM"; 655 dc->vmsd = &vmstate_acpi; 656 device_class_set_props(dc, piix4_pm_properties); 657 /* 658 * Reason: part of PIIX4 southbridge, needs to be wired up, 659 * e.g. by mips_malta_init() 660 */ 661 dc->user_creatable = false; 662 dc->hotpluggable = false; 663 hc->pre_plug = piix4_device_pre_plug_cb; 664 hc->plug = piix4_device_plug_cb; 665 hc->unplug_request = piix4_device_unplug_request_cb; 666 hc->unplug = piix4_device_unplug_cb; 667 adevc->ospm_status = piix4_ospm_status; 668 adevc->send_event = piix4_send_gpe; 669 adevc->madt_cpu = pc_madt_cpu_entry; 670 } 671 672 static const TypeInfo piix4_pm_info = { 673 .name = TYPE_PIIX4_PM, 674 .parent = TYPE_PCI_DEVICE, 675 .instance_size = sizeof(PIIX4PMState), 676 .class_init = piix4_pm_class_init, 677 .interfaces = (InterfaceInfo[]) { 678 { TYPE_HOTPLUG_HANDLER }, 679 { TYPE_ACPI_DEVICE_IF }, 680 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 681 { } 682 } 683 }; 684 685 static void piix4_pm_register_types(void) 686 { 687 type_register_static(&piix4_pm_info); 688 } 689 690 type_init(piix4_pm_register_types) 691