direct-io.hg

view xen/arch/ia64/xen/xensetup.c @ 13875:88c9ba6214bc

[IA64] Xen build warning fixes

Missing include and remove an sprintf

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild2.aw
date Sun Feb 04 12:06:59 2007 -0700 (2007-02-04)
parents 6d38ae7927cf
children 7efb3a06c56a
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/spinlock.h>
11 #include <xen/multiboot.h>
12 #include <xen/sched.h>
13 #include <xen/mm.h>
14 #include <public/version.h>
15 #include <xen/gdbstub.h>
16 #include <xen/version.h>
17 #include <xen/console.h>
18 #include <xen/domain.h>
19 #include <xen/serial.h>
20 #include <xen/trace.h>
21 #include <xen/keyhandler.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>
32 unsigned long xenheap_phys_end, total_pages;
34 char saved_command_line[COMMAND_LINE_SIZE];
35 char dom0_command_line[COMMAND_LINE_SIZE];
37 cpumask_t cpu_present_map;
39 extern unsigned long domain0_ready;
41 int find_max_pfn (unsigned long, unsigned long, void *);
43 /* FIXME: which header these declarations should be there ? */
44 extern long is_platform_hp_ski(void);
45 extern void early_setup_arch(char **);
46 extern void late_setup_arch(char **);
47 extern void hpsim_serial_init(void);
48 extern void alloc_dom0(void);
49 extern void setup_per_cpu_areas(void);
50 extern void mem_init(void);
51 extern void init_IRQ(void);
52 extern void trap_init(void);
53 extern void xen_patch_kernel(void);
55 /* opt_nosmp: If true, secondary processors are ignored. */
56 static int opt_nosmp;
57 boolean_param("nosmp", opt_nosmp);
59 /* maxcpus: maximum number of CPUs to activate. */
60 static unsigned int max_cpus = NR_CPUS;
61 integer_param("maxcpus", max_cpus);
63 /* xencons: if true enable xenconsole input (and irq).
64 Note: you have to disable 8250 serials in domains (to avoid use of the
65 same resource). */
66 static int opt_xencons = 1;
67 integer_param("xencons", opt_xencons);
69 /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
70 static int opt_xencons_poll;
71 boolean_param("xencons_poll", opt_xencons_poll);
73 /*
74 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
75 * xen image
76 * bootmap bits
77 * xen heap
78 * Note: To allow xenheap size configurable, the prerequisite is
79 * to configure elilo allowing relocation defaultly. Then since
80 * elilo chooses 256M as alignment when relocating, alignment issue
81 * on IPF can be addressed.
82 */
83 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
84 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
85 extern long running_on_sim;
86 unsigned long xen_pstart;
87 void *xen_heap_start __read_mostly;
89 static int
90 xen_count_pages(u64 start, u64 end, void *arg)
91 {
92 unsigned long *count = arg;
94 /* FIXME: do we need consider difference between DMA-usable memory and
95 * normal memory? Seems that HV has no requirement to operate DMA which
96 * is owned by Dom0? */
97 *count += (end - start) >> PAGE_SHIFT;
98 return 0;
99 }
101 static void __init do_initcalls(void)
102 {
103 initcall_t *call;
104 for ( call = &__initcall_start; call < &__initcall_end; call++ )
105 (*call)();
106 }
108 /*
109 * IPF loader only supports one commaind line currently, for
110 * both xen and guest kernel. This function provides pre-parse
111 * to mixed command line, to split it into two parts.
112 *
113 * User should split the parameters by "--", with strings after
114 * spliter for guest kernel. Missing "--" means whole line belongs
115 * to guest. Example:
116 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
117 * root=/dev/sda3 ro"
118 */
119 static char null[4] = { 0 };
121 void early_cmdline_parse(char **cmdline_p)
122 {
123 char *guest_cmd;
124 static const char * const split = "--";
126 if (*cmdline_p == NULL) {
127 *cmdline_p = &null[0];
128 saved_command_line[0] = '\0';
129 dom0_command_line[0] = '\0';
130 return;
131 }
133 guest_cmd = strstr(*cmdline_p, split);
134 /* If no spliter, whole line is for guest */
135 if (guest_cmd == NULL) {
136 guest_cmd = *cmdline_p;
137 *cmdline_p = &null[0];
138 } else {
139 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
140 guest_cmd += strlen(split);
141 while (*guest_cmd == ' ') guest_cmd++;
142 }
144 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
145 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
146 return;
147 }
149 struct ns16550_defaults ns16550_com1 = {
150 .baud = BAUD_AUTO,
151 .data_bits = 8,
152 .parity = 'n',
153 .stop_bits = 1
154 };
156 unsigned int ns16550_com1_gsi;
157 unsigned int ns16550_com1_polarity;
158 unsigned int ns16550_com1_trigger;
160 struct ns16550_defaults ns16550_com2 = {
161 .baud = BAUD_AUTO,
162 .data_bits = 8,
163 .parity = 'n',
164 .stop_bits = 1
165 };
167 /* efi_print: print efi table at boot */
168 static int opt_efi_print;
169 boolean_param("efi_print", opt_efi_print);
171 /* print EFI memory map: */
172 static void
173 efi_print(void)
174 {
175 void *efi_map_start, *efi_map_end;
176 u64 efi_desc_size;
178 efi_memory_desc_t *md;
179 void *p;
180 int i;
182 if (!opt_efi_print)
183 return;
185 efi_map_start = __va(ia64_boot_param->efi_memmap);
186 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
187 efi_desc_size = ia64_boot_param->efi_memdesc_size;
189 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
190 md = p;
191 printk("mem%02u: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) "
192 "(%luMB)\n", i, md->type, md->attribute, md->phys_addr,
193 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
194 md->num_pages >> (20 - EFI_PAGE_SHIFT));
195 }
196 }
198 /*
199 * These functions are utility functions for getting and
200 * testing memory descriptors for allocating the xenheap area.
201 */
202 static efi_memory_desc_t *
203 efi_get_md (unsigned long phys_addr)
204 {
205 void *efi_map_start, *efi_map_end, *p;
206 efi_memory_desc_t *md;
207 u64 efi_desc_size;
209 efi_map_start = __va(ia64_boot_param->efi_memmap);
210 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
211 efi_desc_size = ia64_boot_param->efi_memdesc_size;
213 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
214 md = p;
215 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
216 return md;
217 }
218 return 0;
219 }
221 static int
222 is_xenheap_usable_memory(efi_memory_desc_t *md)
223 {
224 if (!(md->attribute & EFI_MEMORY_WB))
225 return 0;
227 switch (md->type) {
228 case EFI_LOADER_CODE:
229 case EFI_LOADER_DATA:
230 case EFI_BOOT_SERVICES_CODE:
231 case EFI_BOOT_SERVICES_DATA:
232 case EFI_CONVENTIONAL_MEMORY:
233 return 1;
234 }
235 return 0;
236 }
238 static inline int
239 md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr)
240 {
241 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
242 }
244 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
246 void start_kernel(void)
247 {
248 char *cmdline;
249 unsigned long nr_pages;
250 unsigned long dom0_memory_start, dom0_memory_size;
251 unsigned long dom0_initrd_start, dom0_initrd_size;
252 unsigned long md_end, relo_start, relo_end, relo_size = 0;
253 struct domain *idle_domain;
254 struct vcpu *dom0_vcpu0;
255 efi_memory_desc_t *kern_md, *last_md, *md;
256 #ifdef CONFIG_SMP
257 int i;
258 #endif
260 /* Be sure the struct shared_info size is <= XSI_SIZE. */
261 BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
263 running_on_sim = is_platform_hp_ski();
264 /* Kernel may be relocated by EFI loader */
265 xen_pstart = ia64_tpa(KERNEL_START);
267 early_setup_arch(&cmdline);
269 /* We initialise the serial devices very early so we can get debugging. */
270 if (running_on_sim) hpsim_serial_init();
271 else {
272 ns16550_init(0, &ns16550_com1);
273 /* Also init com2 for Tiger4. */
274 ns16550_com2.io_base = 0x2f8;
275 ns16550_com2.irq = 3;
276 ns16550_init(1, &ns16550_com2);
277 }
278 serial_init_preirq();
280 init_console();
281 set_printk_prefix("(XEN) ");
283 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
284 ia64_boot_param->domain_size == 0) {
285 /* This is possible only with the old elilo, which does not support
286 a vmm. Fix now, and continue without initrd. */
287 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
288 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
289 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
290 ia64_boot_param->initrd_start = 0;
291 ia64_boot_param->initrd_size = 0;
292 }
294 printk("Xen command line: %s\n", saved_command_line);
295 /* xenheap should be in same TR-covered range with xen image */
296 xenheap_phys_end = xen_pstart + xenheap_size;
297 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
298 xen_pstart, xenheap_phys_end);
300 xen_patch_kernel();
302 kern_md = md = efi_get_md(xen_pstart);
303 md_end = __pa(ia64_imva(&_end));
304 relo_start = xenheap_phys_end;
306 /*
307 * Scan through the memory descriptors after the kernel
308 * image to make sure we have enough room for the xenheap
309 * area, pushing out whatever may already be there.
310 */
311 while (relo_start + relo_size >= md_end) {
312 md = efi_get_md(md_end);
314 BUG_ON(!md);
315 BUG_ON(!is_xenheap_usable_memory(md));
317 md_end = md->phys_addr + MD_SIZE(md);
318 /*
319 * The dom0 kernel or initrd could overlap, reserve space
320 * at the end to relocate them later.
321 */
322 if (md->type == EFI_LOADER_DATA) {
323 /* Test for ranges we're not prepared to move */
324 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
325 md_overlaps(md, ia64_boot_param->efi_memmap) ||
326 md_overlaps(md, ia64_boot_param->command_line));
328 relo_size += MD_SIZE(md);
329 /* If range overlaps the end, push out the relocation start */
330 if (md_end > relo_start)
331 relo_start = md_end;
332 }
333 }
334 last_md = md;
335 relo_end = relo_start + relo_size;
337 md_end = __pa(ia64_imva(&_end));
339 /*
340 * Move any relocated data out into the previously found relocation
341 * area. Any extra memory descriptrs are moved out to the end
342 * and set to zero pages.
343 */
344 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
345 md_end = md->phys_addr + MD_SIZE(md);
347 if (md->type == EFI_LOADER_DATA) {
348 unsigned long relo_offset;
350 if (md_overlaps(md, ia64_boot_param->domain_start)) {
351 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
352 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
353 ia64_boot_param->domain_start, relo_start + relo_offset,
354 ia64_boot_param->domain_size >> 10);
355 ia64_boot_param->domain_start = relo_start + relo_offset;
356 }
357 if (ia64_boot_param->initrd_size &&
358 md_overlaps(md, ia64_boot_param->initrd_start)) {
359 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
360 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
361 ia64_boot_param->initrd_start, relo_start + relo_offset,
362 ia64_boot_param->initrd_size >> 10);
363 ia64_boot_param->initrd_start = relo_start + relo_offset;
364 }
365 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
366 relo_start += MD_SIZE(md);
367 }
369 if (md == kern_md)
370 continue;
371 if (md == last_md)
372 break;
374 md->phys_addr = relo_end;
375 md->num_pages = 0;
376 }
378 /* Trim the last entry */
379 md->phys_addr = relo_end;
380 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
382 /*
383 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
384 * the full size. This range will already be type EFI_LOADER_DATA,
385 * therefore the xenheap area is now protected being allocated for
386 * use by find_memmap_space() in efi.c
387 */
388 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
390 reserve_memory();
392 /* first find highest page frame number */
393 max_page = 0;
394 efi_memmap_walk(find_max_pfn, &max_page);
395 printk("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
396 efi_print();
398 xen_heap_start = memguard_init(ia64_imva(&_end));
399 printk("Before xen_heap_start: %p\n", xen_heap_start);
400 xen_heap_start = __va(init_boot_allocator(__pa(xen_heap_start)));
401 printk("After xen_heap_start: %p\n", xen_heap_start);
403 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
404 efi_memmap_walk(xen_count_pages, &nr_pages);
406 printk("System RAM: %luMB (%lukB)\n",
407 nr_pages >> (20 - PAGE_SHIFT),
408 nr_pages << (PAGE_SHIFT - 10));
409 total_pages = nr_pages;
411 init_frametable();
413 trap_init();
415 alloc_dom0();
417 end_boot_allocator();
419 init_xenheap_pages(__pa(xen_heap_start), xenheap_phys_end);
420 printk("Xen heap: %luMB (%lukB)\n",
421 (xenheap_phys_end-__pa(xen_heap_start)) >> 20,
422 (xenheap_phys_end-__pa(xen_heap_start)) >> 10);
424 late_setup_arch(&cmdline);
426 scheduler_init();
427 idle_vcpu[0] = (struct vcpu*) ia64_r13;
428 idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
429 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
430 BUG();
432 alloc_dom_xen_and_dom_io();
433 setup_per_cpu_areas();
434 mem_init();
436 local_irq_disable();
437 init_IRQ ();
438 init_xen_time(); /* initialise the time */
439 timer_init();
441 rcu_init();
443 #ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
444 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
445 #endif
447 #ifdef CONFIG_SMP
448 if ( opt_nosmp )
449 {
450 max_cpus = 0;
451 smp_num_siblings = 1;
452 //boot_cpu_data.x86_num_cores = 1;
453 }
455 /* A vcpu is created for the idle domain on every physical cpu.
456 Limit the number of cpus to the maximum number of vcpus. */
457 if (max_cpus > MAX_VIRT_CPUS)
458 max_cpus = MAX_VIRT_CPUS;
460 smp_prepare_cpus(max_cpus);
462 /* We aren't hotplug-capable yet. */
463 for_each_cpu ( i )
464 cpu_set(i, cpu_present_map);
466 /* Enable IRQ to receive IPI (needed for ITC sync). */
467 local_irq_enable();
469 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
470 for_each_present_cpu ( i )
471 {
472 if ( num_online_cpus() >= max_cpus )
473 break;
474 if ( !cpu_online(i) ) {
475 rcu_online_cpu(i);
476 __cpu_up(i);
477 }
478 }
480 local_irq_disable();
482 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
483 smp_cpus_done(max_cpus);
484 #endif
486 initialise_gdb(); /* could be moved earlier */
488 do_initcalls();
489 sort_main_extable();
491 init_rid_allocator ();
493 local_irq_enable();
495 if (opt_xencons) {
496 initialize_keytable();
497 if (ns16550_com1_gsi) {
498 if (opt_xencons_poll ||
499 iosapic_register_intr(ns16550_com1_gsi,
500 ns16550_com1_polarity,
501 ns16550_com1_trigger) < 0) {
502 ns16550_com1.irq = 0;
503 ns16550_init(0, &ns16550_com1);
504 }
505 }
506 serial_init_postirq();
508 /* Hide the HCDP table from dom0 */
509 efi.hcdp = NULL;
510 }
512 expose_p2m_init();
514 /* Create initial domain 0. */
515 dom0 = domain_create(0, 0);
516 if (dom0 == NULL)
517 panic("Error creating domain 0\n");
518 dom0_vcpu0 = alloc_vcpu(dom0, 0, 0);
519 if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0)
520 panic("Cannot allocate dom0 vcpu 0\n");
522 dom0->is_privileged = 1;
524 /*
525 * We're going to setup domain0 using the module(s) that we stashed safely
526 * above our heap. The second module, if present, is an initrd ramdisk.
527 */
528 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
529 dom0_memory_size = ia64_boot_param->domain_size;
530 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
531 dom0_initrd_size = ia64_boot_param->initrd_size;
533 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
534 dom0_initrd_start,dom0_initrd_size,
535 0) != 0)
536 panic("Could not set up DOM0 guest OS\n");
538 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
539 scrub_heap_pages();
541 init_trace_bufs();
543 if (opt_xencons) {
544 console_endboot();
545 serial_endboot();
546 }
548 domain0_ready = 1;
550 schedulers_start();
552 domain_unpause_by_systemcontroller(dom0);
554 startup_cpu_idle_loop();
555 }
557 void arch_get_xen_caps(xen_capabilities_info_t *info)
558 {
559 int major = xen_major_version();
560 int minor = xen_minor_version();
561 char s[32];
563 (*info)[0] = '\0';
565 snprintf(s, sizeof(s), "xen-%d.%d-ia64 ", major, minor);
566 safe_strcat(*info, s);
568 if (vmx_enabled)
569 {
570 snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor);
571 safe_strcat(*info, s);
572 }
573 }