Commit cf7a2fe2eb6e100b21089faced28e8dfeaf39748
1 parent
7852e5da
SCI fixes
(Anthony Liguori) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4081 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
50 additions
and
8 deletions
hw/acpi.c
| ... | ... | @@ -49,6 +49,7 @@ typedef struct PIIX4PMState { |
| 49 | 49 | uint8_t smb_data1; |
| 50 | 50 | uint8_t smb_data[32]; |
| 51 | 51 | uint8_t smb_index; |
| 52 | + qemu_irq irq; | |
| 52 | 53 | } PIIX4PMState; |
| 53 | 54 | |
| 54 | 55 | #define RTC_EN (1 << 10) |
| ... | ... | @@ -71,6 +72,8 @@ typedef struct PIIX4PMState { |
| 71 | 72 | #define SMBHSTDAT1 0x06 |
| 72 | 73 | #define SMBBLKDAT 0x07 |
| 73 | 74 | |
| 75 | +PIIX4PMState *pm_state; | |
| 76 | + | |
| 74 | 77 | static uint32_t get_pmtmr(PIIX4PMState *s) |
| 75 | 78 | { |
| 76 | 79 | uint32_t d; |
| ... | ... | @@ -97,11 +100,12 @@ static void pm_update_sci(PIIX4PMState *s) |
| 97 | 100 | pmsts = get_pmsts(s); |
| 98 | 101 | sci_level = (((pmsts & s->pmen) & |
| 99 | 102 | (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); |
| 100 | - qemu_set_irq(s->dev.irq[0], sci_level); | |
| 103 | + qemu_set_irq(s->irq, sci_level); | |
| 101 | 104 | /* schedule a timer interruption if needed */ |
| 102 | 105 | if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) { |
| 103 | 106 | expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ); |
| 104 | 107 | qemu_mod_timer(s->tmr_timer, expire_time); |
| 108 | + s->tmr_overflow_time += 0x800000; | |
| 105 | 109 | } else { |
| 106 | 110 | qemu_del_timer(s->tmr_timer); |
| 107 | 111 | } |
| ... | ... | @@ -467,7 +471,8 @@ static int pm_load(QEMUFile* f,void* opaque,int version_id) |
| 467 | 471 | return 0; |
| 468 | 472 | } |
| 469 | 473 | |
| 470 | -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) | |
| 474 | +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, | |
| 475 | + qemu_irq sci_irq) | |
| 471 | 476 | { |
| 472 | 477 | PIIX4PMState *s; |
| 473 | 478 | uint8_t *pci_conf; |
| ... | ... | @@ -475,6 +480,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) |
| 475 | 480 | s = (PIIX4PMState *)pci_register_device(bus, |
| 476 | 481 | "PM", sizeof(PIIX4PMState), |
| 477 | 482 | devfn, NULL, pm_write_config); |
| 483 | + pm_state = s; | |
| 478 | 484 | pci_conf = s->dev.config; |
| 479 | 485 | pci_conf[0x00] = 0x86; |
| 480 | 486 | pci_conf[0x01] = 0x80; |
| ... | ... | @@ -514,5 +520,16 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) |
| 514 | 520 | register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s); |
| 515 | 521 | |
| 516 | 522 | s->smbus = i2c_init_bus(); |
| 523 | + s->irq = sci_irq; | |
| 517 | 524 | return s->smbus; |
| 518 | 525 | } |
| 526 | + | |
| 527 | +#if defined(TARGET_I386) | |
| 528 | +void qemu_system_powerdown(void) | |
| 529 | +{ | |
| 530 | + if(pm_state->pmen & PWRBTN_EN) { | |
| 531 | + pm_state->pmsts |= PWRBTN_EN; | |
| 532 | + pm_update_sci(pm_state); | |
| 533 | + } | |
| 534 | +} | |
| 535 | +#endif | ... | ... |
hw/mips_malta.c
| ... | ... | @@ -905,7 +905,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
| 905 | 905 | piix4_devfn = piix4_init(pci_bus, 80); |
| 906 | 906 | pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1, i8259); |
| 907 | 907 | usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); |
| 908 | - smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100); | |
| 908 | + smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, i8259[9]); | |
| 909 | 909 | eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ |
| 910 | 910 | for (i = 0; i < 8; i++) { |
| 911 | 911 | /* TODO: Populate SPD eeprom data. */ | ... | ... |
hw/pc.c
| ... | ... | @@ -981,7 +981,7 @@ static void pc_init1(int ram_size, int vga_ram_size, |
| 981 | 981 | i2c_bus *smbus; |
| 982 | 982 | |
| 983 | 983 | /* TODO: Populate SPD eeprom data. */ |
| 984 | - smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100); | |
| 984 | + smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]); | |
| 985 | 985 | for (i = 0; i < 8; i++) { |
| 986 | 986 | smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256)); |
| 987 | 987 | } | ... | ... |
hw/pc.h
| ... | ... | @@ -88,7 +88,8 @@ int ioport_get_a20(void); |
| 88 | 88 | |
| 89 | 89 | /* acpi.c */ |
| 90 | 90 | extern int acpi_enabled; |
| 91 | -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base); | |
| 91 | +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, | |
| 92 | + qemu_irq sci_irq); | |
| 92 | 93 | void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); |
| 93 | 94 | void acpi_bios_init(void); |
| 94 | 95 | ... | ... |
hw/piix_pci.c
| ... | ... | @@ -220,7 +220,6 @@ static void piix3_set_irq(qemu_irq *pic, int irq_num, int level) |
| 220 | 220 | { |
| 221 | 221 | int i, pic_irq, pic_level; |
| 222 | 222 | |
| 223 | - piix3_dev->config[0x60 + irq_num] &= ~0x80; // enable bit | |
| 224 | 223 | pci_irq_levels[irq_num] = level; |
| 225 | 224 | |
| 226 | 225 | /* now we change the pic irq level according to the piix irq mappings */ | ... | ... |
sysemu.h
| ... | ... | @@ -30,12 +30,16 @@ void cpu_disable_ticks(void); |
| 30 | 30 | void qemu_system_reset_request(void); |
| 31 | 31 | void qemu_system_shutdown_request(void); |
| 32 | 32 | void qemu_system_powerdown_request(void); |
| 33 | -#if !defined(TARGET_SPARC) | |
| 33 | +int qemu_shutdown_requested(void); | |
| 34 | +int qemu_reset_requested(void); | |
| 35 | +int qemu_powerdown_requested(void); | |
| 36 | +#if !defined(TARGET_SPARC) && !defined(TARGET_I386) | |
| 34 | 37 | // Please implement a power failure function to signal the OS |
| 35 | 38 | #define qemu_system_powerdown() do{}while(0) |
| 36 | 39 | #else |
| 37 | 40 | void qemu_system_powerdown(void); |
| 38 | 41 | #endif |
| 42 | +void qemu_system_reset(void); | |
| 39 | 43 | |
| 40 | 44 | void cpu_save(QEMUFile *f, void *opaque); |
| 41 | 45 | int cpu_load(QEMUFile *f, void *opaque, int version_id); | ... | ... |
vl.c
| ... | ... | @@ -7306,6 +7306,27 @@ static int reset_requested; |
| 7306 | 7306 | static int shutdown_requested; |
| 7307 | 7307 | static int powerdown_requested; |
| 7308 | 7308 | |
| 7309 | +int qemu_shutdown_requested(void) | |
| 7310 | +{ | |
| 7311 | + int r = shutdown_requested; | |
| 7312 | + shutdown_requested = 0; | |
| 7313 | + return r; | |
| 7314 | +} | |
| 7315 | + | |
| 7316 | +int qemu_reset_requested(void) | |
| 7317 | +{ | |
| 7318 | + int r = reset_requested; | |
| 7319 | + reset_requested = 0; | |
| 7320 | + return r; | |
| 7321 | +} | |
| 7322 | + | |
| 7323 | +int qemu_powerdown_requested(void) | |
| 7324 | +{ | |
| 7325 | + int r = powerdown_requested; | |
| 7326 | + powerdown_requested = 0; | |
| 7327 | + return r; | |
| 7328 | +} | |
| 7329 | + | |
| 7309 | 7330 | void qemu_register_reset(QEMUResetHandler *func, void *opaque) |
| 7310 | 7331 | { |
| 7311 | 7332 | QEMUResetEntry **pre, *re; |
| ... | ... | @@ -7320,7 +7341,7 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque) |
| 7320 | 7341 | *pre = re; |
| 7321 | 7342 | } |
| 7322 | 7343 | |
| 7323 | -static void qemu_system_reset(void) | |
| 7344 | +void qemu_system_reset(void) | |
| 7324 | 7345 | { |
| 7325 | 7346 | QEMUResetEntry *re; |
| 7326 | 7347 | ... | ... |