ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 16786:a739d3edc185

[IA64] domheap: Allocate vm buffer before boot allocator

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 af3550f53874
children 0c2dc9424a68
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 <xen/string.h>
26 #include <asm/vmx.h>
27 #include <linux/efi.h>
28 #include <asm/iosapic.h>
29 #include <xen/softirq.h>
30 #include <xen/rcupdate.h>
31 #include <xsm/acm/acm_hooks.h>
32 #include <asm/sn/simulator.h>
33 #include <linux/asm/sal.h>
35 unsigned long xenheap_phys_end, total_pages;
37 char saved_command_line[COMMAND_LINE_SIZE];
38 char __initdata dom0_command_line[COMMAND_LINE_SIZE];
40 cpumask_t cpu_present_map;
42 extern unsigned long domain0_ready;
44 int find_max_pfn (unsigned long, unsigned long, void *);
46 /* FIXME: which header these declarations should be there ? */
47 extern void early_setup_arch(char **);
48 extern void late_setup_arch(char **);
49 extern void hpsim_serial_init(void);
50 extern void setup_per_cpu_areas(void);
51 extern void mem_init(void);
52 extern void init_IRQ(void);
53 extern void trap_init(void);
54 extern void xen_patch_kernel(void);
56 /* nosmp: ignore secondary processors */
57 static int __initdata opt_nosmp;
58 boolean_param("nosmp", opt_nosmp);
60 /* maxcpus: maximum number of CPUs to activate */
61 static unsigned int __initdata max_cpus = NR_CPUS;
62 integer_param("maxcpus", max_cpus);
64 /* xencons: toggle xenconsole input (and irq).
65 Note: you have to disable 8250 serials in domains (to avoid use of the
66 same resource). */
67 static int __initdata opt_xencons = 1;
68 integer_param("xencons", opt_xencons);
70 /* xencons_poll: toggle non-legacy xencons UARTs to run in polling mode */
71 static int __initdata opt_xencons_poll;
72 boolean_param("xencons_poll", opt_xencons_poll);
74 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
75 unsigned long xen_pstart;
76 void *xen_pickle_offset __read_mostly;
78 static int __init
79 xen_count_pages(u64 start, u64 end, void *arg)
80 {
81 unsigned long *count = arg;
83 /* FIXME: do we need consider difference between DMA-usable memory and
84 * normal memory? Seems that HV has no requirement to operate DMA which
85 * is owned by Dom0? */
86 *count += (end - start) >> PAGE_SHIFT;
87 return 0;
88 }
90 static void __init do_initcalls(void)
91 {
92 initcall_t *call;
93 for ( call = &__initcall_start; call < &__initcall_end; call++ )
94 (*call)();
95 }
97 /*
98 * IPF loader only supports one command line currently, for
99 * both xen and guest kernel. This function provides pre-parse
100 * to mixed command line, to split it into two parts.
101 *
102 * User should split the parameters by "--", with strings after
103 * spliter for guest kernel. Missing "--" means whole line belongs
104 * to guest. Example:
105 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
106 * root=/dev/sda3 ro"
107 */
108 static char null[4] = { 0 };
110 void __init early_cmdline_parse(char **cmdline_p)
111 {
112 char *guest_cmd;
113 static const char * const split = "--";
115 if (*cmdline_p == NULL) {
116 *cmdline_p = &null[0];
117 saved_command_line[0] = '\0';
118 dom0_command_line[0] = '\0';
119 return;
120 }
122 guest_cmd = strstr(*cmdline_p, split);
123 /* If no spliter, whole line is for guest */
124 if (guest_cmd == NULL) {
125 guest_cmd = *cmdline_p;
126 *cmdline_p = &null[0];
127 } else {
128 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
129 guest_cmd += strlen(split);
130 while (*guest_cmd == ' ') guest_cmd++;
131 }
133 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
134 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
135 return;
136 }
138 struct ns16550_defaults ns16550_com1 = {
139 .data_bits = 8,
140 .parity = 'n',
141 .stop_bits = 1
142 };
144 unsigned int ns16550_com1_gsi;
145 unsigned int ns16550_com1_polarity;
146 unsigned int ns16550_com1_trigger;
148 struct ns16550_defaults ns16550_com2 = {
149 .data_bits = 8,
150 .parity = 'n',
151 .stop_bits = 1
152 };
154 /* efi_print: print efi table at boot */
155 static int __initdata opt_efi_print;
156 boolean_param("efi_print", opt_efi_print);
158 /* print EFI memory map: */
159 static void __init
160 efi_print(void)
161 {
162 void *efi_map_start, *efi_map_end;
163 u64 efi_desc_size;
165 efi_memory_desc_t *md;
166 void *p;
167 int i;
169 if (!opt_efi_print)
170 return;
172 efi_map_start = __va(ia64_boot_param->efi_memmap);
173 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
174 efi_desc_size = ia64_boot_param->efi_memdesc_size;
176 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
177 md = p;
178 printk("mem%02u: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) "
179 "(%luMB)\n", i, md->type, md->attribute, md->phys_addr,
180 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
181 md->num_pages >> (20 - EFI_PAGE_SHIFT));
182 }
183 }
185 /*
186 * These functions are utility functions for getting and
187 * testing memory descriptors for allocating the xenheap area.
188 */
189 static efi_memory_desc_t * __init
190 efi_get_md (unsigned long phys_addr)
191 {
192 void *efi_map_start, *efi_map_end, *p;
193 efi_memory_desc_t *md;
194 u64 efi_desc_size;
196 efi_map_start = __va(ia64_boot_param->efi_memmap);
197 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
198 efi_desc_size = ia64_boot_param->efi_memdesc_size;
200 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
201 md = p;
202 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
203 return md;
204 }
205 return 0;
206 }
208 static int __init
209 is_xenheap_usable_memory(efi_memory_desc_t *md)
210 {
211 if (!(md->attribute & EFI_MEMORY_WB))
212 return 0;
214 switch (md->type) {
215 case EFI_LOADER_CODE:
216 case EFI_LOADER_DATA:
217 case EFI_BOOT_SERVICES_CODE:
218 case EFI_BOOT_SERVICES_DATA:
219 case EFI_CONVENTIONAL_MEMORY:
220 return 1;
221 }
222 return 0;
223 }
225 static inline int __init
226 md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr)
227 {
228 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
229 }
231 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
233 extern char __init_begin[], __init_end[];
234 static void noinline init_done(void)
235 {
236 memset(__init_begin, 0, __init_end - __init_begin);
237 flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
238 init_xenheap_pages(__pa(__init_begin), __pa(__init_end));
239 printk("Freed %ldkB init memory.\n",
240 (long)(__init_end-__init_begin)>>10);
242 startup_cpu_idle_loop();
243 }
245 int running_on_sim;
247 static int __init
248 is_platform_hp_ski(void)
249 {
250 int i;
251 long cpuid[6];
253 for (i = 0; i < 5; ++i)
254 cpuid[i] = ia64_get_cpuid(i);
256 if ((cpuid[0] & 0xff) != 'H')
257 return 0;
258 if ((cpuid[3] & 0xff) != 0x4)
259 return 0;
260 if (((cpuid[3] >> 8) & 0xff) != 0x0)
261 return 0;
262 if (((cpuid[3] >> 16) & 0xff) != 0x0)
263 return 0;
264 if (((cpuid[3] >> 24) & 0x7) != 0x7)
265 return 0;
267 return 1;
268 }
270 void __init start_kernel(void)
271 {
272 char *cmdline;
273 unsigned long nr_pages;
274 unsigned long dom0_memory_start, dom0_memory_size;
275 unsigned long dom0_initrd_start, dom0_initrd_size;
276 unsigned long md_end, relo_start, relo_end, relo_size = 0;
277 struct domain *idle_domain;
278 struct vcpu *dom0_vcpu0;
279 efi_memory_desc_t *kern_md, *last_md, *md;
280 void *xen_heap_start;
281 #ifdef CONFIG_SMP
282 int i;
283 #endif
285 /* Be sure the struct shared_info size is <= XSI_SIZE. */
286 BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
288 /* Kernel may be relocated by EFI loader */
289 xen_pstart = ia64_tpa(KERNEL_START);
291 running_on_sim = is_platform_hp_ski();
293 early_setup_arch(&cmdline);
295 /* We initialise the serial devices very early so we can get debugging. */
296 if (running_on_sim)
297 hpsim_serial_init();
298 else {
299 ns16550_init(0, &ns16550_com1);
300 ns16550_init(1, &ns16550_com2);
301 }
302 serial_init_preirq();
304 #ifdef CONFIG_VGA
305 /* Plug in a default VGA mode */
306 vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
307 vga_console_info.u.text_mode_3.font_height = 16; /* generic VGA? */
308 vga_console_info.u.text_mode_3.cursor_x =
309 ia64_boot_param->console_info.orig_x;
310 vga_console_info.u.text_mode_3.cursor_y =
311 ia64_boot_param->console_info.orig_y;
312 vga_console_info.u.text_mode_3.rows =
313 ia64_boot_param->console_info.num_rows;
314 vga_console_info.u.text_mode_3.columns =
315 ia64_boot_param->console_info.num_cols;
316 #endif
318 init_console();
320 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
321 ia64_boot_param->domain_size == 0) {
322 /* This is possible only with the old elilo, which does not support
323 a vmm. Fix now, and continue without initrd. */
324 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
325 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
326 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
327 ia64_boot_param->initrd_start = 0;
328 ia64_boot_param->initrd_size = 0;
329 }
331 printk("Xen command line: %s\n", saved_command_line);
333 xenheap_phys_end = xen_pstart + xenheap_size;
334 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
335 xen_pstart, xenheap_phys_end);
337 xen_patch_kernel();
339 kern_md = md = efi_get_md(xen_pstart);
340 md_end = __pa(ia64_imva(&_end));
341 relo_start = xenheap_phys_end;
343 /*
344 * Scan through the memory descriptors after the kernel
345 * image to make sure we have enough room for the xenheap
346 * area, pushing out whatever may already be there.
347 */
348 while (relo_start + relo_size >= md_end) {
349 md = efi_get_md(md_end);
351 BUG_ON(!md);
352 BUG_ON(!is_xenheap_usable_memory(md));
354 md_end = md->phys_addr + MD_SIZE(md);
355 /*
356 * The dom0 kernel or initrd could overlap, reserve space
357 * at the end to relocate them later.
358 */
359 if (md->type == EFI_LOADER_DATA) {
360 /* Test for ranges we're not prepared to move */
361 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
362 md_overlaps(md, ia64_boot_param->efi_memmap) ||
363 md_overlaps(md, ia64_boot_param->command_line));
365 relo_size += MD_SIZE(md);
366 /* If range overlaps the end, push out the relocation start */
367 if (md_end > relo_start)
368 relo_start = md_end;
369 }
370 }
371 last_md = md;
372 relo_end = relo_start + relo_size;
374 md_end = __pa(ia64_imva(&_end));
376 /*
377 * Move any relocated data out into the previously found relocation
378 * area. Any extra memory descriptrs are moved out to the end
379 * and set to zero pages.
380 */
381 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
382 md_end = md->phys_addr + MD_SIZE(md);
384 if (md->type == EFI_LOADER_DATA) {
385 unsigned long relo_offset;
387 if (md_overlaps(md, ia64_boot_param->domain_start)) {
388 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
389 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
390 ia64_boot_param->domain_start, relo_start + relo_offset,
391 ia64_boot_param->domain_size >> 10);
392 ia64_boot_param->domain_start = relo_start + relo_offset;
393 }
394 if (ia64_boot_param->initrd_size &&
395 md_overlaps(md, ia64_boot_param->initrd_start)) {
396 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
397 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
398 ia64_boot_param->initrd_start, relo_start + relo_offset,
399 ia64_boot_param->initrd_size >> 10);
400 ia64_boot_param->initrd_start = relo_start + relo_offset;
401 }
402 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
403 relo_start += MD_SIZE(md);
404 }
406 if (md == kern_md)
407 continue;
408 if (md == last_md)
409 break;
411 md->phys_addr = relo_end;
412 md->num_pages = 0;
413 }
415 /* Trim the last entry */
416 md->phys_addr = relo_end;
417 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
419 /*
420 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
421 * the full size. This range will already be type EFI_LOADER_DATA,
422 * therefore the xenheap area is now protected being allocated for
423 * use by find_memmap_space() in efi.c
424 */
425 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
427 reserve_memory();
429 /* first find highest page frame number */
430 max_page = 0;
431 efi_memmap_walk(find_max_pfn, &max_page);
432 printk("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
433 efi_print();
435 /*
436 * later [__init_begin, __init_end) will be freed up as xen heap
437 * so that struct domain might be allocated from the init area
438 * which is < xen_heap_start. so we can't simply set
439 * xen_pickle_offset = xen_heap_start.
440 */
441 xen_pickle_offset = ia64_imva(__init_begin);
443 xen_heap_start = memguard_init(ia64_imva(&_end));
444 printk("Before xen_heap_start: %p\n", xen_heap_start);
445 xen_heap_start = __va(init_boot_allocator(__pa(xen_heap_start)));
446 printk("After xen_heap_start: %p\n", xen_heap_start);
448 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
449 efi_memmap_walk(xen_count_pages, &nr_pages);
451 printk("System RAM: %luMB (%lukB)\n",
452 nr_pages >> (20 - PAGE_SHIFT),
453 nr_pages << (PAGE_SHIFT - 10));
454 total_pages = nr_pages;
456 init_frametable();
458 trap_init();
460 /* process SAL system table */
461 /* must be before any pal/sal call */
462 ia64_sal_init(efi.sal_systab);
464 /* early_setup_arch() maps PAL code. */
465 identify_vmx_feature();
466 /* If vmx feature is on, do necessary initialization for vmx */
467 if (vmx_enabled)
468 xen_heap_start = vmx_init_env(xen_heap_start, xenheap_phys_end);
470 init_xenheap_pages(__pa(xen_heap_start), xenheap_phys_end);
471 printk("Xen heap: %luMB (%lukB)\n",
472 (xenheap_phys_end-__pa(xen_heap_start)) >> 20,
473 (xenheap_phys_end-__pa(xen_heap_start)) >> 10);
475 end_boot_allocator();
477 late_setup_arch(&cmdline);
479 scheduler_init();
480 idle_vcpu[0] = (struct vcpu*) ia64_r13;
481 idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
482 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
483 BUG();
485 alloc_dom_xen_and_dom_io();
486 setup_per_cpu_areas();
487 mem_init();
489 local_irq_disable();
490 init_IRQ ();
491 init_xen_time(); /* initialise the time */
492 timer_init();
494 rcu_init();
496 #ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
497 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
498 #endif
500 #ifdef CONFIG_SMP
501 if ( opt_nosmp )
502 {
503 max_cpus = 0;
504 smp_num_siblings = 1;
505 //boot_cpu_data.x86_num_cores = 1;
506 }
508 /* A vcpu is created for the idle domain on every physical cpu.
509 Limit the number of cpus to the maximum number of vcpus. */
510 if (max_cpus > MAX_VIRT_CPUS)
511 max_cpus = MAX_VIRT_CPUS;
513 smp_prepare_cpus(max_cpus);
515 /* We aren't hotplug-capable yet. */
516 for_each_cpu ( i )
517 cpu_set(i, cpu_present_map);
519 /* Enable IRQ to receive IPI (needed for ITC sync). */
520 local_irq_enable();
522 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
523 for_each_present_cpu ( i )
524 {
525 if ( num_online_cpus() >= max_cpus )
526 break;
527 if ( !cpu_online(i) ) {
528 rcu_online_cpu(i);
529 __cpu_up(i);
530 }
531 }
533 local_irq_disable();
535 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
536 smp_cpus_done(max_cpus);
537 #endif
539 initialise_gdb(); /* could be moved earlier */
541 do_initcalls();
542 sort_main_extable();
544 init_rid_allocator ();
546 local_irq_enable();
548 if (opt_xencons) {
549 initialize_keytable();
550 if (ns16550_com1_gsi) {
551 if (opt_xencons_poll ||
552 iosapic_register_intr(ns16550_com1_gsi,
553 ns16550_com1_polarity,
554 ns16550_com1_trigger) < 0) {
555 ns16550_com1.irq = 0;
556 ns16550_init(0, &ns16550_com1);
557 }
558 }
559 serial_init_postirq();
560 }
562 expose_p2m_init();
564 /* Create initial domain 0. */
565 dom0 = domain_create(0, 0, DOM0_SSIDREF);
566 if (dom0 == NULL)
567 panic("Error creating domain 0\n");
568 dom0_vcpu0 = alloc_vcpu(dom0, 0, 0);
569 if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0)
570 panic("Cannot allocate dom0 vcpu 0\n");
572 dom0->is_privileged = 1;
574 /*
575 * We're going to setup domain0 using the module(s) that we stashed safely
576 * above our heap. The second module, if present, is an initrd ramdisk.
577 */
578 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
579 dom0_memory_size = ia64_boot_param->domain_size;
580 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
581 dom0_initrd_size = ia64_boot_param->initrd_size;
583 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
584 dom0_initrd_start,dom0_initrd_size,
585 0) != 0)
586 panic("Could not set up DOM0 guest OS\n");
588 if (!running_on_sim && !IS_MEDUSA()) // slow on ski and pages are pre-initialized to zero
589 scrub_heap_pages();
591 init_trace_bufs();
593 if (opt_xencons) {
594 console_endboot();
595 serial_endboot();
596 }
598 domain0_ready = 1;
600 domain_unpause_by_systemcontroller(dom0);
602 init_done();
603 }
605 void arch_get_xen_caps(xen_capabilities_info_t *info)
606 {
607 /* Interface name is always xen-3.0-* for Xen-3.x. */
608 int major = 3, minor = 0;
609 char s[32];
611 (*info)[0] = '\0';
613 snprintf(s, sizeof(s), "xen-%d.%d-ia64 ", major, minor);
614 safe_strcat(*info, s);
616 snprintf(s, sizeof(s), "xen-%d.%d-ia64be ", major, minor);
617 safe_strcat(*info, s);
619 if (vmx_enabled)
620 {
621 snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor);
622 safe_strcat(*info, s);
623 }
624 }