aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-05-19 09:13:34 -0400
committerTony Luck <tony.luck@intel.com>2008-05-27 17:40:18 -0400
commit1ff730b52f0c3e4e3846c3ff345c5526b2633ba9 (patch)
tree59a614eaa0679ba0ccd99e1f910ceeb22fc31948 /arch/ia64/kernel
parent3e0879deb700f322f6c81ab34f056fc72d15ec02 (diff)
[IA64] pvops: introduce pv_cpu_ops to paravirtualize privileged instructions.
introduce pv_cpu_ops to paravirtualize privleged instructions which are defined by ia64 intrinsics. make them indirect C function calls by introducing function tables, pv_cpu_ops. Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/paravirt.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index d295ea5e59c5..e5482bb6841e 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -26,6 +26,7 @@
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/irq.h> 28#include <linux/irq.h>
29#include <linux/module.h>
29#include <linux/types.h> 30#include <linux/types.h>
30 31
31#include <asm/iosapic.h> 32#include <asm/iosapic.h>
@@ -39,3 +40,249 @@ struct pv_info pv_info = {
39 .paravirt_enabled = 0, 40 .paravirt_enabled = 0,
40 .name = "bare hardware" 41 .name = "bare hardware"
41}; 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
80DEFINE_VOID_FUNC1(fc);
81DEFINE_VOID_FUNC1(intrin_local_irq_restore);
82
83DEFINE_VOID_FUNC2(ptcga);
84DEFINE_VOID_FUNC2(set_rr);
85
86DEFINE_FUNC0(get_psr_i);
87
88DEFINE_FUNC1(thash, unsigned long);
89DEFINE_FUNC1(get_cpuid, int);
90DEFINE_FUNC1(get_pmd, int);
91DEFINE_FUNC1(get_rr, unsigned long);
92
93static void
94ia64_native_ssm_i_func(void)
95{
96 ia64_native_ssm(IA64_PSR_I);
97}
98
99static void
100ia64_native_rsm_i_func(void)
101{
102 ia64_native_rsm(IA64_PSR_I);
103}
104
105static void
106ia64_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
120unsigned long
121ia64_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
200void
201ia64_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
271struct 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};
288EXPORT_SYMBOL(pv_cpu_ops);