ia64/xen-unstable

view xen/arch/ia64/dom_fw.c @ 5803:ea8caf38c914

Oops remove debug output from last changeset
author djm@kirby.fc.hp.com
date Wed Jul 13 13:18:04 2005 -0700 (2005-07-13)
parents d4ecbd89d954
children a83ac0806d6b
line source
1 /*
2 * Xen domain firmware emulation support
3 * Copyright (C) 2004 Hewlett-Packard Co.
4 * Dan Magenheimer (dan.magenheimer@hp.com)
5 *
6 */
8 #include <xen/config.h>
9 #include <asm/system.h>
10 #include <asm/pgalloc.h>
12 #include <linux/efi.h>
13 #include <asm/io.h>
14 #include <asm/pal.h>
15 #include <asm/sal.h>
16 #include <xen/acpi.h>
18 #include <asm/dom_fw.h>
20 struct ia64_boot_param *dom_fw_init(struct domain *, char *,int,char *,int);
21 extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
22 extern struct domain *dom0;
23 extern unsigned long dom0_start;
25 extern unsigned long running_on_sim;
28 unsigned long dom_fw_base_mpa = -1;
29 unsigned long imva_fw_base = -1;
31 // return domain (meta)physical address for a given imva
32 // this function is a call-back from dom_fw_init
33 unsigned long dom_pa(unsigned long imva)
34 {
35 if (dom_fw_base_mpa == -1 || imva_fw_base == -1) {
36 printf("dom_pa: uninitialized! (spinning...)\n");
37 while(1);
38 }
39 if (imva - imva_fw_base > PAGE_SIZE) {
40 printf("dom_pa: bad offset! imva=%p, imva_fw_base=%p (spinning...)\n",imva,imva_fw_base);
41 while(1);
42 }
43 return dom_fw_base_mpa + (imva - imva_fw_base);
44 }
46 // builds a hypercall bundle at domain physical address
47 void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall)
48 {
49 unsigned long imva;
51 if (d == dom0) paddr += dom0_start;
52 imva = domain_mpa_to_imva(d,paddr);
53 build_hypercall_bundle(imva,d->arch.breakimm,hypercall,1);
54 }
57 // builds a hypercall bundle at domain physical address
58 void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall,unsigned long ret)
59 {
60 unsigned long imva;
62 if (d == dom0) paddr += dom0_start;
63 imva = domain_mpa_to_imva(d,paddr);
64 build_hypercall_bundle(imva,d->arch.breakimm,hypercall,ret);
65 }
68 // FIXME: This is really a hack: Forcing the boot parameter block
69 // at domain mpaddr 0 page, then grabbing only the low bits of the
70 // Xen imva, which is the offset into the page
71 unsigned long dom_fw_setup(struct domain *d, char *args, int arglen)
72 {
73 struct ia64_boot_param *bp;
75 dom_fw_base_mpa = 0;
76 if (d == dom0) dom_fw_base_mpa += dom0_start;
77 imva_fw_base = domain_mpa_to_imva(d,dom_fw_base_mpa);
78 bp = dom_fw_init(d,args,arglen,imva_fw_base,PAGE_SIZE);
79 return dom_pa((unsigned long)bp);
80 }
83 /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
85 #define MB (1024*1024UL)
87 #define NUM_EFI_SYS_TABLES 6
88 #define PASS_THRU_IOPORT_SPACE
89 #ifdef PASS_THRU_IOPORT_SPACE
90 # define NUM_MEM_DESCS 4
91 #else
92 # define NUM_MEM_DESCS 3
93 #endif
96 #define SECS_PER_HOUR (60 * 60)
97 #define SECS_PER_DAY (SECS_PER_HOUR * 24)
99 /* Compute the `struct tm' representation of *T,
100 offset OFFSET seconds east of UTC,
101 and store year, yday, mon, mday, wday, hour, min, sec into *TP.
102 Return nonzero if successful. */
103 int
104 offtime (unsigned long t, efi_time_t *tp)
105 {
106 const unsigned short int __mon_yday[2][13] =
107 {
108 /* Normal years. */
109 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
110 /* Leap years. */
111 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
112 };
113 long int days, rem, y;
114 const unsigned short int *ip;
116 days = t / SECS_PER_DAY;
117 rem = t % SECS_PER_DAY;
118 while (rem < 0) {
119 rem += SECS_PER_DAY;
120 --days;
121 }
122 while (rem >= SECS_PER_DAY) {
123 rem -= SECS_PER_DAY;
124 ++days;
125 }
126 tp->hour = rem / SECS_PER_HOUR;
127 rem %= SECS_PER_HOUR;
128 tp->minute = rem / 60;
129 tp->second = rem % 60;
130 /* January 1, 1970 was a Thursday. */
131 y = 1970;
133 # define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
134 # define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
135 # define __isleap(year) \
136 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
138 while (days < 0 || days >= (__isleap (y) ? 366 : 365)) {
139 /* Guess a corrected year, assuming 365 days per year. */
140 long int yg = y + days / 365 - (days % 365 < 0);
142 /* Adjust DAYS and Y to match the guessed year. */
143 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)
144 - LEAPS_THRU_END_OF (y - 1));
145 y = yg;
146 }
147 tp->year = y;
148 ip = __mon_yday[__isleap(y)];
149 for (y = 11; days < (long int) ip[y]; --y)
150 continue;
151 days -= ip[y];
152 tp->month = y + 1;
153 tp->day = days + 1;
154 return 1;
155 }
157 extern struct ia64_pal_retval pal_emulator_static (unsigned long);
159 /* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
161 #define BUILD_CMD(addr) ((0x80000000 | (addr)) & ~3)
163 #define REG_OFFSET(addr) (0x00000000000000FF & (addr))
164 #define DEVICE_FUNCTION(addr) (0x000000000000FF00 & (addr))
165 #define BUS_NUMBER(addr) (0x0000000000FF0000 & (addr))
167 #ifndef XEN
168 static efi_status_t
169 fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
170 {
171 #if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
172 struct {
173 int tv_sec; /* must be 32bits to work */
174 int tv_usec;
175 } tv32bits;
177 ssc((unsigned long) &tv32bits, 0, 0, 0, SSC_GET_TOD);
179 memset(tm, 0, sizeof(*tm));
180 offtime(tv32bits.tv_sec, tm);
182 if (tc)
183 memset(tc, 0, sizeof(*tc));
184 #else
185 # error Not implemented yet...
186 #endif
187 return EFI_SUCCESS;
188 }
190 static void
191 efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
192 {
193 #if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
194 ssc(status, 0, 0, 0, SSC_EXIT);
195 #else
196 # error Not implemented yet...
197 #endif
198 }
200 static efi_status_t
201 efi_unimplemented (void)
202 {
203 return EFI_UNSUPPORTED;
204 }
205 #endif /* !XEN */
207 struct sal_ret_values
208 sal_emulator (long index, unsigned long in1, unsigned long in2,
209 unsigned long in3, unsigned long in4, unsigned long in5,
210 unsigned long in6, unsigned long in7)
211 {
212 long r9 = 0;
213 long r10 = 0;
214 long r11 = 0;
215 long status;
217 /*
218 * Don't do a "switch" here since that gives us code that
219 * isn't self-relocatable.
220 */
221 status = 0;
222 if (index == SAL_FREQ_BASE) {
223 if (!running_on_sim)
224 status = ia64_sal_freq_base(in1,&r9,&r10);
225 else switch (in1) {
226 case SAL_FREQ_BASE_PLATFORM:
227 r9 = 200000000;
228 break;
230 case SAL_FREQ_BASE_INTERVAL_TIMER:
231 r9 = 700000000;
232 break;
234 case SAL_FREQ_BASE_REALTIME_CLOCK:
235 r9 = 1;
236 break;
238 default:
239 status = -1;
240 break;
241 }
242 } else if (index == SAL_PCI_CONFIG_READ) {
243 if (current->domain == dom0) {
244 u64 value;
245 // note that args 2&3 are swapped!!
246 status = ia64_sal_pci_config_read(in1,in3,in2,&value);
247 r9 = value;
248 }
249 else printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_READ\n");
250 } else if (index == SAL_PCI_CONFIG_WRITE) {
251 if (current->domain == dom0) {
252 if (((in1 & ~0xffffffffUL) && (in4 == 0)) ||
253 (in4 > 1) ||
254 (in2 > 8) || (in2 & (in2-1)))
255 printf("*** SAL_PCI_CONF_WRITE?!?(adr=%p,typ=%p,sz=%p,val=%p)\n",in1,in4,in2,in3);
256 // note that args are in a different order!!
257 status = ia64_sal_pci_config_write(in1,in4,in2,in3);
258 }
259 else printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_WRITE\n");
260 } else if (index == SAL_SET_VECTORS) {
261 printf("*** CALLED SAL_SET_VECTORS. IGNORED...\n");
262 } else if (index == SAL_GET_STATE_INFO) {
263 printf("*** CALLED SAL_GET_STATE_INFO. IGNORED...\n");
264 } else if (index == SAL_GET_STATE_INFO_SIZE) {
265 printf("*** CALLED SAL_GET_STATE_INFO_SIZE. IGNORED...\n");
266 } else if (index == SAL_CLEAR_STATE_INFO) {
267 printf("*** CALLED SAL_CLEAR_STATE_INFO. IGNORED...\n");
268 } else if (index == SAL_MC_RENDEZ) {
269 printf("*** CALLED SAL_MC_RENDEZ. IGNORED...\n");
270 } else if (index == SAL_MC_SET_PARAMS) {
271 printf("*** CALLED SAL_MC_SET_PARAMS. IGNORED...\n");
272 } else if (index == SAL_CACHE_FLUSH) {
273 printf("*** CALLED SAL_CACHE_FLUSH. IGNORED...\n");
274 } else if (index == SAL_CACHE_INIT) {
275 printf("*** CALLED SAL_CACHE_INIT. IGNORED...\n");
276 } else if (index == SAL_UPDATE_PAL) {
277 printf("*** CALLED SAL_UPDATE_PAL. IGNORED...\n");
278 } else {
279 printf("*** CALLED SAL_ WITH UNKNOWN INDEX. IGNORED...\n");
280 status = -1;
281 }
282 return ((struct sal_ret_values) {status, r9, r10, r11});
283 }
285 struct ia64_pal_retval
286 xen_pal_emulator(unsigned long index, unsigned long in1,
287 unsigned long in2, unsigned long in3)
288 {
289 long r9 = 0;
290 long r10 = 0;
291 long r11 = 0;
292 long status = -1;
294 if (running_on_sim) return pal_emulator_static(index);
295 if (index >= PAL_COPY_PAL) {
296 printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
297 index);
298 }
299 else switch (index) {
300 case PAL_MEM_ATTRIB:
301 status = ia64_pal_mem_attrib(&r9);
302 break;
303 case PAL_FREQ_BASE:
304 status = ia64_pal_freq_base(&r9);
305 break;
306 case PAL_PROC_GET_FEATURES:
307 status = ia64_pal_proc_get_features(&r9,&r10,&r11);
308 break;
309 case PAL_BUS_GET_FEATURES:
310 status = ia64_pal_bus_get_features(&r9,&r10,&r11);
311 break;
312 case PAL_FREQ_RATIOS:
313 status = ia64_pal_freq_ratios(&r9,&r10,&r11);
314 break;
315 case PAL_PTCE_INFO:
316 {
317 ia64_ptce_info_t ptce;
318 status = ia64_get_ptce(&ptce);
319 if (status != 0) break;
320 r9 = ptce.base;
321 r10 = (ptce.count[0]<<32)|(ptce.count[1]&0xffffffffL);
322 r11 = (ptce.stride[0]<<32)|(ptce.stride[1]&0xffffffffL);
323 }
324 break;
325 case PAL_VERSION:
326 status = ia64_pal_version(&r9,&r10);
327 break;
328 case PAL_VM_PAGE_SIZE:
329 status = ia64_pal_vm_page_size(&r9,&r10);
330 break;
331 case PAL_DEBUG_INFO:
332 status = ia64_pal_debug_info(&r9,&r10);
333 break;
334 case PAL_CACHE_SUMMARY:
335 status = ia64_pal_cache_summary(&r9,&r10);
336 break;
337 case PAL_VM_SUMMARY:
338 status = ia64_pal_vm_summary(&r9,&r10);
339 break;
340 case PAL_RSE_INFO:
341 status = ia64_pal_rse_info(&r9,&r10);
342 break;
343 case PAL_VM_INFO:
344 status = ia64_pal_vm_info(in1,in2,&r9,&r10);
345 break;
346 case PAL_REGISTER_INFO:
347 status = ia64_pal_register_info(in1,&r9,&r10);
348 break;
349 case PAL_CACHE_FLUSH:
350 /* FIXME */
351 printk("PAL_CACHE_FLUSH NOT IMPLEMENTED!\n");
352 BUG();
353 break;
354 case PAL_PERF_MON_INFO:
355 {
356 unsigned long pm_buffer[16];
357 int i;
358 status = ia64_pal_perf_mon_info(pm_buffer,&r9);
359 if (status != 0) {
360 while(1)
361 printk("PAL_PERF_MON_INFO fails ret=%d\n",status);
362 break;
363 }
364 if (copy_to_user((void __user *)in1,pm_buffer,128)) {
365 while(1)
366 printk("xen_pal_emulator: PAL_PERF_MON_INFO "
367 "can't copy to user!!!!\n");
368 status = -1;
369 break;
370 }
371 }
372 break;
373 case PAL_CACHE_INFO:
374 {
375 pal_cache_config_info_t ci;
376 status = ia64_pal_cache_config_info(in1,in2,&ci);
377 if (status != 0) break;
378 r9 = ci.pcci_info_1.pcci1_data;
379 r10 = ci.pcci_info_2.pcci2_data;
380 }
381 break;
382 case PAL_VM_TR_READ: /* FIXME: vcpu_get_tr?? */
383 printk("PAL_VM_TR_READ NOT IMPLEMENTED, IGNORED!\n");
384 break;
385 case PAL_HALT_INFO: /* inappropriate info for guest? */
386 printk("PAL_HALT_INFO NOT IMPLEMENTED, IGNORED!\n");
387 break;
388 default:
389 printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
390 index);
391 break;
392 }
393 return ((struct ia64_pal_retval) {status, r9, r10, r11});
394 }
396 #define NFUNCPTRS 20
398 void print_md(efi_memory_desc_t *md)
399 {
400 #if 1
401 printk("domain mem: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
402 md->type, md->attribute, md->phys_addr,
403 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
404 md->num_pages >> (20 - EFI_PAGE_SHIFT));
405 #endif
406 }
408 #define LSAPIC_NUM 16 // TEMP
409 static u32 lsapic_flag=1;
411 /* Provide only one LP to guest */
412 static int
413 acpi_update_lsapic (acpi_table_entry_header *header)
414 {
415 struct acpi_table_lsapic *lsapic;
417 lsapic = (struct acpi_table_lsapic *) header;
418 if (!lsapic)
419 return -EINVAL;
421 if (lsapic->flags.enabled && lsapic_flag) {
422 printk("enable lsapic entry: 0x%lx\n", (u64)lsapic);
423 lsapic_flag = 0; /* disable all the following processros */
424 } else if (lsapic->flags.enabled) {
425 printk("DISABLE lsapic entry: 0x%lx\n", (u64)lsapic);
426 lsapic->flags.enabled = 0;
427 } else
428 printk("lsapic entry is already disabled: 0x%lx\n", (u64)lsapic);
430 return 0;
431 }
433 static int
434 acpi_update_madt_checksum (unsigned long phys_addr, unsigned long size)
435 {
436 u8 checksum=0;
437 u8* ptr;
438 int len;
439 struct acpi_table_madt* acpi_madt;
441 if (!phys_addr || !size)
442 return -EINVAL;
444 acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
445 acpi_madt->header.checksum=0;
447 /* re-calculate MADT checksum */
448 ptr = (u8*)acpi_madt;
449 len = acpi_madt->header.length;
450 while (len>0){
451 checksum = (u8)( checksum + (*ptr++) );
452 len--;
453 }
454 acpi_madt->header.checksum = 0x0 - checksum;
456 return 0;
457 }
459 /* base is physical address of acpi table */
460 void touch_acpi_table(void)
461 {
462 u64 count = 0;
463 count = acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, NR_CPUS);
464 if ( count < 1)
465 printk("Error parsing MADT - no LAPIC entires\n");
466 printk("Total %d lsapic entry\n", count);
467 acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
469 return;
470 }
473 struct ia64_boot_param *
474 dom_fw_init (struct domain *d, char *args, int arglen, char *fw_mem, int fw_mem_size)
475 {
476 efi_system_table_t *efi_systab;
477 efi_runtime_services_t *efi_runtime;
478 efi_config_table_t *efi_tables;
479 struct ia64_sal_systab *sal_systab;
480 efi_memory_desc_t *efi_memmap, *md;
481 unsigned long *pal_desc, *sal_desc;
482 struct ia64_sal_desc_entry_point *sal_ed;
483 struct ia64_boot_param *bp;
484 unsigned long *pfn;
485 unsigned char checksum = 0;
486 char *cp, *cmd_line, *fw_vendor;
487 int i = 0;
488 unsigned long maxmem = d->max_pages * PAGE_SIZE;
489 unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
491 # define MAKE_MD(typ, attr, start, end, abs) \
492 do { \
493 md = efi_memmap + i++; \
494 md->type = typ; \
495 md->pad = 0; \
496 md->phys_addr = abs ? start : start_mpaddr + start; \
497 md->virt_addr = 0; \
498 md->num_pages = (end - start) >> 12; \
499 md->attribute = attr; \
500 print_md(md); \
501 } while (0)
503 /* FIXME: should check size but for now we have a whole MB to play with.
504 And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
505 if (fw_mem_size < sizeof(fw_mem_proto)) {
506 printf("sys_fw_init: insufficient space for fw_mem\n");
507 return 0;
508 }
509 */
510 memset(fw_mem, 0, fw_mem_size);
512 #ifdef XEN
513 #else
514 pal_desc = (unsigned long *) &pal_emulator_static;
515 sal_desc = (unsigned long *) &sal_emulator;
516 #endif
518 cp = fw_mem;
519 efi_systab = (void *) cp; cp += sizeof(*efi_systab);
520 efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
521 efi_tables = (void *) cp; cp += NUM_EFI_SYS_TABLES * sizeof(*efi_tables);
522 sal_systab = (void *) cp; cp += sizeof(*sal_systab);
523 sal_ed = (void *) cp; cp += sizeof(*sal_ed);
524 efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
525 bp = (void *) cp; cp += sizeof(*bp);
526 pfn = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
527 cmd_line = (void *) cp;
529 if (args) {
530 if (arglen >= 1024)
531 arglen = 1023;
532 memcpy(cmd_line, args, arglen);
533 } else {
534 arglen = 0;
535 }
536 cmd_line[arglen] = '\0';
538 memset(efi_systab, 0, sizeof(efi_systab));
539 efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
540 efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
541 efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
542 cp = fw_vendor = &cmd_line[arglen] + (2-(arglen&1)); // round to 16-bit boundary
543 #define FW_VENDOR "X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
544 cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 64-bit boundary
546 memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
547 efi_systab->fw_vendor = dom_pa(fw_vendor);
549 efi_systab->fw_revision = 1;
550 efi_systab->runtime = (void *) dom_pa(efi_runtime);
551 efi_systab->nr_tables = NUM_EFI_SYS_TABLES;
552 efi_systab->tables = dom_pa(efi_tables);
554 efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
555 efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
556 efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
557 #define EFI_HYPERCALL_PATCH(tgt,call) do { \
558 dom_efi_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call); \
559 tgt = dom_pa(pfn); \
560 *pfn++ = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
561 *pfn++ = 0; \
562 } while (0)
564 EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
565 EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
566 EFI_HYPERCALL_PATCH(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
567 EFI_HYPERCALL_PATCH(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
568 EFI_HYPERCALL_PATCH(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
569 EFI_HYPERCALL_PATCH(efi_runtime->get_variable,EFI_GET_VARIABLE);
570 EFI_HYPERCALL_PATCH(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
571 EFI_HYPERCALL_PATCH(efi_runtime->set_variable,EFI_SET_VARIABLE);
572 EFI_HYPERCALL_PATCH(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
573 EFI_HYPERCALL_PATCH(efi_runtime->reset_system,EFI_RESET_SYSTEM);
575 efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
576 efi_tables[0].table = dom_pa(sal_systab);
577 for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
578 efi_tables[i].guid = NULL_GUID;
579 efi_tables[i].table = 0;
580 }
581 if (d == dom0) {
582 printf("Domain0 EFI passthrough:");
583 i = 1;
584 if (efi.mps) {
585 efi_tables[i].guid = MPS_TABLE_GUID;
586 efi_tables[i].table = __pa(efi.mps);
587 printf(" MPS=%0xlx",efi_tables[i].table);
588 i++;
589 }
591 touch_acpi_table();
593 if (efi.acpi20) {
594 efi_tables[i].guid = ACPI_20_TABLE_GUID;
595 efi_tables[i].table = __pa(efi.acpi20);
596 printf(" ACPI 2.0=%0xlx",efi_tables[i].table);
597 i++;
598 }
599 if (efi.acpi) {
600 efi_tables[i].guid = ACPI_TABLE_GUID;
601 efi_tables[i].table = __pa(efi.acpi);
602 printf(" ACPI=%0xlx",efi_tables[i].table);
603 i++;
604 }
605 if (efi.smbios) {
606 efi_tables[i].guid = SMBIOS_TABLE_GUID;
607 efi_tables[i].table = __pa(efi.smbios);
608 printf(" SMBIOS=%0xlx",efi_tables[i].table);
609 i++;
610 }
611 if (efi.hcdp) {
612 efi_tables[i].guid = HCDP_TABLE_GUID;
613 efi_tables[i].table = __pa(efi.hcdp);
614 printf(" HCDP=%0xlx",efi_tables[i].table);
615 i++;
616 }
617 printf("\n");
618 }
620 /* fill in the SAL system table: */
621 memcpy(sal_systab->signature, "SST_", 4);
622 sal_systab->size = sizeof(*sal_systab);
623 sal_systab->sal_rev_minor = 1;
624 sal_systab->sal_rev_major = 0;
625 sal_systab->entry_count = 1;
627 strcpy(sal_systab->oem_id, "Xen/ia64");
628 strcpy(sal_systab->product_id, "Xen/ia64");
630 /* fill in an entry point: */
631 sal_ed->type = SAL_DESC_ENTRY_POINT;
632 #define FW_HYPERCALL_PATCH(tgt,call,ret) do { \
633 dom_fw_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call,ret); \
634 tgt = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
635 } while (0)
636 FW_HYPERCALL_PATCH(sal_ed->pal_proc,PAL_CALL,0);
637 FW_HYPERCALL_PATCH(sal_ed->sal_proc,SAL_CALL,1);
638 sal_ed->gp = 0; // will be ignored
640 for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
641 checksum += *cp;
643 sal_systab->checksum = -checksum;
645 /* simulate 1MB free memory at physical address zero */
646 i = 0;
647 MAKE_MD(EFI_BOOT_SERVICES_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);
648 /* hypercall patches live here, masquerade as reserved PAL memory */
649 MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB,HYPERCALL_START,HYPERCALL_END, 0);
650 MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 0);
651 #ifdef PASS_THRU_IOPORT_SPACE
652 if (d == dom0 && !running_on_sim) {
653 /* pass through the I/O port space */
654 efi_memory_desc_t *efi_get_io_md(void);
655 efi_memory_desc_t *ia64_efi_io_md = efi_get_io_md();
656 u32 type;
657 u64 iostart, ioend, ioattr;
659 type = ia64_efi_io_md->type;
660 iostart = ia64_efi_io_md->phys_addr;
661 ioend = ia64_efi_io_md->phys_addr +
662 (ia64_efi_io_md->num_pages << 12);
663 ioattr = ia64_efi_io_md->attribute;
664 MAKE_MD(type,ioattr,iostart,ioend, 1);
665 }
666 else
667 MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
668 #endif
670 bp->efi_systab = dom_pa(fw_mem);
671 bp->efi_memmap = dom_pa(efi_memmap);
672 bp->efi_memmap_size = NUM_MEM_DESCS*sizeof(efi_memory_desc_t);
673 bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
674 bp->efi_memdesc_version = 1;
675 bp->command_line = dom_pa(cmd_line);
676 bp->console_info.num_cols = 80;
677 bp->console_info.num_rows = 25;
678 bp->console_info.orig_x = 0;
679 bp->console_info.orig_y = 24;
680 bp->fpswa = 0;
682 return bp;
683 }