• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ia64_native_ssm_i_func(void)101 ia64_native_ssm_i_func(void)
102 {
103 	ia64_native_ssm(IA64_PSR_I);
104 }
105 
106 static void
ia64_native_rsm_i_func(void)107 ia64_native_rsm_i_func(void)
108 {
109 	ia64_native_rsm(IA64_PSR_I);
110 }
111 
112 static void
ia64_native_set_rr0_to_rr4_func(unsigned long val0,unsigned long val1,unsigned long val2,unsigned long val3,unsigned long val4)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
ia64_native_getreg_func(int regnum)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);*/ /* returned ip value shouldn't be constant */
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
ia64_native_setreg_func(int regnum,unsigned long val)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
paravirt_cpu_asm_init(const struct pv_cpu_asm_switch * cpu_asm_switch)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
ia64_native_iosapic_read(char __iomem * iosapic,unsigned int reg)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
ia64_native_iosapic_write(char __iomem * iosapic,unsigned int reg,u32 val)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
ia64_native_do_steal_accounting(unsigned long * new_itm)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 };
370