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:
Minggui Cao 2018-12-14 16:33:14 +08:00 committed by wenlingz
parent 03262a96cf
commit f81fb21a58
5 changed files with 79 additions and 96 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

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

View File

@ -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 */