8
8
struct cpu_context cpu_ctx ;
9
9
10
10
/* 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 = {
12
12
.pm1a_evt = {
13
13
.space_id = PM1A_EVT_SPACE_ID ,
14
14
.bit_width = PM1A_EVT_BIT_WIDTH ,
@@ -51,8 +51,16 @@ struct pm_s_state_data host_pm_s_state = {
51
51
.wake_vector_64 = (uint64_t * )WAKE_VECTOR_64
52
52
};
53
53
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
+ }
56
64
57
65
void restore_msrs (void )
58
66
{
@@ -87,29 +95,24 @@ static uint32_t acpi_gas_read(const struct acpi_generic_address *gas)
87
95
return ret ;
88
96
}
89
97
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 )
92
99
{
93
100
uint32_t s1 , s2 ;
94
- struct pm_s_state_data * sx_data = vm -> pm .sx_state_data ;
95
101
96
- acpi_gas_write (& (sx_data -> pm1a_cnt ), pm1a_cnt_val );
102
+ acpi_gas_write (& (sstate_data -> pm1a_cnt ), pm1a_cnt_val );
97
103
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 );
100
106
}
101
107
102
108
do {
103
109
/* polling PM1 state register to detect wether
104
110
* the Sx state enter is interrupted by wakeup event.
105
111
*/
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 ));
110
113
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 ));
113
116
s1 |= s2 ;
114
117
}
115
118
@@ -120,74 +123,53 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val,
120
123
} while ((s1 & (1U << BIT_WAK_STS )) == 0U );
121
124
}
122
125
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 )
124
127
{
125
128
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 */
132
129
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 ();
142
131
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 ;
153
134
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 ();
157
138
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 );
160
145
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 ();
165
149
166
- asm_enter_s3 (vm , pm1a_cnt_val , pm1b_cnt_val );
150
+ CPU_IRQ_DISABLE ();
151
+ vmx_off ();
167
152
168
- resume_lapic ();
169
- resume_iommu ();
170
- resume_ioapic ();
171
- resume_console ();
153
+ suspend_console ();
154
+ suspend_ioapic ();
155
+ suspend_iommu ();
156
+ suspend_lapic ();
172
157
173
- vmx_on ();
174
- CPU_IRQ_ENABLE ();
158
+ asm_enter_s3 (sstate_data , pm1a_cnt_val , pm1b_cnt_val );
175
159
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 ();
180
164
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 ();
190
167
168
+ /* restore the default main entry */
169
+ stac ();
170
+ write_trampoline_sym (main_entry , pmain_entry_saved );
171
+ clac ();
191
172
192
- return ;
173
+ /* online all APs again */
174
+ start_cpus ();
193
175
}
0 commit comments