ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 9405:29dfadcc5029

[IA64] Followup to xen time cleanup

Clean up to xen time handler. Tristan #if 0 some code because it seems
redundant, which however is actually problematic logic as a reason for
an intermittent timer oops issue of dom0. So delete it now.

Also remove vcpu_wake, since wakeup current has nothing meaningful and
simply waste cpu cycle.

Signed-off-by: Kevin Tian <kevin.tian@intel.com>
author awilliam@xenbuild.aw
date Mon Mar 27 15:32:08 2006 -0700 (2006-03-27)
parents 58a3ed82eee4
children 8e0b9f31cf3f
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 unsigned long xenheap_phys_end;
29 char saved_command_line[COMMAND_LINE_SIZE];
30 char dom0_command_line[COMMAND_LINE_SIZE];
32 struct vcpu *idle_vcpu[NR_CPUS];
34 cpumask_t cpu_present_map;
36 extern unsigned long domain0_ready;
38 int find_max_pfn (unsigned long, unsigned long, void *);
39 void start_of_day(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);
51 /* opt_nosmp: If true, secondary processors are ignored. */
52 static int opt_nosmp = 0;
53 boolean_param("nosmp", opt_nosmp);
55 /* maxcpus: maximum number of CPUs to activate. */
56 static unsigned int max_cpus = NR_CPUS;
57 integer_param("maxcpus", max_cpus);
59 /*
60 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
61 * xen image
62 * bootmap bits
63 * xen heap
64 * Note: To allow xenheap size configurable, the prerequisite is
65 * to configure elilo allowing relocation defaultly. Then since
66 * elilo chooses 256M as alignment when relocating, alignment issue
67 * on IPF can be addressed.
68 */
69 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
70 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
71 extern long running_on_sim;
72 unsigned long xen_pstart;
74 static int
75 xen_count_pages(u64 start, u64 end, void *arg)
76 {
77 unsigned long *count = arg;
79 /* FIXME: do we need consider difference between DMA-usable memory and
80 * normal memory? Seems that HV has no requirement to operate DMA which
81 * is owned by Dom0? */
82 *count += (end - start) >> PAGE_SHIFT;
83 return 0;
84 }
86 /* Find first hole after trunk for xen image */
87 static int
88 xen_find_first_hole(u64 start, u64 end, void *arg)
89 {
90 unsigned long *first_hole = arg;
92 if ((*first_hole) == 0) {
93 if ((start <= KERNEL_START) && (KERNEL_START < end))
94 *first_hole = __pa(end);
95 }
97 return 0;
98 }
100 static void __init do_initcalls(void)
101 {
102 initcall_t *call;
103 for ( call = &__initcall_start; call < &__initcall_end; call++ )
104 (*call)();
105 }
107 /*
108 * IPF loader only supports one commaind line currently, for
109 * both xen and guest kernel. This function provides pre-parse
110 * to mixed command line, to split it into two parts.
111 *
112 * User should split the parameters by "--", with strings after
113 * spliter for guest kernel. Missing "--" means whole line belongs
114 * to guest. Example:
115 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
116 * root=/dev/sda3 ro"
117 */
118 static char null[4] = { 0 };
120 void early_cmdline_parse(char **cmdline_p)
121 {
122 char *guest_cmd;
123 static const char * const split = "--";
125 if (*cmdline_p == NULL) {
126 *cmdline_p = &null[0];
127 saved_command_line[0] = '\0';
128 dom0_command_line[0] = '\0';
129 return;
130 }
132 guest_cmd = strstr(*cmdline_p, split);
133 /* If no spliter, whole line is for guest */
134 if (guest_cmd == NULL) {
135 guest_cmd = *cmdline_p;
136 *cmdline_p = &null[0];
137 } else {
138 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
139 guest_cmd += strlen(split);
140 while (*guest_cmd == ' ') guest_cmd++;
141 }
143 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
144 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
145 return;
146 }
148 struct ns16550_defaults ns16550_com1 = {
149 .baud = BAUD_AUTO,
150 .data_bits = 8,
151 .parity = 'n',
152 .stop_bits = 1
153 };
155 struct ns16550_defaults ns16550_com2 = {
156 .baud = BAUD_AUTO,
157 .data_bits = 8,
158 .parity = 'n',
159 .stop_bits = 1
160 };
162 void start_kernel(void)
163 {
164 unsigned char *cmdline;
165 void *heap_start;
166 unsigned long nr_pages, firsthole_start;
167 unsigned long dom0_memory_start, dom0_memory_size;
168 unsigned long dom0_initrd_start, dom0_initrd_size;
169 unsigned long initial_images_start, initial_images_end;
170 struct domain *idle_domain;
171 #ifdef CONFIG_SMP
172 int i;
173 #endif
175 running_on_sim = is_platform_hp_ski();
176 /* Kernel may be relocated by EFI loader */
177 xen_pstart = ia64_tpa(KERNEL_START);
179 early_setup_arch((char **) &cmdline);
181 /* We initialise the serial devices very early so we can get debugging. */
182 if (running_on_sim) hpsim_serial_init();
183 else {
184 ns16550_init(0, &ns16550_com1);
185 /* Also init com2 for Tiger4. */
186 ns16550_com2.io_base = 0x2f8;
187 ns16550_com2.irq = 3;
188 ns16550_init(1, &ns16550_com2);
189 }
190 serial_init_preirq();
192 init_console();
193 set_printk_prefix("(XEN) ");
195 /* xenheap should be in same TR-covered range with xen image */
196 xenheap_phys_end = xen_pstart + xenheap_size;
197 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
198 xen_pstart, xenheap_phys_end);
200 /* Find next hole */
201 firsthole_start = 0;
202 efi_memmap_walk(xen_find_first_hole, &firsthole_start);
204 if (running_on_sim || ia64_boot_param->domain_start == 0
205 || ia64_boot_param->domain_size == 0) {
206 /* This is possible only with the old elilo, which does not support
207 a vmm. Fix now, and continue without initrd. */
208 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
209 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
210 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
211 ia64_boot_param->initrd_start = 0;
212 ia64_boot_param->initrd_size = 0;
213 }
215 initial_images_start = xenheap_phys_end;
216 initial_images_end = initial_images_start +
217 PAGE_ALIGN(ia64_boot_param->domain_size);
219 /* also reserve space for initrd */
220 if (ia64_boot_param->initrd_start && ia64_boot_param->initrd_size)
221 initial_images_end += PAGE_ALIGN(ia64_boot_param->initrd_size);
222 else {
223 /* sanity cleanup */
224 ia64_boot_param->initrd_size = 0;
225 ia64_boot_param->initrd_start = 0;
226 }
229 /* Later may find another memory trunk, even away from xen image... */
230 if (initial_images_end > firsthole_start) {
231 printk("Not enough memory to stash the DOM0 kernel image.\n");
232 printk("First hole:0x%lx, relocation end: 0x%lx\n",
233 firsthole_start, initial_images_end);
234 for ( ; ; );
235 }
237 /* This copy is time consuming, but elilo may load Dom0 image
238 * within xenheap range */
239 printk("ready to move Dom0 to 0x%lx with len %lx...", initial_images_start,
240 ia64_boot_param->domain_size);
242 memmove(__va(initial_images_start),
243 __va(ia64_boot_param->domain_start),
244 ia64_boot_param->domain_size);
245 // ia64_boot_param->domain_start = initial_images_start;
247 printk("ready to move initrd to 0x%lx with len %lx...",
248 initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size),
249 ia64_boot_param->initrd_size);
250 memmove(__va(initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size)),
252 __va(ia64_boot_param->initrd_start),
253 ia64_boot_param->initrd_size);
254 printk("Done\n");
256 /* first find highest page frame number */
257 max_page = 0;
258 efi_memmap_walk(find_max_pfn, &max_page);
259 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
260 /* this is a bad hack. see dom_fw.c creation of EFI map for dom0 */
261 max_page = (GRANULEROUNDDOWN(max_page << PAGE_SHIFT)
262 - IA64_GRANULE_SIZE) >> PAGE_SHIFT;
263 printf("find_memory: last granule reserved for dom0; xen max_page=%lx\n",
264 max_page);
266 heap_start = memguard_init(ia64_imva(&_end));
267 printf("Before heap_start: %p\n", heap_start);
268 heap_start = __va(init_boot_allocator(__pa(heap_start)));
269 printf("After heap_start: %p\n", heap_start);
271 reserve_memory();
273 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
274 efi_memmap_walk(xen_count_pages, &nr_pages);
276 printk("System RAM: %luMB (%lukB)\n",
277 nr_pages >> (20 - PAGE_SHIFT),
278 nr_pages << (PAGE_SHIFT - 10));
280 init_frametable();
282 ia64_fph_enable();
283 __ia64_init_fpu();
285 alloc_dom0();
287 end_boot_allocator();
289 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
290 printk("Xen heap: %luMB (%lukB)\n",
291 (xenheap_phys_end-__pa(heap_start)) >> 20,
292 (xenheap_phys_end-__pa(heap_start)) >> 10);
294 printk("About to call scheduler_init()\n");
295 scheduler_init();
296 idle_vcpu[0] = (struct vcpu*) ia64_r13;
297 idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
298 BUG_ON(idle_domain == NULL);
300 late_setup_arch((char **) &cmdline);
301 setup_per_cpu_areas();
302 mem_init();
304 local_irq_disable();
305 init_IRQ ();
306 printk("About to call init_xen_time()\n");
307 init_xen_time(); /* initialise the time */
308 printk("About to call timer_init()\n");
309 timer_init();
311 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
312 initialize_keytable();
313 serial_init_postirq();
314 #endif
316 #ifdef CONFIG_SMP
317 if ( opt_nosmp )
318 {
319 max_cpus = 0;
320 smp_num_siblings = 1;
321 //boot_cpu_data.x86_num_cores = 1;
322 }
324 smp_prepare_cpus(max_cpus);
325 /* We aren't hotplug-capable yet. */
326 for_each_cpu ( i )
327 cpu_set(i, cpu_present_map);
329 /* Enable IRQ to receive IPI (needed for ITC sync). */
330 local_irq_enable();
332 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
333 for_each_present_cpu ( i )
334 {
335 if ( num_online_cpus() >= max_cpus )
336 break;
337 if ( !cpu_online(i) ) {
338 __cpu_up(i);
339 }
340 }
342 local_irq_disable();
344 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
345 smp_cpus_done(max_cpus);
346 #endif
348 initialise_gdb(); /* could be moved earlier */
350 do_initcalls();
351 printk("About to call sort_main_extable()\n");
352 sort_main_extable();
355 /* Create initial domain 0. */
356 printk("About to call domain_create()\n");
357 dom0 = domain_create(0, 0);
359 if ( dom0 == NULL )
360 panic("Error creating domain 0\n");
362 set_bit(_DOMF_privileged, &dom0->domain_flags);
364 /*
365 * We're going to setup domain0 using the module(s) that we stashed safely
366 * above our heap. The second module, if present, is an initrd ramdisk.
367 */
368 printk("About to call construct_dom0()\n");
369 dom0_memory_start = (unsigned long) __va(initial_images_start);
370 dom0_memory_size = ia64_boot_param->domain_size;
371 dom0_initrd_start = (unsigned long) __va(initial_images_start +
372 PAGE_ALIGN(ia64_boot_param->domain_size));
373 dom0_initrd_size = ia64_boot_param->initrd_size;
375 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
376 dom0_initrd_start,dom0_initrd_size,
377 0) != 0)
378 panic("Could not set up DOM0 guest OS\n");
380 /* PIN domain0 on CPU 0. */
381 dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
383 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
384 scrub_heap_pages();
386 printk("About to call init_trace_bufs()\n");
387 init_trace_bufs();
389 /* Give up the VGA console if DOM0 is configured to grab it. */
390 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
391 console_endboot(cmdline && strstr(cmdline, "tty0"));
392 #endif
394 domain0_ready = 1;
396 local_irq_enable();
398 printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
399 dom0, &idle_domain);
400 schedulers_start();
402 domain_unpause_by_systemcontroller(dom0);
404 printk("About to call startup_cpu_idle_loop()\n");
405 startup_cpu_idle_loop();
406 }
408 void arch_get_xen_caps(xen_capabilities_info_t info)
409 {
410 char *p=info;
412 p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
414 if (vmx_enabled)
415 p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
417 *(p-1) = 0;
419 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
421 }