debuggers.hg

view xen/arch/ia64/xen/xensetup.c @ 22798:ff97273750b8

cpu hotplug: Core functions are quiet on failure.

This was already inconsistent, so make them consistently quiet and
leave it to callers to log an error. Add suitable error logging to the
arch-specific CPU bringup loops,

In particular this avoids printing error on EBUSY, in which case
caller may want a silent retry loop.

Signed-off-by: Keir Fraser <keir@xen.org>
author Keir Fraser <keir@xen.org>
date Fri Jan 14 09:52:02 2011 +0000 (2011-01-14)
parents e8acb9753ff1
children
line source
1 /******************************************************************************
2 * xensetup.c
3 * Copyright (c) 2004-2005 Hewlett-Packard Co
4 * Dan Magenheimer <dan.magenheimer@hp.com>
5 */
7 #include <xen/config.h>
8 #include <xen/lib.h>
9 #include <xen/errno.h>
10 #include <xen/multiboot.h>
11 #include <xen/sched.h>
12 #include <xen/mm.h>
13 #include <public/version.h>
14 #include <xen/gdbstub.h>
15 #include <xen/version.h>
16 #include <xen/console.h>
17 #include <xen/domain.h>
18 #include <xen/serial.h>
19 #include <xen/trace.h>
20 #include <xen/keyhandler.h>
21 #include <xen/vga.h>
22 #include <asm/meminit.h>
23 #include <asm/page.h>
24 #include <asm/setup.h>
25 #include <asm/vhpt.h>
26 #include <xen/string.h>
27 #include <asm/vmx.h>
28 #include <linux/efi.h>
29 #include <asm/iosapic.h>
30 #include <xen/softirq.h>
31 #include <xen/rcupdate.h>
32 #include <xsm/acm/acm_hooks.h>
33 #include <asm/sn/simulator.h>
34 #include <asm/sal.h>
35 #include <xen/cpu.h>
37 unsigned long total_pages;
39 char saved_command_line[COMMAND_LINE_SIZE];
40 char __initdata dom0_command_line[COMMAND_LINE_SIZE];
42 cpumask_t cpu_present_map;
44 extern unsigned long domain0_ready;
46 int find_max_pfn (unsigned long, unsigned long, void *);
48 /* FIXME: which header these declarations should be there ? */
49 extern void early_setup_arch(char **);
50 extern void late_setup_arch(char **);
51 extern void hpsim_serial_init(void);
52 extern void setup_per_cpu_areas(void);
53 extern void mem_init(void);
54 extern void init_IRQ(void);
55 extern void trap_init(void);
56 extern void xen_patch_kernel(void);
58 /* nosmp: ignore secondary processors */
59 static bool_t __initdata opt_nosmp;
60 boolean_param("nosmp", opt_nosmp);
62 /* maxcpus: maximum number of CPUs to activate */
63 static unsigned int __initdata max_cpus = NR_CPUS;
64 integer_param("maxcpus", max_cpus);
66 /* xencons: toggle xenconsole input (and irq).
67 Note: you have to disable 8250 serials in domains (to avoid use of the
68 same resource). */
69 static int __initdata opt_xencons = 1;
70 integer_param("xencons", opt_xencons);
72 /* xencons_poll: toggle non-legacy xencons UARTs to run in polling mode */
73 static bool_t __initdata opt_xencons_poll;
74 boolean_param("xencons_poll", opt_xencons_poll);
76 #define XENHEAP_DEFAULT_SIZE KERNEL_TR_PAGE_SIZE
77 #define XENHEAP_SIZE_MIN (16 * 1024 * 1024) /* 16MBytes */
78 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
79 unsigned long xen_pstart;
81 static int __init
82 xen_count_pages(u64 start, u64 end, void *arg)
83 {
84 unsigned long *count = arg;
86 /* FIXME: do we need consider difference between DMA-usable memory and
87 * normal memory? Seems that HV has no requirement to operate DMA which
88 * is owned by Dom0? */
89 *count += (end - start) >> PAGE_SHIFT;
90 return 0;
91 }
93 /*
94 * IPF loader only supports one command line currently, for
95 * both xen and guest kernel. This function provides pre-parse
96 * to mixed command line, to split it into two parts.
97 *
98 * User should split the parameters by "--", with strings after
99 * spliter for guest kernel. Missing "--" means whole line belongs
100 * to guest. Example:
101 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
102 * root=/dev/sda3 ro"
103 */
104 static char null[4] = { 0 };
106 void __init early_cmdline_parse(char **cmdline_p)
107 {
108 char *guest_cmd;
109 static const char * const split = "--";
111 if (*cmdline_p == NULL) {
112 *cmdline_p = &null[0];
113 saved_command_line[0] = '\0';
114 dom0_command_line[0] = '\0';
115 return;
116 }
118 guest_cmd = strstr(*cmdline_p, split);
119 /* If no spliter, whole line is for guest */
120 if (guest_cmd == NULL) {
121 guest_cmd = *cmdline_p;
122 *cmdline_p = &null[0];
123 } else {
124 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
125 guest_cmd += strlen(split);
126 while (*guest_cmd == ' ') guest_cmd++;
127 }
129 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
130 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
131 return;
132 }
134 struct ns16550_defaults ns16550_com1 = {
135 .data_bits = 8,
136 .parity = 'n',
137 .stop_bits = 1
138 };
140 unsigned int ns16550_com1_gsi;
141 unsigned int ns16550_com1_polarity;
142 unsigned int ns16550_com1_trigger;
144 struct ns16550_defaults ns16550_com2 = {
145 .data_bits = 8,
146 .parity = 'n',
147 .stop_bits = 1
148 };
150 /* efi_print: print efi table at boot */
151 static bool_t __initdata opt_efi_print;
152 boolean_param("efi_print", opt_efi_print);
154 /* print EFI memory map: */
155 static void __init
156 efi_print(void)
157 {
158 void *efi_map_start, *efi_map_end;
159 u64 efi_desc_size;
161 efi_memory_desc_t *md;
162 void *p;
163 int i;
165 if (!opt_efi_print)
166 return;
168 efi_map_start = __va(ia64_boot_param->efi_memmap);
169 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
170 efi_desc_size = ia64_boot_param->efi_memdesc_size;
172 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
173 md = p;
174 printk("mem%02u: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) "
175 "(%luMB)\n", i, md->type, md->attribute, md->phys_addr,
176 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
177 md->num_pages >> (20 - EFI_PAGE_SHIFT));
178 }
179 }
181 /*
182 * These functions are utility functions for getting and
183 * testing memory descriptors for allocating the xenheap area.
184 */
185 static efi_memory_desc_t * __init
186 efi_get_md (unsigned long phys_addr)
187 {
188 void *efi_map_start, *efi_map_end, *p;
189 efi_memory_desc_t *md;
190 u64 efi_desc_size;
192 efi_map_start = __va(ia64_boot_param->efi_memmap);
193 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
194 efi_desc_size = ia64_boot_param->efi_memdesc_size;
196 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
197 md = p;
198 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
199 return md;
200 }
201 return 0;
202 }
204 static int __init
205 is_xenheap_usable_memory(efi_memory_desc_t *md)
206 {
207 if (!(md->attribute & EFI_MEMORY_WB))
208 return 0;
210 switch (md->type) {
211 case EFI_LOADER_CODE:
212 case EFI_LOADER_DATA:
213 case EFI_BOOT_SERVICES_CODE:
214 case EFI_BOOT_SERVICES_DATA:
215 case EFI_CONVENTIONAL_MEMORY:
216 return 1;
217 }
218 return 0;
219 }
221 static inline int __init
222 md_overlaps(const efi_memory_desc_t *md, unsigned long phys_addr)
223 {
224 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
225 }
227 static inline int __init
228 md_overlap_with_boot_param(const efi_memory_desc_t *md)
229 {
230 return md_overlaps(md, __pa(ia64_boot_param)) ||
231 md_overlaps(md, ia64_boot_param->efi_memmap) ||
232 md_overlaps(md, ia64_boot_param->command_line);
233 }
235 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
236 #define MD_END(md) ((md)->phys_addr + MD_SIZE(md))
238 static unsigned long __init
239 efi_get_max_addr (void)
240 {
241 void *efi_map_start, *efi_map_end, *p;
242 efi_memory_desc_t *md;
243 u64 efi_desc_size;
244 unsigned long max_addr = 0;
246 efi_map_start = __va(ia64_boot_param->efi_memmap);
247 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
248 efi_desc_size = ia64_boot_param->efi_memdesc_size;
250 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
251 md = p;
252 if (is_xenheap_usable_memory(md) && MD_END(md) > max_addr)
253 max_addr = MD_END(md);
254 }
255 return max_addr;
256 }
258 extern char __init_begin[], __init_end[];
259 static void noinline init_done(void)
260 {
261 memset(__init_begin, 0, __init_end - __init_begin);
262 flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
263 init_xenheap_pages(__pa(__init_begin), __pa(__init_end));
264 printk("Freed %ldkB init memory.\n",
265 (long)(__init_end-__init_begin)>>10);
267 startup_cpu_idle_loop();
268 }
270 struct xen_heap_desc {
271 void* xen_heap_start;
272 unsigned long xenheap_phys_end;
273 efi_memory_desc_t* kern_md;
274 };
276 static int __init
277 init_xenheap_mds(unsigned long start, unsigned long end, void *arg)
278 {
279 struct xen_heap_desc *desc = (struct xen_heap_desc*)arg;
280 unsigned long md_end = __pa(desc->xen_heap_start);
281 efi_memory_desc_t* md;
283 start = __pa(start);
284 end = __pa(end);
286 for (md = efi_get_md(md_end);
287 md != NULL && md->phys_addr < desc->xenheap_phys_end;
288 md = efi_get_md(md_end)) {
289 md_end = MD_END(md);
291 if (md == desc->kern_md ||
292 (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) ||
293 ((md->attribute & EFI_MEMORY_WB) &&
294 is_xenheap_usable_memory(md))) {
295 unsigned long s = max(start, max(__pa(desc->xen_heap_start),
296 md->phys_addr));
297 unsigned long e = min(end, min(md_end, desc->xenheap_phys_end));
298 init_boot_pages(s, e);
299 }
300 }
302 return 0;
303 }
305 int running_on_sim;
307 static int __init
308 is_platform_hp_ski(void)
309 {
310 int i;
311 long cpuid[6];
313 for (i = 0; i < 5; ++i)
314 cpuid[i] = ia64_get_cpuid(i);
316 if ((cpuid[0] & 0xff) != 'H')
317 return 0;
318 if ((cpuid[3] & 0xff) != 0x4)
319 return 0;
320 if (((cpuid[3] >> 8) & 0xff) != 0x0)
321 return 0;
322 if (((cpuid[3] >> 16) & 0xff) != 0x0)
323 return 0;
324 if (((cpuid[3] >> 24) & 0x7) != 0x7)
325 return 0;
327 return 1;
328 }
330 #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
331 static int __initdata dom0_vhpt_size_log2;
332 integer_param("dom0_vhpt_size_log2", dom0_vhpt_size_log2);
333 #endif
334 unsigned long xen_fixed_mfn_start __read_mostly;
335 unsigned long xen_fixed_mfn_end __read_mostly;
337 void __init start_kernel(void)
338 {
339 char *cmdline;
340 unsigned long nr_pages;
341 unsigned long dom0_memory_start, dom0_memory_size;
342 unsigned long dom0_initrd_start, dom0_initrd_size;
343 unsigned long md_end, relo_start, relo_end, relo_size = 0;
344 struct vcpu *dom0_vcpu0;
345 efi_memory_desc_t *kern_md, *last_md, *md;
346 unsigned long xenheap_phys_end;
347 void *xen_heap_start;
348 struct xen_heap_desc heap_desc;
349 #ifdef CONFIG_SMP
350 int i;
351 #endif
353 /* Be sure the struct shared_info size is <= XSI_SIZE. */
354 BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
356 /* Kernel may be relocated by EFI loader */
357 xen_pstart = ia64_tpa(KERNEL_START);
359 running_on_sim = is_platform_hp_ski();
361 early_setup_arch(&cmdline);
363 /* We initialise the serial devices very early so we can get debugging. */
364 if (running_on_sim)
365 hpsim_serial_init();
366 else {
367 ns16550_init(0, &ns16550_com1);
368 ns16550_init(1, &ns16550_com2);
369 }
371 #ifdef CONFIG_VGA
372 /* Plug in a default VGA mode */
373 vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
374 vga_console_info.u.text_mode_3.font_height = 16; /* generic VGA? */
375 vga_console_info.u.text_mode_3.cursor_x =
376 ia64_boot_param->console_info.orig_x;
377 vga_console_info.u.text_mode_3.cursor_y =
378 ia64_boot_param->console_info.orig_y;
379 vga_console_info.u.text_mode_3.rows =
380 ia64_boot_param->console_info.num_rows;
381 vga_console_info.u.text_mode_3.columns =
382 ia64_boot_param->console_info.num_cols;
383 #endif
385 console_init_preirq();
387 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
388 ia64_boot_param->domain_size == 0) {
389 /* This is possible only with the old elilo, which does not support
390 a vmm. Fix now, and continue without initrd. */
391 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
392 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
393 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
394 ia64_boot_param->initrd_start = 0;
395 ia64_boot_param->initrd_size = 0;
396 }
398 printk("Xen command line: %s\n", saved_command_line);
400 /*
401 * Test if the boot allocator bitmap will overflow xenheap_size. If
402 * so, continue to bump it up until we have at least a minimum space
403 * for the actual xenheap.
404 */
405 max_page = efi_get_max_addr() >> PAGE_SHIFT;
406 while ((max_page >> 3) > xenheap_size - XENHEAP_SIZE_MIN)
407 xenheap_size <<= 1;
409 xenheap_phys_end = xen_pstart + xenheap_size;
410 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
411 xen_pstart, xenheap_phys_end);
413 xen_patch_kernel();
415 kern_md = md = efi_get_md(xen_pstart);
416 md_end = __pa(ia64_imva(&_end));
417 relo_start = xenheap_phys_end;
419 /*
420 * Scan through the memory descriptors after the kernel
421 * image to make sure we have enough room for the xenheap
422 * area, pushing out whatever may already be there.
423 */
424 while (relo_start + relo_size >= md_end) {
425 md = efi_get_md(md_end);
427 if (md == NULL) {
428 printk("no room to move loader data. skip moving loader data\n");
429 goto skip_move;
430 }
432 md_end = MD_END(md);
433 if (relo_start < md->phys_addr)
434 relo_start = md->phys_addr;
436 if (!is_xenheap_usable_memory(md)) {
437 /* Skip this area */
438 if (md_end > relo_start)
439 relo_start = md_end;
440 continue;
441 }
443 /*
444 * The dom0 kernel or initrd could overlap, reserve space
445 * at the end to relocate them later.
446 */
447 if (md->type == EFI_LOADER_DATA) {
448 /* Test for ranges we're not prepared to move */
449 if (!md_overlap_with_boot_param(md))
450 relo_size += MD_SIZE(md);
452 /* If range overlaps the end, push out the relocation start */
453 if (md_end > relo_start)
454 relo_start = md_end;
455 }
456 }
457 last_md = md;
458 relo_start = md_end - relo_size;
459 relo_end = relo_start + relo_size;
461 md_end = __pa(ia64_imva(&_end));
463 /*
464 * Move any relocated data out into the previously found relocation
465 * area. Any extra memory descriptrs are moved out to the end
466 * and set to zero pages.
467 */
468 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
469 md_end = MD_END(md);
471 if (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) {
472 unsigned long relo_offset;
474 if (md_overlaps(md, ia64_boot_param->domain_start)) {
475 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
476 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
477 ia64_boot_param->domain_start, relo_start + relo_offset,
478 ia64_boot_param->domain_size >> 10);
479 ia64_boot_param->domain_start = relo_start + relo_offset;
480 }
481 if (ia64_boot_param->initrd_size &&
482 md_overlaps(md, ia64_boot_param->initrd_start)) {
483 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
484 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
485 ia64_boot_param->initrd_start, relo_start + relo_offset,
486 ia64_boot_param->initrd_size >> 10);
487 ia64_boot_param->initrd_start = relo_start + relo_offset;
488 }
489 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
490 relo_start += MD_SIZE(md);
491 }
493 if (md == last_md)
494 break;
495 }
497 /* Trim the last entry */
498 md->num_pages -= (relo_size >> EFI_PAGE_SHIFT);
500 skip_move:
501 reserve_memory();
503 /* first find highest page frame number */
504 max_page = 0;
505 efi_memmap_walk(find_max_pfn, &max_page);
506 printk("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
507 efi_print();
509 xen_heap_start = memguard_init(ia64_imva(&_end));
510 printk("xen_heap_start: %p\n", xen_heap_start);
512 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
513 efi_memmap_walk(xen_count_pages, &nr_pages);
515 printk("System RAM: %luMB (%lukB)\n",
516 nr_pages >> (20 - PAGE_SHIFT),
517 nr_pages << (PAGE_SHIFT - 10));
518 total_pages = nr_pages;
520 init_frametable();
522 trap_init();
524 /* process SAL system table */
525 /* must be before any pal/sal call */
526 BUG_ON(efi.sal_systab == EFI_INVALID_TABLE_ADDR);
527 ia64_sal_init(__va(efi.sal_systab));
529 /* early_setup_arch() maps PAL code. */
530 identify_vmx_feature();
531 /* If vmx feature is on, do necessary initialization for vmx */
532 if (vmx_enabled)
533 xen_heap_start = vmx_init_env(xen_heap_start, xenheap_phys_end);
535 /* allocate memory for percpu area
536 * per_cpu_init() called from late_set_arch() is called after
537 * end_boot_allocate(). It's too late to allocate memory in
538 * xenva.
539 */
540 xen_heap_start = per_cpu_allocate(xen_heap_start, xenheap_phys_end);
542 heap_desc.xen_heap_start = xen_heap_start;
543 heap_desc.xenheap_phys_end = xenheap_phys_end;
544 heap_desc.kern_md = kern_md;
545 efi_memmap_walk(&init_xenheap_mds, &heap_desc);
547 printk("Xen heap: %luMB (%lukB)\n",
548 (xenheap_phys_end-__pa(xen_heap_start)) >> 20,
549 (xenheap_phys_end-__pa(xen_heap_start)) >> 10);
551 /* for is_xen_fixed_mfn() */
552 xen_fixed_mfn_start = virt_to_mfn(&_start);
553 xen_fixed_mfn_end = virt_to_mfn(xen_heap_start);
555 end_boot_allocator();
557 softirq_init();
558 tasklet_subsys_init();
560 late_setup_arch(&cmdline);
562 timer_init();
563 idle_vcpu[0] = (struct vcpu*) ia64_r13;
564 scheduler_init();
566 alloc_dom_xen_and_dom_io();
567 setup_per_cpu_areas();
568 mem_init();
570 local_irq_disable();
571 init_IRQ ();
572 init_xen_time(); /* initialise the time */
574 rcu_init();
576 #ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
577 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
578 #endif
580 #ifdef CONFIG_SMP
581 if ( opt_nosmp )
582 {
583 max_cpus = 0;
584 smp_num_siblings = 1;
585 //boot_cpu_data.x86_num_cores = 1;
586 }
588 /* A vcpu is created for the idle domain on every physical cpu.
589 Limit the number of cpus to the maximum number of vcpus. */
590 if (max_cpus > MAX_VIRT_CPUS)
591 max_cpus = MAX_VIRT_CPUS;
593 smp_prepare_cpus(max_cpus);
595 /* We aren't hotplug-capable yet. */
596 cpus_or(cpu_present_map, cpu_present_map, cpu_possible_map);
598 /* Enable IRQ to receive IPI (needed for ITC sync). */
599 local_irq_enable();
601 do_presmp_initcalls();
603 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
604 for_each_present_cpu ( i )
605 {
606 if ( num_online_cpus() >= max_cpus )
607 break;
608 if ( !cpu_online(i) )
609 {
610 int ret = cpu_up(i);
611 if ( ret != 0 )
612 printk("Failed to bring up CPU %u (error %d)\n", i, ret);
613 }
614 }
616 local_irq_disable();
618 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
619 smp_cpus_done(max_cpus);
620 #endif
622 iommu_setup(); /* setup iommu if available */
624 do_initcalls();
625 sort_main_extable();
627 init_rid_allocator ();
629 local_irq_enable();
631 if (opt_xencons) {
632 initialize_keytable();
633 if (ns16550_com1_gsi) {
634 if (opt_xencons_poll ||
635 iosapic_register_intr(ns16550_com1_gsi,
636 ns16550_com1_polarity,
637 ns16550_com1_trigger) < 0) {
638 ns16550_com1.irq = 0;
639 ns16550_init(0, &ns16550_com1);
640 }
641 }
642 console_init_postirq();
643 }
645 expose_p2m_init();
647 /* Create initial domain 0. */
648 dom0 = domain_create(0, 0, DOM0_SSIDREF);
649 if (dom0 == NULL)
650 panic("Error creating domain 0\n");
651 domain_set_vhpt_size(dom0, dom0_vhpt_size_log2);
652 dom0_vcpu0 = alloc_dom0_vcpu0();
653 if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0)
654 panic("Cannot allocate dom0 vcpu 0\n");
656 dom0->is_privileged = 1;
657 dom0->target = NULL;
659 /*
660 * We're going to setup domain0 using the module(s) that we stashed safely
661 * above our heap. The second module, if present, is an initrd ramdisk.
662 */
663 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
664 dom0_memory_size = ia64_boot_param->domain_size;
665 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
666 dom0_initrd_size = ia64_boot_param->initrd_size;
668 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
669 dom0_initrd_start,dom0_initrd_size,
670 0) != 0)
671 panic("Could not set up DOM0 guest OS\n");
673 if (!running_on_sim && !IS_MEDUSA()) // slow on ski and pages are pre-initialized to zero
674 scrub_heap_pages();
676 init_trace_bufs();
678 if (opt_xencons) {
679 console_endboot();
680 serial_endboot();
681 }
683 domain0_ready = 1;
685 domain_unpause_by_systemcontroller(dom0);
687 init_done();
688 }
690 void arch_get_xen_caps(xen_capabilities_info_t *info)
691 {
692 /* Interface name is always xen-3.0-* for Xen-3.x. */
693 int major = 3, minor = 0;
694 char s[32];
696 (*info)[0] = '\0';
698 snprintf(s, sizeof(s), "xen-%d.%d-ia64 ", major, minor);
699 safe_strcat(*info, s);
701 snprintf(s, sizeof(s), "xen-%d.%d-ia64be ", major, minor);
702 safe_strcat(*info, s);
704 if (vmx_enabled)
705 {
706 snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor);
707 safe_strcat(*info, s);
709 snprintf(s, sizeof(s), "hvm-%d.%d-ia64-sioemu ", major, minor);
710 safe_strcat(*info, s);
711 }
712 }
714 int xen_in_range(paddr_t start, paddr_t end)
715 {
716 paddr_t xs = __pa(&_start);
717 paddr_t xe = __pa(&_end);
719 return (start < xe) && (end > xs);
720 }