ia64/xen-unstable

view xen/arch/ia64/xen/dom_fw_common.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 d9c3836e0684
children 13cba2e78a65
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 * Copyright (c) 2006, 2007
7 * Isaku Yamahata <yamahata at valinux co jp>
8 * VA Linux Systems Japan K.K.
9 * dom0 vp model support
10 */
12 #ifdef __XEN__
13 #include <asm/system.h>
14 #include <asm/dom_fw_dom0.h>
15 #include <asm/dom_fw_utils.h>
16 #else
17 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <assert.h>
21 #include <inttypes.h>
23 #include <xen/arch-ia64.h>
24 #include <asm/bundle.h>
26 #include "xg_private.h"
27 #include "xc_dom.h"
28 #include "ia64/xc_dom_ia64_util.h"
30 #define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
31 #endif /* __XEN__ */
33 #include <xen/acpi.h>
34 #include <asm/dom_fw.h>
35 #include <asm/dom_fw_domu.h>
37 void
38 xen_ia64_efi_make_md(efi_memory_desc_t *md,
39 uint32_t type, uint64_t attr,
40 uint64_t start, uint64_t end)
41 {
42 md->type = type;
43 md->pad = 0;
44 md->phys_addr = start;
45 md->virt_addr = 0;
46 md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
47 md->attribute = attr;
48 }
50 #define EFI_HYPERCALL_PATCH(tgt, call) \
51 do { \
52 dom_efi_hypercall_patch(brkimm, \
53 FW_HYPERCALL_##call##_PADDR, \
54 FW_HYPERCALL_##call, hypercalls_imva); \
55 /* Descriptor address. */ \
56 tables->efi_runtime.tgt = \
57 FW_FIELD_MPA(func_ptrs) + 8 * pfn; \
58 /* Descriptor. */ \
59 tables->func_ptrs[pfn++] = FW_HYPERCALL_##call##_PADDR; \
60 tables->func_ptrs[pfn++] = 0; \
61 } while (0)
63 /**************************************************************************
64 Hypercall bundle creation
65 **************************************************************************/
67 static void
68 build_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum, uint64_t ret)
69 {
70 INST64_A5 slot0;
71 INST64_I19 slot1;
72 INST64_B4 slot2;
73 IA64_BUNDLE bundle;
75 // slot1: mov r2 = hypnum (low 20 bits)
76 slot0.inst = 0;
77 slot0.qp = 0; slot0.r1 = 2; slot0.r3 = 0; slot0.major = 0x9;
78 slot0.imm7b = hypnum; slot0.imm9d = hypnum >> 7;
79 slot0.imm5c = hypnum >> 16; slot0.s = 0;
80 // slot1: break brkimm
81 slot1.inst = 0;
82 slot1.qp = 0; slot1.x6 = 0; slot1.x3 = 0; slot1.major = 0x0;
83 slot1.imm20 = brkimm; slot1.i = brkimm >> 20;
84 // if ret slot2: br.ret.sptk.many rp
85 // else slot2: br.cond.sptk.many rp
86 slot2.inst = 0; slot2.qp = 0; slot2.p = 1; slot2.b2 = 0;
87 slot2.wh = 0; slot2.d = 0; slot2.major = 0x0;
88 if (ret) {
89 slot2.btype = 4; slot2.x6 = 0x21;
90 }
91 else {
92 slot2.btype = 0; slot2.x6 = 0x20;
93 }
95 bundle.i64[0] = 0; bundle.i64[1] = 0;
96 bundle.template = 0x11;
97 bundle.slot0 = slot0.inst; bundle.slot2 = slot2.inst;
98 bundle.slot1a = slot1.inst; bundle.slot1b = slot1.inst >> 18;
100 imva[0] = bundle.i64[0]; imva[1] = bundle.i64[1];
101 ia64_fc(imva);
102 ia64_fc(imva + 1);
103 }
105 static void
106 build_pal_hypercall_bundles(uint64_t *imva, uint64_t brkimm, uint64_t hypnum)
107 {
108 extern unsigned long xen_ia64_pal_call_stub[];
109 IA64_BUNDLE bundle;
110 INST64_A5 slot_a5;
111 INST64_M37 slot_m37;
113 /*
114 * The source of the hypercall stub is
115 * the xen_ia64_pal_call_stub function defined in dom_fw_asm.S.
116 */
118 /* Copy the first bundle and patch the hypercall number. */
119 bundle.i64[0] = xen_ia64_pal_call_stub[0];
120 bundle.i64[1] = xen_ia64_pal_call_stub[1];
121 slot_a5.inst = bundle.slot0;
122 slot_a5.imm7b = hypnum;
123 slot_a5.imm9d = hypnum >> 7;
124 slot_a5.imm5c = hypnum >> 16;
125 bundle.slot0 = slot_a5.inst;
126 imva[0] = bundle.i64[0];
127 imva[1] = bundle.i64[1];
128 ia64_fc(imva);
129 ia64_fc(imva + 1);
131 /* Copy the second bundle and patch the hypercall vector. */
132 bundle.i64[0] = xen_ia64_pal_call_stub[2];
133 bundle.i64[1] = xen_ia64_pal_call_stub[3];
134 slot_m37.inst = bundle.slot0;
135 slot_m37.imm20a = brkimm;
136 slot_m37.i = brkimm >> 20;
137 bundle.slot0 = slot_m37.inst;
138 imva[2] = bundle.i64[0];
139 imva[3] = bundle.i64[1];
140 ia64_fc(imva + 2);
141 ia64_fc(imva + 3);
142 }
144 // builds a hypercall bundle at domain physical address
145 static void
146 dom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long imva)
147 {
148 unsigned long *entry_imva, *patch_imva;
149 const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
150 const unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
152 entry_imva = (unsigned long *)(imva + entry_paddr -
153 FW_HYPERCALL_BASE_PADDR);
154 patch_imva = (unsigned long *)(imva + patch_paddr -
155 FW_HYPERCALL_BASE_PADDR);
157 /* Descriptor. */
158 *entry_imva++ = patch_paddr;
159 *entry_imva = 0;
161 build_hypercall_bundle(patch_imva, brkimm, FW_HYPERCALL_FPSWA, 1);
162 }
164 // builds a hypercall bundle at domain physical address
165 static void
166 dom_efi_hypercall_patch(uint64_t brkimm, unsigned long paddr,
167 unsigned long hypercall, unsigned long imva)
168 {
169 build_hypercall_bundle((uint64_t *)(imva + paddr -
170 FW_HYPERCALL_BASE_PADDR),
171 brkimm, hypercall, 1);
172 }
174 // builds a hypercall bundle at domain physical address
175 static void
176 dom_fw_hypercall_patch(uint64_t brkimm, unsigned long paddr,
177 unsigned long hypercall,unsigned long ret,
178 unsigned long imva)
179 {
180 build_hypercall_bundle((uint64_t *)(imva + paddr -
181 FW_HYPERCALL_BASE_PADDR),
182 brkimm, hypercall, ret);
183 }
185 static void
186 dom_fw_pal_hypercall_patch(uint64_t brkimm, unsigned long paddr, unsigned long imva)
187 {
188 build_pal_hypercall_bundles((uint64_t*)(imva + paddr -
189 FW_HYPERCALL_BASE_PADDR),
190 brkimm, FW_HYPERCALL_PAL_CALL);
191 }
193 static inline void
194 print_md(efi_memory_desc_t *md)
195 {
196 uint64_t size;
198 printk(XENLOG_INFO "dom mem: type=%2u, attr=0x%016lx, "
199 "range=[0x%016lx-0x%016lx) ",
200 md->type, md->attribute, md->phys_addr,
201 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
203 size = md->num_pages << EFI_PAGE_SHIFT;
204 if (size > ONE_MB)
205 printk("(%luMB)\n", size >> 20);
206 else
207 printk("(%luKB)\n", size >> 10);
208 }
210 struct fake_acpi_tables {
211 struct acpi20_table_rsdp rsdp;
212 struct xsdt_descriptor_rev2 xsdt;
213 uint64_t madt_ptr;
214 struct fadt_descriptor_rev2 fadt;
215 struct facs_descriptor_rev2 facs;
216 struct acpi_table_header dsdt;
217 uint8_t aml[8 + 11 * MAX_VIRT_CPUS];
218 struct acpi_table_madt madt;
219 struct acpi_table_lsapic lsapic[MAX_VIRT_CPUS];
220 uint8_t pm1a_evt_blk[4];
221 uint8_t pm1a_cnt_blk[1];
222 uint8_t pm_tmr_blk[4];
223 };
224 #define ACPI_TABLE_MPA(field) \
225 FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);
227 /* Create enough of an ACPI structure to make the guest OS ACPI happy. */
228 void
229 dom_fw_fake_acpi(domain_t *d, struct fake_acpi_tables *tables)
230 {
231 struct acpi20_table_rsdp *rsdp = &tables->rsdp;
232 struct xsdt_descriptor_rev2 *xsdt = &tables->xsdt;
233 struct fadt_descriptor_rev2 *fadt = &tables->fadt;
234 struct facs_descriptor_rev2 *facs = &tables->facs;
235 struct acpi_table_header *dsdt = &tables->dsdt;
236 struct acpi_table_madt *madt = &tables->madt;
237 struct acpi_table_lsapic *lsapic = tables->lsapic;
238 int i;
239 int aml_len;
240 int nbr_cpus;
242 BUILD_BUG_ON(sizeof(struct fake_acpi_tables) >
243 (FW_ACPI_END_PADDR - FW_ACPI_BASE_PADDR));
245 memset(tables, 0, sizeof(struct fake_acpi_tables));
247 /* setup XSDT (64bit version of RSDT) */
248 memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
249 /* XSDT points to both the FADT and the MADT, so add one entry */
250 xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(uint64_t);
251 xsdt->revision = 1;
252 memcpy(xsdt->oem_id, "XEN", 3);
253 memcpy(xsdt->oem_table_id, "Xen/ia64", 8);
254 memcpy(xsdt->asl_compiler_id, "XEN", 3);
255 xsdt->asl_compiler_revision = xen_ia64_version(d);
257 xsdt->table_offset_entry[0] = ACPI_TABLE_MPA(fadt);
258 tables->madt_ptr = ACPI_TABLE_MPA(madt);
260 xsdt->checksum = generate_acpi_checksum(xsdt, xsdt->length);
262 /* setup FADT */
263 memcpy(fadt->signature, FADT_SIG, sizeof(fadt->signature));
264 fadt->length = sizeof(struct fadt_descriptor_rev2);
265 fadt->revision = FADT2_REVISION_ID;
266 memcpy(fadt->oem_id, "XEN", 3);
267 memcpy(fadt->oem_table_id, "Xen/ia64", 8);
268 memcpy(fadt->asl_compiler_id, "XEN", 3);
269 fadt->asl_compiler_revision = xen_ia64_version(d);
271 memcpy(facs->signature, FACS_SIG, sizeof(facs->signature));
272 facs->version = 1;
273 facs->length = sizeof(struct facs_descriptor_rev2);
275 fadt->xfirmware_ctrl = ACPI_TABLE_MPA(facs);
276 fadt->Xdsdt = ACPI_TABLE_MPA(dsdt);
278 /*
279 * All of the below FADT entries are filled it to prevent warnings
280 * from sanity checks in the ACPI CA. Emulate required ACPI hardware
281 * registers in system memory.
282 */
283 fadt->pm1_evt_len = 4;
284 fadt->xpm1a_evt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
285 fadt->xpm1a_evt_blk.register_bit_width = 8;
286 fadt->xpm1a_evt_blk.address = ACPI_TABLE_MPA(pm1a_evt_blk);
287 fadt->pm1_cnt_len = 1;
288 fadt->xpm1a_cnt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
289 fadt->xpm1a_cnt_blk.register_bit_width = 8;
290 fadt->xpm1a_cnt_blk.address = ACPI_TABLE_MPA(pm1a_cnt_blk);
291 fadt->pm_tm_len = 4;
292 fadt->xpm_tmr_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
293 fadt->xpm_tmr_blk.register_bit_width = 8;
294 fadt->xpm_tmr_blk.address = ACPI_TABLE_MPA(pm_tmr_blk);
296 fadt->checksum = generate_acpi_checksum(fadt, fadt->length);
298 /* setup RSDP */
299 memcpy(rsdp->signature, RSDP_SIG, strlen(RSDP_SIG));
300 memcpy(rsdp->oem_id, "XEN", 3);
301 rsdp->revision = 2; /* ACPI 2.0 includes XSDT */
302 rsdp->length = sizeof(struct acpi20_table_rsdp);
303 rsdp->xsdt_address = ACPI_TABLE_MPA(xsdt);
305 rsdp->checksum = generate_acpi_checksum(rsdp,
306 ACPI_RSDP_CHECKSUM_LENGTH);
307 rsdp->ext_checksum = generate_acpi_checksum(rsdp, rsdp->length);
309 /* setup DSDT with trivial namespace. */
310 memcpy(dsdt->signature, DSDT_SIG, strlen(DSDT_SIG));
311 dsdt->revision = 1;
312 memcpy(dsdt->oem_id, "XEN", 3);
313 memcpy(dsdt->oem_table_id, "Xen/ia64", 8);
314 memcpy(dsdt->asl_compiler_id, "XEN", 3);
315 dsdt->asl_compiler_revision = xen_ia64_version(d);
317 /* Trivial namespace, avoids ACPI CA complaints */
318 tables->aml[0] = 0x10; /* Scope */
319 tables->aml[1] = 0x40; /* length/offset to next object (patched) */
320 tables->aml[2] = 0x00;
321 memcpy(&tables->aml[3], "_SB_", 4);
323 /* The processor object isn't absolutely necessary, revist for SMP */
324 aml_len = 7;
325 for (i = 0; i < 3; i++) {
326 unsigned char *p = tables->aml + aml_len;
327 p[0] = 0x5b; /* processor object */
328 p[1] = 0x83;
329 p[2] = 0x0b; /* next */
330 p[3] = 'C';
331 p[4] = 'P';
332 snprintf ((char *)p + 5, 3, "%02x", i);
333 if (i < 16)
334 p[5] = 'U';
335 p[7] = i; /* acpi_id */
336 p[8] = 0; /* pblk_addr */
337 p[9] = 0;
338 p[10] = 0;
339 p[11] = 0;
340 p[12] = 0; /* pblk_len */
341 aml_len += 13;
342 }
343 tables->aml[1] = 0x40 + ((aml_len - 1) & 0x0f);
344 tables->aml[2] = (aml_len - 1) >> 4;
345 dsdt->length = sizeof(struct acpi_table_header) + aml_len;
346 dsdt->checksum = generate_acpi_checksum(dsdt, dsdt->length);
348 /* setup MADT */
349 memcpy(madt->header.signature, APIC_SIG, sizeof(madt->header.signature));
350 madt->header.revision = 2;
351 memcpy(madt->header.oem_id, "XEN", 3);
352 memcpy(madt->header.oem_table_id, "Xen/ia64", 8);
353 memcpy(madt->header.asl_compiler_id, "XEN", 3);
354 madt->header.asl_compiler_revision = xen_ia64_version(d);
356 /* An LSAPIC entry describes a CPU. */
357 nbr_cpus = 0;
358 for (i = 0; i < MAX_VIRT_CPUS; i++) {
359 lsapic[i].header.type = ACPI_MADT_LSAPIC;
360 lsapic[i].header.length = sizeof(struct acpi_table_lsapic);
361 lsapic[i].acpi_id = i;
362 lsapic[i].id = i;
363 lsapic[i].eid = 0;
364 if (xen_ia64_is_vcpu_allocated(d, i)) {
365 lsapic[i].flags.enabled = 1;
366 nbr_cpus++;
367 }
368 }
369 madt->header.length = sizeof(struct acpi_table_madt) +
370 nbr_cpus * sizeof(struct acpi_table_lsapic);
371 madt->header.checksum = generate_acpi_checksum(madt,
372 madt->header.length);
373 return;
374 }
376 int
377 efi_mdt_cmp(const void *a, const void *b)
378 {
379 const efi_memory_desc_t *x = a, *y = b;
381 if (x->phys_addr > y->phys_addr)
382 return 1;
383 if (x->phys_addr < y->phys_addr)
384 return -1;
386 /* num_pages == 0 is allowed. */
387 if (x->num_pages > y->num_pages)
388 return 1;
389 if (x->num_pages < y->num_pages)
390 return -1;
392 return 0;
393 }
395 int
396 dom_fw_init(domain_t *d,
397 uint64_t brkimm,
398 struct xen_ia64_boot_param *bp,
399 struct fw_tables *tables,
400 unsigned long hypercalls_imva,
401 unsigned long maxmem)
402 {
403 unsigned long pfn;
404 unsigned char checksum;
405 char *cp;
406 int num_mds, i;
407 int fpswa_supported = 0;
409 /* Caller must zero-clear fw_tables */
411 /* EFI systab. */
412 tables->efi_systab.hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
413 tables->efi_systab.hdr.revision = EFI_SYSTEM_TABLE_REVISION;
414 tables->efi_systab.hdr.headersize = sizeof(tables->efi_systab.hdr);
416 memcpy(tables->fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
417 tables->efi_systab.fw_vendor = FW_FIELD_MPA(fw_vendor);
418 tables->efi_systab.fw_revision = 1;
419 tables->efi_systab.runtime = (void *)FW_FIELD_MPA(efi_runtime);
420 tables->efi_systab.nr_tables = NUM_EFI_SYS_TABLES;
421 tables->efi_systab.tables = FW_FIELD_MPA(efi_tables);
423 /* EFI runtime. */
424 tables->efi_runtime.hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
425 tables->efi_runtime.hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
426 tables->efi_runtime.hdr.headersize = sizeof(tables->efi_runtime.hdr);
428 pfn = 0;
429 EFI_HYPERCALL_PATCH(get_time,EFI_GET_TIME);
430 EFI_HYPERCALL_PATCH(set_time,EFI_SET_TIME);
431 EFI_HYPERCALL_PATCH(get_wakeup_time,EFI_GET_WAKEUP_TIME);
432 EFI_HYPERCALL_PATCH(set_wakeup_time,EFI_SET_WAKEUP_TIME);
433 EFI_HYPERCALL_PATCH(set_virtual_address_map,
434 EFI_SET_VIRTUAL_ADDRESS_MAP);
435 EFI_HYPERCALL_PATCH(get_variable,EFI_GET_VARIABLE);
436 EFI_HYPERCALL_PATCH(get_next_variable,EFI_GET_NEXT_VARIABLE);
437 EFI_HYPERCALL_PATCH(set_variable,EFI_SET_VARIABLE);
438 EFI_HYPERCALL_PATCH(get_next_high_mono_count,
439 EFI_GET_NEXT_HIGH_MONO_COUNT);
440 EFI_HYPERCALL_PATCH(reset_system,EFI_RESET_SYSTEM);
442 /* System tables. */
443 tables->efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
444 tables->efi_tables[0].table = FW_FIELD_MPA(sal_systab);
445 for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
446 tables->efi_tables[i].guid = NULL_GUID;
447 tables->efi_tables[i].table = 0;
448 }
449 if (xen_ia64_is_dom0(d)) {
450 efi_systable_init_dom0(tables);
451 } else {
452 efi_systable_init_domu(tables);
453 }
455 /* fill in the SAL system table: */
456 memcpy(tables->sal_systab.signature, "SST_", 4);
457 tables->sal_systab.size = sizeof(tables->sal_systab);
458 tables->sal_systab.sal_rev_minor = 1;
459 tables->sal_systab.sal_rev_major = 0;
460 tables->sal_systab.entry_count = 2;
462 memcpy((char *)tables->sal_systab.oem_id, "Xen/ia64", 8);
463 memcpy((char *)tables->sal_systab.product_id, "Xen/ia64", 8);
465 /* PAL entry point: */
466 tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
467 tables->sal_ed.pal_proc = FW_HYPERCALL_PAL_CALL_PADDR;
468 dom_fw_pal_hypercall_patch(brkimm, tables->sal_ed.pal_proc,
469 hypercalls_imva);
470 /* SAL entry point. */
471 tables->sal_ed.sal_proc = FW_HYPERCALL_SAL_CALL_PADDR;
472 dom_fw_hypercall_patch(brkimm, tables->sal_ed.sal_proc,
473 FW_HYPERCALL_SAL_CALL, 1, hypercalls_imva);
474 tables->sal_ed.gp = 0; /* will be ignored */
476 /* Fill an AP wakeup descriptor. */
477 tables->sal_wakeup.type = SAL_DESC_AP_WAKEUP;
478 tables->sal_wakeup.mechanism = IA64_SAL_AP_EXTERNAL_INT;
479 tables->sal_wakeup.vector = XEN_SAL_BOOT_RENDEZ_VEC;
481 /* Compute checksum. */
482 checksum = 0;
483 for (cp = (char *)&tables->sal_systab;
484 cp < (char *)&tables->fpswa_inf;
485 ++cp)
486 checksum += *cp;
487 tables->sal_systab.checksum = -checksum;
489 /* SAL return point. */
490 dom_fw_hypercall_patch(brkimm, FW_HYPERCALL_SAL_RETURN_PADDR,
491 FW_HYPERCALL_SAL_RETURN, 0, hypercalls_imva);
493 /* Fill in the FPSWA interface: */
494 if (!xen_ia64_fpswa_revision(d, &tables->fpswa_inf.revision)) {
495 fpswa_supported = 1;
496 dom_fpswa_hypercall_patch(brkimm, hypercalls_imva);
497 tables->fpswa_inf.fpswa =
498 (void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
499 }
501 tables->num_mds = 0;
502 /* hypercall patches live here, masquerade as reserved PAL memory */
503 xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
504 EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
505 FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
506 tables->num_mds++;
508 /* Create dom0/domu md entry for fw and cpi tables area. */
509 xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
510 EFI_ACPI_MEMORY_NVS,
511 EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
512 FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR);
513 tables->num_mds++;
514 xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
515 EFI_RUNTIME_SERVICES_DATA,
516 EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
517 FW_TABLES_BASE_PADDR,
518 tables->fw_tables_end_paddr);
519 tables->num_mds++;
521 if (!xen_ia64_is_dom0(d) || xen_ia64_is_running_on_sim(d)) {
522 /* DomU (or hp-ski).
523 Create a continuous memory area. */
524 /* kludge: bp->efi_memmap is used to pass memmap_info
525 * page's pfn and number of pages to reserve.
526 * Currently the following pages must be reserved.
527 * memmap info page, start info page, xenstore page
528 * and console page.
529 * see ia64_setup_memmap() @ xc_dom_boot.c
530 */
531 num_mds = complete_domu_memmap(d, tables, maxmem,
532 XEN_IA64_MEMMAP_INFO_PFN(bp),
533 XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp));
534 } else {
535 /* Dom0.
536 We must preserve ACPI data from real machine,
537 as well as IO areas. */
538 num_mds = complete_dom0_memmap(d, tables);
539 }
540 if (num_mds < 0)
541 return num_mds;
542 BUG_ON(num_mds != tables->num_mds);
544 /* Display memmap. */
545 for (i = 0 ; i < tables->num_mds; i++)
546 print_md(&tables->efi_memmap[i]);
548 /* Fill boot_param */
549 bp->efi_systab = FW_FIELD_MPA(efi_systab);
550 bp->efi_memmap = FW_FIELD_MPA(efi_memmap);
551 bp->efi_memmap_size = tables->num_mds * sizeof(efi_memory_desc_t);
552 bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
553 bp->efi_memdesc_version = EFI_MEMDESC_VERSION;
554 bp->command_line = 0;
555 bp->console_info.num_cols = 80;
556 bp->console_info.num_rows = 25;
557 bp->console_info.orig_x = 0;
558 bp->console_info.orig_y = 24;
559 if (fpswa_supported)
560 bp->fpswa = FW_FIELD_MPA(fpswa_inf);
561 return 0;
562 }