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