ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 11052:91169603a8e8

[IA64] Remove PIN processing for Domain-0 vcpu0

This patch removes PIN processing for Domain-0 vcpu0 executed
at the time of Xen initialization.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Tue Aug 22 14:45:49 2006 -0600 (2006-08-22)
parents 741fd616f5dc
children 8c4c5e1bf58a
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 <asm/meminit.h>
22 #include <asm/page.h>
23 #include <asm/setup.h>
24 #include <xen/string.h>
25 #include <asm/vmx.h>
26 #include <linux/efi.h>
27 #include <asm/iosapic.h>
29 unsigned long xenheap_phys_end, total_pages;
31 char saved_command_line[COMMAND_LINE_SIZE];
32 char dom0_command_line[COMMAND_LINE_SIZE];
34 cpumask_t cpu_present_map;
36 extern unsigned long domain0_ready;
38 int find_max_pfn (unsigned long, unsigned long, void *);
40 /* FIXME: which header these declarations should be there ? */
41 extern void initialize_keytable(void);
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 /* xenheap should be in same TR-covered range with xen image */
291 xenheap_phys_end = xen_pstart + xenheap_size;
292 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
293 xen_pstart, xenheap_phys_end);
295 kern_md = md = efi_get_md(xen_pstart);
296 md_end = __pa(ia64_imva(&_end));
297 relo_start = xenheap_phys_end;
299 /*
300 * Scan through the memory descriptors after the kernel
301 * image to make sure we have enough room for the xenheap
302 * area, pushing out whatever may already be there.
303 */
304 while (relo_start + relo_size >= md_end) {
305 md = efi_get_md(md_end);
307 BUG_ON(!md);
308 BUG_ON(!is_xenheap_usable_memory(md));
310 md_end = md->phys_addr + MD_SIZE(md);
311 /*
312 * The dom0 kernel or initrd could overlap, reserve space
313 * at the end to relocate them later.
314 */
315 if (md->type == EFI_LOADER_DATA) {
316 /* Test for ranges we're not prepared to move */
317 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
318 md_overlaps(md, ia64_boot_param->efi_memmap) ||
319 md_overlaps(md, ia64_boot_param->command_line));
321 relo_size += MD_SIZE(md);
322 /* If range overlaps the end, push out the relocation start */
323 if (md_end > relo_start)
324 relo_start = md_end;
325 }
326 }
327 last_md = md;
328 relo_end = relo_start + relo_size;
330 md_end = __pa(ia64_imva(&_end));
332 /*
333 * Move any relocated data out into the previously found relocation
334 * area. Any extra memory descriptrs are moved out to the end
335 * and set to zero pages.
336 */
337 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
338 md_end = md->phys_addr + MD_SIZE(md);
340 if (md->type == EFI_LOADER_DATA) {
341 unsigned long relo_offset;
343 if (md_overlaps(md, ia64_boot_param->domain_start)) {
344 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
345 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
346 ia64_boot_param->domain_start, relo_start + relo_offset,
347 ia64_boot_param->domain_size >> 10);
348 ia64_boot_param->domain_start = relo_start + relo_offset;
349 }
350 if (ia64_boot_param->initrd_size &&
351 md_overlaps(md, ia64_boot_param->initrd_start)) {
352 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
353 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
354 ia64_boot_param->initrd_start, relo_start + relo_offset,
355 ia64_boot_param->initrd_size >> 10);
356 ia64_boot_param->initrd_start = relo_start + relo_offset;
357 }
358 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
359 relo_start += MD_SIZE(md);
360 }
362 if (md == kern_md)
363 continue;
364 if (md == last_md)
365 break;
367 md->phys_addr = relo_end;
368 md->num_pages = 0;
369 }
371 /* Trim the last entry */
372 md->phys_addr = relo_end;
373 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
375 /*
376 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
377 * the full size. This range will already be type EFI_LOADER_DATA,
378 * therefore the xenheap area is now protected being allocated for
379 * use by find_memmap_space() in efi.c
380 */
381 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
383 reserve_memory();
385 /* first find highest page frame number */
386 max_page = 0;
387 efi_memmap_walk(find_max_pfn, &max_page);
388 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
389 efi_print();
391 heap_start = memguard_init(ia64_imva(&_end));
392 printf("Before heap_start: %p\n", heap_start);
393 heap_start = __va(init_boot_allocator(__pa(heap_start)));
394 printf("After heap_start: %p\n", heap_start);
396 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
397 efi_memmap_walk(xen_count_pages, &nr_pages);
399 printk("System RAM: %luMB (%lukB)\n",
400 nr_pages >> (20 - PAGE_SHIFT),
401 nr_pages << (PAGE_SHIFT - 10));
402 total_pages = nr_pages;
404 init_frametable();
406 trap_init();
408 alloc_dom0();
410 end_boot_allocator();
412 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
413 printk("Xen heap: %luMB (%lukB)\n",
414 (xenheap_phys_end-__pa(heap_start)) >> 20,
415 (xenheap_phys_end-__pa(heap_start)) >> 10);
417 late_setup_arch(&cmdline);
419 scheduler_init();
420 idle_vcpu[0] = (struct vcpu*) ia64_r13;
421 idle_domain = domain_create(IDLE_DOMAIN_ID);
422 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
423 BUG();
425 alloc_dom_xen_and_dom_io();
426 setup_per_cpu_areas();
427 mem_init();
429 local_irq_disable();
430 init_IRQ ();
431 init_xen_time(); /* initialise the time */
432 timer_init();
434 #ifdef CONFIG_SMP
435 if ( opt_nosmp )
436 {
437 max_cpus = 0;
438 smp_num_siblings = 1;
439 //boot_cpu_data.x86_num_cores = 1;
440 }
442 /* A vcpu is created for the idle domain on every physical cpu.
443 Limit the number of cpus to the maximum number of vcpus. */
444 if (max_cpus > MAX_VIRT_CPUS)
445 max_cpus = MAX_VIRT_CPUS;
447 smp_prepare_cpus(max_cpus);
449 /* We aren't hotplug-capable yet. */
450 for_each_cpu ( i )
451 cpu_set(i, cpu_present_map);
453 /* Enable IRQ to receive IPI (needed for ITC sync). */
454 local_irq_enable();
456 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
457 for_each_present_cpu ( i )
458 {
459 if ( num_online_cpus() >= max_cpus )
460 break;
461 if ( !cpu_online(i) ) {
462 __cpu_up(i);
463 }
464 }
466 local_irq_disable();
468 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
469 smp_cpus_done(max_cpus);
470 #endif
472 initialise_gdb(); /* could be moved earlier */
474 do_initcalls();
475 sort_main_extable();
477 init_rid_allocator ();
479 local_irq_enable();
481 if (opt_xencons) {
482 initialize_keytable();
483 if (ns16550_com1_gsi) {
484 if (opt_xencons_poll ||
485 iosapic_register_intr(ns16550_com1_gsi,
486 ns16550_com1_polarity,
487 ns16550_com1_trigger) < 0) {
488 ns16550_com1.irq = 0;
489 ns16550_init(0, &ns16550_com1);
490 }
491 }
492 serial_init_postirq();
494 /* Hide the HCDP table from dom0 */
495 efi.hcdp = NULL;
496 }
498 /* Create initial domain 0. */
499 dom0 = domain_create(0);
500 if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
501 panic("Error creating domain 0\n");
503 set_bit(_DOMF_privileged, &dom0->domain_flags);
505 /*
506 * We're going to setup domain0 using the module(s) that we stashed safely
507 * above our heap. The second module, if present, is an initrd ramdisk.
508 */
509 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
510 dom0_memory_size = ia64_boot_param->domain_size;
511 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
512 dom0_initrd_size = ia64_boot_param->initrd_size;
514 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
515 dom0_initrd_start,dom0_initrd_size,
516 0) != 0)
517 panic("Could not set up DOM0 guest OS\n");
519 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
520 scrub_heap_pages();
522 init_trace_bufs();
524 if (opt_xencons) {
525 console_endboot();
526 serial_endboot();
527 }
529 domain0_ready = 1;
531 schedulers_start();
533 domain_unpause_by_systemcontroller(dom0);
535 startup_cpu_idle_loop();
536 }
538 void arch_get_xen_caps(xen_capabilities_info_t info)
539 {
540 char *p=info;
541 int major = xen_major_version();
542 int minor = xen_minor_version();
544 p += sprintf(p,"xen-%d.%d-ia64 ", major, minor);
546 if (vmx_enabled)
547 p += sprintf(p,"hvm-%d.%d-ia64 ", major, minor);
549 *(p-1) = 0;
551 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
553 }