ia64/xen-unstable

view xen/arch/ia64/vmx/pal_emul.c @ 10695:6703fed8870f

[IA64] enable acceleration of external interrupt

This patch is to enable acceleration of externel interrupt
which is described in VTI spec.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@xenbuild.aw
date Wed Jul 12 13:20:15 2006 -0600 (2006-07-12)
parents e5c7350b8cbb
children 5791030e6473
line source
1 /*
2 * PAL/SAL call delegation
3 *
4 * Copyright (c) 2004 Li Susie <susie.li@intel.com>
5 * Copyright (c) 2005 Yu Ke <ke.yu@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 */
21 #include <asm/vmx_vcpu.h>
22 #include <asm/pal.h>
23 #include <asm/sal.h>
24 #include <asm/dom_fw.h>
25 #include <asm/tlb.h>
26 #include <asm/vmx_mm_def.h>
27 #include <xen/hypercall.h>
28 #include <public/sched.h>
30 /*
31 * Handy macros to make sure that the PAL return values start out
32 * as something meaningful.
33 */
34 #define INIT_PAL_STATUS_UNIMPLEMENTED(x) \
35 { \
36 x.status = PAL_STATUS_UNIMPLEMENTED; \
37 x.v0 = 0; \
38 x.v1 = 0; \
39 x.v2 = 0; \
40 }
42 #define INIT_PAL_STATUS_SUCCESS(x) \
43 { \
44 x.status = PAL_STATUS_SUCCESS; \
45 x.v0 = 0; \
46 x.v1 = 0; \
47 x.v2 = 0; \
48 }
50 static void
51 get_pal_parameters(VCPU *vcpu, UINT64 *gr29, UINT64 *gr30, UINT64 *gr31) {
53 vcpu_get_gr_nat(vcpu,29,gr29);
54 vcpu_get_gr_nat(vcpu,30,gr30);
55 vcpu_get_gr_nat(vcpu,31,gr31);
56 }
58 static void
59 set_pal_result(VCPU *vcpu,struct ia64_pal_retval result) {
61 vcpu_set_gr(vcpu,8, result.status,0);
62 vcpu_set_gr(vcpu,9, result.v0,0);
63 vcpu_set_gr(vcpu,10, result.v1,0);
64 vcpu_set_gr(vcpu,11, result.v2,0);
65 }
67 static void
68 set_sal_result(VCPU *vcpu,struct sal_ret_values result) {
70 vcpu_set_gr(vcpu,8, result.r8,0);
71 vcpu_set_gr(vcpu,9, result.r9,0);
72 vcpu_set_gr(vcpu,10, result.r10,0);
73 vcpu_set_gr(vcpu,11, result.r11,0);
74 }
76 static struct ia64_pal_retval
77 pal_cache_flush(VCPU *vcpu) {
78 UINT64 gr28,gr29, gr30, gr31;
79 struct ia64_pal_retval result;
81 get_pal_parameters(vcpu, &gr29, &gr30, &gr31);
82 vcpu_get_gr_nat(vcpu, 28, &gr28);
84 /* Always call Host Pal in int=1 */
85 gr30 = gr30 & ~0x2UL;
87 /*
88 * Call Host PAL cache flush
89 * Clear psr.ic when call PAL_CACHE_FLUSH
90 */
91 result = ia64_pal_call_static(gr28 ,gr29, gr30, gr31, 1);
93 /* If host PAL call is interrupted, then loop to complete it */
94 // while (result.status == 1)
95 // ia64_pal_call_static(gr28 ,gr29, gr30, result.v1, 1LL);
96 //
97 if (result.status != 0)
98 panic_domain(vcpu_regs(vcpu), "PAL_CACHE_FLUSH ERROR, "
99 "status %ld", result.status);
101 return result;
102 }
104 static struct ia64_pal_retval
105 pal_vm_tr_read(VCPU *vcpu) {
106 struct ia64_pal_retval result;
108 INIT_PAL_STATUS_UNIMPLEMENTED(result);
110 return result;
111 }
113 static struct ia64_pal_retval
114 pal_prefetch_visibility(VCPU *vcpu) {
115 /* Due to current MM virtualization algorithm,
116 * We do not allow guest to change mapping attribute.
117 * Thus we will not support PAL_PREFETCH_VISIBILITY
118 */
119 struct ia64_pal_retval result;
121 INIT_PAL_STATUS_UNIMPLEMENTED(result);
123 return result;
124 }
126 static struct ia64_pal_retval
127 pal_platform_addr(VCPU *vcpu) {
128 struct ia64_pal_retval result;
130 INIT_PAL_STATUS_SUCCESS(result);
132 return result;
133 }
135 static struct ia64_pal_retval
136 pal_halt(VCPU *vcpu) {
137 //bugbug: to be implement.
138 struct ia64_pal_retval result;
140 INIT_PAL_STATUS_UNIMPLEMENTED(result);
142 return result;
143 }
145 static struct ia64_pal_retval
146 pal_halt_light(VCPU *vcpu) {
147 struct ia64_pal_retval result;
149 if (!is_unmasked_irq(vcpu))
150 do_sched_op_compat(SCHEDOP_block, 0);
152 INIT_PAL_STATUS_SUCCESS(result);
154 return result;
155 }
157 static struct ia64_pal_retval
158 pal_cache_read(VCPU *vcpu) {
159 struct ia64_pal_retval result;
161 INIT_PAL_STATUS_UNIMPLEMENTED(result);
163 return result;
164 }
166 static struct ia64_pal_retval
167 pal_cache_write(VCPU *vcpu) {
168 struct ia64_pal_retval result;
170 INIT_PAL_STATUS_UNIMPLEMENTED(result);
172 return result;
173 }
175 static struct ia64_pal_retval
176 pal_bus_get_features(VCPU *vcpu) {
177 struct ia64_pal_retval result;
179 INIT_PAL_STATUS_UNIMPLEMENTED(result);
181 return result;
182 }
184 static struct ia64_pal_retval
185 pal_cache_summary(VCPU *vcpu) {
186 struct ia64_pal_retval result;
188 INIT_PAL_STATUS_UNIMPLEMENTED(result);
190 return result;
191 }
193 static struct ia64_pal_retval
194 pal_cache_init(VCPU *vcpu) {
195 struct ia64_pal_retval result;
197 INIT_PAL_STATUS_SUCCESS(result);
199 return result;
200 }
202 static struct ia64_pal_retval
203 pal_cache_info(VCPU *vcpu) {
204 struct ia64_pal_retval result;
206 INIT_PAL_STATUS_UNIMPLEMENTED(result);
208 return result;
209 }
211 static struct ia64_pal_retval
212 pal_cache_prot_info(VCPU *vcpu) {
213 struct ia64_pal_retval result;
215 INIT_PAL_STATUS_UNIMPLEMENTED(result);
217 return result;
218 }
220 static struct ia64_pal_retval
221 pal_mem_attrib(VCPU *vcpu) {
222 struct ia64_pal_retval result;
224 INIT_PAL_STATUS_UNIMPLEMENTED(result);
226 return result;
227 }
229 static struct ia64_pal_retval
230 pal_debug_info(VCPU *vcpu) {
231 struct ia64_pal_retval result;
233 INIT_PAL_STATUS_UNIMPLEMENTED(result);
235 return result;
236 }
238 static struct ia64_pal_retval
239 pal_fixed_addr(VCPU *vcpu) {
240 struct ia64_pal_retval result;
242 INIT_PAL_STATUS_UNIMPLEMENTED(result);
244 return result;
245 }
247 static struct ia64_pal_retval
248 pal_freq_base(VCPU *vcpu) {
249 struct ia64_pal_retval result;
250 struct ia64_sal_retval isrv;
252 PAL_CALL(result,PAL_FREQ_BASE, 0, 0, 0);
253 /*
254 * PAL_FREQ_BASE may not be implemented in some platforms,
255 * call SAL instead.
256 */
257 if (result.v0 == 0) {
258 SAL_CALL(isrv, SAL_FREQ_BASE,
259 SAL_FREQ_BASE_PLATFORM, 0, 0, 0, 0, 0, 0);
260 result.status = isrv.status;
261 result.v0 = isrv.v0;
262 result.v1 = result.v2 = 0;
263 }
264 return result;
265 }
267 static struct ia64_pal_retval
268 pal_freq_ratios(VCPU *vcpu) {
269 struct ia64_pal_retval result;
271 PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0);
272 return result;
273 }
275 static struct ia64_pal_retval
276 pal_halt_info(VCPU *vcpu) {
277 struct ia64_pal_retval result;
279 INIT_PAL_STATUS_UNIMPLEMENTED(result);
281 return result;
282 }
284 static struct ia64_pal_retval
285 pal_logical_to_physica(VCPU *vcpu) {
286 struct ia64_pal_retval result;
288 INIT_PAL_STATUS_UNIMPLEMENTED(result);
290 return result;
291 }
293 static struct ia64_pal_retval
294 pal_perf_mon_info(VCPU *vcpu) {
295 struct ia64_pal_retval result;
297 INIT_PAL_STATUS_UNIMPLEMENTED(result);
299 return result;
300 }
302 static struct ia64_pal_retval
303 pal_proc_get_features(VCPU *vcpu) {
304 struct ia64_pal_retval result;
306 INIT_PAL_STATUS_UNIMPLEMENTED(result);
308 return result;
309 }
311 static struct ia64_pal_retval
312 pal_ptce_info(VCPU *vcpu) {
313 struct ia64_pal_retval result;
315 INIT_PAL_STATUS_UNIMPLEMENTED(result);
317 return result;
318 }
320 static struct ia64_pal_retval
321 pal_register_info(VCPU *vcpu) {
322 struct ia64_pal_retval result;
324 INIT_PAL_STATUS_UNIMPLEMENTED(result);
326 return result;
327 }
329 static struct ia64_pal_retval
330 pal_rse_info(VCPU *vcpu) {
331 struct ia64_pal_retval result;
333 INIT_PAL_STATUS_UNIMPLEMENTED(result);
335 return result;
336 }
338 static struct ia64_pal_retval
339 pal_test_info(VCPU *vcpu) {
340 struct ia64_pal_retval result;
342 INIT_PAL_STATUS_UNIMPLEMENTED(result);
344 return result;
345 }
347 static struct ia64_pal_retval
348 pal_vm_summary(VCPU *vcpu) {
349 pal_vm_info_1_u_t vminfo1;
350 pal_vm_info_2_u_t vminfo2;
351 struct ia64_pal_retval result;
353 PAL_CALL(result, PAL_VM_SUMMARY, 0, 0, 0);
354 if (!result.status) {
355 vminfo1.pvi1_val = result.v0;
356 vminfo1.pal_vm_info_1_s.max_itr_entry = NITRS -1;
357 vminfo1.pal_vm_info_1_s.max_dtr_entry = NDTRS -1;
358 result.v0 = vminfo1.pvi1_val;
359 vminfo2.pal_vm_info_2_s.impl_va_msb = GUEST_IMPL_VA_MSB;
360 vminfo2.pal_vm_info_2_s.rid_size =
361 current->domain->arch.rid_bits;
362 result.v1 = vminfo2.pvi2_val;
363 }
364 return result;
365 }
367 static struct ia64_pal_retval
368 pal_vm_info(VCPU *vcpu) {
369 struct ia64_pal_retval result;
371 INIT_PAL_STATUS_UNIMPLEMENTED(result);
373 return result;
374 }
376 static struct ia64_pal_retval
377 pal_vm_page_size(VCPU *vcpu) {
378 struct ia64_pal_retval result;
380 INIT_PAL_STATUS_UNIMPLEMENTED(result);
382 return result;
383 }
385 void
386 pal_emul(VCPU *vcpu) {
387 UINT64 gr28;
388 struct ia64_pal_retval result;
390 vcpu_get_gr_nat(vcpu,28,&gr28); //bank1
392 switch (gr28) {
393 case PAL_CACHE_FLUSH:
394 result = pal_cache_flush(vcpu);
395 break;
397 case PAL_PREFETCH_VISIBILITY:
398 result = pal_prefetch_visibility(vcpu);
399 break;
401 case PAL_VM_TR_READ:
402 result = pal_vm_tr_read(vcpu);
403 break;
405 case PAL_HALT:
406 result = pal_halt(vcpu);
407 break;
409 case PAL_HALT_LIGHT:
410 result = pal_halt_light(vcpu);
411 break;
413 case PAL_CACHE_READ:
414 result = pal_cache_read(vcpu);
415 break;
417 case PAL_CACHE_WRITE:
418 result = pal_cache_write(vcpu);
419 break;
421 case PAL_PLATFORM_ADDR:
422 result = pal_platform_addr(vcpu);
423 break;
425 case PAL_FREQ_RATIOS:
426 result = pal_freq_ratios(vcpu);
427 break;
429 case PAL_FREQ_BASE:
430 result = pal_freq_base(vcpu);
431 break;
433 case PAL_BUS_GET_FEATURES :
434 result = pal_bus_get_features(vcpu);
435 break;
437 case PAL_CACHE_SUMMARY :
438 result = pal_cache_summary(vcpu);
439 break;
441 case PAL_CACHE_INIT :
442 result = pal_cache_init(vcpu);
443 break;
445 case PAL_CACHE_INFO :
446 result = pal_cache_info(vcpu);
447 break;
449 case PAL_CACHE_PROT_INFO :
450 result = pal_cache_prot_info(vcpu);
451 break;
453 case PAL_MEM_ATTRIB :
454 result = pal_mem_attrib(vcpu);
455 break;
457 case PAL_DEBUG_INFO :
458 result = pal_debug_info(vcpu);
459 break;
461 case PAL_FIXED_ADDR :
462 result = pal_fixed_addr(vcpu);
463 break;
465 case PAL_HALT_INFO :
466 result = pal_halt_info(vcpu);
467 break;
469 case PAL_LOGICAL_TO_PHYSICAL :
470 result = pal_logical_to_physica(vcpu);
471 break;
473 case PAL_PERF_MON_INFO :
474 result = pal_perf_mon_info(vcpu);
475 break;
477 case PAL_PROC_GET_FEATURES:
478 result = pal_proc_get_features(vcpu);
479 break;
481 case PAL_PTCE_INFO :
482 result = pal_ptce_info(vcpu);
483 break;
485 case PAL_REGISTER_INFO :
486 result = pal_register_info(vcpu);
487 break;
489 case PAL_RSE_INFO :
490 result = pal_rse_info(vcpu);
491 break;
493 case PAL_TEST_PROC :
494 result = pal_test_info(vcpu);
495 break;
497 case PAL_VM_SUMMARY :
498 result = pal_vm_summary(vcpu);
499 break;
501 case PAL_VM_INFO :
502 result = pal_vm_info(vcpu);
503 break;
505 case PAL_VM_PAGE_SIZE :
506 result = pal_vm_page_size(vcpu);
507 break;
509 default:
510 panic_domain(vcpu_regs(vcpu),"pal_emul(): guest "
511 "call unsupported pal" );
512 }
513 set_pal_result(vcpu, result);
514 }
516 void
517 sal_emul(VCPU *v) {
518 struct sal_ret_values result;
519 result = sal_emulator(vcpu_get_gr(v, 32), vcpu_get_gr(v, 33),
520 vcpu_get_gr(v, 34), vcpu_get_gr(v, 35),
521 vcpu_get_gr(v, 36), vcpu_get_gr(v, 37),
522 vcpu_get_gr(v, 38), vcpu_get_gr(v, 39));
523 set_sal_result(v, result);
524 }