[IA64] pvops: introduce pv_cpu_ops to paravirtualize privileged instructions.
[safe/jmp/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_cpu_ops
46  * intrinsics hooks.
47  */
48
49 /* ia64_native_xxx are macros so that we have to make them real functions */
50
51 #define DEFINE_VOID_FUNC1(name)                                 \
52         static void                                             \
53         ia64_native_ ## name ## _func(unsigned long arg)        \
54         {                                                       \
55                 ia64_native_ ## name(arg);                      \
56         }                                                       \
57
58 #define DEFINE_VOID_FUNC2(name)                                 \
59         static void                                             \
60         ia64_native_ ## name ## _func(unsigned long arg0,       \
61                                       unsigned long arg1)       \
62         {                                                       \
63                 ia64_native_ ## name(arg0, arg1);               \
64         }                                                       \
65
66 #define DEFINE_FUNC0(name)                      \
67         static unsigned long                    \
68         ia64_native_ ## name ## _func(void)     \
69         {                                       \
70                 return ia64_native_ ## name();  \
71         }
72
73 #define DEFINE_FUNC1(name, type)                        \
74         static unsigned long                            \
75         ia64_native_ ## name ## _func(type arg)         \
76         {                                               \
77                 return ia64_native_ ## name(arg);       \
78         }                                               \
79
80 DEFINE_VOID_FUNC1(fc);
81 DEFINE_VOID_FUNC1(intrin_local_irq_restore);
82
83 DEFINE_VOID_FUNC2(ptcga);
84 DEFINE_VOID_FUNC2(set_rr);
85
86 DEFINE_FUNC0(get_psr_i);
87
88 DEFINE_FUNC1(thash, unsigned long);
89 DEFINE_FUNC1(get_cpuid, int);
90 DEFINE_FUNC1(get_pmd, int);
91 DEFINE_FUNC1(get_rr, unsigned long);
92
93 static void
94 ia64_native_ssm_i_func(void)
95 {
96         ia64_native_ssm(IA64_PSR_I);
97 }
98
99 static void
100 ia64_native_rsm_i_func(void)
101 {
102         ia64_native_rsm(IA64_PSR_I);
103 }
104
105 static void
106 ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
107                                 unsigned long val2, unsigned long val3,
108                                 unsigned long val4)
109 {
110         ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
111 }
112
113 #define CASE_GET_REG(id)                                \
114         case _IA64_REG_ ## id:                          \
115         res = ia64_native_getreg(_IA64_REG_ ## id);     \
116         break;
117 #define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
118 #define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
119
120 unsigned long
121 ia64_native_getreg_func(int regnum)
122 {
123         unsigned long res = -1;
124         switch (regnum) {
125         CASE_GET_REG(GP);
126         CASE_GET_REG(IP);
127         CASE_GET_REG(PSR);
128         CASE_GET_REG(TP);
129         CASE_GET_REG(SP);
130
131         CASE_GET_AR(KR0);
132         CASE_GET_AR(KR1);
133         CASE_GET_AR(KR2);
134         CASE_GET_AR(KR3);
135         CASE_GET_AR(KR4);
136         CASE_GET_AR(KR5);
137         CASE_GET_AR(KR6);
138         CASE_GET_AR(KR7);
139         CASE_GET_AR(RSC);
140         CASE_GET_AR(BSP);
141         CASE_GET_AR(BSPSTORE);
142         CASE_GET_AR(RNAT);
143         CASE_GET_AR(FCR);
144         CASE_GET_AR(EFLAG);
145         CASE_GET_AR(CSD);
146         CASE_GET_AR(SSD);
147         CASE_GET_AR(CFLAG);
148         CASE_GET_AR(FSR);
149         CASE_GET_AR(FIR);
150         CASE_GET_AR(FDR);
151         CASE_GET_AR(CCV);
152         CASE_GET_AR(UNAT);
153         CASE_GET_AR(FPSR);
154         CASE_GET_AR(ITC);
155         CASE_GET_AR(PFS);
156         CASE_GET_AR(LC);
157         CASE_GET_AR(EC);
158
159         CASE_GET_CR(DCR);
160         CASE_GET_CR(ITM);
161         CASE_GET_CR(IVA);
162         CASE_GET_CR(PTA);
163         CASE_GET_CR(IPSR);
164         CASE_GET_CR(ISR);
165         CASE_GET_CR(IIP);
166         CASE_GET_CR(IFA);
167         CASE_GET_CR(ITIR);
168         CASE_GET_CR(IIPA);
169         CASE_GET_CR(IFS);
170         CASE_GET_CR(IIM);
171         CASE_GET_CR(IHA);
172         CASE_GET_CR(LID);
173         CASE_GET_CR(IVR);
174         CASE_GET_CR(TPR);
175         CASE_GET_CR(EOI);
176         CASE_GET_CR(IRR0);
177         CASE_GET_CR(IRR1);
178         CASE_GET_CR(IRR2);
179         CASE_GET_CR(IRR3);
180         CASE_GET_CR(ITV);
181         CASE_GET_CR(PMV);
182         CASE_GET_CR(CMCV);
183         CASE_GET_CR(LRR0);
184         CASE_GET_CR(LRR1);
185
186         default:
187                 printk(KERN_CRIT "wrong_getreg %d\n", regnum);
188                 break;
189         }
190         return res;
191 }
192
193 #define CASE_SET_REG(id)                                \
194         case _IA64_REG_ ## id:                          \
195         ia64_native_setreg(_IA64_REG_ ## id, val);      \
196         break;
197 #define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
198 #define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
199
200 void
201 ia64_native_setreg_func(int regnum, unsigned long val)
202 {
203         switch (regnum) {
204         case _IA64_REG_PSR_L:
205                 ia64_native_setreg(_IA64_REG_PSR_L, val);
206                 ia64_dv_serialize_data();
207                 break;
208         CASE_SET_REG(SP);
209         CASE_SET_REG(GP);
210
211         CASE_SET_AR(KR0);
212         CASE_SET_AR(KR1);
213         CASE_SET_AR(KR2);
214         CASE_SET_AR(KR3);
215         CASE_SET_AR(KR4);
216         CASE_SET_AR(KR5);
217         CASE_SET_AR(KR6);
218         CASE_SET_AR(KR7);
219         CASE_SET_AR(RSC);
220         CASE_SET_AR(BSP);
221         CASE_SET_AR(BSPSTORE);
222         CASE_SET_AR(RNAT);
223         CASE_SET_AR(FCR);
224         CASE_SET_AR(EFLAG);
225         CASE_SET_AR(CSD);
226         CASE_SET_AR(SSD);
227         CASE_SET_AR(CFLAG);
228         CASE_SET_AR(FSR);
229         CASE_SET_AR(FIR);
230         CASE_SET_AR(FDR);
231         CASE_SET_AR(CCV);
232         CASE_SET_AR(UNAT);
233         CASE_SET_AR(FPSR);
234         CASE_SET_AR(ITC);
235         CASE_SET_AR(PFS);
236         CASE_SET_AR(LC);
237         CASE_SET_AR(EC);
238
239         CASE_SET_CR(DCR);
240         CASE_SET_CR(ITM);
241         CASE_SET_CR(IVA);
242         CASE_SET_CR(PTA);
243         CASE_SET_CR(IPSR);
244         CASE_SET_CR(ISR);
245         CASE_SET_CR(IIP);
246         CASE_SET_CR(IFA);
247         CASE_SET_CR(ITIR);
248         CASE_SET_CR(IIPA);
249         CASE_SET_CR(IFS);
250         CASE_SET_CR(IIM);
251         CASE_SET_CR(IHA);
252         CASE_SET_CR(LID);
253         CASE_SET_CR(IVR);
254         CASE_SET_CR(TPR);
255         CASE_SET_CR(EOI);
256         CASE_SET_CR(IRR0);
257         CASE_SET_CR(IRR1);
258         CASE_SET_CR(IRR2);
259         CASE_SET_CR(IRR3);
260         CASE_SET_CR(ITV);
261         CASE_SET_CR(PMV);
262         CASE_SET_CR(CMCV);
263         CASE_SET_CR(LRR0);
264         CASE_SET_CR(LRR1);
265         default:
266                 printk(KERN_CRIT "wrong setreg %d\n", regnum);
267                 break;
268         }
269 }
270
271 struct pv_cpu_ops pv_cpu_ops = {
272         .fc             = ia64_native_fc_func,
273         .thash          = ia64_native_thash_func,
274         .get_cpuid      = ia64_native_get_cpuid_func,
275         .get_pmd        = ia64_native_get_pmd_func,
276         .ptcga          = ia64_native_ptcga_func,
277         .get_rr         = ia64_native_get_rr_func,
278         .set_rr         = ia64_native_set_rr_func,
279         .set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
280         .ssm_i          = ia64_native_ssm_i_func,
281         .getreg         = ia64_native_getreg_func,
282         .setreg         = ia64_native_setreg_func,
283         .rsm_i          = ia64_native_rsm_i_func,
284         .get_psr_i      = ia64_native_get_psr_i_func,
285         .intrin_local_irq_restore
286                         = ia64_native_intrin_local_irq_restore_func,
287 };
288 EXPORT_SYMBOL(pv_cpu_ops);