Lines Matching +full:acpi +full:- +full:based

10  * This is based on piix.c, but heavily modified.
44 #include "hw/acpi/acpi.h"
45 #include "hw/acpi/ich9.h"
46 #include "hw/acpi/ich9_timer.h"
48 #include "hw/qdev-properties.h"
54 #include "hw/acpi/acpi_aml_interface.h"
90 /* D{25 - 31}IR, but D30IR is read only to 0. */ in ich9_cc_update()
95 ich9_cc_update_ir(lpc->irr[slot], in ich9_cc_update()
96 pci_get_word(lpc->chip_config + *offset)); in ich9_cc_update()
102 * the bridge are connected to pirq lines. Our choice is PIRQ[E-H]. in ich9_cc_update()
103 * INT[A-D] are connected to PIRQ[E-H] in ich9_cc_update()
106 lpc->irr[30][pci_intx] = pci_intx + 4; in ich9_cc_update()
116 * acpi irq routing table. in ich9_cc_init()
121 * int[A-D] -> pirq[E-F] in ich9_cc_init()
122 * avoid pirq A-D because they are used for pci express port in ich9_cc_init()
126 lpc->irr[slot][intx] = (slot + intx) % 4 + 4; in ich9_cc_init()
134 uint8_t *c = lpc->chip_config; in ich9_cc_reset()
136 memset(lpc->chip_config, 0, sizeof(lpc->chip_config)); in ich9_cc_reset()
154 *len = ICH9_CC_SIZE - *addr; in ich9_cc_addr_len()
166 memcpy(lpc->chip_config + addr, &val, len); in ich9_cc_write()
167 pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d)); in ich9_cc_write()
179 memcpy(&val, lpc->chip_config + addr, len); in ich9_cc_read()
195 case 0 ... 3: /* A-D */ in ich9_lpc_pic_irq()
196 ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQA_ROUT + pirq_num], in ich9_lpc_pic_irq()
199 case 4 ... 7: /* E-H */ in ich9_lpc_pic_irq()
200 ich9_lpc_rout(lpc->d.config[ICH9_LPC_PIRQE_ROUT + (pirq_num - 4)], in ich9_lpc_pic_irq()
209 /* gsi: i8259+ioapic irq 0-15, otherwise assert */
223 pic_level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), i); in ich9_lpc_update_pic()
226 if (gsi == lpc->sci_gsi) { in ich9_lpc_update_pic()
227 pic_level |= lpc->sci_level; in ich9_lpc_update_pic()
230 qemu_set_irq(lpc->gsi[gsi], pic_level); in ich9_lpc_update_pic()
233 /* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */
241 return gsi - ICH9_LPC_PIC_NUM_PINS; in ich9_gsi_to_pirq()
244 /* gsi: ioapic irq 16-23, otherwise assert */
251 level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), ich9_gsi_to_pirq(gsi)); in ich9_lpc_update_apic()
252 if (gsi == lpc->sci_gsi) { in ich9_lpc_update_apic()
253 level |= lpc->sci_level; in ich9_lpc_update_apic()
256 qemu_set_irq(lpc->gsi[gsi], level); in ich9_lpc_update_apic()
272 /* return the pirq number (PIRQ[A-H]:0-7) corresponding to
277 BusState *bus = qdev_get_parent_bus(&pci_dev->qdev); in ich9_lpc_map_irq()
280 pci_bus->devices[PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC)]; in ich9_lpc_map_irq()
283 return lpc->irr[PCI_SLOT(pci_dev->devfn)][intx]; in ich9_lpc_map_irq()
303 route.irq = -1; in ich9_route_intx_pin_to_irq()
309 * I/O APIC has a fixed mapping to IRQ16-23, while the PIC is in ich9_route_intx_pin_to_irq()
312 * between PIC and I/O APIC, and neither does the in-kernel KVM in ich9_route_intx_pin_to_irq()
332 /* Returns -1 on error, IRQ number on success */
335 uint8_t sel = lpc->d.config[ICH9_LPC_ACPI_CTRL] & in ich9_lpc_sci_irq()
354 return -1; in ich9_lpc_sci_irq()
364 if (level == lpc->sci_level) { in ich9_set_sci()
367 lpc->sci_level = level; in ich9_set_sci()
369 irq = lpc->sci_gsi; in ich9_set_sci()
387 if (lpc->smi_features_ok) { in smi_features_ok_callback()
392 memcpy(&guest_features, lpc->smi_guest_features_le, sizeof guest_features); in smi_features_ok_callback()
394 if (guest_features & ~lpc->smi_host_features) { in smi_features_ok_callback()
405 * cpu hot-[un]plug with SMI requires SMI broadcast, in smi_features_ok_callback()
413 /* cpu hot-unplug is unsupported without cpu-hotplug */ in smi_features_ok_callback()
418 lpc->smi_negotiated_features = guest_features; in smi_features_ok_callback()
419 lpc->smi_features_ok = 1; in smi_features_ok_callback()
428 ich9_pm_init(PCI_DEVICE(lpc), &lpc->pm, sci_irq); in ich9_lpc_pm_init()
430 if (lpc->smi_host_features && fw_cfg) { in ich9_lpc_pm_init()
433 host_features_le = cpu_to_le64(lpc->smi_host_features); in ich9_lpc_pm_init()
434 memcpy(lpc->smi_host_features_le, &host_features_le, in ich9_lpc_pm_init()
436 fw_cfg_add_file(fw_cfg, "etc/smi/supported-features", in ich9_lpc_pm_init()
437 lpc->smi_host_features_le, in ich9_lpc_pm_init()
438 sizeof lpc->smi_host_features_le); in ich9_lpc_pm_init()
440 /* The other two guest-visible fields are cleared on device reset, we in ich9_lpc_pm_init()
443 fw_cfg_add_file_callback(fw_cfg, "etc/smi/requested-features", in ich9_lpc_pm_init()
445 lpc->smi_guest_features_le, in ich9_lpc_pm_init()
446 sizeof lpc->smi_guest_features_le, in ich9_lpc_pm_init()
448 fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok", in ich9_lpc_pm_init()
450 &lpc->smi_features_ok, in ich9_lpc_pm_init()
451 sizeof lpc->smi_features_ok, in ich9_lpc_pm_init()
462 /* ACPI specs 3.0, 4.7.2.5 */ in ich9_apm_ctrl_changed()
463 acpi_pm1_cnt_update(&lpc->pm.acpi_regs, in ich9_apm_ctrl_changed()
471 if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) { in ich9_apm_ctrl_changed()
472 if (lpc->smi_negotiated_features & in ich9_apm_ctrl_changed()
488 uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE); in ich9_lpc_pmbase_sci_update()
489 uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL); in ich9_lpc_pmbase_sci_update()
498 ich9_pm_iospace_update(&lpc->pm, pm_io_base); in ich9_lpc_pmbase_sci_update()
501 if (new_gsi == -1) { in ich9_lpc_pmbase_sci_update()
504 if (lpc->sci_level && new_gsi != lpc->sci_gsi) { in ich9_lpc_pmbase_sci_update()
505 qemu_set_irq(lpc->pm.irq, 0); in ich9_lpc_pmbase_sci_update()
506 lpc->sci_gsi = new_gsi; in ich9_lpc_pmbase_sci_update()
507 qemu_set_irq(lpc->pm.irq, 1); in ich9_lpc_pmbase_sci_update()
509 lpc->sci_gsi = new_gsi; in ich9_lpc_pmbase_sci_update()
515 uint32_t rcba = pci_get_long(lpc->d.config + ICH9_LPC_RCBA); in ich9_lpc_rcba_update()
518 memory_region_del_subregion(get_system_memory(), &lpc->rcrb_mem); in ich9_lpc_rcba_update()
523 &lpc->rcrb_mem, 1); in ich9_lpc_rcba_update()
531 uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1); in ich9_lpc_pmcon_update()
534 if (lpc->pm.swsmi_timer_enabled) { in ich9_lpc_pmcon_update()
536 &lpc->pm, lpc->pm.smi_en & ICH9_PMIO_SMI_EN_SWSMI_EN); in ich9_lpc_pmcon_update()
538 if (lpc->pm.periodic_timer_enabled) { in ich9_lpc_pmcon_update()
540 &lpc->pm, lpc->pm.smi_en & ICH9_PMIO_SMI_EN_PERIODIC_EN); in ich9_lpc_pmcon_update()
544 wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1); in ich9_lpc_pmcon_update()
546 pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask); in ich9_lpc_pmcon_update()
547 lpc->pm.smi_en_wmask &= ~1; in ich9_lpc_pmcon_update()
565 uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA); in ich9_lpc_config_write()
576 pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d)); in ich9_lpc_config_write()
579 pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d)); in ich9_lpc_config_write()
590 uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA); in ich9_lpc_reset()
594 pci_set_byte(d->config + ICH9_LPC_PIRQA_ROUT + i, in ich9_lpc_reset()
598 pci_set_byte(d->config + ICH9_LPC_PIRQE_ROUT + i, in ich9_lpc_reset()
601 pci_set_byte(d->config + ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_DEFAULT); in ich9_lpc_reset()
603 pci_set_long(d->config + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_DEFAULT); in ich9_lpc_reset()
604 pci_set_long(d->config + ICH9_LPC_RCBA, ICH9_LPC_RCBA_DEFAULT); in ich9_lpc_reset()
611 lpc->sci_level = 0; in ich9_lpc_reset()
612 lpc->rst_cnt = 0; in ich9_lpc_reset()
614 memset(lpc->smi_guest_features_le, 0, sizeof lpc->smi_guest_features_le); in ich9_lpc_reset()
615 lpc->smi_features_ok = 0; in ich9_lpc_reset()
616 lpc->smi_negotiated_features = 0; in ich9_lpc_reset()
629 MemoryRegion *io_as = pci_address_space_io(&s->d); in ich9_lpc_machine_ready()
632 pci_conf = s->d.config; in ich9_lpc_machine_ready()
661 lpc->rst_cnt = val & 0xA; /* keep FULL_RST (bit 3) and SYS_RST (bit 1) */ in ich9_rst_cnt_write()
668 return lpc->rst_cnt; in ich9_rst_cnt_read()
684 object_initialize_child(obj, "rtc", &lpc->rtc, TYPE_MC146818_RTC); in ich9_lpc_initfn()
686 qdev_init_gpio_out_named(DEVICE(lpc), lpc->gsi, ICH9_GPIO_GSI, in ich9_lpc_initfn()
690 &lpc->sci_gsi, OBJ_PROP_FLAG_READ); in ich9_lpc_initfn()
696 &lpc->smi_negotiated_features, in ich9_lpc_initfn()
699 ich9_pm_add_properties(obj, &lpc->pm); in ich9_lpc_initfn()
709 if ((lpc->smi_host_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT)) && in ich9_lpc_realize()
710 !(lpc->smi_host_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT))) { in ich9_lpc_realize()
717 error_setg(errp, "cpu hot-unplug requires cpu hot-plug"); in ich9_lpc_realize()
727 pci_set_long(d->wmask + ICH9_LPC_PMBASE, in ich9_lpc_realize()
729 pci_set_byte(d->wmask + ICH9_LPC_PMBASE, in ich9_lpc_realize()
733 memory_region_init_io(&lpc->rcrb_mem, OBJECT(d), &rcrb_mmio_ops, lpc, in ich9_lpc_realize()
734 "lpc-rcrb-mmio", ICH9_CC_SIZE); in ich9_lpc_realize()
737 apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc); in ich9_lpc_realize()
739 lpc->machine_ready.notify = ich9_lpc_machine_ready; in ich9_lpc_realize()
740 qemu_add_machine_init_done_notifier(&lpc->machine_ready); in ich9_lpc_realize()
742 memory_region_init_io(&lpc->rst_cnt_mem, OBJECT(d), &ich9_rst_cnt_ops, lpc, in ich9_lpc_realize()
743 "lpc-reset-control", 1); in ich9_lpc_realize()
745 ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem, in ich9_lpc_realize()
748 isa_bus_register_input_irqs(isa_bus, lpc->gsi); in ich9_lpc_realize()
753 qdev_prop_set_int32(DEVICE(&lpc->rtc), "base_year", 2000); in ich9_lpc_realize()
754 if (!qdev_realize(DEVICE(&lpc->rtc), BUS(isa_bus), errp)) { in ich9_lpc_realize()
757 irq = object_property_get_uint(OBJECT(&lpc->rtc), "irq", &error_fatal); in ich9_lpc_realize()
758 isa_connect_gpio_out(ISA_DEVICE(&lpc->rtc), 0, irq); in ich9_lpc_realize()
771 return (lpc->rst_cnt != 0); in ich9_rst_cnt_needed()
789 return !buffer_is_zero(lpc->smi_guest_features_le, in ich9_smi_feat_needed()
790 sizeof lpc->smi_guest_features_le) || in ich9_smi_feat_needed()
791 lpc->smi_features_ok; in ich9_smi_feat_needed()
830 DEFINE_PROP_BOOL("smm-compat", ICH9LPCState, pm.smm_compat, false),
831 DEFINE_PROP_BOOL("smm-enabled", ICH9LPCState, pm.smm_enabled, false),
832 DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
834 DEFINE_PROP_BIT64("x-smi-cpu-hotplug", ICH9LPCState, smi_host_features,
836 DEFINE_PROP_BIT64("x-smi-cpu-hotunplug", ICH9LPCState, smi_host_features,
838 DEFINE_PROP_BOOL("x-smi-swsmi-timer", ICH9LPCState,
840 DEFINE_PROP_BOOL("x-smi-periodic-timer", ICH9LPCState,
848 acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev); in ich9_send_gpe()
885 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); in ich9_lpc_class_init()
887 k->realize = ich9_lpc_realize; in ich9_lpc_class_init()
888 dc->vmsd = &vmstate_ich9_lpc; in ich9_lpc_class_init()
890 k->config_write = ich9_lpc_config_write; in ich9_lpc_class_init()
891 dc->desc = "ICH9 LPC bridge"; in ich9_lpc_class_init()
892 k->vendor_id = PCI_VENDOR_ID_INTEL; in ich9_lpc_class_init()
893 k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8; in ich9_lpc_class_init()
894 k->revision = ICH9_A2_LPC_REVISION; in ich9_lpc_class_init()
895 k->class_id = PCI_CLASS_BRIDGE_ISA; in ich9_lpc_class_init()
900 dc->user_creatable = false; in ich9_lpc_class_init()
901 hc->pre_plug = ich9_pm_device_pre_plug_cb; in ich9_lpc_class_init()
902 hc->plug = ich9_pm_device_plug_cb; in ich9_lpc_class_init()
903 hc->unplug_request = ich9_pm_device_unplug_request_cb; in ich9_lpc_class_init()
904 hc->unplug = ich9_pm_device_unplug_cb; in ich9_lpc_class_init()
905 hc->is_hotpluggable_bus = ich9_pm_is_hotpluggable_bus; in ich9_lpc_class_init()
906 adevc->ospm_status = ich9_pm_ospm_status; in ich9_lpc_class_init()
907 adevc->send_event = ich9_send_gpe; in ich9_lpc_class_init()
908 amldevc->build_dev_aml = build_ich9_isa_aml; in ich9_lpc_class_init()