ia64/xen-unstable

view xen/arch/ia64/hypercall.c @ 6552:a9873d384da4

Merge.
author adsharma@los-vmm.sc.intel.com
date Thu Aug 25 12:24:48 2005 -0700 (2005-08-25)
parents 112d44270733 fa0754a9f64f
children dfaf788ab18c
line source
1 /*
2 * Hypercall implementations
3 *
4 * Copyright (C) 2005 Hewlett-Packard Co.
5 * Dan Magenheimer (dan.magenheimer@hp.com)
6 *
7 */
9 #include <xen/config.h>
10 #include <xen/sched.h>
12 #include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */
13 #include <asm/sal.h> /* FOR struct ia64_sal_retval */
15 #include <asm/vcpu.h>
16 #include <asm/dom_fw.h>
18 extern unsigned long translate_domain_mpaddr(unsigned long);
19 extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
20 extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
22 unsigned long idle_when_pending = 0;
23 unsigned long pal_halt_light_count = 0;
25 int
26 ia64_hypercall (struct pt_regs *regs)
27 {
28 struct vcpu *v = (struct domain *) current;
29 struct ia64_sal_retval x;
30 struct ia64_pal_retval y;
31 unsigned long *tv, *tc;
32 int pi;
34 switch (regs->r2) {
35 case FW_HYPERCALL_PAL_CALL:
36 //printf("*** PAL hypercall: index=%d\n",regs->r28);
37 //FIXME: This should call a C routine
38 #if 0
39 // This is very conservative, but avoids a possible
40 // (and deadly) freeze in paravirtualized domains due
41 // to a yet-to-be-found bug where pending_interruption
42 // is zero when it shouldn't be. Since PAL is called
43 // in the idle loop, this should resolve it
44 VCPU(v,pending_interruption) = 1;
45 #endif
46 if (regs->r28 == PAL_HALT_LIGHT) {
47 #define SPURIOUS_VECTOR 15
48 pi = vcpu_check_pending_interrupts(v);
49 if (pi != SPURIOUS_VECTOR) {
50 if (!VCPU(v,pending_interruption))
51 idle_when_pending++;
52 vcpu_pend_unspecified_interrupt(v);
53 //printf("idle w/int#%d pending!\n",pi);
54 //this shouldn't happen, but it apparently does quite a bit! so don't
55 //allow it to happen... i.e. if a domain has an interrupt pending and
56 //it tries to halt itself because it thinks it is idle, just return here
57 //as deliver_pending_interrupt is called on the way out and will deliver it
58 }
59 else {
60 pal_halt_light_count++;
61 do_sched_op(SCHEDOP_yield);
62 }
63 //break;
64 }
65 else if (regs->r28 >= PAL_COPY_PAL) { /* FIXME */
66 printf("stacked PAL hypercalls not supported\n");
67 regs->r8 = -1;
68 break;
69 }
70 else y = xen_pal_emulator(regs->r28,regs->r29,
71 regs->r30,regs->r31);
72 regs->r8 = y.status; regs->r9 = y.v0;
73 regs->r10 = y.v1; regs->r11 = y.v2;
74 break;
75 case FW_HYPERCALL_SAL_CALL:
76 x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
77 vcpu_get_gr(v,34),vcpu_get_gr(v,35),
78 vcpu_get_gr(v,36),vcpu_get_gr(v,37),
79 vcpu_get_gr(v,38),vcpu_get_gr(v,39));
80 regs->r8 = x.status; regs->r9 = x.v0;
81 regs->r10 = x.v1; regs->r11 = x.v2;
82 break;
83 case FW_HYPERCALL_EFI_RESET_SYSTEM:
84 printf("efi.reset_system called ");
85 if (current->domain == dom0) {
86 printf("(by dom0)\n ");
87 (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
88 }
89 #ifdef DOMU_AUTO_RESTART
90 else {
91 reconstruct_domU(current);
92 return 0; // don't increment ip!
93 }
94 #else
95 printf("(not supported for non-0 domain)\n");
96 regs->r8 = EFI_UNSUPPORTED;
97 #endif
98 break;
99 case FW_HYPERCALL_EFI_GET_TIME:
100 tv = vcpu_get_gr(v,32);
101 tc = vcpu_get_gr(v,33);
102 //printf("efi_get_time(%p,%p) called...",tv,tc);
103 tv = __va(translate_domain_mpaddr(tv));
104 if (tc) tc = __va(translate_domain_mpaddr(tc));
105 regs->r8 = (*efi.get_time)(tv,tc);
106 //printf("and returns %lx\n",regs->r8);
107 break;
108 case FW_HYPERCALL_EFI_SET_TIME:
109 case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
110 case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
111 // FIXME: need fixes in efi.h from 2.6.9
112 case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
113 // FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
114 // SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS
115 // POINTER ARGUMENTS WILL BE VIRTUAL!!
116 case FW_HYPERCALL_EFI_GET_VARIABLE:
117 // FIXME: need fixes in efi.h from 2.6.9
118 case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
119 case FW_HYPERCALL_EFI_SET_VARIABLE:
120 case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
121 // FIXME: need fixes in efi.h from 2.6.9
122 regs->r8 = EFI_UNSUPPORTED;
123 break;
124 case 0xffff: // test dummy hypercall
125 regs->r8 = dump_privop_counts_to_user(
126 vcpu_get_gr(v,32),
127 vcpu_get_gr(v,33));
128 break;
129 case 0xfffe: // test dummy hypercall
130 regs->r8 = zero_privop_counts_to_user(
131 vcpu_get_gr(v,32),
132 vcpu_get_gr(v,33));
133 break;
134 case 0xfffd: // test dummy hypercall
135 regs->r8 = launch_domainU(
136 vcpu_get_gr(v,32));
137 break;
138 case 0xfffc: // test dummy hypercall
139 regs->r8 = domU_staging_write_32(
140 vcpu_get_gr(v,32),
141 vcpu_get_gr(v,33),
142 vcpu_get_gr(v,34),
143 vcpu_get_gr(v,35),
144 vcpu_get_gr(v,36));
145 break;
146 case 0xfffb: // test dummy hypercall
147 regs->r8 = domU_staging_read_8(vcpu_get_gr(v,32));
148 break;
150 case __HYPERVISOR_dom0_op:
151 regs->r8 = do_dom0_op(regs->r14);
152 break;
154 case __HYPERVISOR_dom_mem_op:
155 #ifdef CONFIG_VTI
156 regs->r8 = do_dom_mem_op(regs->r14, regs->r15, regs->r16, regs->r17, regs->r18);
157 #else
158 /* we don't handle reservations; just return success */
159 regs->r8 = regs->r16;
160 #endif
161 break;
163 case __HYPERVISOR_event_channel_op:
164 regs->r8 = do_event_channel_op(regs->r14);
165 break;
167 #ifndef CONFIG_VTI
168 case __HYPERVISOR_grant_table_op:
169 regs->r8 = do_grant_table_op(regs->r14, regs->r15, regs->r16);
170 break;
171 #endif
173 case __HYPERVISOR_console_io:
174 regs->r8 = do_console_io(regs->r14, regs->r15, regs->r16);
175 break;
177 default:
178 printf("unknown hypercall %x\n", regs->r2);
179 regs->r8 = (unsigned long)-1;
180 }
181 return 1;
182 }