Commit 0bacd1300dbcd7f56bdbf1ca73438b6a68c31b8f
1 parent
6f484e73
Handle suspend in qemu (Gleb Natapov)
Reset a PC and tell BIOS that resume from ram is required on the next boot. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6080 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
32 additions
and
0 deletions
hw/acpi.c
| ... | ... | @@ -53,6 +53,8 @@ typedef struct PIIX4PMState { |
| 53 | 53 | qemu_irq irq; |
| 54 | 54 | } PIIX4PMState; |
| 55 | 55 | |
| 56 | +#define RSM_STS (1 << 15) | |
| 57 | +#define PWRBTN_STS (1 << 8) | |
| 56 | 58 | #define RTC_EN (1 << 10) |
| 57 | 59 | #define PWRBTN_EN (1 << 8) |
| 58 | 60 | #define GBL_EN (1 << 5) |
| ... | ... | @@ -151,6 +153,14 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) |
| 151 | 153 | case 0: /* soft power off */ |
| 152 | 154 | qemu_system_shutdown_request(); |
| 153 | 155 | break; |
| 156 | + case 1: | |
| 157 | + /* RSM_STS should be set on resume. Pretend that resume | |
| 158 | + was caused by power button */ | |
| 159 | + s->pmsts |= (RSM_STS | PWRBTN_STS); | |
| 160 | + qemu_system_reset_request(); | |
| 161 | +#if defined(TARGET_I386) | |
| 162 | + cmos_set_s3_resume(); | |
| 163 | +#endif | |
| 154 | 164 | default: |
| 155 | 165 | break; |
| 156 | 166 | } |
| ... | ... | @@ -471,6 +481,17 @@ static int pm_load(QEMUFile* f,void* opaque,int version_id) |
| 471 | 481 | return 0; |
| 472 | 482 | } |
| 473 | 483 | |
| 484 | +static void piix4_reset(void *opaque) | |
| 485 | +{ | |
| 486 | + PIIX4PMState *s = opaque; | |
| 487 | + uint8_t *pci_conf = s->dev.config; | |
| 488 | + | |
| 489 | + pci_conf[0x58] = 0; | |
| 490 | + pci_conf[0x59] = 0; | |
| 491 | + pci_conf[0x5a] = 0; | |
| 492 | + pci_conf[0x5b] = 0; | |
| 493 | +} | |
| 494 | + | |
| 474 | 495 | i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, |
| 475 | 496 | qemu_irq sci_irq) |
| 476 | 497 | { |
| ... | ... | @@ -527,6 +548,8 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, |
| 527 | 548 | |
| 528 | 549 | s->smbus = i2c_init_bus(); |
| 529 | 550 | s->irq = sci_irq; |
| 551 | + qemu_register_reset(piix4_reset, s); | |
| 552 | + | |
| 530 | 553 | return s->smbus; |
| 531 | 554 | } |
| 532 | 555 | ... | ... |
hw/pc.c
| ... | ... | @@ -1135,6 +1135,14 @@ static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size, |
| 1135 | 1135 | initrd_filename, 0, cpu_model); |
| 1136 | 1136 | } |
| 1137 | 1137 | |
| 1138 | +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE) | |
| 1139 | + BIOS will read it and start S3 resume at POST Entry */ | |
| 1140 | +void cmos_set_s3_resume(void) | |
| 1141 | +{ | |
| 1142 | + if (rtc_state) | |
| 1143 | + rtc_set_memory(rtc_state, 0xF, 0xFE); | |
| 1144 | +} | |
| 1145 | + | |
| 1138 | 1146 | QEMUMachine pc_machine = { |
| 1139 | 1147 | .name = "pc", |
| 1140 | 1148 | .desc = "Standard PC", | ... | ... |
hw/pc.h
| ... | ... | @@ -82,6 +82,7 @@ RTCState *rtc_init(int base, qemu_irq irq); |
| 82 | 82 | RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq); |
| 83 | 83 | void rtc_set_memory(RTCState *s, int addr, int val); |
| 84 | 84 | void rtc_set_date(RTCState *s, const struct tm *tm); |
| 85 | +void cmos_set_s3_resume(void); | |
| 85 | 86 | |
| 86 | 87 | /* pc.c */ |
| 87 | 88 | extern int fd_bootchk; | ... | ... |