1 /*
2 * Copyright (C) 2018-2022 Intel Corporation.
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 #include <acrn_common.h>
7 #include <asm/default_acpi_info.h>
8 #include <platform_acpi_info.h>
9 #include <asm/per_cpu.h>
10 #include <asm/io.h>
11 #include <asm/msr.h>
12 #include <asm/pgtable.h>
13 #include <asm/host_pm.h>
14 #include <asm/trampoline.h>
15 #include <asm/vmx.h>
16 #include <console.h>
17 #include <asm/ioapic.h>
18 #include <asm/vtd.h>
19 #include <asm/lapic.h>
20 #include <asm/tsc.h>
21 #include <delay.h>
22 #include <asm/board.h>
23 #include <asm/cpuid.h>
24
25 struct cpu_context cpu_ctx;
26
27 /* The values in this structure should come from host ACPI table */
28 static struct pm_s_state_data host_pm_s_state = {
29 .pm1a_evt = {
30 .space_id = PM1A_EVT_SPACE_ID,
31 .bit_width = PM1A_EVT_BIT_WIDTH,
32 .bit_offset = PM1A_EVT_BIT_OFFSET,
33 .access_size = PM1A_EVT_ACCESS_SIZE,
34 .address = PM1A_EVT_ADDRESS
35 },
36 .pm1b_evt = {
37 .space_id = PM1B_EVT_SPACE_ID,
38 .bit_width = PM1B_EVT_BIT_WIDTH,
39 .bit_offset = PM1B_EVT_BIT_OFFSET,
40 .access_size = PM1B_EVT_ACCESS_SIZE,
41 .address = PM1B_EVT_ADDRESS
42 },
43 .pm1a_cnt = {
44 .space_id = PM1A_CNT_SPACE_ID,
45 .bit_width = PM1A_CNT_BIT_WIDTH,
46 .bit_offset = PM1A_CNT_BIT_OFFSET,
47 .access_size = PM1A_CNT_ACCESS_SIZE,
48 .address = PM1A_CNT_ADDRESS
49 },
50 .pm1b_cnt = {
51 .space_id = PM1B_CNT_SPACE_ID,
52 .bit_width = PM1B_CNT_BIT_WIDTH,
53 .bit_offset = PM1B_CNT_BIT_OFFSET,
54 .access_size = PM1B_CNT_ACCESS_SIZE,
55 .address = PM1B_CNT_ADDRESS
56 },
57 .s3_pkg = {
58 .val_pm1a = S3_PKG_VAL_PM1A,
59 .val_pm1b = S3_PKG_VAL_PM1B,
60 .reserved = S3_PKG_RESERVED
61 },
62 .s5_pkg = {
63 .val_pm1a = S5_PKG_VAL_PM1A,
64 .val_pm1b = S5_PKG_VAL_PM1B,
65 .reserved = S5_PKG_RESERVED
66 },
67 .wake_vector_32 = (uint32_t *)WAKE_VECTOR_32,
68 .wake_vector_64 = (uint64_t *)WAKE_VECTOR_64
69 };
70
71 /* host reset register defined in ACPI */
72 static struct acpi_reset_reg host_reset_reg = {
73 .reg = {
74 .space_id = RESET_REGISTER_SPACE_ID,
75 .bit_width = RESET_REGISTER_BIT_WIDTH,
76 .bit_offset = RESET_REGISTER_BIT_OFFSET,
77 .access_size = RESET_REGISTER_ACCESS_SIZE,
78 .address = RESET_REGISTER_ADDRESS,
79 },
80 .val = RESET_REGISTER_VALUE
81 };
82
get_host_sstate_data(void)83 struct pm_s_state_data *get_host_sstate_data(void)
84 {
85 return &host_pm_s_state;
86 }
87
get_host_reset_reg_data(void)88 struct acpi_reset_reg *get_host_reset_reg_data(void)
89 {
90 return &host_reset_reg;
91 }
92
restore_msrs(void)93 void restore_msrs(void)
94 {
95 #ifdef STACK_PROTECTOR
96 struct stack_canary *psc = &get_cpu_var(stk_canary);
97
98 msr_write(MSR_IA32_FS_BASE, (uint64_t)psc);
99 #endif
100 }
101
acpi_gas_write(const struct acrn_acpi_generic_address * gas,uint32_t val)102 static void acpi_gas_write(const struct acrn_acpi_generic_address *gas, uint32_t val)
103 {
104 uint16_t val16 = (uint16_t)val;
105
106 if (gas->space_id == SPACE_SYSTEM_MEMORY) {
107 mmio_write16(val16, hpa2hva(gas->address));
108 } else {
109 pio_write16(val16, (uint16_t)gas->address);
110 }
111 }
112
acpi_gas_read(const struct acrn_acpi_generic_address * gas)113 static uint32_t acpi_gas_read(const struct acrn_acpi_generic_address *gas)
114 {
115 uint32_t ret = 0U;
116
117 if (gas->space_id == SPACE_SYSTEM_MEMORY) {
118 ret = mmio_read16(hpa2hva(gas->address));
119 } else {
120 ret = pio_read16((uint16_t)gas->address);
121 }
122
123 return ret;
124 }
125
126 /* This function supports enter S3 or S5 according to the value given to pm1a_cnt_val and pm1b_cnt_val */
do_acpi_sx(const struct pm_s_state_data * sstate_data,uint32_t pm1a_cnt_val,uint32_t pm1b_cnt_val)127 void do_acpi_sx(const struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
128 {
129 uint32_t s1, s2;
130
131 acpi_gas_write(&(sstate_data->pm1a_cnt), pm1a_cnt_val);
132
133 if (sstate_data->pm1b_cnt.address != 0U) {
134 acpi_gas_write(&(sstate_data->pm1b_cnt), pm1b_cnt_val);
135 }
136
137 do {
138 /* polling PM1 state register to detect wether
139 * the Sx state enter is interrupted by wakeup event.
140 */
141 s1 = acpi_gas_read(&(sstate_data->pm1a_evt));
142
143 if (sstate_data->pm1b_evt.address != 0U) {
144 s2 = acpi_gas_read(&(sstate_data->pm1b_evt));
145 s1 |= s2;
146 }
147
148 /* According to ACPI spec 4.8.3.1.1 PM1 state register, the bit
149 * WAK_STS(bit 15) is set if system will transition to working
150 * state.
151 */
152 } while ((s1 & (1U << BIT_WAK_STS)) == 0U);
153 }
154
155 static uint32_t system_pm1a_cnt_val, system_pm1b_cnt_val;
save_s5_reg_val(uint32_t pm1a_cnt_val,uint32_t pm1b_cnt_val)156 void save_s5_reg_val(uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
157 {
158 system_pm1a_cnt_val = pm1a_cnt_val;
159 system_pm1b_cnt_val = pm1b_cnt_val;
160 }
161
shutdown_system(void)162 void shutdown_system(void)
163 {
164 struct pm_s_state_data *sx_data = get_host_sstate_data();
165 do_acpi_sx(sx_data, system_pm1a_cnt_val, system_pm1b_cnt_val);
166 }
167
suspend_tsc(__unused void * data)168 static void suspend_tsc(__unused void *data)
169 {
170 per_cpu(tsc_suspend, get_pcpu_id()) = rdtsc();
171 }
172
resume_tsc(__unused void * data)173 static void resume_tsc(__unused void *data)
174 {
175 msr_write(MSR_IA32_TIME_STAMP_COUNTER, per_cpu(tsc_suspend, get_pcpu_id()));
176 }
177
host_enter_s3(const struct pm_s_state_data * sstate_data,uint32_t pm1a_cnt_val,uint32_t pm1b_cnt_val)178 void host_enter_s3(const struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
179 {
180 uint64_t pmain_entry_saved;
181
182 stac();
183
184 /* set ACRN wakeup vec instead */
185 *(sstate_data->wake_vector_32) = (uint32_t)get_trampoline_start16_paddr();
186
187 clac();
188
189 /* Save TSC on all PCPU */
190 smp_call_function(get_active_pcpu_bitmap(), suspend_tsc, NULL);
191
192 /* offline all APs */
193 stop_pcpus();
194
195 stac();
196 /* Save default main entry and we will restore it after
197 * back from S3. So the AP online could jmp to correct
198 * main entry.
199 */
200 pmain_entry_saved = read_trampoline_sym(main_entry);
201
202 /* Set the main entry for resume from S3 state */
203 write_trampoline_sym(main_entry, (uint64_t)restore_s3_context);
204 clac();
205
206 CPU_IRQ_DISABLE_ON_CONFIG();
207 vmx_off();
208
209 suspend_console();
210 suspend_vrtc();
211 suspend_sched();
212 suspend_ioapic();
213 suspend_iommu();
214 suspend_lapic();
215
216 asm_enter_s3(sstate_data, pm1a_cnt_val, pm1b_cnt_val);
217
218 resume_lapic();
219 resume_iommu();
220 resume_ioapic();
221 init_frequency_policy();
222
223 vmx_on();
224 CPU_IRQ_ENABLE_ON_CONFIG();
225
226 /* restore the default main entry */
227 stac();
228 write_trampoline_sym(main_entry, pmain_entry_saved);
229 clac();
230
231 /* online all APs again */
232 if (!start_pcpus(AP_MASK)) {
233 panic("Failed to start all APs!");
234 }
235
236 /* Restore TSC on all PCPU
237 * Caution: There should no timer setup before TSC resumed.
238 */
239 smp_call_function(get_active_pcpu_bitmap(), resume_tsc, NULL);
240
241 /* console must be resumed after TSC restored since it will setup timer base on TSC */
242 resume_sched();
243 resume_vrtc();
244 resume_console();
245 }
246
reset_host(bool warm)247 void reset_host(bool warm)
248 {
249 struct acrn_acpi_generic_address *gas = &(host_reset_reg.reg);
250 uint8_t reboot_code = warm ? CF9_RESET_WARM : CF9_RESET_COLD;
251
252 /* TODO: gracefully shut down all guests before doing host reset. */
253
254 /*
255 * Assumption:
256 * The platform we are running must support at least one of reset method:
257 * - ACPI reset
258 * - 0xcf9 reset
259 */
260 if ((gas->space_id == SPACE_SYSTEM_IO) &&
261 (gas->bit_width == 8U) && (gas->bit_offset == 0U) &&
262 (gas->address != 0U) && (gas->address != 0xcf9U)) {
263 pio_write8(host_reset_reg.val, (uint16_t)host_reset_reg.reg.address);
264 } else {
265 /* making sure bit 2 (RST_CPU) is '0', when the reset command is issued. */
266 pio_write8(0x2U, 0xcf9U);
267 udelay(50U);
268 pio_write8(reboot_code, 0xcf9U);
269 udelay(50U);
270 }
271
272 pr_fatal("%s(): can't reset host.", __func__);
273 while (1) {
274 asm_pause();
275 }
276 }
277
278 static enum acrn_cpufreq_policy_type cpufreq_policy = CPUFREQ_POLICY_PERFORMANCE;
279
init_frequency_policy(void)280 void init_frequency_policy(void)
281 {
282 uint32_t cpuid_06_eax, unused;
283 struct acrn_boot_info *abi = get_acrn_boot_info();
284 const char *cmd_src = abi->cmdline;
285
286 /*
287 * Parse cmdline, decide which policy type to use.
288 * User can either specify cpu_perf_policy=Nominal or cpu_perf_policy=Performance
289 * The default type is 'Performance'
290 */
291 if(strstr_s(cmd_src, MAX_BOOTARGS_SIZE, "cpu_perf_policy=Nominal", 24U) != NULL) {
292 cpufreq_policy = CPUFREQ_POLICY_NOMINAL;
293 }
294
295 cpuid_subleaf(0x6U, 0U, &cpuid_06_eax, &unused, &unused, &unused);
296 if ((cpuid_06_eax & CPUID_EAX_HWP) != 0U) {
297 /* If HWP is available, enable HWP early. This will unlock other HWP MSRs. */
298 msr_write(MSR_IA32_PM_ENABLE, 1U);
299 }
300 }
301
302 /*
303 * This Function is to be called by each pcpu after init_cpufreq().
304 * It applies the frequency policy, which can be specified from boot parameters.
305 * - cpu_perf_policy=Performance: HWP autonomous selection, between highest HWP level and
306 * lowest HWP level. If HWP is not available, the frequency is fixed to highest p-state.
307 * - cpu_perf_policy=Nominal: frequency is fixed to guaranteed HWP level or nominal p-state.
308 * The default policy is 'Performance'.
309 *
310 * ACRN will not be governing pcpu's frequency after this.
311 */
apply_frequency_policy(void)312 void apply_frequency_policy(void)
313 {
314 struct acrn_cpufreq_limits *limits = &cpufreq_limits[get_pcpu_id()];
315 uint64_t highest_lvl_req = limits->highest_hwp_lvl, lowest_lvl_req = limits->lowest_hwp_lvl, reg;
316 uint8_t pstate_req = limits->performance_pstate;
317 uint32_t cpuid_06_eax, cpuid_01_ecx, unused;
318
319 cpuid_subleaf(0x6U, 0U, &cpuid_06_eax, &unused, &unused, &unused);
320 cpuid_subleaf(0x1U, 0U, &unused, &unused, &cpuid_01_ecx, &unused);
321 /* Both HWP and ACPI p-state are supported. HWP is the first choice. */
322 if ((cpuid_06_eax & CPUID_EAX_HWP) != 0U) {
323 /*
324 * For Performance policy(default): CPU frequency will be autonomously selected between highest and lowest
325 * For Nominal policy: set to fixed frequency by letting highest=lowest=guaranteed
326 */
327 if (cpufreq_policy == CPUFREQ_POLICY_NOMINAL) {
328 highest_lvl_req = limits->guaranteed_hwp_lvl;
329 lowest_lvl_req = limits->guaranteed_hwp_lvl;
330 }
331 /* EPP(0x80: default) | Desired_Performance(0: HWP auto) | Maximum_Performance | Minimum_Performance */
332 reg = (0x80UL << 24U) | (0x00UL << 16U) | (highest_lvl_req << 8U) | lowest_lvl_req;
333 msr_write(MSR_IA32_HWP_REQUEST, reg);
334 } else if ((cpuid_01_ecx & CPUID_ECX_EST) != 0U) {
335 struct cpu_state_info *pm_s_state_data = get_cpu_pm_state_info();
336
337 /*
338 * Set to fixed frequency in ACPI p-state mode.
339 * Performance policy: performance_pstate
340 * Nominal policy: nominal_pstate
341 */
342 if (cpufreq_policy == CPUFREQ_POLICY_NOMINAL) {
343 pstate_req = limits->nominal_pstate;
344 }
345
346 /* PX info might be missing on some platforms (px_cnt equals 0). Do nothing if so. */
347 if (pm_s_state_data->px_cnt != 0) {
348 if (pstate_req < pm_s_state_data->px_cnt) {
349 msr_write(MSR_IA32_PERF_CTL, pm_s_state_data->px_data[pstate_req].control);
350 } else {
351 ASSERT(false, "invalid p-state index");
352 }
353 }
354 } else {
355 /* If no frequency interface is presented, just let CPU run by itself. Do nothing here.*/
356 }
357 }
358