1 /* 2 * 3 * Copyright (c) 2018 Intel Corporation 4 * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd 5 * Written by Samuel Ortiz, Shameer Kolothum 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms and conditions of the GNU General Public License, 9 * version 2 or later, as published by the Free Software Foundation. 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qapi/error.h" 14 #include "hw/acpi/acpi.h" 15 #include "hw/acpi/pcihp.h" 16 #include "hw/acpi/generic_event_device.h" 17 #include "hw/pci/pci.h" 18 #include "hw/irq.h" 19 #include "hw/mem/pc-dimm.h" 20 #include "hw/mem/nvdimm.h" 21 #include "hw/pci/pci_device.h" 22 #include "hw/qdev-properties.h" 23 #include "migration/vmstate.h" 24 #include "qemu/error-report.h" 25 #include "system/runstate.h" 26 27 static const uint32_t ged_supported_events[] = { 28 ACPI_GED_MEM_HOTPLUG_EVT, 29 ACPI_GED_PWR_DOWN_EVT, 30 ACPI_GED_NVDIMM_HOTPLUG_EVT, 31 ACPI_GED_CPU_HOTPLUG_EVT, 32 ACPI_GED_PCI_HOTPLUG_EVT, 33 }; 34 35 /* 36 * The ACPI Generic Event Device (GED) is a hardware-reduced specific 37 * device[ACPI v6.1 Section 5.6.9] that handles all platform events, 38 * including the hotplug ones. Platforms need to specify their own 39 * GED Event bitmap to describe what kind of events they want to support 40 * through GED. This routine uses a single interrupt for the GED device, 41 * relying on IO memory region to communicate the type of device 42 * affected by the interrupt. This way, we can support up to 32 events 43 * with a unique interrupt. 44 */ 45 void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev, 46 uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base) 47 { 48 AcpiGedState *s = ACPI_GED(hotplug_dev); 49 Aml *crs = aml_resource_template(); 50 Aml *evt, *field; 51 Aml *dev = aml_device("%s", name); 52 Aml *evt_sel = aml_local(0); 53 Aml *esel = aml_name(AML_GED_EVT_SEL); 54 55 /* _CRS interrupt */ 56 aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, 57 AML_EXCLUSIVE, &ged_irq, 1)); 58 59 aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0013"))); 60 aml_append(dev, aml_name_decl("_UID", aml_string(GED_DEVICE))); 61 aml_append(dev, aml_name_decl("_CRS", crs)); 62 63 /* Append IO region */ 64 aml_append(dev, aml_operation_region(AML_GED_EVT_REG, rs, 65 aml_int(ged_base + ACPI_GED_EVT_SEL_OFFSET), 66 ACPI_GED_EVT_SEL_LEN)); 67 field = aml_field(AML_GED_EVT_REG, AML_DWORD_ACC, AML_NOLOCK, 68 AML_WRITE_AS_ZEROS); 69 aml_append(field, aml_named_field(AML_GED_EVT_SEL, 70 ACPI_GED_EVT_SEL_LEN * BITS_PER_BYTE)); 71 aml_append(dev, field); 72 73 /* 74 * For each GED event we: 75 * - Add a conditional block for each event, inside a loop. 76 * - Call a method for each supported GED event type. 77 * 78 * The resulting ASL code looks like: 79 * 80 * Local0 = ESEL 81 * If ((Local0 & One) == One) 82 * { 83 * MethodEvent0() 84 * } 85 * 86 * If ((Local0 & 0x2) == 0x2) 87 * { 88 * MethodEvent1() 89 * } 90 * ... 91 */ 92 evt = aml_method("_EVT", 1, AML_SERIALIZED); 93 { 94 Aml *if_ctx; 95 uint32_t i; 96 uint32_t ged_events = ctpop32(s->ged_event_bitmap); 97 98 /* Local0 = ESEL */ 99 aml_append(evt, aml_store(esel, evt_sel)); 100 101 for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) { 102 uint32_t event = s->ged_event_bitmap & ged_supported_events[i]; 103 104 if (!event) { 105 continue; 106 } 107 108 if_ctx = aml_if(aml_equal(aml_and(evt_sel, aml_int(event), NULL), 109 aml_int(event))); 110 switch (event) { 111 case ACPI_GED_MEM_HOTPLUG_EVT: 112 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "." 113 MEMORY_SLOT_SCAN_METHOD)); 114 break; 115 case ACPI_GED_CPU_HOTPLUG_EVT: 116 aml_append(if_ctx, aml_call0(AML_GED_EVT_CPU_SCAN_METHOD)); 117 break; 118 case ACPI_GED_PWR_DOWN_EVT: 119 aml_append(if_ctx, 120 aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE), 121 aml_int(0x80))); 122 break; 123 case ACPI_GED_NVDIMM_HOTPLUG_EVT: 124 aml_append(if_ctx, 125 aml_notify(aml_name("\\_SB.NVDR"), 126 aml_int(0x80))); 127 break; 128 case ACPI_GED_PCI_HOTPLUG_EVT: 129 aml_append(if_ctx, 130 aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); 131 aml_append(if_ctx, aml_call0("\\_SB.PCI0.PCNT")); 132 aml_append(if_ctx, aml_release(aml_name("\\_SB.PCI0.BLCK"))); 133 break; 134 default: 135 /* 136 * Please make sure all the events in ged_supported_events[] 137 * are handled above. 138 */ 139 g_assert_not_reached(); 140 } 141 142 aml_append(evt, if_ctx); 143 ged_events--; 144 } 145 146 if (ged_events) { 147 error_report("Unsupported events specified"); 148 abort(); 149 } 150 } 151 152 /* Append _EVT method */ 153 aml_append(dev, evt); 154 155 aml_append(table, dev); 156 } 157 158 void acpi_dsdt_add_power_button(Aml *scope) 159 { 160 Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE); 161 aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C"))); 162 aml_append(dev, aml_name_decl("_UID", aml_int(0))); 163 aml_append(scope, dev); 164 } 165 166 /* Memory read by the GED _EVT AML dynamic method */ 167 static uint64_t ged_evt_read(void *opaque, hwaddr addr, unsigned size) 168 { 169 uint64_t val = 0; 170 GEDState *ged_st = opaque; 171 172 switch (addr) { 173 case ACPI_GED_EVT_SEL_OFFSET: 174 /* Read the selector value and reset it */ 175 val = ged_st->sel; 176 ged_st->sel = 0; 177 break; 178 default: 179 break; 180 } 181 182 return val; 183 } 184 185 /* Nothing is expected to be written to the GED memory region */ 186 static void ged_evt_write(void *opaque, hwaddr addr, uint64_t data, 187 unsigned int size) 188 { 189 } 190 191 static const MemoryRegionOps ged_evt_ops = { 192 .read = ged_evt_read, 193 .write = ged_evt_write, 194 .endianness = DEVICE_LITTLE_ENDIAN, 195 .valid = { 196 .min_access_size = 4, 197 .max_access_size = 4, 198 }, 199 }; 200 201 static uint64_t ged_regs_read(void *opaque, hwaddr addr, unsigned size) 202 { 203 return 0; 204 } 205 206 static void ged_regs_write(void *opaque, hwaddr addr, uint64_t data, 207 unsigned int size) 208 { 209 bool slp_en; 210 int slp_typ; 211 212 switch (addr) { 213 case ACPI_GED_REG_SLEEP_CTL: 214 slp_typ = (data >> ACPI_GED_SLP_TYP_POS) & ACPI_GED_SLP_TYP_MASK; 215 slp_en = !!(data & ACPI_GED_SLP_EN); 216 if (slp_en && slp_typ == ACPI_GED_SLP_TYP_S5) { 217 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 218 } 219 return; 220 case ACPI_GED_REG_SLEEP_STS: 221 return; 222 case ACPI_GED_REG_RESET: 223 if (data == ACPI_GED_RESET_VALUE) { 224 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 225 } 226 return; 227 } 228 } 229 230 static const MemoryRegionOps ged_regs_ops = { 231 .read = ged_regs_read, 232 .write = ged_regs_write, 233 .endianness = DEVICE_LITTLE_ENDIAN, 234 .valid = { 235 .min_access_size = 1, 236 .max_access_size = 1, 237 }, 238 }; 239 240 static void acpi_ged_device_pre_plug_cb(HotplugHandler *hotplug_dev, 241 DeviceState *dev, Error **errp) 242 { 243 if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 244 acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp); 245 } 246 } 247 248 static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev, 249 DeviceState *dev, Error **errp) 250 { 251 AcpiGedState *s = ACPI_GED(hotplug_dev); 252 253 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 254 if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { 255 nvdimm_acpi_plug_cb(hotplug_dev, dev); 256 } else { 257 acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); 258 } 259 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { 260 acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp); 261 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 262 acpi_pcihp_device_plug_cb(hotplug_dev, &s->pcihp_state, dev, errp); 263 } else { 264 error_setg(errp, "virt: device plug request for unsupported device" 265 " type: %s", object_get_typename(OBJECT(dev))); 266 } 267 } 268 269 static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev, 270 DeviceState *dev, Error **errp) 271 { 272 AcpiGedState *s = ACPI_GED(hotplug_dev); 273 274 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) && 275 !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) { 276 acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp); 277 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { 278 acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp); 279 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 280 acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->pcihp_state, 281 dev, errp); 282 } else { 283 error_setg(errp, "acpi: device unplug request for unsupported device" 284 " type: %s", object_get_typename(OBJECT(dev))); 285 } 286 } 287 288 static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev, 289 DeviceState *dev, Error **errp) 290 { 291 AcpiGedState *s = ACPI_GED(hotplug_dev); 292 293 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 294 acpi_memory_unplug_cb(&s->memhp_state, dev, errp); 295 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { 296 acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp); 297 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 298 acpi_pcihp_device_unplug_cb(hotplug_dev, &s->pcihp_state, dev, errp); 299 } else { 300 error_setg(errp, "acpi: device unplug for unsupported device" 301 " type: %s", object_get_typename(OBJECT(dev))); 302 } 303 } 304 305 static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) 306 { 307 AcpiGedState *s = ACPI_GED(adev); 308 309 acpi_memory_ospm_status(&s->memhp_state, list); 310 acpi_cpu_ospm_status(&s->cpuhp_state, list); 311 } 312 313 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) 314 { 315 AcpiGedState *s = ACPI_GED(adev); 316 GEDState *ged_st = &s->ged_state; 317 uint32_t sel; 318 319 if (ev & ACPI_MEMORY_HOTPLUG_STATUS) { 320 sel = ACPI_GED_MEM_HOTPLUG_EVT; 321 } else if (ev & ACPI_POWER_DOWN_STATUS) { 322 sel = ACPI_GED_PWR_DOWN_EVT; 323 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { 324 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT; 325 } else if (ev & ACPI_CPU_HOTPLUG_STATUS) { 326 sel = ACPI_GED_CPU_HOTPLUG_EVT; 327 } else if (ev & ACPI_PCI_HOTPLUG_STATUS) { 328 sel = ACPI_GED_PCI_HOTPLUG_EVT; 329 } else { 330 /* Unknown event. Return without generating interrupt. */ 331 warn_report("GED: Unsupported event %d. No irq injected", ev); 332 return; 333 } 334 335 /* 336 * Set the GED selector field to communicate the event type. 337 * This will be read by GED aml code to select the appropriate 338 * event method. 339 */ 340 ged_st->sel |= sel; 341 342 /* Trigger the event by sending an interrupt to the guest. */ 343 qemu_irq_pulse(s->irq); 344 } 345 346 static const Property acpi_ged_properties[] = { 347 DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0), 348 DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, AcpiGedState, 349 pcihp_state.use_acpi_hotplug_bridge, 0), 350 DEFINE_PROP_LINK("bus", AcpiGedState, pcihp_state.root, 351 TYPE_PCI_BUS, PCIBus *), 352 }; 353 354 static const VMStateDescription vmstate_memhp_state = { 355 .name = "acpi-ged/memhp", 356 .version_id = 1, 357 .minimum_version_id = 1, 358 .fields = (const VMStateField[]) { 359 VMSTATE_MEMORY_HOTPLUG(memhp_state, AcpiGedState), 360 VMSTATE_END_OF_LIST() 361 } 362 }; 363 364 static bool cpuhp_needed(void *opaque) 365 { 366 MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); 367 368 return mc->has_hotpluggable_cpus; 369 } 370 371 static const VMStateDescription vmstate_cpuhp_state = { 372 .name = "acpi-ged/cpuhp", 373 .version_id = 1, 374 .minimum_version_id = 1, 375 .needed = cpuhp_needed, 376 .fields = (VMStateField[]) { 377 VMSTATE_CPU_HOTPLUG(cpuhp_state, AcpiGedState), 378 VMSTATE_END_OF_LIST() 379 } 380 }; 381 382 static const VMStateDescription vmstate_ged_state = { 383 .name = "acpi-ged-state", 384 .version_id = 1, 385 .minimum_version_id = 1, 386 .fields = (const VMStateField[]) { 387 VMSTATE_UINT32(sel, GEDState), 388 VMSTATE_END_OF_LIST() 389 } 390 }; 391 392 static const VMStateDescription vmstate_ghes = { 393 .name = "acpi-ghes", 394 .version_id = 1, 395 .minimum_version_id = 1, 396 .fields = (const VMStateField[]) { 397 VMSTATE_UINT64(hw_error_le, AcpiGhesState), 398 VMSTATE_END_OF_LIST() 399 }, 400 }; 401 402 static bool ghes_needed(void *opaque) 403 { 404 AcpiGedState *s = opaque; 405 return s->ghes_state.hw_error_le; 406 } 407 408 static const VMStateDescription vmstate_ghes_state = { 409 .name = "acpi-ged/ghes", 410 .version_id = 1, 411 .minimum_version_id = 1, 412 .needed = ghes_needed, 413 .fields = (const VMStateField[]) { 414 VMSTATE_STRUCT(ghes_state, AcpiGedState, 1, 415 vmstate_ghes, AcpiGhesState), 416 VMSTATE_END_OF_LIST() 417 } 418 }; 419 420 static bool pcihp_needed(void *opaque) 421 { 422 AcpiGedState *s = opaque; 423 return s->pcihp_state.use_acpi_hotplug_bridge; 424 } 425 426 static const VMStateDescription vmstate_pcihp_state = { 427 .name = "acpi-ged/pcihp", 428 .version_id = 1, 429 .minimum_version_id = 1, 430 .needed = pcihp_needed, 431 .fields = (const VMStateField[]) { 432 VMSTATE_PCI_HOTPLUG(pcihp_state, 433 AcpiGedState, 434 NULL, NULL), 435 VMSTATE_END_OF_LIST() 436 } 437 }; 438 439 static const VMStateDescription vmstate_acpi_ged = { 440 .name = "acpi-ged", 441 .version_id = 1, 442 .minimum_version_id = 1, 443 .fields = (const VMStateField[]) { 444 VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState), 445 VMSTATE_END_OF_LIST(), 446 }, 447 .subsections = (const VMStateDescription * const []) { 448 &vmstate_memhp_state, 449 &vmstate_cpuhp_state, 450 &vmstate_ghes_state, 451 &vmstate_pcihp_state, 452 NULL 453 } 454 }; 455 456 static void acpi_ged_realize(DeviceState *dev, Error **errp) 457 { 458 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 459 AcpiGedState *s = ACPI_GED(dev); 460 AcpiPciHpState *pcihp_state = &s->pcihp_state; 461 uint32_t ged_events; 462 int i; 463 464 if (pcihp_state->use_acpi_hotplug_bridge) { 465 s->ged_event_bitmap |= ACPI_GED_PCI_HOTPLUG_EVT; 466 } 467 ged_events = ctpop32(s->ged_event_bitmap); 468 469 for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) { 470 uint32_t event = s->ged_event_bitmap & ged_supported_events[i]; 471 472 if (!event) { 473 continue; 474 } 475 476 switch (event) { 477 case ACPI_GED_CPU_HOTPLUG_EVT: 478 /* initialize CPU Hotplug related regions */ 479 memory_region_init(&s->container_cpuhp, OBJECT(dev), 480 "cpuhp container", 481 ACPI_CPU_HOTPLUG_REG_LEN); 482 sysbus_init_mmio(sbd, &s->container_cpuhp); 483 cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev), 484 &s->cpuhp_state, 0); 485 break; 486 case ACPI_GED_PCI_HOTPLUG_EVT: 487 memory_region_init(&s->container_pcihp, OBJECT(dev), 488 ACPI_PCIHP_REGION_NAME, ACPI_PCIHP_SIZE); 489 sysbus_init_mmio(sbd, &s->container_pcihp); 490 acpi_pcihp_init(OBJECT(s), &s->pcihp_state, 491 &s->container_pcihp, 0); 492 qbus_set_hotplug_handler(BUS(s->pcihp_state.root), OBJECT(dev)); 493 } 494 ged_events--; 495 } 496 497 if (ged_events) { 498 error_report("Unsupported events specified"); 499 abort(); 500 } 501 } 502 503 static void acpi_ged_initfn(Object *obj) 504 { 505 DeviceState *dev = DEVICE(obj); 506 AcpiGedState *s = ACPI_GED(dev); 507 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 508 GEDState *ged_st = &s->ged_state; 509 510 memory_region_init_io(&ged_st->evt, obj, &ged_evt_ops, ged_st, 511 TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN); 512 sysbus_init_mmio(sbd, &ged_st->evt); 513 514 sysbus_init_irq(sbd, &s->irq); 515 516 s->memhp_state.is_enabled = true; 517 /* 518 * GED handles memory hotplug event and acpi-mem-hotplug 519 * memory region gets initialized here. Create an exclusive 520 * container for memory hotplug IO and expose it as GED sysbus 521 * MMIO so that boards can map it separately. 522 */ 523 memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container", 524 MEMORY_HOTPLUG_IO_LEN); 525 sysbus_init_mmio(sbd, &s->container_memhp); 526 acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev), 527 &s->memhp_state, 0); 528 529 memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st, 530 TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT); 531 sysbus_init_mmio(sbd, &ged_st->regs); 532 } 533 534 static void ged_reset_hold(Object *obj, ResetType type) 535 { 536 AcpiGedState *s = ACPI_GED(obj); 537 538 if (s->pcihp_state.use_acpi_hotplug_bridge) { 539 acpi_pcihp_reset(&s->pcihp_state); 540 } 541 } 542 543 static void acpi_ged_class_init(ObjectClass *class, const void *data) 544 { 545 DeviceClass *dc = DEVICE_CLASS(class); 546 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class); 547 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class); 548 ResettableClass *rc = RESETTABLE_CLASS(class); 549 AcpiGedClass *gedc = ACPI_GED_CLASS(class); 550 551 dc->desc = "ACPI Generic Event Device"; 552 device_class_set_props(dc, acpi_ged_properties); 553 dc->vmsd = &vmstate_acpi_ged; 554 dc->realize = acpi_ged_realize; 555 556 hc->pre_plug = acpi_ged_device_pre_plug_cb; 557 hc->plug = acpi_ged_device_plug_cb; 558 hc->unplug_request = acpi_ged_unplug_request_cb; 559 hc->unplug = acpi_ged_unplug_cb; 560 resettable_class_set_parent_phases(rc, NULL, ged_reset_hold, NULL, 561 &gedc->parent_phases); 562 563 adevc->ospm_status = acpi_ged_ospm_status; 564 adevc->send_event = acpi_ged_send_event; 565 } 566 567 static const TypeInfo acpi_ged_info = { 568 .name = TYPE_ACPI_GED, 569 .parent = TYPE_SYS_BUS_DEVICE, 570 .instance_size = sizeof(AcpiGedState), 571 .instance_init = acpi_ged_initfn, 572 .class_init = acpi_ged_class_init, 573 .class_size = sizeof(AcpiGedClass), 574 .interfaces = (const InterfaceInfo[]) { 575 { TYPE_HOTPLUG_HANDLER }, 576 { TYPE_ACPI_DEVICE_IF }, 577 { } 578 } 579 }; 580 581 static void acpi_ged_register_types(void) 582 { 583 type_register_static(&acpi_ged_info); 584 } 585 586 type_init(acpi_ged_register_types) 587