Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux...
[linux-2.6] / arch / ia64 / kernel / paravirt.c
1 /******************************************************************************
2  * arch/ia64/kernel/paravirt.c
3  *
4  * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
5  *                    VA Linux Systems Japan K.K.
6  *     Yaozu (Eddie) Dong <eddie.dong@intel.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include <linux/init.h>
25
26 #include <linux/compiler.h>
27 #include <linux/io.h>
28 #include <linux/irq.h>
29 #include <linux/module.h>
30 #include <linux/types.h>
31
32 #include <asm/iosapic.h>
33 #include <asm/paravirt.h>
34
35 /***************************************************************************
36  * general info
37  */
38 struct pv_info pv_info = {
39         .kernel_rpl = 0,
40         .paravirt_enabled = 0,
41         .name = "bare hardware"
42 };
43
44 /***************************************************************************
45  * pv_init_ops
46  * initialization hooks.
47  */
48
49 struct pv_init_ops pv_init_ops;
50
51 /***************************************************************************
52  * pv_cpu_ops
53  * intrinsics hooks.
54  */
55
56 /* ia64_native_xxx are macros so that we have to make them real functions */
57
58 #define DEFINE_VOID_FUNC1(name)                                 \
59         static void                                             \
60         ia64_native_ ## name ## _func(unsigned long arg)        \
61         {                                                       \
62                 ia64_native_ ## name(arg);                      \
63         }                                                       \
64
65 #define DEFINE_VOID_FUNC2(name)                                 \
66         static void                                             \
67         ia64_native_ ## name ## _func(unsigned long arg0,       \
68                                       unsigned long arg1)       \
69         {                                                       \
70                 ia64_native_ ## name(arg0, arg1);               \
71         }                                                       \
72
73 #define DEFINE_FUNC0(name)                      \
74         static unsigned long                    \
75         ia64_native_ ## name ## _func(void)     \
76         {                                       \
77                 return ia64_native_ ## name();  \
78         }
79
80 #define DEFINE_FUNC1(name, type)                        \
81         static unsigned long                            \
82         ia64_native_ ## name ## _func(type arg)         \
83         {                                               \
84                 return ia64_native_ ## name(arg);       \
85         }                                               \
86
87 DEFINE_VOID_FUNC1(fc);
88 DEFINE_VOID_FUNC1(intrin_local_irq_restore);
89
90 DEFINE_VOID_FUNC2(ptcga);
91 DEFINE_VOID_FUNC2(set_rr);
92
93 DEFINE_FUNC0(get_psr_i);
94
95 DEFINE_FUNC1(thash, unsigned long);
96 DEFINE_FUNC1(get_cpuid, int);
97 DEFINE_FUNC1(get_pmd, int);
98 DEFINE_FUNC1(get_rr, unsigned long);
99
100 static void
101 ia64_native_ssm_i_func(void)
102 {
103         ia64_native_ssm(IA64_PSR_I);
104 }
105
106 static void
107 ia64_native_rsm_i_func(void)
108 {
109         ia64_native_rsm(IA64_PSR_I);
110 }
111
112 static void
113 ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
114                                 unsigned long val2, unsigned long val3,
115                                 unsigned long val4)
116 {
117         ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
118 }
119
120 #define CASE_GET_REG(id)                                \
121         case _IA64_REG_ ## id:                          \
122         res = ia64_native_getreg(_IA64_REG_ ## id);     \
123         break;
124 #define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
125 #define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
126
127 unsigned long
128 ia64_native_getreg_func(int regnum)
129 {
130         unsigned long res = -1;
131         switch (regnum) {
132         CASE_GET_REG(GP);
133         CASE_GET_REG(IP);
134         CASE_GET_REG(PSR);
135         CASE_GET_REG(TP);
136         CASE_GET_REG(SP);
137
138         CASE_GET_AR(KR0);
139         CASE_GET_AR(KR1);
140         CASE_GET_AR(KR2);
141         CASE_GET_AR(KR3);
142         CASE_GET_AR(KR4);
143         CASE_GET_AR(KR5);
144         CASE_GET_AR(KR6);
145         CASE_GET_AR(KR7);
146         CASE_GET_AR(RSC);
147         CASE_GET_AR(BSP);
148         CASE_GET_AR(BSPSTORE);
149         CASE_GET_AR(RNAT);
150         CASE_GET_AR(FCR);
151         CASE_GET_AR(EFLAG);
152         CASE_GET_AR(CSD);
153         CASE_GET_AR(SSD);
154         CASE_GET_AR(CFLAG);
155         CASE_GET_AR(FSR);
156         CASE_GET_AR(FIR);
157         CASE_GET_AR(FDR);
158         CASE_GET_AR(CCV);
159         CASE_GET_AR(UNAT);
160         CASE_GET_AR(FPSR);
161         CASE_GET_AR(ITC);
162         CASE_GET_AR(PFS);
163         CASE_GET_AR(LC);
164         CASE_GET_AR(EC);
165
166         CASE_GET_CR(DCR);
167         CASE_GET_CR(ITM);
168         CASE_GET_CR(IVA);
169         CASE_GET_CR(PTA);
170         CASE_GET_CR(IPSR);
171         CASE_GET_CR(ISR);
172         CASE_GET_CR(IIP);
173         CASE_GET_CR(IFA);
174         CASE_GET_CR(ITIR);
175         CASE_GET_CR(IIPA);
176         CASE_GET_CR(IFS);
177         CASE_GET_CR(IIM);
178         CASE_GET_CR(IHA);
179         CASE_GET_CR(LID);
180         CASE_GET_CR(IVR);
181         CASE_GET_CR(TPR);
182         CASE_GET_CR(EOI);
183         CASE_GET_CR(IRR0);
184         CASE_GET_CR(IRR1);
185         CASE_GET_CR(IRR2);
186         CASE_GET_CR(IRR3);
187         CASE_GET_CR(ITV);
188         CASE_GET_CR(PMV);
189         CASE_GET_CR(CMCV);
190         CASE_GET_CR(LRR0);
191         CASE_GET_CR(LRR1);
192
193         default:
194                 printk(KERN_CRIT "wrong_getreg %d\n", regnum);
195                 break;
196         }
197         return res;
198 }
199
200 #define CASE_SET_REG(id)                                \
201         case _IA64_REG_ ## id:                          \
202         ia64_native_setreg(_IA64_REG_ ## id, val);      \
203         break;
204 #define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
205 #define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
206
207 void
208 ia64_native_setreg_func(int regnum, unsigned long val)
209 {
210         switch (regnum) {
211         case _IA64_REG_PSR_L:
212                 ia64_native_setreg(_IA64_REG_PSR_L, val);
213                 ia64_dv_serialize_data();
214                 break;
215         CASE_SET_REG(SP);
216         CASE_SET_REG(GP);
217
218         CASE_SET_AR(KR0);
219         CASE_SET_AR(KR1);
220         CASE_SET_AR(KR2);
221         CASE_SET_AR(KR3);
222         CASE_SET_AR(KR4);
223         CASE_SET_AR(KR5);
224         CASE_SET_AR(KR6);
225         CASE_SET_AR(KR7);
226         CASE_SET_AR(RSC);
227         CASE_SET_AR(BSP);
228         CASE_SET_AR(BSPSTORE);
229         CASE_SET_AR(RNAT);
230         CASE_SET_AR(FCR);
231         CASE_SET_AR(EFLAG);
232         CASE_SET_AR(CSD);
233         CASE_SET_AR(SSD);
234         CASE_SET_AR(CFLAG);
235         CASE_SET_AR(FSR);
236         CASE_SET_AR(FIR);
237         CASE_SET_AR(FDR);
238         CASE_SET_AR(CCV);
239         CASE_SET_AR(UNAT);
240         CASE_SET_AR(FPSR);
241         CASE_SET_AR(ITC);
242         CASE_SET_AR(PFS);
243         CASE_SET_AR(LC);
244         CASE_SET_AR(EC);
245
246         CASE_SET_CR(DCR);
247         CASE_SET_CR(ITM);
248         CASE_SET_CR(IVA);
249         CASE_SET_CR(PTA);
250         CASE_SET_CR(IPSR);
251         CASE_SET_CR(ISR);
252         CASE_SET_CR(IIP);
253         CASE_SET_CR(IFA);
254         CASE_SET_CR(ITIR);
255         CASE_SET_CR(IIPA);
256         CASE_SET_CR(IFS);
257         CASE_SET_CR(IIM);
258         CASE_SET_CR(IHA);
259         CASE_SET_CR(LID);
260         CASE_SET_CR(IVR);
261         CASE_SET_CR(TPR);
262         CASE_SET_CR(EOI);
263         CASE_SET_CR(IRR0);
264         CASE_SET_CR(IRR1);
265         CASE_SET_CR(IRR2);
266         CASE_SET_CR(IRR3);
267         CASE_SET_CR(ITV);
268         CASE_SET_CR(PMV);
269         CASE_SET_CR(CMCV);
270         CASE_SET_CR(LRR0);
271         CASE_SET_CR(LRR1);
272         default:
273                 printk(KERN_CRIT "wrong setreg %d\n", regnum);
274                 break;
275         }
276 }
277
278 struct pv_cpu_ops pv_cpu_ops = {
279         .fc             = ia64_native_fc_func,
280         .thash          = ia64_native_thash_func,
281         .get_cpuid      = ia64_native_get_cpuid_func,
282         .get_pmd        = ia64_native_get_pmd_func,
283         .ptcga          = ia64_native_ptcga_func,
284         .get_rr         = ia64_native_get_rr_func,
285         .set_rr         = ia64_native_set_rr_func,
286         .set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
287         .ssm_i          = ia64_native_ssm_i_func,
288         .getreg         = ia64_native_getreg_func,
289         .setreg         = ia64_native_setreg_func,
290         .rsm_i          = ia64_native_rsm_i_func,
291         .get_psr_i      = ia64_native_get_psr_i_func,
292         .intrin_local_irq_restore
293                         = ia64_native_intrin_local_irq_restore_func,
294 };
295 EXPORT_SYMBOL(pv_cpu_ops);
296
297 /******************************************************************************
298  * replacement of hand written assembly codes.
299  */
300
301 void
302 paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
303 {
304         extern unsigned long paravirt_switch_to_targ;
305         extern unsigned long paravirt_leave_syscall_targ;
306         extern unsigned long paravirt_work_processed_syscall_targ;
307         extern unsigned long paravirt_leave_kernel_targ;
308
309         paravirt_switch_to_targ = cpu_asm_switch->switch_to;
310         paravirt_leave_syscall_targ = cpu_asm_switch->leave_syscall;
311         paravirt_work_processed_syscall_targ =
312                 cpu_asm_switch->work_processed_syscall;
313         paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
314 }
315
316 /***************************************************************************
317  * pv_iosapic_ops
318  * iosapic read/write hooks.
319  */
320
321 static unsigned int
322 ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
323 {
324         return __ia64_native_iosapic_read(iosapic, reg);
325 }
326
327 static void
328 ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
329 {
330         __ia64_native_iosapic_write(iosapic, reg, val);
331 }
332
333 struct pv_iosapic_ops pv_iosapic_ops = {
334         .pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
335         .__get_irq_chip = ia64_native_iosapic_get_irq_chip,
336
337         .__read = ia64_native_iosapic_read,
338         .__write = ia64_native_iosapic_write,
339 };
340
341 /***************************************************************************
342  * pv_irq_ops
343  * irq operations
344  */
345
346 struct pv_irq_ops pv_irq_ops = {
347         .register_ipi = ia64_native_register_ipi,
348
349         .assign_irq_vector = ia64_native_assign_irq_vector,
350         .free_irq_vector = ia64_native_free_irq_vector,
351         .register_percpu_irq = ia64_native_register_percpu_irq,
352
353         .resend_irq = ia64_native_resend_irq,
354 };
355
356 /***************************************************************************
357  * pv_time_ops
358  * time operations
359  */
360
361 static int
362 ia64_native_do_steal_accounting(unsigned long *new_itm)
363 {
364         return 0;
365 }
366
367 struct pv_time_ops pv_time_ops = {
368         .do_steal_accounting = ia64_native_do_steal_accounting,
369 };