ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 10157:faae893d428e

[IA64] support FPSWA emulation

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Thu May 25 15:47:33 2006 -0600 (2006-05-25)
parents 2cab08ac143b
children 0a226de3fc37 4122e88b6c75
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/compile.h>
17 #include <xen/console.h>
18 #include <xen/serial.h>
19 #include <xen/trace.h>
20 #include <asm/meminit.h>
21 #include <asm/page.h>
22 #include <asm/setup.h>
23 #include <xen/string.h>
24 #include <asm/vmx.h>
25 #include <linux/efi.h>
27 /* Be sure the struct shared_info fits on a page because it is mapped in
28 domain. */
29 #if SHARED_INFO_SIZE > PAGE_SIZE
30 #error "struct shared_info does not not fit in PAGE_SIZE"
31 #endif
33 unsigned long xenheap_phys_end, total_pages;
35 char saved_command_line[COMMAND_LINE_SIZE];
36 char dom0_command_line[COMMAND_LINE_SIZE];
38 struct vcpu *idle_vcpu[NR_CPUS];
40 cpumask_t cpu_present_map;
42 extern unsigned long domain0_ready;
44 int find_max_pfn (unsigned long, unsigned long, void *);
45 void start_of_day(void);
47 /* FIXME: which header these declarations should be there ? */
48 extern long is_platform_hp_ski(void);
49 extern void early_setup_arch(char **);
50 extern void late_setup_arch(char **);
51 extern void hpsim_serial_init(void);
52 extern void alloc_dom0(void);
53 extern void setup_per_cpu_areas(void);
54 extern void mem_init(void);
55 extern void init_IRQ(void);
56 extern void trap_init(void);
58 /* opt_nosmp: If true, secondary processors are ignored. */
59 static int opt_nosmp = 0;
60 boolean_param("nosmp", opt_nosmp);
62 /* maxcpus: maximum number of CPUs to activate. */
63 static unsigned int max_cpus = NR_CPUS;
64 integer_param("maxcpus", max_cpus);
66 /*
67 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
68 * xen image
69 * bootmap bits
70 * xen heap
71 * Note: To allow xenheap size configurable, the prerequisite is
72 * to configure elilo allowing relocation defaultly. Then since
73 * elilo chooses 256M as alignment when relocating, alignment issue
74 * on IPF can be addressed.
75 */
76 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
77 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
78 extern long running_on_sim;
79 unsigned long xen_pstart;
81 static int
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 /* Find first hole after trunk for xen image */
94 static int
95 xen_find_first_hole(u64 start, u64 end, void *arg)
96 {
97 unsigned long *first_hole = arg;
99 if ((*first_hole) == 0) {
100 if ((start <= KERNEL_START) && (KERNEL_START < end))
101 *first_hole = __pa(end);
102 }
104 return 0;
105 }
107 static void __init do_initcalls(void)
108 {
109 initcall_t *call;
110 for ( call = &__initcall_start; call < &__initcall_end; call++ )
111 (*call)();
112 }
114 /*
115 * IPF loader only supports one commaind line currently, for
116 * both xen and guest kernel. This function provides pre-parse
117 * to mixed command line, to split it into two parts.
118 *
119 * User should split the parameters by "--", with strings after
120 * spliter for guest kernel. Missing "--" means whole line belongs
121 * to guest. Example:
122 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
123 * root=/dev/sda3 ro"
124 */
125 static char null[4] = { 0 };
127 void early_cmdline_parse(char **cmdline_p)
128 {
129 char *guest_cmd;
130 static const char * const split = "--";
132 if (*cmdline_p == NULL) {
133 *cmdline_p = &null[0];
134 saved_command_line[0] = '\0';
135 dom0_command_line[0] = '\0';
136 return;
137 }
139 guest_cmd = strstr(*cmdline_p, split);
140 /* If no spliter, whole line is for guest */
141 if (guest_cmd == NULL) {
142 guest_cmd = *cmdline_p;
143 *cmdline_p = &null[0];
144 } else {
145 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
146 guest_cmd += strlen(split);
147 while (*guest_cmd == ' ') guest_cmd++;
148 }
150 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
151 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
152 return;
153 }
155 struct ns16550_defaults ns16550_com1 = {
156 .baud = BAUD_AUTO,
157 .data_bits = 8,
158 .parity = 'n',
159 .stop_bits = 1
160 };
162 struct ns16550_defaults ns16550_com2 = {
163 .baud = BAUD_AUTO,
164 .data_bits = 8,
165 .parity = 'n',
166 .stop_bits = 1
167 };
169 /* efi_print: print efi table at boot */
170 static int opt_efi_print = 0;
171 boolean_param("efi_print", opt_efi_print);
173 /* print EFI memory map: */
174 static void
175 efi_print(void)
176 {
177 void *efi_map_start, *efi_map_end;
178 u64 efi_desc_size;
180 efi_memory_desc_t *md;
181 void *p;
182 int i;
184 if (!opt_efi_print)
185 return;
187 efi_map_start = __va(ia64_boot_param->efi_memmap);
188 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
189 efi_desc_size = ia64_boot_param->efi_memdesc_size;
191 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
192 md = p;
193 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
194 i, md->type, md->attribute, md->phys_addr,
195 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
196 md->num_pages >> (20 - EFI_PAGE_SHIFT));
197 }
198 }
200 void start_kernel(void)
201 {
202 unsigned char *cmdline;
203 void *heap_start;
204 unsigned long nr_pages, firsthole_start;
205 unsigned long dom0_memory_start, dom0_memory_size;
206 unsigned long dom0_initrd_start, dom0_initrd_size;
207 unsigned long initial_images_start, initial_images_end;
208 struct domain *idle_domain;
209 #ifdef CONFIG_SMP
210 int i;
211 #endif
213 running_on_sim = is_platform_hp_ski();
214 /* Kernel may be relocated by EFI loader */
215 xen_pstart = ia64_tpa(KERNEL_START);
217 early_setup_arch((char **) &cmdline);
219 /* We initialise the serial devices very early so we can get debugging. */
220 if (running_on_sim) hpsim_serial_init();
221 else {
222 ns16550_init(0, &ns16550_com1);
223 /* Also init com2 for Tiger4. */
224 ns16550_com2.io_base = 0x2f8;
225 ns16550_com2.irq = 3;
226 ns16550_init(1, &ns16550_com2);
227 }
228 serial_init_preirq();
230 init_console();
231 set_printk_prefix("(XEN) ");
233 /* xenheap should be in same TR-covered range with xen image */
234 xenheap_phys_end = xen_pstart + xenheap_size;
235 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
236 xen_pstart, xenheap_phys_end);
238 /* Find next hole */
239 firsthole_start = 0;
240 efi_memmap_walk(xen_find_first_hole, &firsthole_start);
242 if (running_on_sim || ia64_boot_param->domain_start == 0
243 || ia64_boot_param->domain_size == 0) {
244 /* This is possible only with the old elilo, which does not support
245 a vmm. Fix now, and continue without initrd. */
246 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
247 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
248 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
249 ia64_boot_param->initrd_start = 0;
250 ia64_boot_param->initrd_size = 0;
251 }
253 initial_images_start = xenheap_phys_end;
254 initial_images_end = initial_images_start +
255 PAGE_ALIGN(ia64_boot_param->domain_size);
257 /* also reserve space for initrd */
258 if (ia64_boot_param->initrd_start && ia64_boot_param->initrd_size)
259 initial_images_end += PAGE_ALIGN(ia64_boot_param->initrd_size);
260 else {
261 /* sanity cleanup */
262 ia64_boot_param->initrd_size = 0;
263 ia64_boot_param->initrd_start = 0;
264 }
267 /* Later may find another memory trunk, even away from xen image... */
268 if (initial_images_end > firsthole_start) {
269 printk("Not enough memory to stash the DOM0 kernel image.\n");
270 printk("First hole:0x%lx, relocation end: 0x%lx\n",
271 firsthole_start, initial_images_end);
272 for ( ; ; );
273 }
275 /* This copy is time consuming, but elilo may load Dom0 image
276 * within xenheap range */
277 printk("ready to move Dom0 to 0x%lx with len %lx...", initial_images_start,
278 ia64_boot_param->domain_size);
280 memmove(__va(initial_images_start),
281 __va(ia64_boot_param->domain_start),
282 ia64_boot_param->domain_size);
283 ia64_boot_param->domain_start = initial_images_start;
285 printk("ready to move initrd to 0x%lx with len %lx...",
286 initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size),
287 ia64_boot_param->initrd_size);
288 memmove(__va(initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size)),
289 __va(ia64_boot_param->initrd_start),
290 ia64_boot_param->initrd_size);
291 printk("Done\n");
292 ia64_boot_param->initrd_start = initial_images_start +
293 PAGE_ALIGN(ia64_boot_param->domain_size);
295 /* first find highest page frame number */
296 max_page = 0;
297 efi_memmap_walk(find_max_pfn, &max_page);
298 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
299 #ifndef CONFIG_XEN_IA64_DOM0_VP
300 /* this is a bad hack. see dom_fw.c creation of EFI map for dom0 */
301 max_page = (GRANULEROUNDDOWN(max_page << PAGE_SHIFT)
302 - IA64_GRANULE_SIZE) >> PAGE_SHIFT;
303 printf("find_memory: last granule reserved for dom0; xen max_page=%lx\n",
304 max_page);
305 #endif
306 efi_print();
308 heap_start = memguard_init(ia64_imva(&_end));
309 printf("Before heap_start: %p\n", heap_start);
310 heap_start = __va(init_boot_allocator(__pa(heap_start)));
311 printf("After heap_start: %p\n", heap_start);
313 reserve_memory();
315 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
316 efi_memmap_walk(xen_count_pages, &nr_pages);
318 printk("System RAM: %luMB (%lukB)\n",
319 nr_pages >> (20 - PAGE_SHIFT),
320 nr_pages << (PAGE_SHIFT - 10));
321 total_pages = nr_pages;
323 init_frametable();
325 trap_init();
327 alloc_dom0();
329 end_boot_allocator();
331 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
332 printk("Xen heap: %luMB (%lukB)\n",
333 (xenheap_phys_end-__pa(heap_start)) >> 20,
334 (xenheap_phys_end-__pa(heap_start)) >> 10);
336 printk("About to call scheduler_init()\n");
337 scheduler_init();
338 idle_vcpu[0] = (struct vcpu*) ia64_r13;
339 idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
340 BUG_ON(idle_domain == NULL);
342 late_setup_arch((char **) &cmdline);
343 alloc_dom_xen_and_dom_io();
344 setup_per_cpu_areas();
345 mem_init();
347 local_irq_disable();
348 init_IRQ ();
349 printk("About to call init_xen_time()\n");
350 init_xen_time(); /* initialise the time */
351 printk("About to call timer_init()\n");
352 timer_init();
354 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
355 initialize_keytable();
356 serial_init_postirq();
357 #endif
359 #ifdef CONFIG_SMP
360 if ( opt_nosmp )
361 {
362 max_cpus = 0;
363 smp_num_siblings = 1;
364 //boot_cpu_data.x86_num_cores = 1;
365 }
367 /* A vcpu is created for the idle domain on every physical cpu.
368 Limit the number of cpus to the maximum number of vcpus. */
369 if (max_cpus > MAX_VIRT_CPUS)
370 max_cpus = MAX_VIRT_CPUS;
372 smp_prepare_cpus(max_cpus);
374 /* We aren't hotplug-capable yet. */
375 for_each_cpu ( i )
376 cpu_set(i, cpu_present_map);
378 /* Enable IRQ to receive IPI (needed for ITC sync). */
379 local_irq_enable();
381 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
382 for_each_present_cpu ( i )
383 {
384 if ( num_online_cpus() >= max_cpus )
385 break;
386 if ( !cpu_online(i) ) {
387 __cpu_up(i);
388 }
389 }
391 local_irq_disable();
393 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
394 smp_cpus_done(max_cpus);
395 #endif
397 initialise_gdb(); /* could be moved earlier */
399 do_initcalls();
400 printk("About to call sort_main_extable()\n");
401 sort_main_extable();
404 init_rid_allocator ();
406 /* Create initial domain 0. */
407 printk("About to call domain_create()\n");
408 dom0 = domain_create(0, 0);
410 if ( dom0 == NULL )
411 panic("Error creating domain 0\n");
413 set_bit(_DOMF_privileged, &dom0->domain_flags);
415 /*
416 * We're going to setup domain0 using the module(s) that we stashed safely
417 * above our heap. The second module, if present, is an initrd ramdisk.
418 */
419 printk("About to call construct_dom0()\n");
420 dom0_memory_start = (unsigned long) __va(initial_images_start);
421 dom0_memory_size = ia64_boot_param->domain_size;
422 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
423 dom0_initrd_size = ia64_boot_param->initrd_size;
425 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
426 dom0_initrd_start,dom0_initrd_size,
427 0) != 0)
428 panic("Could not set up DOM0 guest OS\n");
430 /* PIN domain0 on CPU 0. */
431 dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
433 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
434 scrub_heap_pages();
436 printk("About to call init_trace_bufs()\n");
437 init_trace_bufs();
439 /* Give up the VGA console if DOM0 is configured to grab it. */
440 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
441 console_endboot(cmdline && strstr(cmdline, "tty0"));
442 #endif
444 domain0_ready = 1;
446 local_irq_enable();
448 printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
449 dom0, &idle_domain);
450 schedulers_start();
452 domain_unpause_by_systemcontroller(dom0);
454 printk("About to call startup_cpu_idle_loop()\n");
455 startup_cpu_idle_loop();
456 }
458 void arch_get_xen_caps(xen_capabilities_info_t info)
459 {
460 char *p=info;
462 p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
464 if (vmx_enabled)
465 p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
467 *(p-1) = 0;
469 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
471 }