qemu_register_wakeup_notifier(&ar->wakeup);
}
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4)
{
ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
qemu_system_suspend_request();
break;
default:
+ if (sus_typ == s4) { /* S4 request */
+ qemu_system_shutdown_request();
+ }
break;
}
}
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
void acpi_pm1_cnt_init(ACPIREGS *ar);
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val);
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
#include "sysemu.h"
#include "range.h"
#include "ioport.h"
+#include "fw_cfg.h"
//#define DEBUG
struct pci_status pci0_status;
uint32_t pci0_hotplug_enable;
uint32_t pci0_slot_device_present;
+
+ uint8_t disable_s3;
+ uint8_t disable_s4;
+ uint8_t s4_val;
} PIIX4PMState;
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->ar, val);
+ acpi_pm1_cnt_write(&s->ar, val, s->s4_val);
break;
default:
break;
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
- int kvm_enabled)
+ int kvm_enabled, void *fw_cfg)
{
PCIDevice *dev;
PIIX4PMState *s;
qdev_init_nofail(&dev->qdev);
+ if (fw_cfg) {
+ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+ suspend[3] = 1 | ((!s->disable_s3) << 7);
+ suspend[4] = s->s4_val | ((!s->disable_s4) << 7);
+
+ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+ }
+
return s->smb.smbus;
}
static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+ DEFINE_PROP_UINT8("disable_s3", PIIX4PMState, disable_s3, 0),
+ DEFINE_PROP_UINT8("disable_s4", PIIX4PMState, disable_s4, 0),
+ DEFINE_PROP_UINT8("s4_val", PIIX4PMState, s4_val, 2),
DEFINE_PROP_END_OF_LIST(),
};
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
- isa_get_irq(NULL, 9), NULL, 0);
+ isa_get_irq(NULL, 9), NULL, 0, NULL);
/* TODO: Populate SPD eeprom data. */
smbus_eeprom_init(smbus, 8, NULL, 0);
pit = pit_init(isa_bus, 0x40, 0, NULL);
}
}
-void pc_memory_init(MemoryRegion *system_memory,
+void *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
for (i = 0; i < nb_option_roms; i++) {
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
}
+ return fw_cfg;
}
qemu_irq *pc_allocate_cpu_irq(void)
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
void pc_cpus_init(const char *cpu_model);
-void pc_memory_init(MemoryRegion *system_memory,
+void *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
- int kvm_enabled);
+ int kvm_enabled, void *fw_cfg);
void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
/* hpet.c */
MemoryRegion *ram_memory;
MemoryRegion *pci_memory;
MemoryRegion *rom_memory;
+ void *fw_cfg = NULL;
pc_cpus_init(cpu_model);
/* allocate ram and load rom/bios */
if (!xen_enabled()) {
- pc_memory_init(system_memory,
+ fw_cfg = pc_memory_init(system_memory,
kernel_filename, kernel_cmdline, initrd_filename,
below_4g_mem_size, above_4g_mem_size,
pci_enabled ? rom_memory : system_memory, &ram_memory);
/* TODO: Populate SPD eeprom data. */
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
gsi[9], *smi_irq,
- kvm_enabled());
+ kvm_enabled(), fw_cfg);
smbus_eeprom_init(smbus, 8, NULL, 0);
}
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->ar, val);
+ acpi_pm1_cnt_write(&s->ar, val, 0);
break;
default:
break;