mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-04 19:17:34 +00:00
HV: modularization to refine pm related code.
1. move out vm related code from arch/pm. 2. remove unnecssary global variables. 3. keep the global variables as static, not used by other modules directlly. Tracked-On: #1842 Signed-off-by: Minggui Cao <minggui.cao@intel.com> Reviewed-by: Victor Sun <victor.sun@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
03262a96cf
commit
f81fb21a58
@ -106,7 +106,7 @@ void vm_setup_cpu_state(struct acrn_vm *vm)
|
||||
int32_t vm_load_pm_s_state(struct acrn_vm *vm)
|
||||
{
|
||||
#ifdef ACPI_INFO_VALIDATED
|
||||
vm->pm.sx_state_data = (struct pm_s_state_data *)&host_pm_s_state;
|
||||
vm->pm.sx_state_data = get_host_sstate_data();
|
||||
pr_info("System S3/S5 is supported.");
|
||||
return 0;
|
||||
#else
|
||||
@ -126,24 +126,28 @@ static inline uint8_t get_slp_typx(uint32_t pm1_cnt)
|
||||
return (uint8_t)((pm1_cnt & 0x1fffU) >> BIT_SLP_TYPx);
|
||||
}
|
||||
|
||||
static uint32_t pm1ab_io_read(__unused struct acrn_vm *vm, uint16_t addr,
|
||||
size_t width)
|
||||
static uint32_t pm1ab_io_read(__unused struct acrn_vm *vm, uint16_t addr, size_t width)
|
||||
{
|
||||
uint32_t val = pio_read(addr, width);
|
||||
|
||||
if (host_enter_s3_success == 0U) {
|
||||
/* If host S3 enter failes, we should set BIT_WAK_STS
|
||||
* bit for vm0 and let vm0 back from S3 failure path.
|
||||
*/
|
||||
if (addr == vm->pm.sx_state_data->pm1a_evt.address) {
|
||||
val |= (1U << BIT_WAK_STS);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
return pio_read(addr, width);
|
||||
}
|
||||
|
||||
static void pm1ab_io_write(__unused struct acrn_vm *vm, uint16_t addr, size_t width,
|
||||
uint32_t v)
|
||||
static inline void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
{
|
||||
uint32_t guest_wakeup_vec32;
|
||||
|
||||
/* Save the wakeup vec set by guest OS. Will return to guest
|
||||
* with this wakeup vec as entry.
|
||||
*/
|
||||
stac();
|
||||
guest_wakeup_vec32 = *(vm->pm.sx_state_data->wake_vector_32);
|
||||
clac();
|
||||
|
||||
pause_vm(vm); /* pause vm0 before suspend system */
|
||||
host_enter_s3(vm->pm.sx_state_data, pm1a_cnt_val, pm1b_cnt_val);
|
||||
resume_vm_from_s3(vm, guest_wakeup_vec32); /* jump back to vm */
|
||||
}
|
||||
|
||||
static void pm1ab_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, uint32_t v)
|
||||
{
|
||||
static uint32_t pm1a_cnt_ready = 0U;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
struct cpu_context cpu_ctx;
|
||||
|
||||
/* The values in this structure should come from host ACPI table */
|
||||
struct pm_s_state_data host_pm_s_state = {
|
||||
static struct pm_s_state_data host_pm_s_state = {
|
||||
.pm1a_evt = {
|
||||
.space_id = PM1A_EVT_SPACE_ID,
|
||||
.bit_width = PM1A_EVT_BIT_WIDTH,
|
||||
@ -51,8 +51,16 @@ struct pm_s_state_data host_pm_s_state = {
|
||||
.wake_vector_64 = (uint64_t *)WAKE_VECTOR_64
|
||||
};
|
||||
|
||||
/* whether the host enter s3 success */
|
||||
uint8_t host_enter_s3_success = 1U;
|
||||
void set_host_wake_vectors(void *vector_32, void *vector_64)
|
||||
{
|
||||
host_pm_s_state.wake_vector_32 = (uint32_t *)vector_32;
|
||||
host_pm_s_state.wake_vector_64 = (uint64_t *)vector_64;
|
||||
}
|
||||
|
||||
struct pm_s_state_data *get_host_sstate_data(void)
|
||||
{
|
||||
return &host_pm_s_state;
|
||||
}
|
||||
|
||||
void restore_msrs(void)
|
||||
{
|
||||
@ -87,29 +95,24 @@ static uint32_t acpi_gas_read(const struct acpi_generic_address *gas)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
|
||||
uint32_t pm1b_cnt_val)
|
||||
void do_acpi_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
{
|
||||
uint32_t s1, s2;
|
||||
struct pm_s_state_data *sx_data = vm->pm.sx_state_data;
|
||||
|
||||
acpi_gas_write(&(sx_data->pm1a_cnt), pm1a_cnt_val);
|
||||
acpi_gas_write(&(sstate_data->pm1a_cnt), pm1a_cnt_val);
|
||||
|
||||
if (vm->pm.sx_state_data->pm1b_cnt.address != 0U) {
|
||||
acpi_gas_write(&(sx_data->pm1b_cnt), pm1b_cnt_val);
|
||||
if (sstate_data->pm1b_cnt.address != 0U) {
|
||||
acpi_gas_write(&(sstate_data->pm1b_cnt), pm1b_cnt_val);
|
||||
}
|
||||
|
||||
do {
|
||||
/* polling PM1 state register to detect wether
|
||||
* the Sx state enter is interrupted by wakeup event.
|
||||
*/
|
||||
s1 = 0U;
|
||||
s2 = 0U;
|
||||
s1 = acpi_gas_read(&(sstate_data->pm1a_evt));
|
||||
|
||||
s1 = acpi_gas_read(&(sx_data->pm1a_evt));
|
||||
|
||||
if (vm->pm.sx_state_data->pm1b_evt.address != 0U) {
|
||||
s2 = acpi_gas_read(&(sx_data->pm1b_evt));
|
||||
if (sstate_data->pm1b_evt.address != 0U) {
|
||||
s2 = acpi_gas_read(&(sstate_data->pm1b_evt));
|
||||
s1 |= s2;
|
||||
}
|
||||
|
||||
@ -120,25 +123,14 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
|
||||
} while ((s1 & (1U << BIT_WAK_STS)) == 0U);
|
||||
}
|
||||
|
||||
void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
void host_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
{
|
||||
uint64_t pmain_entry_saved;
|
||||
uint32_t guest_wakeup_vec32;
|
||||
|
||||
/* We assume enter s3 success by default */
|
||||
host_enter_s3_success = 1U;
|
||||
if (vm->pm.sx_state_data != NULL) {
|
||||
pause_vm(vm); /* pause vm0 before suspend system */
|
||||
|
||||
stac();
|
||||
/* Save the wakeup vec set by guest. Will return to guest
|
||||
* with this wakeup vec as entry.
|
||||
*/
|
||||
guest_wakeup_vec32 = *vm->pm.sx_state_data->wake_vector_32;
|
||||
|
||||
/* set ACRN wakeup vec instead */
|
||||
*vm->pm.sx_state_data->wake_vector_32 =
|
||||
(uint32_t) trampoline_start16_paddr;
|
||||
*(sstate_data->wake_vector_32) = (uint32_t)trampoline_start16_paddr;
|
||||
|
||||
clac();
|
||||
/* offline all APs */
|
||||
@ -163,7 +155,7 @@ void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
suspend_iommu();
|
||||
suspend_lapic();
|
||||
|
||||
asm_enter_s3(vm, pm1a_cnt_val, pm1b_cnt_val);
|
||||
asm_enter_s3(sstate_data, pm1a_cnt_val, pm1b_cnt_val);
|
||||
|
||||
resume_lapic();
|
||||
resume_iommu();
|
||||
@ -180,14 +172,4 @@ void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
|
||||
|
||||
/* online all APs again */
|
||||
start_cpus();
|
||||
|
||||
/* jump back to vm */
|
||||
resume_vm_from_s3(vm, guest_wakeup_vec32);
|
||||
} else {
|
||||
pr_err("No Sx state info avaiable. No Sx support");
|
||||
host_enter_s3_success = 0U;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ asm_enter_s3:
|
||||
/*16U=0x10=CPU_CONTEXT_OFFSET_RDX*/
|
||||
movq 0x10 + cpu_ctx(%rip), %rdx /* pm1b_cnt_val */
|
||||
/*56U=0x38=CPU_CONTEXT_OFFSET_RDI*/
|
||||
movq 0x38 + cpu_ctx(%rip), %rdi /* *vm */
|
||||
movq 0x38 + cpu_ctx(%rip), %rdi /* pm sstate_data */
|
||||
/*48U=0x30=CPU_CONTEXT_OFFSET_RSI*/
|
||||
movq 0x30 + cpu_ctx(%rip), %rsi /* pm1a_cnt_val */
|
||||
|
||||
|
@ -369,8 +369,7 @@ void acpi_fixup(void)
|
||||
void *facs_addr = get_facs_table();
|
||||
|
||||
if (facs_addr != NULL) {
|
||||
host_pm_s_state.wake_vector_32 = (uint32_t *)(facs_addr + OFFSET_WAKE_VECTOR_32);
|
||||
host_pm_s_state.wake_vector_64 = (uint64_t *)(facs_addr + OFFSET_WAKE_VECTOR_64);
|
||||
set_host_wake_vectors(facs_addr + OFFSET_WAKE_VECTOR_32, facs_addr + OFFSET_WAKE_VECTOR_64);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -10,13 +10,11 @@
|
||||
#define BIT_SLP_EN 13U
|
||||
#define BIT_WAK_STS 15U
|
||||
|
||||
extern struct pm_s_state_data host_pm_s_state;
|
||||
void set_host_wake_vectors(void *vector_32, void *vector_64);
|
||||
struct pm_s_state_data *get_host_sstate_data(void);
|
||||
|
||||
extern uint8_t host_enter_s3_success;
|
||||
|
||||
void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
|
||||
extern void asm_enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
|
||||
uint32_t pm1b_cnt_val);
|
||||
void host_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
|
||||
extern void asm_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
|
||||
extern void restore_s3_context(void);
|
||||
|
||||
#endif /* HOST_PM_H */
|
||||
|
Loading…
Reference in New Issue
Block a user