-#include "acpi-dsdt.hex"
-
-static int acpi_checksum(const uint8_t *data, int len)
-{
- int sum, i;
- sum = 0;
- for(i = 0; i < len; i++)
- sum += data[i];
- return (-sum) & 0xff;
-}
-
-static void acpi_build_table_header(struct acpi_table_header *h,
- char *sig, int len)
-{
- memcpy(h->signature, sig, 4);
- h->length = cpu_to_le32(len);
- h->revision = 0;
- memcpy(h->oem_id, "QEMU ", 6);
- memcpy(h->oem_table_id, "QEMU", 4);
- memcpy(h->oem_table_id + 4, sig, 4);
- h->oem_revision = cpu_to_le32(1);
- memcpy(h->asl_compiler_id, "QEMU", 4);
- h->asl_compiler_revision = cpu_to_le32(1);
- h->checksum = acpi_checksum((void *)h, len);
-}
-
-#define ACPI_TABLES_BASE 0x000e8000
-
-/* base_addr must be a multiple of 4KB */
-void acpi_bios_init(void)
-{
- struct rsdp_descriptor *rsdp;
- struct rsdt_descriptor_rev1 *rsdt;
- struct fadt_descriptor_rev1 *fadt;
- struct facs_descriptor_rev1 *facs;
- struct multiple_apic_table *madt;
- uint8_t *dsdt;
- uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;
- uint32_t pm_io_base, acpi_tables_size, madt_addr, madt_size;
- int i;
-
- /* compute PCI I/O addresses */
- pm_io_base = (piix4_pm_state->dev.config[0x40] |
- (piix4_pm_state->dev.config[0x41] << 8)) & ~0x3f;
-
- base_addr = ACPI_TABLES_BASE;
-
- /* reserve memory space for tables */
- addr = base_addr;
- rsdp = (void *)(phys_ram_base + addr);
- addr += sizeof(*rsdp);
-
- rsdt_addr = addr;
- rsdt = (void *)(phys_ram_base + addr);
- addr += sizeof(*rsdt);
-
- fadt_addr = addr;
- fadt = (void *)(phys_ram_base + addr);
- addr += sizeof(*fadt);
-
- /* XXX: FACS should be in RAM */
- addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
- facs_addr = addr;
- facs = (void *)(phys_ram_base + addr);
- addr += sizeof(*facs);
-
- dsdt_addr = addr;
- dsdt = (void *)(phys_ram_base + addr);
- addr += sizeof(AmlCode);
-
- madt_addr = addr;
- madt_size = sizeof(*madt) +
- sizeof(struct madt_processor_apic) * smp_cpus +
- sizeof(struct madt_io_apic);
- madt = (void *)(phys_ram_base + addr);
- addr += madt_size;
-
- acpi_tables_size = addr - base_addr;
-
- cpu_register_physical_memory(base_addr, acpi_tables_size,
- base_addr | IO_MEM_ROM);
-
- /* RSDP */
- memset(rsdp, 0, sizeof(*rsdp));
- memcpy(rsdp->signature, "RSD PTR ", 8);
- memcpy(rsdp->oem_id, "QEMU ", 6);
- rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
- rsdp->checksum = acpi_checksum((void *)rsdp, 20);
-
- /* RSDT */
- rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
- rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
- acpi_build_table_header((struct acpi_table_header *)rsdt,
- "RSDT", sizeof(*rsdt));
-
- /* FADT */
- memset(fadt, 0, sizeof(*fadt));
- fadt->firmware_ctrl = cpu_to_le32(facs_addr);
- fadt->dsdt = cpu_to_le32(dsdt_addr);
- fadt->model = 1;
- fadt->reserved1 = 0;
- fadt->sci_int = cpu_to_le16(piix4_pm_state->dev.config[0x3c]);
- fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
- fadt->acpi_enable = 0xf1;
- fadt->acpi_disable = 0xf0;
- fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
- fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
- fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
- fadt->pm1_evt_len = 4;
- fadt->pm1_cnt_len = 2;
- fadt->pm_tmr_len = 4;
- fadt->plvl2_lat = cpu_to_le16(50);
- fadt->plvl3_lat = cpu_to_le16(50);
- fadt->plvl3_lat = cpu_to_le16(50);
- /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
- fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
- acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
- sizeof(*fadt));
-
- /* FACS */
- memset(facs, 0, sizeof(*facs));
- memcpy(facs->signature, "FACS", 4);
- facs->length = cpu_to_le32(sizeof(*facs));
-
- /* DSDT */
- memcpy(dsdt, AmlCode, sizeof(AmlCode));
-
- /* MADT */
- {
- struct madt_processor_apic *apic;
- struct madt_io_apic *io_apic;
-
- memset(madt, 0, madt_size);
- madt->local_apic_address = cpu_to_le32(0xfee00000);
- madt->flags = cpu_to_le32(1);
- apic = (void *)(madt + 1);
- for(i=0;i<smp_cpus;i++) {
- apic->type = APIC_PROCESSOR;
- apic->length = sizeof(*apic);
- apic->processor_id = i;
- apic->local_apic_id = i;
- apic->flags = cpu_to_le32(1);
- apic++;
- }
- io_apic = (void *)apic;
- io_apic->type = APIC_IO;
- io_apic->length = sizeof(*io_apic);
- io_apic->io_apic_id = smp_cpus;
- io_apic->address = cpu_to_le32(0xfec00000);
- io_apic->interrupt = cpu_to_le32(0);
-
- acpi_build_table_header((struct acpi_table_header *)madt,
- "APIC", madt_size);
- }
+static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
+{
+#if defined (TARGET_I386)
+ int slot = ffs(val) - 1;
+
+ pci_device_hot_remove_success(0, slot);
+#endif
+
+#if defined(DEBUG)
+ printf("pciej write %lx <== %d\n", addr, val);
+#endif
+}
+
+void qemu_system_hot_add_init(void)
+{
+ register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
+ register_ioport_read(GPE_BASE, 4, 1, gpe_readb, &gpe);
+
+ register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
+ register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status);
+
+ register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
+ register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, NULL);
+}
+
+static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->up |= (1 << slot);
+}
+
+static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->down |= (1 << slot);
+}
+
+void qemu_system_device_hot_add(int bus, int slot, int state)
+{
+ qemu_set_irq(pm_state->irq, 1);
+ pci0_status.up = 0;
+ pci0_status.down = 0;
+ if (state)
+ enable_device(&pci0_status, &gpe, slot);
+ else
+ disable_device(&pci0_status, &gpe, slot);
+ qemu_set_irq(pm_state->irq, 0);