ia64/xen-unstable

view xen/arch/ia64/xen/xensetup.c @ 10934:2aaad9cbc926

[IA64] enable ioports_deny_access for dom0

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Tue Aug 08 14:36:21 2006 -0600 (2006-08-08)
parents c3e20511c745
children 54550e85f25a
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 /* Be sure the struct shared_info size is <= XSI_SIZE. */
30 #if SHARED_INFO_SIZE > XSI_SIZE
31 #error "struct shared_info bigger than XSI_SIZE"
32 #endif
34 unsigned long xenheap_phys_end, total_pages;
36 char saved_command_line[COMMAND_LINE_SIZE];
37 char dom0_command_line[COMMAND_LINE_SIZE];
39 cpumask_t cpu_present_map;
41 extern unsigned long domain0_ready;
43 int find_max_pfn (unsigned long, unsigned long, void *);
45 /* FIXME: which header these declarations should be there ? */
46 extern void initialize_keytable(void);
47 extern long is_platform_hp_ski(void);
48 extern void early_setup_arch(char **);
49 extern void late_setup_arch(char **);
50 extern void hpsim_serial_init(void);
51 extern void alloc_dom0(void);
52 extern void setup_per_cpu_areas(void);
53 extern void mem_init(void);
54 extern void init_IRQ(void);
55 extern void trap_init(void);
57 /* opt_nosmp: If true, secondary processors are ignored. */
58 static int opt_nosmp = 0;
59 boolean_param("nosmp", opt_nosmp);
61 /* maxcpus: maximum number of CPUs to activate. */
62 static unsigned int max_cpus = NR_CPUS;
63 integer_param("maxcpus", max_cpus);
65 /* xencons: if true enable xenconsole input (and irq).
66 Note: you have to disable 8250 serials in domains (to avoid use of the
67 same resource). */
68 static int opt_xencons = 1;
69 integer_param("xencons", opt_xencons);
71 /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
72 static int opt_xencons_poll = 0;
73 boolean_param("xencons_poll", opt_xencons_poll);
75 /*
76 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
77 * xen image
78 * bootmap bits
79 * xen heap
80 * Note: To allow xenheap size configurable, the prerequisite is
81 * to configure elilo allowing relocation defaultly. Then since
82 * elilo chooses 256M as alignment when relocating, alignment issue
83 * on IPF can be addressed.
84 */
85 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
86 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
87 extern long running_on_sim;
88 unsigned long xen_pstart;
90 static int
91 xen_count_pages(u64 start, u64 end, void *arg)
92 {
93 unsigned long *count = arg;
95 /* FIXME: do we need consider difference between DMA-usable memory and
96 * normal memory? Seems that HV has no requirement to operate DMA which
97 * is owned by Dom0? */
98 *count += (end - start) >> PAGE_SHIFT;
99 return 0;
100 }
102 static void __init do_initcalls(void)
103 {
104 initcall_t *call;
105 for ( call = &__initcall_start; call < &__initcall_end; call++ )
106 (*call)();
107 }
109 /*
110 * IPF loader only supports one commaind line currently, for
111 * both xen and guest kernel. This function provides pre-parse
112 * to mixed command line, to split it into two parts.
113 *
114 * User should split the parameters by "--", with strings after
115 * spliter for guest kernel. Missing "--" means whole line belongs
116 * to guest. Example:
117 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
118 * root=/dev/sda3 ro"
119 */
120 static char null[4] = { 0 };
122 void early_cmdline_parse(char **cmdline_p)
123 {
124 char *guest_cmd;
125 static const char * const split = "--";
127 if (*cmdline_p == NULL) {
128 *cmdline_p = &null[0];
129 saved_command_line[0] = '\0';
130 dom0_command_line[0] = '\0';
131 return;
132 }
134 guest_cmd = strstr(*cmdline_p, split);
135 /* If no spliter, whole line is for guest */
136 if (guest_cmd == NULL) {
137 guest_cmd = *cmdline_p;
138 *cmdline_p = &null[0];
139 } else {
140 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
141 guest_cmd += strlen(split);
142 while (*guest_cmd == ' ') guest_cmd++;
143 }
145 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
146 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
147 return;
148 }
150 struct ns16550_defaults ns16550_com1 = {
151 .baud = BAUD_AUTO,
152 .data_bits = 8,
153 .parity = 'n',
154 .stop_bits = 1
155 };
157 unsigned int ns16550_com1_gsi;
158 unsigned int ns16550_com1_polarity;
159 unsigned int ns16550_com1_trigger;
161 struct ns16550_defaults ns16550_com2 = {
162 .baud = BAUD_AUTO,
163 .data_bits = 8,
164 .parity = 'n',
165 .stop_bits = 1
166 };
168 /* efi_print: print efi table at boot */
169 static int opt_efi_print = 0;
170 boolean_param("efi_print", opt_efi_print);
172 /* print EFI memory map: */
173 static void
174 efi_print(void)
175 {
176 void *efi_map_start, *efi_map_end;
177 u64 efi_desc_size;
179 efi_memory_desc_t *md;
180 void *p;
181 int i;
183 if (!opt_efi_print)
184 return;
186 efi_map_start = __va(ia64_boot_param->efi_memmap);
187 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
188 efi_desc_size = ia64_boot_param->efi_memdesc_size;
190 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
191 md = p;
192 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
193 i, md->type, md->attribute, md->phys_addr,
194 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
195 md->num_pages >> (20 - EFI_PAGE_SHIFT));
196 }
197 }
199 /*
200 * These functions are utility functions for getting and
201 * testing memory descriptors for allocating the xenheap area.
202 */
203 static efi_memory_desc_t *
204 efi_get_md (unsigned long phys_addr)
205 {
206 void *efi_map_start, *efi_map_end, *p;
207 efi_memory_desc_t *md;
208 u64 efi_desc_size;
210 efi_map_start = __va(ia64_boot_param->efi_memmap);
211 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
212 efi_desc_size = ia64_boot_param->efi_memdesc_size;
214 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
215 md = p;
216 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
217 return md;
218 }
219 return 0;
220 }
222 static int
223 is_xenheap_usable_memory(efi_memory_desc_t *md)
224 {
225 if (!(md->attribute & EFI_MEMORY_WB))
226 return 0;
228 switch (md->type) {
229 case EFI_LOADER_CODE:
230 case EFI_LOADER_DATA:
231 case EFI_BOOT_SERVICES_CODE:
232 case EFI_BOOT_SERVICES_DATA:
233 case EFI_CONVENTIONAL_MEMORY:
234 return 1;
235 }
236 return 0;
237 }
239 static inline int
240 md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr)
241 {
242 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
243 }
245 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
247 void start_kernel(void)
248 {
249 char *cmdline;
250 void *heap_start;
251 unsigned long nr_pages;
252 unsigned long dom0_memory_start, dom0_memory_size;
253 unsigned long dom0_initrd_start, dom0_initrd_size;
254 unsigned long md_end, relo_start, relo_end, relo_size = 0;
255 struct domain *idle_domain;
256 efi_memory_desc_t *kern_md, *last_md, *md;
257 #ifdef CONFIG_SMP
258 int i;
259 #endif
261 running_on_sim = is_platform_hp_ski();
262 /* Kernel may be relocated by EFI loader */
263 xen_pstart = ia64_tpa(KERNEL_START);
265 early_setup_arch(&cmdline);
267 /* We initialise the serial devices very early so we can get debugging. */
268 if (running_on_sim) hpsim_serial_init();
269 else {
270 ns16550_init(0, &ns16550_com1);
271 /* Also init com2 for Tiger4. */
272 ns16550_com2.io_base = 0x2f8;
273 ns16550_com2.irq = 3;
274 ns16550_init(1, &ns16550_com2);
275 }
276 serial_init_preirq();
278 init_console();
279 set_printk_prefix("(XEN) ");
281 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
282 ia64_boot_param->domain_size == 0) {
283 /* This is possible only with the old elilo, which does not support
284 a vmm. Fix now, and continue without initrd. */
285 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
286 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
287 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
288 ia64_boot_param->initrd_start = 0;
289 ia64_boot_param->initrd_size = 0;
290 }
292 /* xenheap should be in same TR-covered range with xen image */
293 xenheap_phys_end = xen_pstart + xenheap_size;
294 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
295 xen_pstart, xenheap_phys_end);
297 kern_md = md = efi_get_md(xen_pstart);
298 md_end = __pa(ia64_imva(&_end));
299 relo_start = xenheap_phys_end;
301 /*
302 * Scan through the memory descriptors after the kernel
303 * image to make sure we have enough room for the xenheap
304 * area, pushing out whatever may already be there.
305 */
306 while (relo_start + relo_size >= md_end) {
307 md = efi_get_md(md_end);
309 BUG_ON(!md);
310 BUG_ON(!is_xenheap_usable_memory(md));
312 md_end = md->phys_addr + MD_SIZE(md);
313 /*
314 * The dom0 kernel or initrd could overlap, reserve space
315 * at the end to relocate them later.
316 */
317 if (md->type == EFI_LOADER_DATA) {
318 /* Test for ranges we're not prepared to move */
319 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
320 md_overlaps(md, ia64_boot_param->efi_memmap) ||
321 md_overlaps(md, ia64_boot_param->command_line));
323 relo_size += MD_SIZE(md);
324 /* If range overlaps the end, push out the relocation start */
325 if (md_end > relo_start)
326 relo_start = md_end;
327 }
328 }
329 last_md = md;
330 relo_end = relo_start + relo_size;
332 md_end = __pa(ia64_imva(&_end));
334 /*
335 * Move any relocated data out into the previously found relocation
336 * area. Any extra memory descriptrs are moved out to the end
337 * and set to zero pages.
338 */
339 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
340 md_end = md->phys_addr + MD_SIZE(md);
342 if (md->type == EFI_LOADER_DATA) {
343 unsigned long relo_offset;
345 if (md_overlaps(md, ia64_boot_param->domain_start)) {
346 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
347 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
348 ia64_boot_param->domain_start, relo_start + relo_offset,
349 ia64_boot_param->domain_size >> 10);
350 ia64_boot_param->domain_start = relo_start + relo_offset;
351 }
352 if (ia64_boot_param->initrd_size &&
353 md_overlaps(md, ia64_boot_param->initrd_start)) {
354 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
355 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
356 ia64_boot_param->initrd_start, relo_start + relo_offset,
357 ia64_boot_param->initrd_size >> 10);
358 ia64_boot_param->initrd_start = relo_start + relo_offset;
359 }
360 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
361 relo_start += MD_SIZE(md);
362 }
364 if (md == kern_md)
365 continue;
366 if (md == last_md)
367 break;
369 md->phys_addr = relo_end;
370 md->num_pages = 0;
371 }
373 /* Trim the last entry */
374 md->phys_addr = relo_end;
375 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
377 /*
378 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
379 * the full size. This range will already be type EFI_LOADER_DATA,
380 * therefore the xenheap area is now protected being allocated for
381 * use by find_memmap_space() in efi.c
382 */
383 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
385 reserve_memory();
387 /* first find highest page frame number */
388 max_page = 0;
389 efi_memmap_walk(find_max_pfn, &max_page);
390 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
391 efi_print();
393 heap_start = memguard_init(ia64_imva(&_end));
394 printf("Before heap_start: %p\n", heap_start);
395 heap_start = __va(init_boot_allocator(__pa(heap_start)));
396 printf("After heap_start: %p\n", heap_start);
398 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
399 efi_memmap_walk(xen_count_pages, &nr_pages);
401 printk("System RAM: %luMB (%lukB)\n",
402 nr_pages >> (20 - PAGE_SHIFT),
403 nr_pages << (PAGE_SHIFT - 10));
404 total_pages = nr_pages;
406 init_frametable();
408 trap_init();
410 alloc_dom0();
412 end_boot_allocator();
414 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
415 printk("Xen heap: %luMB (%lukB)\n",
416 (xenheap_phys_end-__pa(heap_start)) >> 20,
417 (xenheap_phys_end-__pa(heap_start)) >> 10);
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 late_setup_arch(&cmdline);
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 /* PIN domain0 on CPU 0. */
521 dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
523 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
524 scrub_heap_pages();
526 init_trace_bufs();
528 if (opt_xencons) {
529 console_endboot();
530 serial_endboot();
531 }
533 domain0_ready = 1;
535 schedulers_start();
537 domain_unpause_by_systemcontroller(dom0);
539 startup_cpu_idle_loop();
540 }
542 void arch_get_xen_caps(xen_capabilities_info_t info)
543 {
544 char *p=info;
545 int major = xen_major_version();
546 int minor = xen_minor_version();
548 p += sprintf(p,"xen-%d.%d-ia64 ", major, minor);
550 if (vmx_enabled)
551 p += sprintf(p,"hvm-%d.%d-ia64 ", major, minor);
553 *(p-1) = 0;
555 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
557 }