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 | ... | ... |