ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 11718:6df04adab323

[IA64] Fix implicit declaration of initialize_keytable().
Signed-off-by: Aron Griffis <aron@hp.com>
author kfraser@localhost.localdomain
date Tue Oct 03 11:33:37 2006 +0100 (2006-10-03)
parents b7b653e36d20
children 5f077cd6f58c 29b02d929b7e
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>
30 unsigned long xenheap_phys_end, total_pages;
32 char saved_command_line[COMMAND_LINE_SIZE];
33 char dom0_command_line[COMMAND_LINE_SIZE];
35 cpumask_t cpu_present_map;
37 extern unsigned long domain0_ready;
39 int find_max_pfn (unsigned long, unsigned long, void *);
41 /* FIXME: which header these declarations should be there ? */
42 extern long is_platform_hp_ski(void);
43 extern void early_setup_arch(char **);
44 extern void late_setup_arch(char **);
45 extern void hpsim_serial_init(void);
46 extern void alloc_dom0(void);
47 extern void setup_per_cpu_areas(void);
48 extern void mem_init(void);
49 extern void init_IRQ(void);
50 extern void trap_init(void);
52 /* opt_nosmp: If true, secondary processors are ignored. */
53 static int opt_nosmp = 0;
54 boolean_param("nosmp", opt_nosmp);
56 /* maxcpus: maximum number of CPUs to activate. */
57 static unsigned int max_cpus = NR_CPUS;
58 integer_param("maxcpus", max_cpus);
60 /* xencons: if true enable xenconsole input (and irq).
61 Note: you have to disable 8250 serials in domains (to avoid use of the
62 same resource). */
63 static int opt_xencons = 1;
64 integer_param("xencons", opt_xencons);
66 /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
67 static int opt_xencons_poll = 0;
68 boolean_param("xencons_poll", opt_xencons_poll);
70 /*
71 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
72 * xen image
73 * bootmap bits
74 * xen heap
75 * Note: To allow xenheap size configurable, the prerequisite is
76 * to configure elilo allowing relocation defaultly. Then since
77 * elilo chooses 256M as alignment when relocating, alignment issue
78 * on IPF can be addressed.
79 */
80 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
81 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
82 extern long running_on_sim;
83 unsigned long xen_pstart;
85 static int
86 xen_count_pages(u64 start, u64 end, void *arg)
87 {
88 unsigned long *count = arg;
90 /* FIXME: do we need consider difference between DMA-usable memory and
91 * normal memory? Seems that HV has no requirement to operate DMA which
92 * is owned by Dom0? */
93 *count += (end - start) >> PAGE_SHIFT;
94 return 0;
95 }
97 static void __init do_initcalls(void)
98 {
99 initcall_t *call;
100 for ( call = &__initcall_start; call < &__initcall_end; call++ )
101 (*call)();
102 }
104 /*
105 * IPF loader only supports one commaind line currently, for
106 * both xen and guest kernel. This function provides pre-parse
107 * to mixed command line, to split it into two parts.
108 *
109 * User should split the parameters by "--", with strings after
110 * spliter for guest kernel. Missing "--" means whole line belongs
111 * to guest. Example:
112 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
113 * root=/dev/sda3 ro"
114 */
115 static char null[4] = { 0 };
117 void early_cmdline_parse(char **cmdline_p)
118 {
119 char *guest_cmd;
120 static const char * const split = "--";
122 if (*cmdline_p == NULL) {
123 *cmdline_p = &null[0];
124 saved_command_line[0] = '\0';
125 dom0_command_line[0] = '\0';
126 return;
127 }
129 guest_cmd = strstr(*cmdline_p, split);
130 /* If no spliter, whole line is for guest */
131 if (guest_cmd == NULL) {
132 guest_cmd = *cmdline_p;
133 *cmdline_p = &null[0];
134 } else {
135 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
136 guest_cmd += strlen(split);
137 while (*guest_cmd == ' ') guest_cmd++;
138 }
140 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
141 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
142 return;
143 }
145 struct ns16550_defaults ns16550_com1 = {
146 .baud = BAUD_AUTO,
147 .data_bits = 8,
148 .parity = 'n',
149 .stop_bits = 1
150 };
152 unsigned int ns16550_com1_gsi;
153 unsigned int ns16550_com1_polarity;
154 unsigned int ns16550_com1_trigger;
156 struct ns16550_defaults ns16550_com2 = {
157 .baud = BAUD_AUTO,
158 .data_bits = 8,
159 .parity = 'n',
160 .stop_bits = 1
161 };
163 /* efi_print: print efi table at boot */
164 static int opt_efi_print = 0;
165 boolean_param("efi_print", opt_efi_print);
167 /* print EFI memory map: */
168 static void
169 efi_print(void)
170 {
171 void *efi_map_start, *efi_map_end;
172 u64 efi_desc_size;
174 efi_memory_desc_t *md;
175 void *p;
176 int i;
178 if (!opt_efi_print)
179 return;
181 efi_map_start = __va(ia64_boot_param->efi_memmap);
182 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
183 efi_desc_size = ia64_boot_param->efi_memdesc_size;
185 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
186 md = p;
187 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
188 i, md->type, md->attribute, md->phys_addr,
189 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
190 md->num_pages >> (20 - EFI_PAGE_SHIFT));
191 }
192 }
194 /*
195 * These functions are utility functions for getting and
196 * testing memory descriptors for allocating the xenheap area.
197 */
198 static efi_memory_desc_t *
199 efi_get_md (unsigned long phys_addr)
200 {
201 void *efi_map_start, *efi_map_end, *p;
202 efi_memory_desc_t *md;
203 u64 efi_desc_size;
205 efi_map_start = __va(ia64_boot_param->efi_memmap);
206 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
207 efi_desc_size = ia64_boot_param->efi_memdesc_size;
209 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
210 md = p;
211 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
212 return md;
213 }
214 return 0;
215 }
217 static int
218 is_xenheap_usable_memory(efi_memory_desc_t *md)
219 {
220 if (!(md->attribute & EFI_MEMORY_WB))
221 return 0;
223 switch (md->type) {
224 case EFI_LOADER_CODE:
225 case EFI_LOADER_DATA:
226 case EFI_BOOT_SERVICES_CODE:
227 case EFI_BOOT_SERVICES_DATA:
228 case EFI_CONVENTIONAL_MEMORY:
229 return 1;
230 }
231 return 0;
232 }
234 static inline int
235 md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr)
236 {
237 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
238 }
240 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
242 void start_kernel(void)
243 {
244 char *cmdline;
245 void *heap_start;
246 unsigned long nr_pages;
247 unsigned long dom0_memory_start, dom0_memory_size;
248 unsigned long dom0_initrd_start, dom0_initrd_size;
249 unsigned long md_end, relo_start, relo_end, relo_size = 0;
250 struct domain *idle_domain;
251 efi_memory_desc_t *kern_md, *last_md, *md;
252 #ifdef CONFIG_SMP
253 int i;
254 #endif
256 /* Be sure the struct shared_info size is <= XSI_SIZE. */
257 BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
259 running_on_sim = is_platform_hp_ski();
260 /* Kernel may be relocated by EFI loader */
261 xen_pstart = ia64_tpa(KERNEL_START);
263 early_setup_arch(&cmdline);
265 /* We initialise the serial devices very early so we can get debugging. */
266 if (running_on_sim) hpsim_serial_init();
267 else {
268 ns16550_init(0, &ns16550_com1);
269 /* Also init com2 for Tiger4. */
270 ns16550_com2.io_base = 0x2f8;
271 ns16550_com2.irq = 3;
272 ns16550_init(1, &ns16550_com2);
273 }
274 serial_init_preirq();
276 init_console();
277 set_printk_prefix("(XEN) ");
279 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
280 ia64_boot_param->domain_size == 0) {
281 /* This is possible only with the old elilo, which does not support
282 a vmm. Fix now, and continue without initrd. */
283 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
284 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
285 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
286 ia64_boot_param->initrd_start = 0;
287 ia64_boot_param->initrd_size = 0;
288 }
290 printk("Xen command line: %s\n", saved_command_line);
291 /* xenheap should be in same TR-covered range with xen image */
292 xenheap_phys_end = xen_pstart + xenheap_size;
293 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
294 xen_pstart, xenheap_phys_end);
296 kern_md = md = efi_get_md(xen_pstart);
297 md_end = __pa(ia64_imva(&_end));
298 relo_start = xenheap_phys_end;
300 /*
301 * Scan through the memory descriptors after the kernel
302 * image to make sure we have enough room for the xenheap
303 * area, pushing out whatever may already be there.
304 */
305 while (relo_start + relo_size >= md_end) {
306 md = efi_get_md(md_end);
308 BUG_ON(!md);
309 BUG_ON(!is_xenheap_usable_memory(md));
311 md_end = md->phys_addr + MD_SIZE(md);
312 /*
313 * The dom0 kernel or initrd could overlap, reserve space
314 * at the end to relocate them later.
315 */
316 if (md->type == EFI_LOADER_DATA) {
317 /* Test for ranges we're not prepared to move */
318 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
319 md_overlaps(md, ia64_boot_param->efi_memmap) ||
320 md_overlaps(md, ia64_boot_param->command_line));
322 relo_size += MD_SIZE(md);
323 /* If range overlaps the end, push out the relocation start */
324 if (md_end > relo_start)
325 relo_start = md_end;
326 }
327 }
328 last_md = md;
329 relo_end = relo_start + relo_size;
331 md_end = __pa(ia64_imva(&_end));
333 /*
334 * Move any relocated data out into the previously found relocation
335 * area. Any extra memory descriptrs are moved out to the end
336 * and set to zero pages.
337 */
338 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
339 md_end = md->phys_addr + MD_SIZE(md);
341 if (md->type == EFI_LOADER_DATA) {
342 unsigned long relo_offset;
344 if (md_overlaps(md, ia64_boot_param->domain_start)) {
345 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
346 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
347 ia64_boot_param->domain_start, relo_start + relo_offset,
348 ia64_boot_param->domain_size >> 10);
349 ia64_boot_param->domain_start = relo_start + relo_offset;
350 }
351 if (ia64_boot_param->initrd_size &&
352 md_overlaps(md, ia64_boot_param->initrd_start)) {
353 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
354 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
355 ia64_boot_param->initrd_start, relo_start + relo_offset,
356 ia64_boot_param->initrd_size >> 10);
357 ia64_boot_param->initrd_start = relo_start + relo_offset;
358 }
359 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
360 relo_start += MD_SIZE(md);
361 }
363 if (md == kern_md)
364 continue;
365 if (md == last_md)
366 break;
368 md->phys_addr = relo_end;
369 md->num_pages = 0;
370 }
372 /* Trim the last entry */
373 md->phys_addr = relo_end;
374 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
376 /*
377 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
378 * the full size. This range will already be type EFI_LOADER_DATA,
379 * therefore the xenheap area is now protected being allocated for
380 * use by find_memmap_space() in efi.c
381 */
382 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
384 reserve_memory();
386 /* first find highest page frame number */
387 max_page = 0;
388 efi_memmap_walk(find_max_pfn, &max_page);
389 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
390 efi_print();
392 heap_start = memguard_init(ia64_imva(&_end));
393 printf("Before heap_start: %p\n", heap_start);
394 heap_start = __va(init_boot_allocator(__pa(heap_start)));
395 printf("After heap_start: %p\n", heap_start);
397 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
398 efi_memmap_walk(xen_count_pages, &nr_pages);
400 printk("System RAM: %luMB (%lukB)\n",
401 nr_pages >> (20 - PAGE_SHIFT),
402 nr_pages << (PAGE_SHIFT - 10));
403 total_pages = nr_pages;
405 init_frametable();
407 trap_init();
409 alloc_dom0();
411 end_boot_allocator();
413 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
414 printk("Xen heap: %luMB (%lukB)\n",
415 (xenheap_phys_end-__pa(heap_start)) >> 20,
416 (xenheap_phys_end-__pa(heap_start)) >> 10);
418 late_setup_arch(&cmdline);
420 scheduler_init();
421 idle_vcpu[0] = (struct vcpu*) ia64_r13;
422 idle_domain = domain_create(IDLE_DOMAIN_ID);
423 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
424 BUG();
426 alloc_dom_xen_and_dom_io();
427 setup_per_cpu_areas();
428 mem_init();
430 local_irq_disable();
431 init_IRQ ();
432 init_xen_time(); /* initialise the time */
433 timer_init();
435 #ifdef CONFIG_SMP
436 if ( opt_nosmp )
437 {
438 max_cpus = 0;
439 smp_num_siblings = 1;
440 //boot_cpu_data.x86_num_cores = 1;
441 }
443 /* A vcpu is created for the idle domain on every physical cpu.
444 Limit the number of cpus to the maximum number of vcpus. */
445 if (max_cpus > MAX_VIRT_CPUS)
446 max_cpus = MAX_VIRT_CPUS;
448 smp_prepare_cpus(max_cpus);
450 /* We aren't hotplug-capable yet. */
451 for_each_cpu ( i )
452 cpu_set(i, cpu_present_map);
454 /* Enable IRQ to receive IPI (needed for ITC sync). */
455 local_irq_enable();
457 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
458 for_each_present_cpu ( i )
459 {
460 if ( num_online_cpus() >= max_cpus )
461 break;
462 if ( !cpu_online(i) ) {
463 __cpu_up(i);
464 }
465 }
467 local_irq_disable();
469 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
470 smp_cpus_done(max_cpus);
471 #endif
473 initialise_gdb(); /* could be moved earlier */
475 do_initcalls();
476 sort_main_extable();
478 init_rid_allocator ();
480 local_irq_enable();
482 if (opt_xencons) {
483 initialize_keytable();
484 if (ns16550_com1_gsi) {
485 if (opt_xencons_poll ||
486 iosapic_register_intr(ns16550_com1_gsi,
487 ns16550_com1_polarity,
488 ns16550_com1_trigger) < 0) {
489 ns16550_com1.irq = 0;
490 ns16550_init(0, &ns16550_com1);
491 }
492 }
493 serial_init_postirq();
495 /* Hide the HCDP table from dom0 */
496 efi.hcdp = NULL;
497 }
499 /* Create initial domain 0. */
500 dom0 = domain_create(0);
501 if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
502 panic("Error creating domain 0\n");
504 set_bit(_DOMF_privileged, &dom0->domain_flags);
506 /*
507 * We're going to setup domain0 using the module(s) that we stashed safely
508 * above our heap. The second module, if present, is an initrd ramdisk.
509 */
510 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
511 dom0_memory_size = ia64_boot_param->domain_size;
512 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
513 dom0_initrd_size = ia64_boot_param->initrd_size;
515 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
516 dom0_initrd_start,dom0_initrd_size,
517 0) != 0)
518 panic("Could not set up DOM0 guest OS\n");
520 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
521 scrub_heap_pages();
523 init_trace_bufs();
525 if (opt_xencons) {
526 console_endboot();
527 serial_endboot();
528 }
530 domain0_ready = 1;
532 schedulers_start();
534 domain_unpause_by_systemcontroller(dom0);
536 startup_cpu_idle_loop();
537 }
539 void arch_get_xen_caps(xen_capabilities_info_t info)
540 {
541 char *p=info;
542 int major = xen_major_version();
543 int minor = xen_minor_version();
545 p += sprintf(p,"xen-%d.%d-ia64 ", major, minor);
547 if (vmx_enabled)
548 p += sprintf(p,"hvm-%d.%d-ia64 ", major, minor);
550 *(p-1) = 0;
552 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
554 }