From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JL47o-0008St-B0 for qemu-devel@nongnu.org; Fri, 01 Feb 2008 17:12:44 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JL47m-0008Qd-3I for qemu-devel@nongnu.org; Fri, 01 Feb 2008 17:12:42 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JL47k-0008Q5-81 for qemu-devel@nongnu.org; Fri, 01 Feb 2008 17:12:40 -0500 Received: from e31.co.us.ibm.com ([32.97.110.149]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JL47j-0002fe-OO for qemu-devel@nongnu.org; Fri, 01 Feb 2008 17:12:40 -0500 Received: from d03relay02.boulder.ibm.com (d03relay02.boulder.ibm.com [9.17.195.227]) by e31.co.us.ibm.com (8.13.8/8.13.8) with ESMTP id m11MCWus019078 for ; Fri, 1 Feb 2008 17:12:32 -0500 Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m11MCWjd181858 for ; Fri, 1 Feb 2008 15:12:32 -0700 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m11MCVU2022616 for ; Fri, 1 Feb 2008 15:12:32 -0700 From: Anthony Liguori Date: Fri, 1 Feb 2008 16:11:58 -0600 Message-Id: <1201903921-1125-4-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1201903921-1125-1-git-send-email-aliguori@us.ibm.com> References: <1201903921-1125-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 3/6] SCI fixes (v2) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kvm-devel@lists.sourceforge.net, Paul Brook KVM supports the ability to use ACPI to shutdown guests. In order to enable this requires some fixes to be able to generate the SCI interrupt and the appropriate plumbing. This patch hasn't changed since v1. Index: qemu/hw/acpi.c =================================================================== --- qemu.orig/hw/acpi.c 2008-02-01 10:00:45.000000000 -0600 +++ qemu/hw/acpi.c 2008-02-01 11:12:46.000000000 -0600 @@ -49,6 +49,7 @@ 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 @@ #define SMBHSTDAT1 0x06 #define SMBBLKDAT 0x07 +PIIX4PMState *pm_state; + static uint32_t get_pmtmr(PIIX4PMState *s) { uint32_t d; @@ -97,11 +100,12 @@ 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 @@ 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 @@ 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 @@ 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 Index: qemu/hw/mips_malta.c =================================================================== --- qemu.orig/hw/mips_malta.c 2008-02-01 11:06:54.000000000 -0600 +++ qemu/hw/mips_malta.c 2008-02-01 11:12:46.000000000 -0600 @@ -905,7 +905,7 @@ 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. */ Index: qemu/hw/pc.c =================================================================== --- qemu.orig/hw/pc.c 2008-02-01 11:07:04.000000000 -0600 +++ qemu/hw/pc.c 2008-02-01 11:12:46.000000000 -0600 @@ -1006,7 +1006,7 @@ 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)); } Index: qemu/hw/pc.h =================================================================== --- qemu.orig/hw/pc.h 2008-02-01 10:00:45.000000000 -0600 +++ qemu/hw/pc.h 2008-02-01 11:12:46.000000000 -0600 @@ -88,7 +88,8 @@ /* 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); Index: qemu/hw/piix_pci.c =================================================================== --- qemu.orig/hw/piix_pci.c 2008-02-01 10:00:45.000000000 -0600 +++ qemu/hw/piix_pci.c 2008-02-01 11:12:46.000000000 -0600 @@ -220,7 +220,6 @@ { 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 */ Index: qemu/sysemu.h =================================================================== --- qemu.orig/sysemu.h 2008-02-01 11:06:54.000000000 -0600 +++ qemu/sysemu.h 2008-02-01 11:12:46.000000000 -0600 @@ -31,12 +31,16 @@ 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); Index: qemu/vl.c =================================================================== --- qemu.orig/vl.c 2008-02-01 11:11:39.000000000 -0600 +++ qemu/vl.c 2008-02-01 11:12:46.000000000 -0600 @@ -7262,6 +7262,27 @@ 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; @@ -7276,7 +7297,7 @@ *pre = re; } -static void qemu_system_reset(void) +void qemu_system_reset(void) { QEMUResetEntry *re;