From ae1b06dac5cd3f4e03d41083e9e3c7058cda1dca Mon Sep 17 00:00:00 2001 From: Haiwei Li Date: Fri, 21 Jun 2024 12:50:17 +0800 Subject: [PATCH] dm: pm: add s3 support for an User VM with elf/bzImage For an elf-loaded or beImage-loaded User VM, acrn-dm is responsible for handling s3 related matters. After resume from S3, acrn-dm should read waking_vector and set related registers to make guest to resume. Tracked-On: #8536 Signed-off-by: Haiwei Li --- devicemodel/core/main.c | 27 ++++++++++++++++++++++++++- devicemodel/hw/platform/acpi/acpi.c | 18 ++++++++++++++++++ devicemodel/include/acpi.h | 2 ++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index ff650485b8..e2d2905243 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -742,6 +742,7 @@ vm_system_reset(struct vmctx *ctx) static void vm_suspend_resume(struct vmctx *ctx) { + struct acrn_vcpu_regs bsp_regs; /* * If we get warm reboot request, we don't want to exit the * vcpu_loop/vm_loop/mevent_loop. So we do: @@ -764,8 +765,32 @@ vm_suspend_resume(struct vmctx *ctx) vm_reset_watchdog(ctx); vm_reset(ctx); + bsp_regs = ctx->bsp_regs; + /* for bzImage or elf */ + if (!ovmf_loaded) { + uint32_t *guest_wakeup_vec32; + /* 64BIT_WAKE_SUPPORTED_F is not set */ + guest_wakeup_vec32 = paddr_guest2host(ctx, + get_acpi_wakingvector_offset(), + get_acpi_wakingvector_length()); + /* set the BSP waking vector */ + bsp_regs.vcpu_regs.cs_sel = (uint16_t)((*guest_wakeup_vec32 >> 4U) & 0xFFFFU); + bsp_regs.vcpu_regs.cs_base = bsp_regs.vcpu_regs.cs_sel << 4U; + /* real mode code segment */ + bsp_regs.vcpu_regs.cs_ar = 0x009FU; + bsp_regs.vcpu_regs.cs_limit = 0xFFFFU; + bsp_regs.vcpu_regs.rip = 0x0U; + /* CR0_ET | CR0_NE */ + bsp_regs.vcpu_regs.cr0 = 0x30; + /* real mode gdt */ + bsp_regs.vcpu_regs.gdt.limit = 0xFFFFU; + bsp_regs.vcpu_regs.gdt.base = 0UL; + /* real mode idt */ + bsp_regs.vcpu_regs.idt.limit = 0xFFFFU; + bsp_regs.vcpu_regs.idt.base = 0UL; + } /* set the BSP init state */ - vm_set_vcpu_regs(ctx, &ctx->bsp_regs); + vm_set_vcpu_regs(ctx, &bsp_regs); vm_run(ctx); } diff --git a/devicemodel/hw/platform/acpi/acpi.c b/devicemodel/hw/platform/acpi/acpi.c index c5f6a40af4..1d2c0731e2 100644 --- a/devicemodel/hw/platform/acpi/acpi.c +++ b/devicemodel/hw/platform/acpi/acpi.c @@ -93,6 +93,12 @@ #define RTCT_OFFSET 0xF00 #define DSDT_OFFSET 0x1100 +/* Define the byte offset and byte length in FACS table */ +#define WAKING_VECTOR_OFFSET 12 +#define WAKING_VECTOR_LEN 4 +#define X_WAKING_VECTOR_OFFSET 24 +#define X_WAKING_VECTOR_LEN 8 + #define ASL_TEMPLATE "dm.XXXXXXX" #define ASL_SUFFIX ".aml" @@ -1112,6 +1118,18 @@ get_acpi_table_length(void) return ACPI_LENGTH; } +uint32_t +get_acpi_wakingvector_offset(void) +{ + return basl_acpi_base + FACS_OFFSET + WAKING_VECTOR_OFFSET; +} + +uint32_t +get_acpi_wakingvector_length(void) +{ + return WAKING_VECTOR_LEN; +} + int get_default_iasl_compiler(void) { diff --git a/devicemodel/include/acpi.h b/devicemodel/include/acpi.h index b8d088a09a..c2f68bbebe 100644 --- a/devicemodel/include/acpi.h +++ b/devicemodel/include/acpi.h @@ -99,6 +99,8 @@ struct acpi_madt_local_apic { void acpi_table_enable(int num); uint32_t get_acpi_base(void); uint32_t get_acpi_table_length(void); +uint32_t get_acpi_wakingvector_offset(void); +uint32_t get_acpi_wakingvector_length(void); struct vmctx;