Skip to content

Commit f81fb21

Browse files
mgcaowenlingz
authored andcommitted
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>
1 parent 03262a9 commit f81fb21

File tree

5 files changed

+78
-95
lines changed

5 files changed

+78
-95
lines changed

hypervisor/arch/x86/guest/pm.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void vm_setup_cpu_state(struct acrn_vm *vm)
106106
int32_t vm_load_pm_s_state(struct acrn_vm *vm)
107107
{
108108
#ifdef ACPI_INFO_VALIDATED
109-
vm->pm.sx_state_data = (struct pm_s_state_data *)&host_pm_s_state;
109+
vm->pm.sx_state_data = get_host_sstate_data();
110110
pr_info("System S3/S5 is supported.");
111111
return 0;
112112
#else
@@ -126,24 +126,28 @@ static inline uint8_t get_slp_typx(uint32_t pm1_cnt)
126126
return (uint8_t)((pm1_cnt & 0x1fffU) >> BIT_SLP_TYPx);
127127
}
128128

129-
static uint32_t pm1ab_io_read(__unused struct acrn_vm *vm, uint16_t addr,
130-
size_t width)
129+
static uint32_t pm1ab_io_read(__unused struct acrn_vm *vm, uint16_t addr, size_t width)
131130
{
132-
uint32_t val = pio_read(addr, width);
131+
return pio_read(addr, width);
132+
}
133133

134-
if (host_enter_s3_success == 0U) {
135-
/* If host S3 enter failes, we should set BIT_WAK_STS
136-
* bit for vm0 and let vm0 back from S3 failure path.
137-
*/
138-
if (addr == vm->pm.sx_state_data->pm1a_evt.address) {
139-
val |= (1U << BIT_WAK_STS);
140-
}
141-
}
142-
return val;
134+
static inline void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
135+
{
136+
uint32_t guest_wakeup_vec32;
137+
138+
/* Save the wakeup vec set by guest OS. Will return to guest
139+
* with this wakeup vec as entry.
140+
*/
141+
stac();
142+
guest_wakeup_vec32 = *(vm->pm.sx_state_data->wake_vector_32);
143+
clac();
144+
145+
pause_vm(vm); /* pause vm0 before suspend system */
146+
host_enter_s3(vm->pm.sx_state_data, pm1a_cnt_val, pm1b_cnt_val);
147+
resume_vm_from_s3(vm, guest_wakeup_vec32); /* jump back to vm */
143148
}
144149

145-
static void pm1ab_io_write(__unused struct acrn_vm *vm, uint16_t addr, size_t width,
146-
uint32_t v)
150+
static void pm1ab_io_write(struct acrn_vm *vm, uint16_t addr, size_t width, uint32_t v)
147151
{
148152
static uint32_t pm1a_cnt_ready = 0U;
149153

hypervisor/arch/x86/pm.c

Lines changed: 53 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
struct cpu_context cpu_ctx;
99

1010
/* The values in this structure should come from host ACPI table */
11-
struct pm_s_state_data host_pm_s_state = {
11+
static struct pm_s_state_data host_pm_s_state = {
1212
.pm1a_evt = {
1313
.space_id = PM1A_EVT_SPACE_ID,
1414
.bit_width = PM1A_EVT_BIT_WIDTH,
@@ -51,8 +51,16 @@ struct pm_s_state_data host_pm_s_state = {
5151
.wake_vector_64 = (uint64_t *)WAKE_VECTOR_64
5252
};
5353

54-
/* whether the host enter s3 success */
55-
uint8_t host_enter_s3_success = 1U;
54+
void set_host_wake_vectors(void *vector_32, void *vector_64)
55+
{
56+
host_pm_s_state.wake_vector_32 = (uint32_t *)vector_32;
57+
host_pm_s_state.wake_vector_64 = (uint64_t *)vector_64;
58+
}
59+
60+
struct pm_s_state_data *get_host_sstate_data(void)
61+
{
62+
return &host_pm_s_state;
63+
}
5664

5765
void restore_msrs(void)
5866
{
@@ -87,29 +95,24 @@ static uint32_t acpi_gas_read(const struct acpi_generic_address *gas)
8795
return ret;
8896
}
8997

90-
void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
91-
uint32_t pm1b_cnt_val)
98+
void do_acpi_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
9299
{
93100
uint32_t s1, s2;
94-
struct pm_s_state_data *sx_data = vm->pm.sx_state_data;
95101

96-
acpi_gas_write(&(sx_data->pm1a_cnt), pm1a_cnt_val);
102+
acpi_gas_write(&(sstate_data->pm1a_cnt), pm1a_cnt_val);
97103

98-
if (vm->pm.sx_state_data->pm1b_cnt.address != 0U) {
99-
acpi_gas_write(&(sx_data->pm1b_cnt), pm1b_cnt_val);
104+
if (sstate_data->pm1b_cnt.address != 0U) {
105+
acpi_gas_write(&(sstate_data->pm1b_cnt), pm1b_cnt_val);
100106
}
101107

102108
do {
103109
/* polling PM1 state register to detect wether
104110
* the Sx state enter is interrupted by wakeup event.
105111
*/
106-
s1 = 0U;
107-
s2 = 0U;
108-
109-
s1 = acpi_gas_read(&(sx_data->pm1a_evt));
112+
s1 = acpi_gas_read(&(sstate_data->pm1a_evt));
110113

111-
if (vm->pm.sx_state_data->pm1b_evt.address != 0U) {
112-
s2 = acpi_gas_read(&(sx_data->pm1b_evt));
114+
if (sstate_data->pm1b_evt.address != 0U) {
115+
s2 = acpi_gas_read(&(sstate_data->pm1b_evt));
113116
s1 |= s2;
114117
}
115118

@@ -120,74 +123,53 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
120123
} while ((s1 & (1U << BIT_WAK_STS)) == 0U);
121124
}
122125

123-
void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
126+
void host_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
124127
{
125128
uint64_t pmain_entry_saved;
126-
uint32_t guest_wakeup_vec32;
127-
128-
/* We assume enter s3 success by default */
129-
host_enter_s3_success = 1U;
130-
if (vm->pm.sx_state_data != NULL) {
131-
pause_vm(vm); /* pause vm0 before suspend system */
132129

133-
stac();
134-
/* Save the wakeup vec set by guest. Will return to guest
135-
* with this wakeup vec as entry.
136-
*/
137-
guest_wakeup_vec32 = *vm->pm.sx_state_data->wake_vector_32;
138-
139-
/* set ACRN wakeup vec instead */
140-
*vm->pm.sx_state_data->wake_vector_32 =
141-
(uint32_t) trampoline_start16_paddr;
130+
stac();
142131

143-
clac();
144-
/* offline all APs */
145-
stop_cpus();
146-
147-
stac();
148-
/* Save default main entry and we will restore it after
149-
* back from S3. So the AP online could jmp to correct
150-
* main entry.
151-
*/
152-
pmain_entry_saved = read_trampoline_sym(main_entry);
132+
/* set ACRN wakeup vec instead */
133+
*(sstate_data->wake_vector_32) = (uint32_t)trampoline_start16_paddr;
153134

154-
/* Set the main entry for resume from S3 state */
155-
write_trampoline_sym(main_entry, (uint64_t)restore_s3_context);
156-
clac();
135+
clac();
136+
/* offline all APs */
137+
stop_cpus();
157138

158-
CPU_IRQ_DISABLE();
159-
vmx_off();
139+
stac();
140+
/* Save default main entry and we will restore it after
141+
* back from S3. So the AP online could jmp to correct
142+
* main entry.
143+
*/
144+
pmain_entry_saved = read_trampoline_sym(main_entry);
160145

161-
suspend_console();
162-
suspend_ioapic();
163-
suspend_iommu();
164-
suspend_lapic();
146+
/* Set the main entry for resume from S3 state */
147+
write_trampoline_sym(main_entry, (uint64_t)restore_s3_context);
148+
clac();
165149

166-
asm_enter_s3(vm, pm1a_cnt_val, pm1b_cnt_val);
150+
CPU_IRQ_DISABLE();
151+
vmx_off();
167152

168-
resume_lapic();
169-
resume_iommu();
170-
resume_ioapic();
171-
resume_console();
153+
suspend_console();
154+
suspend_ioapic();
155+
suspend_iommu();
156+
suspend_lapic();
172157

173-
vmx_on();
174-
CPU_IRQ_ENABLE();
158+
asm_enter_s3(sstate_data, pm1a_cnt_val, pm1b_cnt_val);
175159

176-
/* restore the default main entry */
177-
stac();
178-
write_trampoline_sym(main_entry, pmain_entry_saved);
179-
clac();
160+
resume_lapic();
161+
resume_iommu();
162+
resume_ioapic();
163+
resume_console();
180164

181-
/* online all APs again */
182-
start_cpus();
183-
184-
/* jump back to vm */
185-
resume_vm_from_s3(vm, guest_wakeup_vec32);
186-
} else {
187-
pr_err("No Sx state info avaiable. No Sx support");
188-
host_enter_s3_success = 0U;
189-
}
165+
vmx_on();
166+
CPU_IRQ_ENABLE();
190167

168+
/* restore the default main entry */
169+
stac();
170+
write_trampoline_sym(main_entry, pmain_entry_saved);
171+
clac();
191172

192-
return;
173+
/* online all APs again */
174+
start_cpus();
193175
}

hypervisor/arch/x86/wakeup.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ asm_enter_s3:
9292
/*16U=0x10=CPU_CONTEXT_OFFSET_RDX*/
9393
movq 0x10 + cpu_ctx(%rip), %rdx /* pm1b_cnt_val */
9494
/*56U=0x38=CPU_CONTEXT_OFFSET_RDI*/
95-
movq 0x38 + cpu_ctx(%rip), %rdi /* *vm */
95+
movq 0x38 + cpu_ctx(%rip), %rdi /* pm sstate_data */
9696
/*48U=0x30=CPU_CONTEXT_OFFSET_RSI*/
9797
movq 0x30 + cpu_ctx(%rip), %rsi /* pm1a_cnt_val */
9898

hypervisor/boot/acpi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,7 @@ void acpi_fixup(void)
369369
void *facs_addr = get_facs_table();
370370

371371
if (facs_addr != NULL) {
372-
host_pm_s_state.wake_vector_32 = (uint32_t *)(facs_addr + OFFSET_WAKE_VECTOR_32);
373-
host_pm_s_state.wake_vector_64 = (uint64_t *)(facs_addr + OFFSET_WAKE_VECTOR_64);
372+
set_host_wake_vectors(facs_addr + OFFSET_WAKE_VECTOR_32, facs_addr + OFFSET_WAKE_VECTOR_64);
374373
}
375374
}
376375
#endif

hypervisor/include/arch/x86/host_pm.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@
1010
#define BIT_SLP_EN 13U
1111
#define BIT_WAK_STS 15U
1212

13-
extern struct pm_s_state_data host_pm_s_state;
13+
void set_host_wake_vectors(void *vector_32, void *vector_64);
14+
struct pm_s_state_data *get_host_sstate_data(void);
1415

15-
extern uint8_t host_enter_s3_success;
16-
17-
void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
18-
extern void asm_enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
19-
uint32_t pm1b_cnt_val);
16+
void host_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
17+
extern void asm_enter_s3(struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val);
2018
extern void restore_s3_context(void);
2119

2220
#endif /* HOST_PM_H */

0 commit comments

Comments
 (0)