ia64/xen-unstable

view xen/arch/ia64/xen/fw_emul.c @ 16785:af3550f53874

[IA64] domheap: Don't pin xenheap down. Now it's unnecessary.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Jan 17 12:05:43 2008 -0700 (2008-01-17)
parents e6069a715fd7
children b03e24f9c1d8
line source
1 /*
2 * fw_emul.c:
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 */
18 #include <xen/config.h>
19 #include <asm/system.h>
20 #include <asm/pgalloc.h>
22 #include <linux/efi.h>
23 #include <asm/pal.h>
24 #include <asm/sal.h>
25 #include <asm/sn/sn_sal.h>
26 #include <asm/sn/hubdev.h>
27 #include <asm/xenmca.h>
29 #include <public/sched.h>
30 #include "hpsim_ssc.h"
31 #include <asm/vcpu.h>
32 #include <asm/vmx_vcpu.h>
33 #include <asm/dom_fw.h>
34 #include <asm/uaccess.h>
35 #include <xen/console.h>
36 #include <xen/hypercall.h>
37 #include <xen/softirq.h>
38 #include <xen/time.h>
39 #include <asm/debugger.h>
40 #include <asm/vmx_phy_mode.h>
42 static DEFINE_SPINLOCK(efi_time_services_lock);
44 struct sal_mc_params {
45 u64 param_type;
46 u64 i_or_m;
47 u64 i_or_m_val;
48 u64 timeout;
49 u64 rz_always;
50 } sal_mc_params[SAL_MC_PARAM_CPE_INT + 1];
52 struct sal_vectors {
53 u64 vector_type;
54 u64 handler_addr1;
55 u64 gp1;
56 u64 handler_len1;
57 u64 handler_addr2;
58 u64 gp2;
59 u64 handler_len2;
60 } sal_vectors[SAL_VECTOR_OS_BOOT_RENDEZ + 1];
62 struct smp_call_args_t {
63 u64 type;
64 u64 ret;
65 u64 target;
66 struct domain *domain;
67 int corrected;
68 int status;
69 void *data;
70 };
72 extern sal_log_record_header_t *sal_record;
73 DEFINE_SPINLOCK(sal_record_lock);
75 extern spinlock_t sal_queue_lock;
77 #define IA64_SAL_NO_INFORMATION_AVAILABLE -5
79 #if defined(IA64_SAL_DEBUG_INFO)
80 static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
82 # define IA64_SAL_DEBUG(fmt...) printk("sal_emulator: " fmt)
83 #else
84 # define IA64_SAL_DEBUG(fmt...)
85 #endif
87 void get_state_info_on(void *data) {
88 struct smp_call_args_t *arg = data;
89 int flags;
91 spin_lock_irqsave(&sal_record_lock, flags);
92 memset(sal_record, 0, ia64_sal_get_state_info_size(arg->type));
93 arg->ret = ia64_sal_get_state_info(arg->type, (u64 *)sal_record);
94 IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) on CPU#%d returns %ld.\n",
95 rec_name[arg->type], smp_processor_id(), arg->ret);
96 if (arg->corrected) {
97 sal_record->severity = sal_log_severity_corrected;
98 IA64_SAL_DEBUG("%s: IA64_SAL_CLEAR_STATE_INFO(SAL_INFO_TYPE_MCA)"
99 " force\n", __FUNCTION__);
100 }
101 if (arg->ret > 0) {
102 /*
103 * Save current->domain and set to local(caller) domain for
104 * xencomm_paddr_to_maddr() which calculates maddr from
105 * paddr using mpa value of current->domain.
106 */
107 struct domain *save;
108 save = current->domain;
109 current->domain = arg->domain;
110 if (xencomm_copy_to_guest((void*)arg->target,
111 sal_record, arg->ret, 0)) {
112 printk("SAL_GET_STATE_INFO can't copy to user!!!!\n");
113 arg->status = IA64_SAL_NO_INFORMATION_AVAILABLE;
114 arg->ret = 0;
115 }
116 /* Restore current->domain to saved value. */
117 current->domain = save;
118 }
119 spin_unlock_irqrestore(&sal_record_lock, flags);
120 }
122 void clear_state_info_on(void *data) {
123 struct smp_call_args_t *arg = data;
125 arg->ret = ia64_sal_clear_state_info(arg->type);
126 IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) on CPU#%d returns %ld.\n",
127 rec_name[arg->type], smp_processor_id(), arg->ret);
129 }
131 struct sal_ret_values
132 sal_emulator (long index, unsigned long in1, unsigned long in2,
133 unsigned long in3, unsigned long in4, unsigned long in5,
134 unsigned long in6, unsigned long in7)
135 {
136 struct ia64_sal_retval ret_stuff;
137 unsigned long r9 = 0;
138 unsigned long r10 = 0;
139 long r11 = 0;
140 long status;
142 debugger_event(XEN_IA64_DEBUG_ON_SAL);
144 status = 0;
145 switch (index) {
146 case SAL_FREQ_BASE:
147 if (likely(!running_on_sim))
148 status = ia64_sal_freq_base(in1,&r9,&r10);
149 else switch (in1) {
150 case SAL_FREQ_BASE_PLATFORM:
151 r9 = 200000000;
152 break;
154 case SAL_FREQ_BASE_INTERVAL_TIMER:
155 r9 = 700000000;
156 break;
158 case SAL_FREQ_BASE_REALTIME_CLOCK:
159 r9 = 1;
160 break;
162 default:
163 status = -1;
164 break;
165 }
166 break;
167 case SAL_PCI_CONFIG_READ:
168 if (current->domain == dom0) {
169 u64 value;
170 // note that args 2&3 are swapped!!
171 status = ia64_sal_pci_config_read(in1,in3,in2,&value);
172 r9 = value;
173 }
174 else
175 printk("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_READ\n");
176 break;
177 case SAL_PCI_CONFIG_WRITE:
178 if (current->domain == dom0) {
179 if (((in1 & ~0xffffffffUL) && (in4 == 0)) ||
180 (in4 > 1) ||
181 (in2 > 8) || (in2 & (in2-1)))
182 printk("*** SAL_PCI_CONF_WRITE?!?(adr=0x%lx,typ=0x%lx,sz=0x%lx,val=0x%lx)\n",
183 in1,in4,in2,in3);
184 // note that args are in a different order!!
185 status = ia64_sal_pci_config_write(in1,in4,in2,in3);
186 }
187 else
188 printk("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_WRITE\n");
189 break;
190 case SAL_SET_VECTORS:
191 if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
192 if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) {
193 /* Sanity check: cs_length1 must be 0,
194 second vector is reserved. */
195 status = -2;
196 }
197 else {
198 struct domain *d = current->domain;
199 d->arch.sal_data->boot_rdv_ip = in2;
200 d->arch.sal_data->boot_rdv_r1 = in3;
201 }
202 }
203 else
204 {
205 if (in1 > sizeof(sal_vectors)/sizeof(sal_vectors[0])-1)
206 BUG();
207 sal_vectors[in1].vector_type = in1;
208 sal_vectors[in1].handler_addr1 = in2;
209 sal_vectors[in1].gp1 = in3;
210 sal_vectors[in1].handler_len1 = in4;
211 sal_vectors[in1].handler_addr2 = in5;
212 sal_vectors[in1].gp2 = in6;
213 sal_vectors[in1].handler_len2 = in7;
214 }
215 break;
216 case SAL_GET_STATE_INFO:
217 if (current->domain == dom0) {
218 sal_queue_entry_t *e;
219 unsigned long flags;
220 struct smp_call_args_t arg;
222 spin_lock_irqsave(&sal_queue_lock, flags);
223 if (!sal_queue || list_empty(&sal_queue[in1])) {
224 sal_log_record_header_t header;
225 XEN_GUEST_HANDLE(void) handle =
226 *(XEN_GUEST_HANDLE(void)*)&in3;
228 IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
229 "no sal_queue entry found.\n",
230 rec_name[in1]);
231 memset(&header, 0, sizeof(header));
233 if (copy_to_guest(handle, &header, 1)) {
234 printk("sal_emulator: "
235 "SAL_GET_STATE_INFO can't copy "
236 "empty header to user: 0x%lx\n",
237 in3);
238 }
239 status = IA64_SAL_NO_INFORMATION_AVAILABLE;
240 r9 = 0;
241 spin_unlock_irqrestore(&sal_queue_lock, flags);
242 break;
243 }
244 e = list_entry(sal_queue[in1].next,
245 sal_queue_entry_t, list);
247 list_del(&e->list);
248 spin_unlock_irqrestore(&sal_queue_lock, flags);
250 IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s <= %s) "
251 "on CPU#%d.\n",
252 rec_name[e->sal_info_type],
253 rec_name[in1], e->cpuid);
255 arg.type = e->sal_info_type;
256 arg.target = in3;
257 arg.corrected = !!((in1 != e->sal_info_type) &&
258 (e->sal_info_type == SAL_INFO_TYPE_MCA));
259 arg.domain = current->domain;
260 arg.status = 0;
262 if (e->cpuid == smp_processor_id()) {
263 IA64_SAL_DEBUG("SAL_GET_STATE_INFO: local\n");
264 get_state_info_on(&arg);
265 } else {
266 int ret;
267 IA64_SAL_DEBUG("SAL_GET_STATE_INFO: remote\n");
268 ret = smp_call_function_single(e->cpuid,
269 get_state_info_on,
270 &arg, 0, 1);
271 if (ret < 0) {
272 printk("SAL_GET_STATE_INFO "
273 "smp_call_function_single error:"
274 " %d\n", ret);
275 arg.ret = 0;
276 arg.status =
277 IA64_SAL_NO_INFORMATION_AVAILABLE;
278 }
279 }
280 r9 = arg.ret;
281 status = arg.status;
282 if (r9 == 0) {
283 xfree(e);
284 } else {
285 /* Re-add the entry to sal_queue */
286 spin_lock_irqsave(&sal_queue_lock, flags);
287 list_add(&e->list, &sal_queue[in1]);
288 spin_unlock_irqrestore(&sal_queue_lock, flags);
289 }
290 } else {
291 status = IA64_SAL_NO_INFORMATION_AVAILABLE;
292 r9 = 0;
293 }
294 break;
295 case SAL_GET_STATE_INFO_SIZE:
296 r9 = ia64_sal_get_state_info_size(in1);
297 break;
298 case SAL_CLEAR_STATE_INFO:
299 if (current->domain == dom0) {
300 sal_queue_entry_t *e;
301 unsigned long flags;
302 struct smp_call_args_t arg;
304 spin_lock_irqsave(&sal_queue_lock, flags);
305 if (list_empty(&sal_queue[in1])) {
306 IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
307 "no sal_queue entry found.\n",
308 rec_name[in1]);
309 status = IA64_SAL_NO_INFORMATION_AVAILABLE;
310 r9 = 0;
311 spin_unlock_irqrestore(&sal_queue_lock, flags);
312 break;
313 }
314 e = list_entry(sal_queue[in1].next,
315 sal_queue_entry_t, list);
317 list_del(&e->list);
318 spin_unlock_irqrestore(&sal_queue_lock, flags);
320 IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s <= %s) "
321 "on CPU#%d.\n",
322 rec_name[e->sal_info_type],
323 rec_name[in1], e->cpuid);
325 arg.type = e->sal_info_type;
326 arg.status = 0;
328 if (e->cpuid == smp_processor_id()) {
329 IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: local\n");
330 clear_state_info_on(&arg);
331 } else {
332 int ret;
333 IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: remote\n");
334 ret = smp_call_function_single(e->cpuid,
335 clear_state_info_on, &arg, 0, 1);
336 if (ret < 0) {
337 printk("sal_emulator: "
338 "SAL_CLEAR_STATE_INFO "
339 "smp_call_function_single error:"
340 " %d\n", ret);
341 arg.ret = 0;
342 arg.status =
343 IA64_SAL_NO_INFORMATION_AVAILABLE;
344 }
345 }
346 r9 = arg.ret;
347 status = arg.status;
348 xfree(e);
349 }
350 break;
351 case SAL_MC_RENDEZ:
352 printk("*** CALLED SAL_MC_RENDEZ. IGNORED...\n");
353 break;
354 case SAL_MC_SET_PARAMS:
355 if (in1 > sizeof(sal_mc_params)/sizeof(sal_mc_params[0]))
356 BUG();
357 sal_mc_params[in1].param_type = in1;
358 sal_mc_params[in1].i_or_m = in2;
359 sal_mc_params[in1].i_or_m_val = in3;
360 sal_mc_params[in1].timeout = in4;
361 sal_mc_params[in1].rz_always = in5;
362 break;
363 case SAL_CACHE_FLUSH:
364 if (1) {
365 /* Flush using SAL.
366 This method is faster but has a side effect on
367 other vcpu running on this cpu. */
368 status = ia64_sal_cache_flush (in1);
369 }
370 else {
371 /* Flush with fc all the domain.
372 This method is slower but has no side effects. */
373 domain_cache_flush (current->domain, in1 == 4 ? 1 : 0);
374 status = 0;
375 }
376 break;
377 case SAL_CACHE_INIT:
378 printk("*** CALLED SAL_CACHE_INIT. IGNORED...\n");
379 break;
380 case SAL_UPDATE_PAL:
381 printk("*** CALLED SAL_UPDATE_PAL. IGNORED...\n");
382 break;
383 case SAL_PHYSICAL_ID_INFO:
384 status = -1;
385 break;
386 case SAL_XEN_SAL_RETURN:
387 if (!test_and_set_bit(_VPF_down, &current->pause_flags))
388 vcpu_sleep_nosync(current);
389 break;
390 case SN_SAL_GET_MASTER_NASID:
391 status = -1;
392 if (current->domain == dom0) {
393 /* printk("*** Emulating SN_SAL_GET_MASTER_NASID ***\n"); */
394 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_MASTER_NASID,
395 0, 0, 0, 0, 0, 0, 0);
396 status = ret_stuff.status;
397 r9 = ret_stuff.v0;
398 r10 = ret_stuff.v1;
399 r11 = ret_stuff.v2;
400 }
401 break;
402 case SN_SAL_GET_KLCONFIG_ADDR:
403 status = -1;
404 if (current->domain == dom0) {
405 /* printk("*** Emulating SN_SAL_GET_KLCONFIG_ADDR ***\n"); */
406 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR,
407 in1, 0, 0, 0, 0, 0, 0);
408 status = ret_stuff.status;
409 r9 = ret_stuff.v0;
410 r10 = ret_stuff.v1;
411 r11 = ret_stuff.v2;
412 }
413 break;
414 case SN_SAL_GET_SAPIC_INFO:
415 status = -1;
416 if (current->domain == dom0) {
417 /* printk("*** Emulating SN_SAL_GET_SAPIC_INFO ***\n"); */
418 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO,
419 in1, 0, 0, 0, 0, 0, 0);
420 status = ret_stuff.status;
421 r9 = ret_stuff.v0;
422 r10 = ret_stuff.v1;
423 r11 = ret_stuff.v2;
424 }
425 break;
426 case SN_SAL_GET_SN_INFO:
427 status = -1;
428 if (current->domain == dom0) {
429 /* printk("*** Emulating SN_SAL_GET_SN_INFO ***\n"); */
430 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO,
431 in1, 0, 0, 0, 0, 0, 0);
432 status = ret_stuff.status;
433 r9 = ret_stuff.v0;
434 r10 = ret_stuff.v1;
435 r11 = ret_stuff.v2;
436 }
437 break;
438 case SN_SAL_IOIF_GET_HUBDEV_INFO:
439 status = -1;
440 if (current->domain == dom0) {
441 /* printk("*** Emulating SN_SAL_IOIF_GET_HUBDEV_INFO ***\n"); */
442 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_IOIF_GET_HUBDEV_INFO,
443 in1, in2, 0, 0, 0, 0, 0);
444 status = ret_stuff.status;
445 r9 = ret_stuff.v0;
446 r10 = ret_stuff.v1;
447 r11 = ret_stuff.v2;
448 }
449 break;
450 case SN_SAL_IOIF_INIT:
451 status = -1;
452 if (current->domain == dom0) {
453 /* printk("*** Emulating SN_SAL_IOIF_INIT ***\n"); */
454 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_IOIF_INIT,
455 0, 0, 0, 0, 0, 0, 0);
456 status = ret_stuff.status;
457 r9 = ret_stuff.v0;
458 r10 = ret_stuff.v1;
459 r11 = ret_stuff.v2;
460 }
461 break;
462 case SN_SAL_GET_PROM_FEATURE_SET:
463 status = -1;
464 if (current->domain == dom0) {
465 /* printk("*** Emulating SN_SAL_GET_PROM_FEATURE_SET ***\n"); */
466 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_PROM_FEATURE_SET,
467 in1, 0, 0, 0, 0, 0, 0);
468 status = ret_stuff.status;
469 r9 = ret_stuff.v0;
470 r10 = ret_stuff.v1;
471 r11 = ret_stuff.v2;
472 }
473 break;
474 case SN_SAL_SET_OS_FEATURE_SET:
475 status = -1;
476 if (current->domain == dom0) {
477 /* printk("*** Emulating SN_SAL_SET_OS_FEATURE_SET ***\n"); */
478 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SET_OS_FEATURE_SET,
479 in1, 0, 0, 0, 0, 0, 0);
480 status = ret_stuff.status;
481 r9 = ret_stuff.v0;
482 r10 = ret_stuff.v1;
483 r11 = ret_stuff.v2;
484 }
485 break;
486 case SN_SAL_SET_ERROR_HANDLING_FEATURES:
487 status = -1;
488 if (current->domain == dom0) {
489 /* printk("*** Emulating SN_SAL_SET_ERROR_HANDLING_FEATURES ***\n"); */
490 SAL_CALL_NOLOCK(ret_stuff,
491 SN_SAL_SET_ERROR_HANDLING_FEATURES,
492 in1, 0, 0, 0, 0, 0, 0);
493 status = ret_stuff.status;
494 r9 = ret_stuff.v0;
495 r10 = ret_stuff.v1;
496 r11 = ret_stuff.v2;
497 }
498 break;
499 #if 0
500 /*
501 * Somehow ACPI breaks if allowing this one
502 */
503 case SN_SAL_SET_CPU_NUMBER:
504 status = -1;
505 if (current->domain == dom0) {
506 printk("*** Emulating SN_SAL_SET_CPU_NUMBER ***\n");
507 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SET_CPU_NUMBER,
508 in1, 0, 0, 0, 0, 0, 0);
509 status = ret_stuff.status;
510 r9 = ret_stuff.v0;
511 r10 = ret_stuff.v1;
512 r11 = ret_stuff.v2;
513 }
514 break;
515 #endif
516 case SN_SAL_LOG_CE:
517 status = -1;
518 if (current->domain == dom0) {
519 static int log_ce = 0;
520 if (!log_ce) {
521 printk("*** Emulating SN_SAL_LOG_CE *** "
522 " this will only be printed once\n");
523 log_ce = 1;
524 }
525 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE,
526 0, 0, 0, 0, 0, 0, 0);
527 status = ret_stuff.status;
528 r9 = ret_stuff.v0;
529 r10 = ret_stuff.v1;
530 r11 = ret_stuff.v2;
531 }
532 break;
533 case SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST:
534 status = -1;
535 if (current->domain == dom0) {
536 struct sn_flush_device_common flush;
537 int flush_size;
539 flush_size = sizeof(struct sn_flush_device_common);
540 memset(&flush, 0, flush_size);
541 SAL_CALL_NOLOCK(ret_stuff,
542 SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
543 in1, in2, in3, &flush, 0, 0, 0);
544 #if 0
545 printk("*** Emulating "
546 "SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST ***\n");
547 #endif
548 if (ret_stuff.status == SALRET_OK) {
549 XEN_GUEST_HANDLE(void) handle =
550 *(XEN_GUEST_HANDLE(void)*)&in4;
551 if (copy_to_guest(handle, &flush, 1)) {
552 printk("SN_SAL_IOIF_GET_DEVICE_"
553 "DMAFLUSH_LIST can't copy "
554 "to user!\n");
555 ret_stuff.status = SALRET_ERROR;
556 }
557 }
559 status = ret_stuff.status;
560 r9 = ret_stuff.v0;
561 r10 = ret_stuff.v1;
562 r11 = ret_stuff.v2;
563 }
564 break;
565 default:
566 printk("*** CALLED SAL_ WITH UNKNOWN INDEX (%lx). "
567 "IGNORED...\n", index);
568 status = -1;
569 break;
570 }
571 return ((struct sal_ret_values) {status, r9, r10, r11});
572 }
574 static int
575 safe_copy_to_guest(unsigned long to, void *from, long size)
576 {
577 BUG_ON((unsigned)size > PAGE_SIZE);
579 if (VMX_DOMAIN(current)) {
580 if (is_virtual_mode(current)) {
581 thash_data_t *data;
582 unsigned long gpa, poff;
584 /* The caller must provide a DTR or DTC mapping */
585 data = vtlb_lookup(current, to, DSIDE_TLB);
586 if (data) {
587 gpa = data->page_flags & _PAGE_PPN_MASK;
588 } else {
589 data = vhpt_lookup(to);
590 if (!data)
591 return -1;
592 gpa = __mpa_to_gpa(
593 data->page_flags & _PAGE_PPN_MASK);
594 gpa &= _PAGE_PPN_MASK;
595 }
596 poff = POFFSET(to, data->ps);
597 if (poff + size > PSIZE(data->ps))
598 return -1;
599 to = PAGEALIGN(gpa, data->ps) | poff;
600 }
601 to |= XENCOMM_INLINE_FLAG;
602 if (xencomm_copy_to_guest((void *)to, from, size, 0) != 0)
603 return -1;
604 return 0;
605 } else {
606 /* check for vulnerability */
607 if (IS_VMM_ADDRESS(to) || IS_VMM_ADDRESS(to + size - 1))
608 panic_domain(NULL, "copy to bad address:0x%lx\n", to);
609 return copy_to_user((void __user *)to, from, size);
610 }
611 }
613 cpumask_t cpu_cache_coherent_map;
615 struct cache_flush_args {
616 u64 cache_type;
617 u64 operation;
618 u64 progress;
619 long status;
620 };
622 static void
623 remote_pal_cache_flush(void *v)
624 {
625 struct cache_flush_args *args = v;
626 long status;
627 u64 progress = args->progress;
629 status = ia64_pal_cache_flush(args->cache_type, args->operation,
630 &progress, NULL);
631 if (status != 0)
632 args->status = status;
633 }
635 static void
636 remote_pal_prefetch_visibility(void *v)
637 {
638 s64 trans_type = (s64)v;
639 ia64_pal_prefetch_visibility(trans_type);
640 }
642 static void
643 remote_pal_mc_drain(void *v)
644 {
645 ia64_pal_mc_drain();
646 }
648 struct ia64_pal_retval
649 xen_pal_emulator(unsigned long index, u64 in1, u64 in2, u64 in3)
650 {
651 unsigned long r9 = 0;
652 unsigned long r10 = 0;
653 unsigned long r11 = 0;
654 long status = PAL_STATUS_UNIMPLEMENTED;
655 unsigned long flags;
656 int processor;
658 if (unlikely(running_on_sim))
659 return pal_emulator_static(index);
661 debugger_event(XEN_IA64_DEBUG_ON_PAL);
663 // pal code must be mapped by a TR when pal is called, however
664 // calls are rare enough that we will map it lazily rather than
665 // at every context switch
666 //efi_map_pal_code();
667 switch (index) {
668 case PAL_MEM_ATTRIB:
669 status = ia64_pal_mem_attrib(&r9);
670 break;
671 case PAL_FREQ_BASE:
672 status = ia64_pal_freq_base(&r9);
673 if (status == PAL_STATUS_UNIMPLEMENTED) {
674 status = ia64_sal_freq_base(0, &r9, &r10);
675 r10 = 0;
676 }
677 break;
678 case PAL_PROC_GET_FEATURES:
679 status = ia64_pal_proc_get_features(&r9,&r10,&r11);
680 break;
681 case PAL_BUS_GET_FEATURES:
682 status = ia64_pal_bus_get_features(
683 (pal_bus_features_u_t *) &r9,
684 (pal_bus_features_u_t *) &r10,
685 (pal_bus_features_u_t *) &r11);
686 break;
687 case PAL_FREQ_RATIOS:
688 status = ia64_pal_freq_ratios(
689 (struct pal_freq_ratio *) &r9,
690 (struct pal_freq_ratio *) &r10,
691 (struct pal_freq_ratio *) &r11);
692 break;
693 case PAL_PTCE_INFO:
694 /*
695 * return hard-coded xen-specific values because ptc.e
696 * is emulated on xen to always flush everything
697 * these values result in only one ptc.e instruction
698 */
699 status = PAL_STATUS_SUCCESS;
700 r10 = (1L << 32) | 1L;
701 break;
702 case PAL_VERSION:
703 status = ia64_pal_version(
704 (pal_version_u_t *) &r9,
705 (pal_version_u_t *) &r10);
706 break;
707 case PAL_VM_PAGE_SIZE:
708 status = ia64_pal_vm_page_size(&r9,&r10);
709 break;
710 case PAL_DEBUG_INFO:
711 status = ia64_pal_debug_info(&r9,&r10);
712 break;
713 case PAL_CACHE_SUMMARY:
714 status = ia64_pal_cache_summary(&r9,&r10);
715 break;
716 case PAL_VM_SUMMARY:
717 if (VMX_DOMAIN(current)) {
718 pal_vm_info_1_u_t v1;
719 pal_vm_info_2_u_t v2;
720 status = ia64_pal_vm_summary((pal_vm_info_1_u_t *)&v1,
721 (pal_vm_info_2_u_t *)&v2);
722 v1.pal_vm_info_1_s.max_itr_entry = NITRS - 1;
723 v1.pal_vm_info_1_s.max_dtr_entry = NDTRS - 1;
724 v2.pal_vm_info_2_s.impl_va_msb -= 1;
725 v2.pal_vm_info_2_s.rid_size =
726 current->domain->arch.rid_bits;
727 r9 = v1.pvi1_val;
728 r10 = v2.pvi2_val;
729 } else {
730 /* Use xen-specific values.
731 hash_tag_id is somewhat random! */
732 static const pal_vm_info_1_u_t v1 =
733 {.pal_vm_info_1_s =
734 { .vw = 1,
735 .phys_add_size = 44,
736 .key_size = 16,
737 .max_pkr = XEN_IA64_NPKRS,
738 .hash_tag_id = 0x30,
739 .max_dtr_entry = NDTRS - 1,
740 .max_itr_entry = NITRS - 1,
741 .max_unique_tcs = 3,
742 .num_tc_levels = 2
743 }};
744 pal_vm_info_2_u_t v2;
745 v2.pvi2_val = 0;
746 v2.pal_vm_info_2_s.rid_size =
747 current->domain->arch.rid_bits;
748 v2.pal_vm_info_2_s.impl_va_msb = 50;
749 r9 = v1.pvi1_val;
750 r10 = v2.pvi2_val;
751 status = PAL_STATUS_SUCCESS;
752 }
753 break;
754 case PAL_VM_INFO:
755 if (VMX_DOMAIN(current)) {
756 status = ia64_pal_vm_info(in1, in2,
757 (pal_tc_info_u_t *)&r9, &r10);
758 break;
759 }
760 if (in1 == 0 && in2 == 2) {
761 /* Level 1: VHPT */
762 const pal_tc_info_u_t v =
763 { .pal_tc_info_s = {.num_sets = 128,
764 .associativity = 1,
765 .num_entries = 128,
766 .pf = 1,
767 .unified = 1,
768 .reduce_tr = 0,
769 .reserved = 0}};
770 r9 = v.pti_val;
771 /* Only support PAGE_SIZE tc. */
772 r10 = PAGE_SIZE;
773 status = PAL_STATUS_SUCCESS;
774 }
775 else if (in1 == 1 && (in2 == 1 || in2 == 2)) {
776 /* Level 2: itlb/dtlb, 1 entry. */
777 const pal_tc_info_u_t v =
778 { .pal_tc_info_s = {.num_sets = 1,
779 .associativity = 1,
780 .num_entries = 1,
781 .pf = 1,
782 .unified = 0,
783 .reduce_tr = 0,
784 .reserved = 0}};
785 r9 = v.pti_val;
786 /* Only support PAGE_SIZE tc. */
787 r10 = PAGE_SIZE;
788 status = PAL_STATUS_SUCCESS;
789 } else
790 status = PAL_STATUS_EINVAL;
791 break;
792 case PAL_RSE_INFO:
793 status = ia64_pal_rse_info(&r9, (pal_hints_u_t *)&r10);
794 break;
795 case PAL_REGISTER_INFO:
796 status = ia64_pal_register_info(in1, &r9, &r10);
797 break;
798 case PAL_CACHE_FLUSH:
799 if (in3 != 0) /* Initially progress_indicator must be 0 */
800 panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
801 "progress_indicator=%lx", in3);
803 /* Always call Host Pal in int=0 */
804 in2 &= ~PAL_CACHE_FLUSH_CHK_INTRS;
806 if (in1 != PAL_CACHE_TYPE_COHERENT) {
807 struct cache_flush_args args = {
808 .cache_type = in1,
809 .operation = in2,
810 .progress = 0,
811 .status = 0
812 };
813 smp_call_function(remote_pal_cache_flush,
814 (void *)&args, 1, 1);
815 if (args.status != 0)
816 panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
817 "remote status %lx", args.status);
818 }
820 /*
821 * Call Host PAL cache flush
822 * Clear psr.ic when call PAL_CACHE_FLUSH
823 */
824 r10 = in3;
825 local_irq_save(flags);
826 processor = current->processor;
827 status = ia64_pal_cache_flush(in1, in2, &r10, &r9);
828 local_irq_restore(flags);
830 if (status != 0)
831 panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
832 "status %lx", status);
834 if (in1 == PAL_CACHE_TYPE_COHERENT) {
835 cpus_setall(current->arch.cache_coherent_map);
836 cpu_clear(processor, current->arch.cache_coherent_map);
837 cpus_setall(cpu_cache_coherent_map);
838 cpu_clear(processor, cpu_cache_coherent_map);
839 }
840 break;
841 case PAL_PERF_MON_INFO:
842 {
843 unsigned long pm_buffer[16];
844 status = ia64_pal_perf_mon_info(
845 pm_buffer,
846 (pal_perf_mon_info_u_t *) &r9);
847 if (status != 0) {
848 printk("PAL_PERF_MON_INFO fails ret=%ld\n", status);
849 break;
850 }
851 if (safe_copy_to_guest(
852 in1, pm_buffer, sizeof(pm_buffer))) {
853 status = PAL_STATUS_EINVAL;
854 goto fail_to_copy;
855 }
856 }
857 break;
858 case PAL_CACHE_INFO:
859 {
860 pal_cache_config_info_t ci;
861 status = ia64_pal_cache_config_info(in1,in2,&ci);
862 if (status != 0)
863 break;
864 r9 = ci.pcci_info_1.pcci1_data;
865 r10 = ci.pcci_info_2.pcci2_data;
866 }
867 break;
868 case PAL_VM_TR_READ: /* FIXME: vcpu_get_tr?? */
869 printk("%s: PAL_VM_TR_READ unimplmented, ignored\n", __func__);
870 break;
871 case PAL_HALT_INFO:
872 {
873 /* 1000 cycles to enter/leave low power state,
874 consumes 10 mW, implemented and cache/TLB coherent. */
875 unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32)
876 | (1UL << 61) | (1UL << 60);
877 if (safe_copy_to_guest (in1, &res, sizeof (res))) {
878 status = PAL_STATUS_EINVAL;
879 goto fail_to_copy;
880 }
881 status = PAL_STATUS_SUCCESS;
882 }
883 break;
884 case PAL_HALT:
885 set_bit(_VPF_down, &current->pause_flags);
886 vcpu_sleep_nosync(current);
887 status = PAL_STATUS_SUCCESS;
888 break;
889 case PAL_HALT_LIGHT:
890 if (VMX_DOMAIN(current)) {
891 /* Called by VTI. */
892 if (!is_unmasked_irq(current)) {
893 do_sched_op_compat(SCHEDOP_block, 0);
894 do_softirq();
895 }
896 status = PAL_STATUS_SUCCESS;
897 }
898 break;
899 case PAL_PLATFORM_ADDR:
900 if (VMX_DOMAIN(current))
901 status = PAL_STATUS_SUCCESS;
902 break;
903 case PAL_FIXED_ADDR:
904 status = PAL_STATUS_SUCCESS;
905 r9 = current->vcpu_id;
906 break;
907 case PAL_PREFETCH_VISIBILITY:
908 status = ia64_pal_prefetch_visibility(in1);
909 if (status == 0) {
910 /* must be performed on all remote processors
911 in the coherence domain. */
912 smp_call_function(remote_pal_prefetch_visibility,
913 (void *)in1, 1, 1);
914 status = 1; /* no more necessary on remote processor */
915 }
916 break;
917 case PAL_MC_DRAIN:
918 status = ia64_pal_mc_drain();
919 /* FIXME: All vcpus likely call PAL_MC_DRAIN.
920 That causes the congestion. */
921 smp_call_function(remote_pal_mc_drain, NULL, 1, 1);
922 break;
923 case PAL_BRAND_INFO:
924 if (in1 == 0) {
925 char brand_info[128];
926 status = ia64_pal_get_brand_info(brand_info);
927 if (status != PAL_STATUS_SUCCESS)
928 break;
929 if (safe_copy_to_guest(in2, brand_info,
930 sizeof(brand_info))) {
931 status = PAL_STATUS_EINVAL;
932 goto fail_to_copy;
933 }
934 } else {
935 status = PAL_STATUS_EINVAL;
936 }
937 break;
938 case PAL_LOGICAL_TO_PHYSICAL:
939 case PAL_GET_PSTATE:
940 case PAL_CACHE_SHARED_INFO:
941 /* Optional, no need to complain about being unimplemented */
942 break;
943 default:
944 printk("%s: Unimplemented PAL Call %lu\n", __func__, index);
945 break;
946 }
947 return ((struct ia64_pal_retval) {status, r9, r10, r11});
949 fail_to_copy:
950 gdprintk(XENLOG_WARNING,
951 "PAL(%ld) fail to copy!!! args 0x%lx 0x%lx 0x%lx\n",
952 index, in1, in2, in3);
953 return ((struct ia64_pal_retval) {status, r9, r10, r11});
954 }
956 // given a current domain (virtual or metaphysical) address, return the virtual address
957 static unsigned long
958 efi_translate_domain_addr(unsigned long domain_addr, IA64FAULT *fault,
959 struct page_info** page)
960 {
961 struct vcpu *v = current;
962 unsigned long mpaddr = domain_addr;
963 unsigned long virt;
964 *fault = IA64_NO_FAULT;
966 again:
967 if (v->domain->arch.sal_data->efi_virt_mode) {
968 *fault = vcpu_tpa(v, domain_addr, &mpaddr);
969 if (*fault != IA64_NO_FAULT) return 0;
970 }
972 virt = (unsigned long)domain_mpa_to_imva(v->domain, mpaddr);
973 *page = virt_to_page(virt);
974 if (get_page(*page, current->domain) == 0) {
975 if (page_get_owner(*page) != current->domain) {
976 // which code is appropriate?
977 *fault = IA64_FAULT;
978 return 0;
979 }
980 goto again;
981 }
983 return virt;
984 }
986 static efi_status_t
987 efi_emulate_get_time(
988 unsigned long tv_addr, unsigned long tc_addr,
989 IA64FAULT *fault)
990 {
991 unsigned long tv, tc = 0;
992 struct page_info *tv_page = NULL;
993 struct page_info *tc_page = NULL;
994 efi_status_t status = 0;
995 efi_time_t *tvp;
996 struct tm timeptr;
997 unsigned long xtimesec;
999 tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
1000 if (*fault != IA64_NO_FAULT)
1001 goto errout;
1002 if (tc_addr) {
1003 tc = efi_translate_domain_addr(tc_addr, fault, &tc_page);
1004 if (*fault != IA64_NO_FAULT)
1005 goto errout;
1008 spin_lock(&efi_time_services_lock);
1009 status = (*efi.get_time)((efi_time_t *) tv, (efi_time_cap_t *) tc);
1010 tvp = (efi_time_t *)tv;
1011 xtimesec = mktime(tvp->year, tvp->month, tvp->day, tvp->hour,
1012 tvp->minute, tvp->second);
1013 xtimesec += current->domain->time_offset_seconds;
1014 timeptr = gmtime(xtimesec);
1015 tvp->second = timeptr.tm_sec;
1016 tvp->minute = timeptr.tm_min;
1017 tvp->hour = timeptr.tm_hour;
1018 tvp->day = timeptr.tm_mday;
1019 tvp->month = timeptr.tm_mon + 1;
1020 tvp->year = timeptr.tm_year + 1900;
1021 spin_unlock(&efi_time_services_lock);
1023 errout:
1024 if (tc_page != NULL)
1025 put_page(tc_page);
1026 if (tv_page != NULL)
1027 put_page(tv_page);
1029 return status;
1032 static efi_status_t
1033 efi_emulate_set_time(
1034 unsigned long tv_addr, IA64FAULT *fault)
1036 unsigned long tv;
1037 struct page_info *tv_page = NULL;
1038 efi_status_t status = 0;
1040 if (current->domain != dom0)
1041 return EFI_UNSUPPORTED;
1043 tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
1044 if (*fault != IA64_NO_FAULT)
1045 goto errout;
1047 spin_lock(&efi_time_services_lock);
1048 status = (*efi.set_time)((efi_time_t *)tv);
1049 spin_unlock(&efi_time_services_lock);
1051 errout:
1052 if (tv_page != NULL)
1053 put_page(tv_page);
1055 return status;
1058 static efi_status_t
1059 efi_emulate_get_wakeup_time(
1060 unsigned long e_addr, unsigned long p_addr,
1061 unsigned long tv_addr, IA64FAULT *fault)
1063 unsigned long enabled, pending, tv;
1064 struct page_info *e_page = NULL, *p_page = NULL,
1065 *tv_page = NULL;
1066 efi_status_t status = 0;
1068 if (current->domain != dom0)
1069 return EFI_UNSUPPORTED;
1071 if (!e_addr || !p_addr || !tv_addr)
1072 return EFI_INVALID_PARAMETER;
1074 enabled = efi_translate_domain_addr(e_addr, fault, &e_page);
1075 if (*fault != IA64_NO_FAULT)
1076 goto errout;
1077 pending = efi_translate_domain_addr(p_addr, fault, &p_page);
1078 if (*fault != IA64_NO_FAULT)
1079 goto errout;
1080 tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
1081 if (*fault != IA64_NO_FAULT)
1082 goto errout;
1084 spin_lock(&efi_time_services_lock);
1085 status = (*efi.get_wakeup_time)((efi_bool_t *)enabled,
1086 (efi_bool_t *)pending,
1087 (efi_time_t *)tv);
1088 spin_unlock(&efi_time_services_lock);
1090 errout:
1091 if (e_page != NULL)
1092 put_page(e_page);
1093 if (p_page != NULL)
1094 put_page(p_page);
1095 if (tv_page != NULL)
1096 put_page(tv_page);
1098 return status;
1101 static efi_status_t
1102 efi_emulate_set_wakeup_time(
1103 unsigned long enabled, unsigned long tv_addr,
1104 IA64FAULT *fault)
1106 unsigned long tv = 0;
1107 struct page_info *tv_page = NULL;
1108 efi_status_t status = 0;
1110 if (current->domain != dom0)
1111 return EFI_UNSUPPORTED;
1113 if (tv_addr) {
1114 tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
1115 if (*fault != IA64_NO_FAULT)
1116 goto errout;
1119 spin_lock(&efi_time_services_lock);
1120 status = (*efi.set_wakeup_time)((efi_bool_t)enabled,
1121 (efi_time_t *)tv);
1122 spin_unlock(&efi_time_services_lock);
1124 errout:
1125 if (tv_page != NULL)
1126 put_page(tv_page);
1128 return status;
1131 static efi_status_t
1132 efi_emulate_get_variable(
1133 unsigned long name_addr, unsigned long vendor_addr,
1134 unsigned long attr_addr, unsigned long data_size_addr,
1135 unsigned long data_addr, IA64FAULT *fault)
1137 unsigned long name, vendor, attr = 0, data_size, data;
1138 struct page_info *name_page = NULL, *vendor_page = NULL,
1139 *attr_page = NULL, *data_size_page = NULL,
1140 *data_page = NULL;
1141 efi_status_t status = 0;
1143 if (current->domain != dom0)
1144 return EFI_UNSUPPORTED;
1146 name = efi_translate_domain_addr(name_addr, fault, &name_page);
1147 if (*fault != IA64_NO_FAULT)
1148 goto errout;
1149 vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
1150 if (*fault != IA64_NO_FAULT)
1151 goto errout;
1152 data_size = efi_translate_domain_addr(data_size_addr, fault,
1153 &data_size_page);
1154 if (*fault != IA64_NO_FAULT)
1155 goto errout;
1156 data = efi_translate_domain_addr(data_addr, fault, &data_page);
1157 if (*fault != IA64_NO_FAULT)
1158 goto errout;
1159 if (attr_addr) {
1160 attr = efi_translate_domain_addr(attr_addr, fault, &attr_page);
1161 if (*fault != IA64_NO_FAULT)
1162 goto errout;
1165 status = (*efi.get_variable)((efi_char16_t *)name,
1166 (efi_guid_t *)vendor,
1167 (u32 *)attr,
1168 (unsigned long *)data_size,
1169 (void *)data);
1171 errout:
1172 if (name_page != NULL)
1173 put_page(name_page);
1174 if (vendor_page != NULL)
1175 put_page(vendor_page);
1176 if (attr_page != NULL)
1177 put_page(attr_page);
1178 if (data_size_page != NULL)
1179 put_page(data_size_page);
1180 if (data_page != NULL)
1181 put_page(data_page);
1183 return status;
1186 static efi_status_t
1187 efi_emulate_get_next_variable(
1188 unsigned long name_size_addr, unsigned long name_addr,
1189 unsigned long vendor_addr, IA64FAULT *fault)
1191 unsigned long name_size, name, vendor;
1192 struct page_info *name_size_page = NULL, *name_page = NULL,
1193 *vendor_page = NULL;
1194 efi_status_t status = 0;
1196 if (current->domain != dom0)
1197 return EFI_UNSUPPORTED;
1199 name_size = efi_translate_domain_addr(name_size_addr, fault,
1200 &name_size_page);
1201 if (*fault != IA64_NO_FAULT)
1202 goto errout;
1203 name = efi_translate_domain_addr(name_addr, fault, &name_page);
1204 if (*fault != IA64_NO_FAULT)
1205 goto errout;
1206 vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
1207 if (*fault != IA64_NO_FAULT)
1208 goto errout;
1210 status = (*efi.get_next_variable)((unsigned long *)name_size,
1211 (efi_char16_t *)name,
1212 (efi_guid_t *)vendor);
1214 errout:
1215 if (name_size_page != NULL)
1216 put_page(name_size_page);
1217 if (name_page != NULL)
1218 put_page(name_page);
1219 if (vendor_page != NULL)
1220 put_page(vendor_page);
1222 return status;
1225 static efi_status_t
1226 efi_emulate_set_variable(
1227 unsigned long name_addr, unsigned long vendor_addr,
1228 unsigned long attr, unsigned long data_size,
1229 unsigned long data_addr, IA64FAULT *fault)
1231 unsigned long name, vendor, data;
1232 struct page_info *name_page = NULL, *vendor_page = NULL,
1233 *data_page = NULL;
1234 efi_status_t status = 0;
1236 if (current->domain != dom0)
1237 return EFI_UNSUPPORTED;
1239 name = efi_translate_domain_addr(name_addr, fault, &name_page);
1240 if (*fault != IA64_NO_FAULT)
1241 goto errout;
1242 vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
1243 if (*fault != IA64_NO_FAULT)
1244 goto errout;
1245 data = efi_translate_domain_addr(data_addr, fault, &data_page);
1246 if (*fault != IA64_NO_FAULT)
1247 goto errout;
1249 status = (*efi.set_variable)((efi_char16_t *)name,
1250 (efi_guid_t *)vendor,
1251 attr,
1252 data_size,
1253 (void *)data);
1255 errout:
1256 if (name_page != NULL)
1257 put_page(name_page);
1258 if (vendor_page != NULL)
1259 put_page(vendor_page);
1260 if (data_page != NULL)
1261 put_page(data_page);
1263 return status;
1266 static efi_status_t
1267 efi_emulate_set_virtual_address_map(
1268 unsigned long memory_map_size, unsigned long descriptor_size,
1269 u32 descriptor_version, efi_memory_desc_t *virtual_map)
1271 void *efi_map_start, *efi_map_end, *p;
1272 efi_memory_desc_t entry, *md = &entry;
1273 u64 efi_desc_size;
1275 unsigned long *vfn;
1276 struct domain *d = current->domain;
1277 efi_runtime_services_t *efi_runtime = d->arch.efi_runtime;
1278 fpswa_interface_t *fpswa_inf = d->arch.fpswa_inf;
1280 if (descriptor_version != EFI_MEMDESC_VERSION) {
1281 printk ("efi_emulate_set_virtual_address_map: memory "
1282 "descriptor version unmatched (%d vs %d)\n",
1283 (int)descriptor_version, EFI_MEMDESC_VERSION);
1284 return EFI_INVALID_PARAMETER;
1287 if (descriptor_size != sizeof(efi_memory_desc_t)) {
1288 printk ("efi_emulate_set_virtual_address_map: memory descriptor size unmatched\n");
1289 return EFI_INVALID_PARAMETER;
1292 if (d->arch.sal_data->efi_virt_mode)
1293 return EFI_UNSUPPORTED;
1295 efi_map_start = virtual_map;
1296 efi_map_end = efi_map_start + memory_map_size;
1297 efi_desc_size = sizeof(efi_memory_desc_t);
1299 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
1300 if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) {
1301 printk ("efi_emulate_set_virtual_address_map: copy_from_user() fault. addr=0x%p\n", p);
1302 return EFI_UNSUPPORTED;
1305 /* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is included in PAL_CODE. */
1306 if (md->type != EFI_PAL_CODE)
1307 continue;
1309 #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \
1310 do { \
1311 vfn = (unsigned long *) domain_mpa_to_imva(d, tgt); \
1312 *vfn++ = FW_HYPERCALL_##call##_INDEX * 16UL + md->virt_addr; \
1313 *vfn++ = 0; \
1314 } while (0)
1316 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_time,EFI_GET_TIME);
1317 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_time,EFI_SET_TIME);
1318 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
1319 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
1320 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
1321 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_variable,EFI_GET_VARIABLE);
1322 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
1323 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_variable,EFI_SET_VARIABLE);
1324 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
1325 EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->reset_system,EFI_RESET_SYSTEM);
1327 vfn = (unsigned long *) domain_mpa_to_imva(d, (unsigned long) fpswa_inf->fpswa);
1328 *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
1329 *vfn = 0;
1330 fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr);
1331 break;
1334 /* The virtual address map has been applied. */
1335 d->arch.sal_data->efi_virt_mode = 1;
1337 return EFI_SUCCESS;
1340 efi_status_t
1341 efi_emulator (struct pt_regs *regs, IA64FAULT *fault)
1343 struct vcpu *v = current;
1344 efi_status_t status;
1346 debugger_event(XEN_IA64_DEBUG_ON_EFI);
1348 *fault = IA64_NO_FAULT;
1350 switch (regs->r2) {
1351 case FW_HYPERCALL_EFI_RESET_SYSTEM:
1353 u8 reason;
1354 unsigned long val = vcpu_get_gr(v,32);
1355 switch (val)
1357 case EFI_RESET_SHUTDOWN:
1358 reason = SHUTDOWN_poweroff;
1359 break;
1360 case EFI_RESET_COLD:
1361 case EFI_RESET_WARM:
1362 default:
1363 reason = SHUTDOWN_reboot;
1364 break;
1366 domain_shutdown (current->domain, reason);
1368 status = EFI_UNSUPPORTED;
1369 break;
1370 case FW_HYPERCALL_EFI_GET_TIME:
1371 status = efi_emulate_get_time (
1372 vcpu_get_gr(v,32),
1373 vcpu_get_gr(v,33),
1374 fault);
1375 break;
1376 case FW_HYPERCALL_EFI_SET_TIME:
1377 status = efi_emulate_set_time (
1378 vcpu_get_gr(v,32),
1379 fault);
1380 break;
1381 case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
1382 status = efi_emulate_get_wakeup_time (
1383 vcpu_get_gr(v,32),
1384 vcpu_get_gr(v,33),
1385 vcpu_get_gr(v,34),
1386 fault);
1387 break;
1388 case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
1389 status = efi_emulate_set_wakeup_time (
1390 vcpu_get_gr(v,32),
1391 vcpu_get_gr(v,33),
1392 fault);
1393 break;
1394 case FW_HYPERCALL_EFI_GET_VARIABLE:
1395 status = efi_emulate_get_variable (
1396 vcpu_get_gr(v,32),
1397 vcpu_get_gr(v,33),
1398 vcpu_get_gr(v,34),
1399 vcpu_get_gr(v,35),
1400 vcpu_get_gr(v,36),
1401 fault);
1402 break;
1403 case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
1404 status = efi_emulate_get_next_variable (
1405 vcpu_get_gr(v,32),
1406 vcpu_get_gr(v,33),
1407 vcpu_get_gr(v,34),
1408 fault);
1409 break;
1410 case FW_HYPERCALL_EFI_SET_VARIABLE:
1411 status = efi_emulate_set_variable (
1412 vcpu_get_gr(v,32),
1413 vcpu_get_gr(v,33),
1414 vcpu_get_gr(v,34),
1415 vcpu_get_gr(v,35),
1416 vcpu_get_gr(v,36),
1417 fault);
1418 break;
1419 case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
1420 status = efi_emulate_set_virtual_address_map (
1421 vcpu_get_gr(v,32),
1422 vcpu_get_gr(v,33),
1423 (u32) vcpu_get_gr(v,34),
1424 (efi_memory_desc_t *) vcpu_get_gr(v,35));
1425 break;
1426 case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
1427 // FIXME: need fixes in efi.h from 2.6.9
1428 status = EFI_UNSUPPORTED;
1429 break;
1430 default:
1431 printk("unknown ia64 fw hypercall %lx\n", regs->r2);
1432 status = EFI_UNSUPPORTED;
1435 return status;
1438 void
1439 do_ssc(unsigned long ssc, struct pt_regs *regs)
1441 unsigned long arg0, arg1, arg2, arg3, retval;
1442 char buf[2];
1443 /**/ static int last_fd, last_count; // FIXME FIXME FIXME
1444 /**/ // BROKEN FOR MULTIPLE DOMAINS & SMP
1445 /**/ struct ssc_disk_stat { int fd; unsigned count;} *stat, last_stat;
1447 arg0 = vcpu_get_gr(current,32);
1448 switch(ssc) {
1449 case SSC_PUTCHAR:
1450 buf[0] = arg0;
1451 buf[1] = '\0';
1452 printk(buf);
1453 break;
1454 case SSC_GETCHAR:
1455 retval = ia64_ssc(0,0,0,0,ssc);
1456 vcpu_set_gr(current,8,retval,0);
1457 break;
1458 case SSC_WAIT_COMPLETION:
1459 if (arg0) { // metaphysical address
1461 arg0 = translate_domain_mpaddr(arg0, NULL);
1462 /**/ stat = (struct ssc_disk_stat *)__va(arg0);
1463 ///**/ if (stat->fd == last_fd) stat->count = last_count;
1464 /**/ stat->count = last_count;
1465 //if (last_count >= PAGE_SIZE) printk("ssc_wait: stat->fd=%d,last_fd=%d,last_count=%d\n",stat->fd,last_fd,last_count);
1466 ///**/ retval = ia64_ssc(arg0,0,0,0,ssc);
1467 /**/ retval = 0;
1469 else retval = -1L;
1470 vcpu_set_gr(current,8,retval,0);
1471 break;
1472 case SSC_OPEN:
1473 arg1 = vcpu_get_gr(current,33); // access rights
1474 if (!running_on_sim) {
1475 printk("SSC_OPEN, not implemented on hardware. (ignoring...)\n");
1476 arg0 = 0;
1478 if (arg0) { // metaphysical address
1479 arg0 = translate_domain_mpaddr(arg0, NULL);
1480 retval = ia64_ssc(arg0,arg1,0,0,ssc);
1482 else retval = -1L;
1483 vcpu_set_gr(current,8,retval,0);
1484 break;
1485 case SSC_WRITE:
1486 case SSC_READ:
1487 //if (ssc == SSC_WRITE) printk("DOING AN SSC_WRITE\n");
1488 arg1 = vcpu_get_gr(current,33);
1489 arg2 = vcpu_get_gr(current,34);
1490 arg3 = vcpu_get_gr(current,35);
1491 if (arg2) { // metaphysical address of descriptor
1492 struct ssc_disk_req *req;
1493 unsigned long mpaddr;
1494 long len;
1496 arg2 = translate_domain_mpaddr(arg2, NULL);
1497 req = (struct ssc_disk_req *) __va(arg2);
1498 req->len &= 0xffffffffL; // avoid strange bug
1499 len = req->len;
1500 /**/ last_fd = arg1;
1501 /**/ last_count = len;
1502 mpaddr = req->addr;
1503 //if (last_count >= PAGE_SIZE) printk("do_ssc: read fd=%d, addr=%p, len=%lx ",last_fd,mpaddr,len);
1504 retval = 0;
1505 if ((mpaddr & PAGE_MASK) != ((mpaddr+len-1) & PAGE_MASK)) {
1506 // do partial page first
1507 req->addr = translate_domain_mpaddr(mpaddr, NULL);
1508 req->len = PAGE_SIZE - (req->addr & ~PAGE_MASK);
1509 len -= req->len; mpaddr += req->len;
1510 retval = ia64_ssc(arg0,arg1,arg2,arg3,ssc);
1511 arg3 += req->len; // file offset
1512 /**/ last_stat.fd = last_fd;
1513 /**/ (void)ia64_ssc(__pa(&last_stat),0,0,0,SSC_WAIT_COMPLETION);
1514 //if (last_count >= PAGE_SIZE) printk("ssc(%p,%lx)[part]=%x ",req->addr,req->len,retval);
1516 if (retval >= 0) while (len > 0) {
1517 req->addr = translate_domain_mpaddr(mpaddr, NULL);
1518 req->len = (len > PAGE_SIZE) ? PAGE_SIZE : len;
1519 len -= PAGE_SIZE; mpaddr += PAGE_SIZE;
1520 retval = ia64_ssc(arg0,arg1,arg2,arg3,ssc);
1521 arg3 += req->len; // file offset
1522 // TEMP REMOVED AGAIN arg3 += req->len; // file offset
1523 /**/ last_stat.fd = last_fd;
1524 /**/ (void)ia64_ssc(__pa(&last_stat),0,0,0,SSC_WAIT_COMPLETION);
1525 //if (last_count >= PAGE_SIZE) printk("ssc(%p,%lx)=%x ",req->addr,req->len,retval);
1527 // set it back to the original value
1528 req->len = last_count;
1530 else retval = -1L;
1531 vcpu_set_gr(current,8,retval,0);
1532 //if (last_count >= PAGE_SIZE) printk("retval=%x\n",retval);
1533 break;
1534 case SSC_CONNECT_INTERRUPT:
1535 arg1 = vcpu_get_gr(current,33);
1536 arg2 = vcpu_get_gr(current,34);
1537 arg3 = vcpu_get_gr(current,35);
1538 if (!running_on_sim) {
1539 printk("SSC_CONNECT_INTERRUPT, not implemented on hardware. (ignoring...)\n");
1540 break;
1542 (void)ia64_ssc(arg0,arg1,arg2,arg3,ssc);
1543 break;
1544 case SSC_NETDEV_PROBE:
1545 vcpu_set_gr(current,8,-1L,0);
1546 break;
1547 default:
1548 panic_domain(regs,
1549 "%s: bad ssc code %lx, iip=0x%lx, b0=0x%lx\n",
1550 __func__, ssc, regs->cr_iip, regs->b0);
1551 break;
1553 vcpu_increment_iip(current);