diff options
-rw-r--r-- | hw/acpi.c | 21 | ||||
-rw-r--r-- | hw/mips_malta.c | 2 | ||||
-rw-r--r-- | hw/pc.c | 2 | ||||
-rw-r--r-- | hw/pc.h | 3 | ||||
-rw-r--r-- | hw/piix_pci.c | 1 | ||||
-rw-r--r-- | sysemu.h | 6 | ||||
-rw-r--r-- | vl.c | 23 |
7 files changed, 50 insertions, 8 deletions
@@ -49,6 +49,7 @@ typedef struct PIIX4PMState { uint8_t smb_data1; uint8_t smb_data[32]; uint8_t smb_index; + qemu_irq irq; } PIIX4PMState; #define RTC_EN (1 << 10) @@ -71,6 +72,8 @@ typedef struct PIIX4PMState { #define SMBHSTDAT1 0x06 #define SMBBLKDAT 0x07 +PIIX4PMState *pm_state; + static uint32_t get_pmtmr(PIIX4PMState *s) { uint32_t d; @@ -97,11 +100,12 @@ static void pm_update_sci(PIIX4PMState *s) pmsts = get_pmsts(s); sci_level = (((pmsts & s->pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); - qemu_set_irq(s->dev.irq[0], sci_level); + qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) { expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ); qemu_mod_timer(s->tmr_timer, expire_time); + s->tmr_overflow_time += 0x800000; } else { qemu_del_timer(s->tmr_timer); } @@ -467,7 +471,8 @@ static int pm_load(QEMUFile* f,void* opaque,int version_id) return 0; } -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, + qemu_irq sci_irq) { PIIX4PMState *s; uint8_t *pci_conf; @@ -475,6 +480,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) s = (PIIX4PMState *)pci_register_device(bus, "PM", sizeof(PIIX4PMState), devfn, NULL, pm_write_config); + pm_state = s; pci_conf = s->dev.config; pci_conf[0x00] = 0x86; pci_conf[0x01] = 0x80; @@ -514,5 +520,16 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s); s->smbus = i2c_init_bus(); + s->irq = sci_irq; return s->smbus; } + +#if defined(TARGET_I386) +void qemu_system_powerdown(void) +{ + if(pm_state->pmen & PWRBTN_EN) { + pm_state->pmsts |= PWRBTN_EN; + pm_update_sci(pm_state); + } +} +#endif diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 1ab594098e..d39a02b909 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -905,7 +905,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, piix4_devfn = piix4_init(pci_bus, 80); pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1, i8259); usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); - smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100); + smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, i8259[9]); eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ for (i = 0; i < 8; i++) { /* TODO: Populate SPD eeprom data. */ @@ -981,7 +981,7 @@ static void pc_init1(int ram_size, int vga_ram_size, i2c_bus *smbus; /* TODO: Populate SPD eeprom data. */ - smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100); + smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]); for (i = 0; i < 8; i++) { smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256)); } @@ -88,7 +88,8 @@ int ioport_get_a20(void); /* acpi.c */ extern int acpi_enabled; -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base); +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, + qemu_irq sci_irq); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); void acpi_bios_init(void); diff --git a/hw/piix_pci.c b/hw/piix_pci.c index d5c7e1e5c5..a1e04d470f 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -220,7 +220,6 @@ static void piix3_set_irq(qemu_irq *pic, int irq_num, int level) { int i, pic_irq, pic_level; - piix3_dev->config[0x60 + irq_num] &= ~0x80; // enable bit pci_irq_levels[irq_num] = level; /* now we change the pic irq level according to the piix irq mappings */ @@ -30,12 +30,16 @@ void cpu_disable_ticks(void); void qemu_system_reset_request(void); void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); -#if !defined(TARGET_SPARC) +int qemu_shutdown_requested(void); +int qemu_reset_requested(void); +int qemu_powerdown_requested(void); +#if !defined(TARGET_SPARC) && !defined(TARGET_I386) // Please implement a power failure function to signal the OS #define qemu_system_powerdown() do{}while(0) #else void qemu_system_powerdown(void); #endif +void qemu_system_reset(void); void cpu_save(QEMUFile *f, void *opaque); int cpu_load(QEMUFile *f, void *opaque, int version_id); @@ -7306,6 +7306,27 @@ static int reset_requested; static int shutdown_requested; static int powerdown_requested; +int qemu_shutdown_requested(void) +{ + int r = shutdown_requested; + shutdown_requested = 0; + return r; +} + +int qemu_reset_requested(void) +{ + int r = reset_requested; + reset_requested = 0; + return r; +} + +int qemu_powerdown_requested(void) +{ + int r = powerdown_requested; + powerdown_requested = 0; + return r; +} + void qemu_register_reset(QEMUResetHandler *func, void *opaque) { QEMUResetEntry **pre, *re; @@ -7320,7 +7341,7 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque) *pre = re; } -static void qemu_system_reset(void) +void qemu_system_reset(void) { QEMUResetEntry *re; |