1 /* drivers/acpi/sleep/power.c - PM core functionality for Xen
2 *
3 * Copyrights from Linux side:
4 * Copyright (c) 2000-2003 Patrick Mochel
5 * Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
6 * Copyright (c) 2003 Open Source Development Lab
7 * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
8 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
9 *
10 * Slimmed with Xen specific support.
11 */
12
13 #include <asm/io.h>
14 #include <xen/acpi.h>
15 #include <xen/errno.h>
16 #include <xen/iocap.h>
17 #include <xen/sched.h>
18 #include <asm/acpi.h>
19 #include <asm/irq.h>
20 #include <asm/init.h>
21 #include <xen/spinlock.h>
22 #include <xen/sched.h>
23 #include <xen/domain.h>
24 #include <xen/console.h>
25 #include <xen/iommu.h>
26 #include <xen/cpu.h>
27 #include <public/platform.h>
28 #include <asm/tboot.h>
29 #include <asm/apic.h>
30 #include <asm/io_apic.h>
31 #include <acpi/cpufreq/cpufreq.h>
32
33 uint32_t system_reset_counter = 1;
34
35 static char __initdata opt_acpi_sleep[20];
36 string_param("acpi_sleep", opt_acpi_sleep);
37
38 static u8 sleep_states[ACPI_S_STATE_COUNT];
39 static DEFINE_SPINLOCK(pm_lock);
40
41 struct acpi_sleep_info acpi_sinfo;
42
43 void do_suspend_lowlevel(void);
44
45 enum dev_power_saved
46 {
47 SAVED_NONE,
48 SAVED_CONSOLE,
49 SAVED_TIME,
50 SAVED_I8259A,
51 SAVED_IOAPIC,
52 SAVED_IOMMU,
53 SAVED_LAPIC,
54 SAVED_ALL,
55 };
56
device_power_down(void)57 static int device_power_down(void)
58 {
59 if ( console_suspend() )
60 return SAVED_NONE;
61
62 if ( time_suspend() )
63 return SAVED_CONSOLE;
64
65 if ( i8259A_suspend() )
66 return SAVED_TIME;
67
68 /* ioapic_suspend cannot fail */
69 ioapic_suspend();
70
71 if ( iommu_suspend() )
72 return SAVED_IOAPIC;
73
74 if ( lapic_suspend() )
75 return SAVED_IOMMU;
76
77 return SAVED_ALL;
78 }
79
device_power_up(enum dev_power_saved saved)80 static void device_power_up(enum dev_power_saved saved)
81 {
82 switch ( saved )
83 {
84 case SAVED_ALL:
85 case SAVED_LAPIC:
86 lapic_resume();
87 /* fall through */
88 case SAVED_IOMMU:
89 iommu_resume();
90 /* fall through */
91 case SAVED_IOAPIC:
92 ioapic_resume();
93 /* fall through */
94 case SAVED_I8259A:
95 i8259A_resume();
96 /* fall through */
97 case SAVED_TIME:
98 time_resume();
99 /* fall through */
100 case SAVED_CONSOLE:
101 console_resume();
102 /* fall through */
103 case SAVED_NONE:
104 break;
105 default:
106 BUG();
107 break;
108 }
109 }
110
freeze_domains(void)111 static void freeze_domains(void)
112 {
113 struct domain *d;
114
115 rcu_read_lock(&domlist_read_lock);
116 /*
117 * Note that we iterate in order of domain-id. Hence we will pause dom0
118 * first which is required for correctness (as only dom0 can add domains to
119 * the domain list). Otherwise we could miss concurrently-created domains.
120 */
121 for_each_domain ( d )
122 domain_pause(d);
123 rcu_read_unlock(&domlist_read_lock);
124 }
125
thaw_domains(void)126 static void thaw_domains(void)
127 {
128 struct domain *d;
129
130 rcu_read_lock(&domlist_read_lock);
131 for_each_domain ( d )
132 {
133 restore_vcpu_affinity(d);
134 domain_unpause(d);
135 }
136 rcu_read_unlock(&domlist_read_lock);
137 }
138
acpi_sleep_prepare(u32 state)139 static void acpi_sleep_prepare(u32 state)
140 {
141 void *wakeup_vector_va;
142
143 if ( state != ACPI_STATE_S3 )
144 return;
145
146 wakeup_vector_va = __acpi_map_table(
147 acpi_sinfo.wakeup_vector, sizeof(uint64_t));
148
149 /* TBoot will set resume vector itself (when it is safe to do so). */
150 if ( tboot_in_measured_env() )
151 return;
152
153 if ( acpi_sinfo.vector_width == 32 )
154 *(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
155 else
156 *(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
157 }
158
acpi_sleep_post(u32 state)159 static void acpi_sleep_post(u32 state) {}
160
161 /* Main interface to do xen specific suspend/resume */
enter_state(u32 state)162 static int enter_state(u32 state)
163 {
164 unsigned long flags;
165 int error;
166 unsigned long cr4;
167
168 if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
169 return -EINVAL;
170
171 if ( !spin_trylock(&pm_lock) )
172 return -EBUSY;
173
174 BUG_ON(system_state != SYS_STATE_active);
175 system_state = SYS_STATE_suspend;
176
177 printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state);
178
179 freeze_domains();
180
181 acpi_dmar_reinstate();
182
183 if ( (error = disable_nonboot_cpus()) )
184 {
185 system_state = SYS_STATE_resume;
186 goto enable_cpu;
187 }
188
189 cpufreq_del_cpu(0);
190
191 hvm_cpu_down();
192
193 acpi_sleep_prepare(state);
194
195 console_start_sync();
196 printk("Entering ACPI S%d state.\n", state);
197
198 local_irq_save(flags);
199 spin_debug_disable();
200
201 if ( (error = device_power_down()) != SAVED_ALL )
202 {
203 printk(XENLOG_ERR "Some devices failed to power down.");
204 system_state = SYS_STATE_resume;
205 device_power_up(error);
206 error = -EIO;
207 goto done;
208 }
209 else
210 error = 0;
211
212 ACPI_FLUSH_CPU_CACHE();
213
214 switch ( state )
215 {
216 case ACPI_STATE_S3:
217 do_suspend_lowlevel();
218 system_reset_counter++;
219 error = tboot_s3_resume();
220 break;
221 case ACPI_STATE_S5:
222 acpi_enter_sleep_state(ACPI_STATE_S5);
223 break;
224 default:
225 error = -EINVAL;
226 break;
227 }
228
229 system_state = SYS_STATE_resume;
230
231 /* Restore CR4 and EFER from cached values. */
232 cr4 = read_cr4();
233 write_cr4(cr4 & ~X86_CR4_MCE);
234 write_efer(read_efer());
235
236 device_power_up(SAVED_ALL);
237
238 mcheck_init(&boot_cpu_data, false);
239 write_cr4(cr4);
240
241 printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);
242
243 if ( (state == ACPI_STATE_S3) && error )
244 tboot_s3_error(error);
245
246 done:
247 spin_debug_enable();
248 local_irq_restore(flags);
249 console_end_sync();
250 acpi_sleep_post(state);
251 if ( hvm_cpu_up() )
252 BUG();
253
254 enable_cpu:
255 cpufreq_add_cpu(0);
256 microcode_resume_cpu(0);
257 rcu_barrier();
258 mtrr_aps_sync_begin();
259 enable_nonboot_cpus();
260 mtrr_aps_sync_end();
261 adjust_vtd_irq_affinities();
262 acpi_dmar_zap();
263 thaw_domains();
264 system_state = SYS_STATE_active;
265 spin_unlock(&pm_lock);
266 return error;
267 }
268
enter_state_helper(void * data)269 static long enter_state_helper(void *data)
270 {
271 struct acpi_sleep_info *sinfo = (struct acpi_sleep_info *)data;
272 return enter_state(sinfo->sleep_state);
273 }
274
275 /*
276 * Dom0 issues this hypercall in place of writing pm1a_cnt. Xen then
277 * takes over the control and put the system into sleep state really.
278 */
acpi_enter_sleep(struct xenpf_enter_acpi_sleep * sleep)279 int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep)
280 {
281 if ( sleep->flags & XENPF_ACPI_SLEEP_EXTENDED )
282 {
283 if ( !acpi_sinfo.sleep_control.address ||
284 !acpi_sinfo.sleep_status.address )
285 return -EPERM;
286
287 if ( sleep->flags & ~XENPF_ACPI_SLEEP_EXTENDED )
288 return -EINVAL;
289
290 if ( sleep->val_a > ACPI_SLEEP_TYPE_MAX ||
291 (sleep->val_b != ACPI_SLEEP_TYPE_INVALID &&
292 sleep->val_b > ACPI_SLEEP_TYPE_MAX) )
293 return -ERANGE;
294
295 acpi_sinfo.sleep_type_a = sleep->val_a;
296 acpi_sinfo.sleep_type_b = sleep->val_b;
297
298 acpi_sinfo.sleep_extended = 1;
299 }
300
301 else if ( !acpi_sinfo.pm1a_cnt_blk.address )
302 return -EPERM;
303
304 /* Sanity check */
305 else if ( sleep->val_b &&
306 ((sleep->val_a ^ sleep->val_b) & ACPI_BITMASK_SLEEP_ENABLE) )
307 {
308 gdprintk(XENLOG_ERR, "Mismatched pm1a/pm1b setting\n");
309 return -EINVAL;
310 }
311
312 else if ( sleep->flags )
313 return -EINVAL;
314
315 else
316 {
317 acpi_sinfo.pm1a_cnt_val = sleep->val_a;
318 acpi_sinfo.pm1b_cnt_val = sleep->val_b;
319 acpi_sinfo.sleep_extended = 0;
320 }
321
322 acpi_sinfo.sleep_state = sleep->sleep_state;
323
324 return continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo);
325 }
326
acpi_get_wake_status(void)327 static int acpi_get_wake_status(void)
328 {
329 uint32_t val;
330 acpi_status status;
331
332 if ( acpi_sinfo.sleep_extended )
333 {
334 status = acpi_hw_register_read(ACPI_REGISTER_SLEEP_STATUS, &val);
335
336 return ACPI_FAILURE(status) ? 0 : val & ACPI_X_WAKE_STATUS;
337 }
338
339 /* Wake status is the 15th bit of PM1 status register. (ACPI spec 3.0) */
340 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &val);
341 if ( ACPI_FAILURE(status) )
342 return 0;
343
344 val &= ACPI_BITMASK_WAKE_STATUS;
345 val >>= ACPI_BITPOSITION_WAKE_STATUS;
346 return val;
347 }
348
tboot_sleep(u8 sleep_state)349 static void tboot_sleep(u8 sleep_state)
350 {
351 uint32_t shutdown_type;
352
353 #define TB_COPY_GAS(tbg, g) \
354 tbg.space_id = g.space_id; \
355 tbg.bit_width = g.bit_width; \
356 tbg.bit_offset = g.bit_offset; \
357 tbg.access_width = g.access_width; \
358 tbg.address = g.address;
359
360 /* sizes are not same (due to packing) so copy each one */
361 TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1a_cnt_blk,
362 acpi_sinfo.pm1a_cnt_blk);
363 TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1b_cnt_blk,
364 acpi_sinfo.pm1b_cnt_blk);
365 TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1a_evt_blk,
366 acpi_sinfo.pm1a_evt_blk);
367 TB_COPY_GAS(g_tboot_shared->acpi_sinfo.pm1b_evt_blk,
368 acpi_sinfo.pm1b_evt_blk);
369 g_tboot_shared->acpi_sinfo.pm1a_cnt_val = acpi_sinfo.pm1a_cnt_val;
370 g_tboot_shared->acpi_sinfo.pm1b_cnt_val = acpi_sinfo.pm1b_cnt_val;
371 g_tboot_shared->acpi_sinfo.wakeup_vector = acpi_sinfo.wakeup_vector;
372 g_tboot_shared->acpi_sinfo.vector_width = acpi_sinfo.vector_width;
373 g_tboot_shared->acpi_sinfo.kernel_s3_resume_vector =
374 bootsym_phys(wakeup_start);
375
376 switch ( sleep_state )
377 {
378 case ACPI_STATE_S3:
379 shutdown_type = TB_SHUTDOWN_S3;
380 break;
381 case ACPI_STATE_S4:
382 shutdown_type = TB_SHUTDOWN_S4;
383 break;
384 case ACPI_STATE_S5:
385 shutdown_type = TB_SHUTDOWN_S5;
386 break;
387 default:
388 return;
389 }
390
391 tboot_shutdown(shutdown_type);
392 }
393
394 /* System is really put into sleep state by this stub */
acpi_enter_sleep_state(u8 sleep_state)395 acpi_status acpi_enter_sleep_state(u8 sleep_state)
396 {
397 acpi_status status;
398
399 if ( tboot_in_measured_env() )
400 {
401 tboot_sleep(sleep_state);
402 printk(XENLOG_ERR "TBOOT failed entering s3 state\n");
403 return_ACPI_STATUS(AE_ERROR);
404 }
405
406 ACPI_FLUSH_CPU_CACHE();
407
408 if ( acpi_sinfo.sleep_extended )
409 {
410 /*
411 * Set the SLP_TYP and SLP_EN bits.
412 *
413 * Note: We only use the first value returned by the \_Sx method
414 * (acpi_sinfo.sleep_type_a) - As per ACPI specification.
415 */
416 u8 sleep_type_value =
417 ((acpi_sinfo.sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
418 ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE;
419
420 status = acpi_hw_register_write(ACPI_REGISTER_SLEEP_CONTROL,
421 sleep_type_value);
422 }
423 else
424 {
425 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
426 acpi_sinfo.pm1a_cnt_val);
427 if ( !ACPI_FAILURE(status) && acpi_sinfo.pm1b_cnt_blk.address )
428 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
429 acpi_sinfo.pm1b_cnt_val);
430 }
431
432 if ( ACPI_FAILURE(status) )
433 return_ACPI_STATUS(AE_ERROR);
434
435 /* Wait until we enter sleep state, and spin until we wake */
436 while ( !acpi_get_wake_status() )
437 continue;
438
439 return_ACPI_STATUS(AE_OK);
440 }
441
acpi_sleep_init(void)442 static int __init acpi_sleep_init(void)
443 {
444 int i;
445 char *p = opt_acpi_sleep;
446
447 while ( (p != NULL) && (*p != '\0') )
448 {
449 if ( !strncmp(p, "s3_bios", 7) )
450 acpi_video_flags |= 1;
451 if ( !strncmp(p, "s3_mode", 7) )
452 acpi_video_flags |= 2;
453 p = strchr(p, ',');
454 if ( p != NULL )
455 p += strspn(p, ", \t");
456 }
457
458 printk(XENLOG_INFO "ACPI sleep modes:");
459 for ( i = 0; i < ACPI_S_STATE_COUNT; i++ )
460 {
461 if ( i == ACPI_STATE_S3 )
462 {
463 sleep_states[i] = 1;
464 printk(" S%d", i);
465 }
466 else
467 sleep_states[i] = 0;
468 }
469 printk("\n");
470
471 return 0;
472 }
473 __initcall(acpi_sleep_init);
474