From 8d12c06270c7eea2171f010e548d6e106313fd43 Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Mon, 21 May 2018 16:32:32 +0800 Subject: [PATCH] dm: introduce system/full reset and suspend Guest has erquirement to support system/full reboot and S3. Which could trigger different reset path in guest Signed-off-by: Yin Fengwei Acked-by: Anthony Xu --- devicemodel/arch/x86/pm.c | 22 +++++++++++++--------- devicemodel/core/main.c | 2 +- devicemodel/core/mevent.c | 3 ++- devicemodel/hw/pci/wdt_i6300esb.c | 2 +- devicemodel/hw/platform/atkbdc.c | 6 ++++-- devicemodel/include/vmm.h | 4 +++- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/devicemodel/arch/x86/pm.c b/devicemodel/arch/x86/pm.c index 11541c9ef..38c344190 100644 --- a/devicemodel/arch/x86/pm.c +++ b/devicemodel/arch/x86/pm.c @@ -25,6 +25,9 @@ * SUCH DAMAGE. */ +#include +#include +#include #include #include #include @@ -53,7 +56,6 @@ reset_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, uint32_t *eax, void *arg) { int error; - static uint8_t reset_control; if (bytes != 1) @@ -63,15 +65,17 @@ reset_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, else { reset_control = *eax; - /* Treat hard and soft resets the same. */ - if (reset_control & 0x4) { - error = vm_suspend(ctx, VM_SUSPEND_RESET); - assert(error == 0 || errno == EALREADY); - } - - /* cold reset should clear the value in 0xcf9 */ - if (reset_control & 0x8) { + if (*eax & 0x8) { + fprintf(stderr, "full reset\r\n"); + error = vm_suspend(ctx, VM_SUSPEND_FULL_RESET); + assert(error ==0 || errno == EALREADY); + mevent_notify(); reset_control = 0; + } else if (*eax & 0x4) { + fprintf(stderr, "system reset\r\n"); + error = vm_suspend(ctx, VM_SUSPEND_SYSTEM_RESET); + assert(error ==0 || errno == EALREADY); + mevent_notify(); } } return 0; diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index a7af095d4..c451e107d 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -887,7 +887,7 @@ main(int argc, char *argv[]) vm_pause(ctx); delete_cpu(ctx, BSP); - if (vm_get_suspend_mode() != VM_SUSPEND_RESET) + if (vm_get_suspend_mode() != VM_SUSPEND_FULL_RESET) break; vm_deinit_vdevs(ctx); diff --git a/devicemodel/core/mevent.c b/devicemodel/core/mevent.c index e2b9d0d92..86860a6ce 100644 --- a/devicemodel/core/mevent.c +++ b/devicemodel/core/mevent.c @@ -328,7 +328,8 @@ mevent_dispatch(void) */ mevent_handle(eventlist, ret); - if (vm_get_suspend_mode() != VM_SUSPEND_NONE) + if ((vm_get_suspend_mode() != VM_SUSPEND_NONE) && + (vm_get_suspend_mode() != VM_SUSPEND_SYSTEM_RESET)) break; } } diff --git a/devicemodel/hw/pci/wdt_i6300esb.c b/devicemodel/hw/pci/wdt_i6300esb.c index a41833fb2..61f2a0b94 100644 --- a/devicemodel/hw/pci/wdt_i6300esb.c +++ b/devicemodel/hw/pci/wdt_i6300esb.c @@ -105,7 +105,7 @@ wdt_expired_thread(union sigval v) wdt_timeout = 1; /* watchdog timer out, set the uos to reboot */ - vm_set_suspend_mode(VM_SUSPEND_RESET); + vm_set_suspend_mode(VM_SUSPEND_FULL_RESET); mevent_notify(); } else { /* if not need reboot, just loop timer */ diff --git a/devicemodel/hw/platform/atkbdc.c b/devicemodel/hw/platform/atkbdc.c index 8de009f80..a436004c0 100644 --- a/devicemodel/hw/platform/atkbdc.c +++ b/devicemodel/hw/platform/atkbdc.c @@ -42,6 +42,7 @@ #include "ps2kbd.h" #include "ps2mouse.h" #include "vmmapi.h" +#include "mevent.h" static void atkbdc_assert_kbd_intr(struct atkbdc_base *base) @@ -359,8 +360,9 @@ atkbdc_sts_ctl_handler(struct vmctx *ctx, int vcpu, int in, int port, base->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL; break; - case KBDC_RESET: /* Pulse "reset" line */ - error = vm_suspend(ctx, VM_SUSPEND_RESET); + case KBDC_RESET: /* Pulse "cold reset" line */ + error = vm_suspend(ctx, VM_SUSPEND_FULL_RESET); + mevent_notify(); assert(error == 0 || errno == EALREADY); break; default: diff --git a/devicemodel/include/vmm.h b/devicemodel/include/vmm.h index cef929ca9..e6fd5709a 100644 --- a/devicemodel/include/vmm.h +++ b/devicemodel/include/vmm.h @@ -57,8 +57,10 @@ enum vm_suspend_how { VM_SUSPEND_NONE, - VM_SUSPEND_RESET, + VM_SUSPEND_SYSTEM_RESET, + VM_SUSPEND_FULL_RESET, VM_SUSPEND_POWEROFF, + VM_SUSPEND_SUSPEND, VM_SUSPEND_HALT, VM_SUSPEND_TRIPLEFAULT, VM_SUSPEND_LAST