ia64/xen-unstable

view xen/arch/x86/machine_kexec.c @ 18806:ed8524f4a044

x86: Re-initialise HPET on resume from S3

Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Nov 18 15:55:14 2008 +0000 (2008-11-18)
parents 8a0415fac759
children 845aa241e163
line source
1 /******************************************************************************
2 * machine_kexec.c
3 *
4 * Xen port written by:
5 * - Simon 'Horms' Horman <horms@verge.net.au>
6 * - Magnus Damm <magnus@valinux.co.jp>
7 */
9 #include <xen/lib.h>
10 #include <asm/irq.h>
11 #include <asm/page.h>
12 #include <asm/flushtlb.h>
13 #include <xen/smp.h>
14 #include <xen/nmi.h>
15 #include <xen/types.h>
16 #include <xen/console.h>
17 #include <xen/kexec.h>
18 #include <xen/domain_page.h>
19 #include <asm/fixmap.h>
20 #include <asm/hvm/hvm.h>
22 typedef void (*relocate_new_kernel_t)(
23 unsigned long indirection_page,
24 unsigned long *page_list,
25 unsigned long start_address);
27 extern int machine_kexec_get_xen(xen_kexec_range_t *range);
30 int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
31 {
32 unsigned long prev_ma = 0;
33 int fix_base = FIX_KEXEC_BASE_0 + (slot * (KEXEC_XEN_NO_PAGES >> 1));
34 int k;
36 /* setup fixmap to point to our pages and record the virtual address
37 * in every odd index in page_list[].
38 */
40 for ( k = 0; k < KEXEC_XEN_NO_PAGES; k++ )
41 {
42 if ( (k & 1) == 0 )
43 {
44 /* Even pages: machine address. */
45 prev_ma = image->page_list[k];
46 }
47 else
48 {
49 /* Odd pages: va for previous ma. */
50 if ( is_pv_32on64_domain(dom0) )
51 {
52 /*
53 * The compatability bounce code sets up a page table
54 * with a 1-1 mapping of the first 1G of memory so
55 * VA==PA here.
56 *
57 * This Linux purgatory code still sets up separate
58 * high and low mappings on the control page (entries
59 * 0 and 1) but it is harmless if they are equal since
60 * that PT is not live at the time.
61 */
62 image->page_list[k] = prev_ma;
63 }
64 else
65 {
66 set_fixmap(fix_base + (k >> 1), prev_ma);
67 image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
68 }
69 }
70 }
72 return 0;
73 }
75 void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
76 {
77 }
79 static void __machine_reboot_kexec(void *data)
80 {
81 xen_kexec_image_t *image = (xen_kexec_image_t *)data;
83 watchdog_disable();
84 console_start_sync();
86 smp_send_stop();
88 machine_kexec(image);
89 }
91 void machine_reboot_kexec(xen_kexec_image_t *image)
92 {
93 int reboot_cpu_id;
94 cpumask_t reboot_cpu;
96 reboot_cpu_id = 0;
98 if ( !cpu_isset(reboot_cpu_id, cpu_online_map) )
99 reboot_cpu_id = smp_processor_id();
101 if ( reboot_cpu_id != smp_processor_id() )
102 {
103 cpus_clear(reboot_cpu);
104 cpu_set(reboot_cpu_id, reboot_cpu);
105 on_selected_cpus(reboot_cpu, __machine_reboot_kexec, image, 1, 0);
106 for (;;)
107 ; /* nothing */
108 }
109 else
110 {
111 __machine_reboot_kexec(image);
112 }
113 BUG();
114 }
116 void machine_kexec(xen_kexec_image_t *image)
117 {
118 #ifdef CONFIG_COMPAT
119 if ( is_pv_32on64_domain(dom0) )
120 {
121 extern void compat_machine_kexec(unsigned long rnk,
122 unsigned long indirection_page,
123 unsigned long *page_list,
124 unsigned long start_address);
125 compat_machine_kexec(image->page_list[1],
126 image->indirection_page,
127 image->page_list,
128 image->start_address);
129 }
130 else
131 #endif
132 {
133 relocate_new_kernel_t rnk;
135 rnk = (relocate_new_kernel_t) image->page_list[1];
136 (*rnk)(image->indirection_page, image->page_list,
137 image->start_address);
138 }
139 }
141 int machine_kexec_get(xen_kexec_range_t *range)
142 {
143 if (range->range != KEXEC_RANGE_MA_XEN)
144 return -EINVAL;
145 return machine_kexec_get_xen(range);
146 }
148 void arch_crash_save_vmcoreinfo(void)
149 {
150 VMCOREINFO_SYMBOL(dom_xen);
151 VMCOREINFO_SYMBOL(dom_io);
153 #ifdef CONFIG_X86_PAE
154 VMCOREINFO_SYMBOL_ALIAS(pgd_l3, idle_pg_table);
155 #endif
156 #ifdef CONFIG_X86_64
157 VMCOREINFO_SYMBOL_ALIAS(pgd_l4, idle_pg_table);
158 #endif
159 }
161 /*
162 * Local variables:
163 * mode: C
164 * c-set-style: "BSD"
165 * c-basic-offset: 4
166 * tab-width: 4
167 * indent-tabs-mode: nil
168 * End:
169 */