ia64/xen-unstable

annotate xen/arch/ia64/xen/xensetup.c @ 19848:5839491bbf20

[IA64] replace MAX_VCPUS with d->max_vcpus where necessary.

don't use MAX_VCPUS, and use vcpu::max_vcpus.
The changeset of 2f9e1348aa98 introduced max_vcpus to allow more vcpus
per guest. This patch is ia64 counter part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 11:26:05 2009 +0900 (2009-06-29)
parents 2f9e1348aa98
children
rev   line source
djm@6458 1 /******************************************************************************
djm@6458 2 * xensetup.c
djm@6458 3 * Copyright (c) 2004-2005 Hewlett-Packard Co
djm@6458 4 * Dan Magenheimer <dan.magenheimer@hp.com>
djm@6458 5 */
djm@6458 6
djm@6458 7 #include <xen/config.h>
djm@6458 8 #include <xen/lib.h>
djm@6458 9 #include <xen/errno.h>
djm@6458 10 #include <xen/multiboot.h>
djm@6458 11 #include <xen/sched.h>
djm@6458 12 #include <xen/mm.h>
djm@6723 13 #include <public/version.h>
kaf24@9117 14 #include <xen/gdbstub.h>
kfraser@10890 15 #include <xen/version.h>
awilliam@9005 16 #include <xen/console.h>
awilliam@10664 17 #include <xen/domain.h>
djm@6458 18 #include <xen/serial.h>
djm@6458 19 #include <xen/trace.h>
kfraser@11718 20 #include <xen/keyhandler.h>
alex@15563 21 #include <xen/vga.h>
djm@6458 22 #include <asm/meminit.h>
djm@6458 23 #include <asm/page.h>
djm@6458 24 #include <asm/setup.h>
alex@16817 25 #include <asm/vhpt.h>
djm@6458 26 #include <xen/string.h>
djm@8475 27 #include <asm/vmx.h>
awilliam@9005 28 #include <linux/efi.h>
awilliam@10445 29 #include <asm/iosapic.h>
awilliam@13479 30 #include <xen/softirq.h>
awilliam@13780 31 #include <xen/rcupdate.h>
kfraser@15819 32 #include <xsm/acm/acm_hooks.h>
alex@15135 33 #include <asm/sn/simulator.h>
yamahata@18091 34 #include <asm/sal.h>
djm@6458 35
yamahata@19130 36 unsigned long total_pages;
djm@6458 37
djm@6458 38 char saved_command_line[COMMAND_LINE_SIZE];
alex@15131 39 char __initdata dom0_command_line[COMMAND_LINE_SIZE];
djm@6458 40
djm@6458 41 cpumask_t cpu_present_map;
djm@6458 42
djm@6458 43 extern unsigned long domain0_ready;
djm@6458 44
djm@6458 45 int find_max_pfn (unsigned long, unsigned long, void *);
djm@6458 46
awilliam@9005 47 /* FIXME: which header these declarations should be there ? */
awilliam@9005 48 extern void early_setup_arch(char **);
awilliam@9005 49 extern void late_setup_arch(char **);
awilliam@9005 50 extern void hpsim_serial_init(void);
awilliam@9005 51 extern void setup_per_cpu_areas(void);
awilliam@9005 52 extern void mem_init(void);
awilliam@9005 53 extern void init_IRQ(void);
awilliam@10157 54 extern void trap_init(void);
awilliam@11639 55 extern void xen_patch_kernel(void);
awilliam@9005 56
alex@15765 57 /* nosmp: ignore secondary processors */
alex@15765 58 static int __initdata opt_nosmp;
djm@6458 59 boolean_param("nosmp", opt_nosmp);
djm@6458 60
alex@15765 61 /* maxcpus: maximum number of CPUs to activate */
alex@15131 62 static unsigned int __initdata max_cpus = NR_CPUS;
djm@6458 63 integer_param("maxcpus", max_cpus);
djm@6458 64
alex@15765 65 /* xencons: toggle xenconsole input (and irq).
awilliam@10442 66 Note: you have to disable 8250 serials in domains (to avoid use of the
awilliam@10442 67 same resource). */
alex@15131 68 static int __initdata opt_xencons = 1;
awilliam@10698 69 integer_param("xencons", opt_xencons);
awilliam@10442 70
alex@15765 71 /* xencons_poll: toggle non-legacy xencons UARTs to run in polling mode */
alex@15131 72 static int __initdata opt_xencons_poll;
awilliam@10445 73 boolean_param("xencons_poll", opt_xencons_poll);
awilliam@10445 74
yamahata@19130 75 #define XENHEAP_DEFAULT_SIZE KERNEL_TR_PAGE_SIZE
yamahata@19130 76 #define XENHEAP_SIZE_MIN (16 * 1024 * 1024) /* 16MBytes */
djm@6458 77 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
djm@6458 78 unsigned long xen_pstart;
djm@6458 79
alex@15131 80 static int __init
djm@6458 81 xen_count_pages(u64 start, u64 end, void *arg)
djm@6458 82 {
djm@6458 83 unsigned long *count = arg;
djm@6458 84
djm@6458 85 /* FIXME: do we need consider difference between DMA-usable memory and
djm@6458 86 * normal memory? Seems that HV has no requirement to operate DMA which
djm@6458 87 * is owned by Dom0? */
djm@6458 88 *count += (end - start) >> PAGE_SHIFT;
djm@6458 89 return 0;
djm@6458 90 }
djm@6458 91
djm@6458 92 static void __init do_initcalls(void)
djm@6458 93 {
djm@6458 94 initcall_t *call;
djm@6458 95 for ( call = &__initcall_start; call < &__initcall_end; call++ )
djm@6458 96 (*call)();
djm@6458 97 }
djm@6458 98
djm@6458 99 /*
alex@15765 100 * IPF loader only supports one command line currently, for
djm@6458 101 * both xen and guest kernel. This function provides pre-parse
djm@6458 102 * to mixed command line, to split it into two parts.
djm@6458 103 *
djm@6458 104 * User should split the parameters by "--", with strings after
djm@6458 105 * spliter for guest kernel. Missing "--" means whole line belongs
djm@6458 106 * to guest. Example:
djm@6458 107 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
djm@6458 108 * root=/dev/sda3 ro"
djm@6458 109 */
djm@6458 110 static char null[4] = { 0 };
djm@6458 111
alex@15131 112 void __init early_cmdline_parse(char **cmdline_p)
djm@6458 113 {
djm@6458 114 char *guest_cmd;
awilliam@9270 115 static const char * const split = "--";
djm@6458 116
djm@6458 117 if (*cmdline_p == NULL) {
djm@6458 118 *cmdline_p = &null[0];
djm@6458 119 saved_command_line[0] = '\0';
awilliam@9270 120 dom0_command_line[0] = '\0';
djm@6458 121 return;
djm@6458 122 }
djm@6458 123
djm@6458 124 guest_cmd = strstr(*cmdline_p, split);
djm@6458 125 /* If no spliter, whole line is for guest */
djm@6458 126 if (guest_cmd == NULL) {
djm@6458 127 guest_cmd = *cmdline_p;
djm@6458 128 *cmdline_p = &null[0];
djm@6458 129 } else {
djm@6458 130 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
djm@6458 131 guest_cmd += strlen(split);
djm@6458 132 while (*guest_cmd == ' ') guest_cmd++;
djm@6458 133 }
djm@6458 134
awilliam@9270 135 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
awilliam@9270 136 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
djm@6458 137 return;
djm@6458 138 }
djm@6458 139
djm@6458 140 struct ns16550_defaults ns16550_com1 = {
djm@6458 141 .data_bits = 8,
djm@6458 142 .parity = 'n',
djm@6458 143 .stop_bits = 1
djm@6458 144 };
djm@6458 145
awilliam@10445 146 unsigned int ns16550_com1_gsi;
awilliam@10445 147 unsigned int ns16550_com1_polarity;
awilliam@10445 148 unsigned int ns16550_com1_trigger;
awilliam@10445 149
djm@6458 150 struct ns16550_defaults ns16550_com2 = {
djm@6458 151 .data_bits = 8,
djm@6458 152 .parity = 'n',
djm@6458 153 .stop_bits = 1
djm@6458 154 };
djm@6458 155
awilliam@9750 156 /* efi_print: print efi table at boot */
alex@15131 157 static int __initdata opt_efi_print;
awilliam@9750 158 boolean_param("efi_print", opt_efi_print);
awilliam@9750 159
awilliam@9750 160 /* print EFI memory map: */
alex@15131 161 static void __init
awilliam@9750 162 efi_print(void)
awilliam@9750 163 {
awilliam@9750 164 void *efi_map_start, *efi_map_end;
awilliam@9750 165 u64 efi_desc_size;
awilliam@9750 166
awilliam@9750 167 efi_memory_desc_t *md;
awilliam@9750 168 void *p;
awilliam@9750 169 int i;
awilliam@9750 170
awilliam@9750 171 if (!opt_efi_print)
awilliam@9750 172 return;
awilliam@9750 173
awilliam@9750 174 efi_map_start = __va(ia64_boot_param->efi_memmap);
awilliam@9750 175 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
awilliam@9750 176 efi_desc_size = ia64_boot_param->efi_memdesc_size;
awilliam@9750 177
awilliam@9750 178 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
awilliam@9750 179 md = p;
awilliam@11741 180 printk("mem%02u: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) "
awilliam@11741 181 "(%luMB)\n", i, md->type, md->attribute, md->phys_addr,
awilliam@9750 182 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
awilliam@9750 183 md->num_pages >> (20 - EFI_PAGE_SHIFT));
awilliam@9750 184 }
awilliam@9750 185 }
awilliam@9750 186
awilliam@10270 187 /*
awilliam@10270 188 * These functions are utility functions for getting and
awilliam@10270 189 * testing memory descriptors for allocating the xenheap area.
awilliam@10270 190 */
alex@15765 191 static efi_memory_desc_t * __init
awilliam@10270 192 efi_get_md (unsigned long phys_addr)
awilliam@10270 193 {
awilliam@10270 194 void *efi_map_start, *efi_map_end, *p;
awilliam@10270 195 efi_memory_desc_t *md;
awilliam@10270 196 u64 efi_desc_size;
awilliam@10270 197
awilliam@10270 198 efi_map_start = __va(ia64_boot_param->efi_memmap);
awilliam@10270 199 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
awilliam@10270 200 efi_desc_size = ia64_boot_param->efi_memdesc_size;
awilliam@10270 201
awilliam@10270 202 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
awilliam@10270 203 md = p;
awilliam@10270 204 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
awilliam@10270 205 return md;
awilliam@10270 206 }
awilliam@10270 207 return 0;
awilliam@10270 208 }
awilliam@10270 209
alex@15765 210 static int __init
awilliam@10270 211 is_xenheap_usable_memory(efi_memory_desc_t *md)
awilliam@10270 212 {
awilliam@10270 213 if (!(md->attribute & EFI_MEMORY_WB))
awilliam@10270 214 return 0;
awilliam@10270 215
awilliam@10270 216 switch (md->type) {
awilliam@10270 217 case EFI_LOADER_CODE:
awilliam@10270 218 case EFI_LOADER_DATA:
awilliam@10270 219 case EFI_BOOT_SERVICES_CODE:
awilliam@10270 220 case EFI_BOOT_SERVICES_DATA:
awilliam@10270 221 case EFI_CONVENTIONAL_MEMORY:
awilliam@10270 222 return 1;
awilliam@10270 223 }
awilliam@10270 224 return 0;
awilliam@10270 225 }
awilliam@10270 226
alex@15765 227 static inline int __init
alex@16791 228 md_overlaps(const efi_memory_desc_t *md, unsigned long phys_addr)
awilliam@10270 229 {
awilliam@10270 230 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
awilliam@10270 231 }
awilliam@10270 232
alex@16791 233 static inline int __init
alex@16791 234 md_overlap_with_boot_param(const efi_memory_desc_t *md)
alex@16791 235 {
alex@16791 236 return md_overlaps(md, __pa(ia64_boot_param)) ||
alex@16791 237 md_overlaps(md, ia64_boot_param->efi_memmap) ||
alex@16791 238 md_overlaps(md, ia64_boot_param->command_line);
alex@16791 239 }
alex@16791 240
awilliam@10270 241 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
alex@16792 242 #define MD_END(md) ((md)->phys_addr + MD_SIZE(md))
awilliam@10270 243
alex@17198 244 static unsigned long __init
alex@17198 245 efi_get_max_addr (void)
alex@17198 246 {
alex@17198 247 void *efi_map_start, *efi_map_end, *p;
alex@17198 248 efi_memory_desc_t *md;
alex@17198 249 u64 efi_desc_size;
alex@17198 250 unsigned long max_addr = 0;
alex@17198 251
alex@17198 252 efi_map_start = __va(ia64_boot_param->efi_memmap);
alex@17198 253 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
alex@17198 254 efi_desc_size = ia64_boot_param->efi_memdesc_size;
alex@17198 255
alex@17198 256 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
alex@17198 257 md = p;
alex@17198 258 if (is_xenheap_usable_memory(md) && MD_END(md) > max_addr)
alex@17198 259 max_addr = MD_END(md);
alex@17198 260 }
alex@17198 261 return max_addr;
alex@17198 262 }
alex@17198 263
alex@15131 264 extern char __init_begin[], __init_end[];
alex@15131 265 static void noinline init_done(void)
alex@15131 266 {
alex@15131 267 memset(__init_begin, 0, __init_end - __init_begin);
alex@15131 268 flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
alex@15131 269 init_xenheap_pages(__pa(__init_begin), __pa(__init_end));
alex@15131 270 printk("Freed %ldkB init memory.\n",
alex@15131 271 (long)(__init_end-__init_begin)>>10);
alex@15131 272
alex@15131 273 startup_cpu_idle_loop();
alex@15131 274 }
alex@15131 275
alex@16792 276 struct xen_heap_desc {
alex@16792 277 void* xen_heap_start;
alex@16792 278 unsigned long xenheap_phys_end;
alex@16792 279 efi_memory_desc_t* kern_md;
alex@16792 280 };
alex@16792 281
alex@16792 282 static int __init
alex@16792 283 init_xenheap_mds(unsigned long start, unsigned long end, void *arg)
alex@16792 284 {
alex@16792 285 struct xen_heap_desc *desc = (struct xen_heap_desc*)arg;
alex@16792 286 unsigned long md_end = __pa(desc->xen_heap_start);
alex@16792 287 efi_memory_desc_t* md;
alex@16792 288
alex@16792 289 start = __pa(start);
alex@16792 290 end = __pa(end);
alex@16792 291
alex@16792 292 for (md = efi_get_md(md_end);
alex@16792 293 md != NULL && md->phys_addr < desc->xenheap_phys_end;
alex@16792 294 md = efi_get_md(md_end)) {
alex@16792 295 md_end = MD_END(md);
alex@16792 296
alex@16792 297 if (md == desc->kern_md ||
alex@16792 298 (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) ||
alex@16792 299 ((md->attribute & EFI_MEMORY_WB) &&
alex@16792 300 is_xenheap_usable_memory(md))) {
alex@16792 301 unsigned long s = max(start, max(__pa(desc->xen_heap_start),
alex@16792 302 md->phys_addr));
alex@16792 303 unsigned long e = min(end, min(md_end, desc->xenheap_phys_end));
yamahata@19130 304 init_boot_pages(s, e);
alex@16792 305 }
alex@16792 306 }
alex@16792 307
alex@16792 308 return 0;
alex@16792 309 }
alex@16792 310
alex@15423 311 int running_on_sim;
alex@15423 312
alex@15423 313 static int __init
alex@15423 314 is_platform_hp_ski(void)
alex@15423 315 {
alex@15423 316 int i;
alex@15423 317 long cpuid[6];
alex@15423 318
alex@15423 319 for (i = 0; i < 5; ++i)
alex@15423 320 cpuid[i] = ia64_get_cpuid(i);
alex@15423 321
alex@15423 322 if ((cpuid[0] & 0xff) != 'H')
alex@15423 323 return 0;
alex@15423 324 if ((cpuid[3] & 0xff) != 0x4)
alex@15423 325 return 0;
alex@15423 326 if (((cpuid[3] >> 8) & 0xff) != 0x0)
alex@15423 327 return 0;
alex@15423 328 if (((cpuid[3] >> 16) & 0xff) != 0x0)
alex@15423 329 return 0;
alex@15423 330 if (((cpuid[3] >> 24) & 0x7) != 0x7)
alex@15423 331 return 0;
alex@15423 332
alex@15423 333 return 1;
alex@15423 334 }
alex@15423 335
alex@16817 336 #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
alex@16817 337 static int __initdata dom0_vhpt_size_log2;
alex@16817 338 integer_param("dom0_vhpt_size_log2", dom0_vhpt_size_log2);
alex@16817 339 #endif
keir@19295 340 unsigned long xen_fixed_mfn_start __read_mostly;
keir@19295 341 unsigned long xen_fixed_mfn_end __read_mostly;
alex@16817 342
alex@15131 343 void __init start_kernel(void)
djm@6458 344 {
awilliam@10442 345 char *cmdline;
awilliam@10270 346 unsigned long nr_pages;
djm@7735 347 unsigned long dom0_memory_start, dom0_memory_size;
djm@7735 348 unsigned long dom0_initrd_start, dom0_initrd_size;
awilliam@10270 349 unsigned long md_end, relo_start, relo_end, relo_size = 0;
kaf24@8552 350 struct domain *idle_domain;
awilliam@13434 351 struct vcpu *dom0_vcpu0;
awilliam@10270 352 efi_memory_desc_t *kern_md, *last_md, *md;
yamahata@19130 353 unsigned long xenheap_phys_end;
alex@15131 354 void *xen_heap_start;
alex@16792 355 struct xen_heap_desc heap_desc;
awilliam@9314 356 #ifdef CONFIG_SMP
awilliam@9314 357 int i;
awilliam@9314 358 #endif
djm@6458 359
awilliam@11036 360 /* Be sure the struct shared_info size is <= XSI_SIZE. */
awilliam@11036 361 BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
awilliam@11036 362
djm@6458 363 /* Kernel may be relocated by EFI loader */
djm@6458 364 xen_pstart = ia64_tpa(KERNEL_START);
djm@6458 365
alex@15423 366 running_on_sim = is_platform_hp_ski();
alex@15423 367
awilliam@10442 368 early_setup_arch(&cmdline);
djm@6458 369
djm@6458 370 /* We initialise the serial devices very early so we can get debugging. */
awilliam@13845 371 if (running_on_sim)
awilliam@13845 372 hpsim_serial_init();
djm@6458 373 else {
awilliam@13845 374 ns16550_init(0, &ns16550_com1);
awilliam@13904 375 ns16550_init(1, &ns16550_com2);
djm@6458 376 }
djm@6458 377
alex@15563 378 #ifdef CONFIG_VGA
alex@15563 379 /* Plug in a default VGA mode */
alex@15563 380 vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
alex@15563 381 vga_console_info.u.text_mode_3.font_height = 16; /* generic VGA? */
alex@15563 382 vga_console_info.u.text_mode_3.cursor_x =
alex@15563 383 ia64_boot_param->console_info.orig_x;
alex@15563 384 vga_console_info.u.text_mode_3.cursor_y =
alex@15563 385 ia64_boot_param->console_info.orig_y;
alex@15563 386 vga_console_info.u.text_mode_3.rows =
alex@15563 387 ia64_boot_param->console_info.num_rows;
alex@15563 388 vga_console_info.u.text_mode_3.columns =
alex@15563 389 ia64_boot_param->console_info.num_cols;
alex@15563 390 #endif
alex@15563 391
keir@19543 392 console_init_preirq();
djm@6458 393
awilliam@10270 394 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
awilliam@10270 395 ia64_boot_param->domain_size == 0) {
awilliam@10270 396 /* This is possible only with the old elilo, which does not support
awilliam@10270 397 a vmm. Fix now, and continue without initrd. */
awilliam@10270 398 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
awilliam@10270 399 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
awilliam@10270 400 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
awilliam@10270 401 ia64_boot_param->initrd_start = 0;
awilliam@10270 402 ia64_boot_param->initrd_size = 0;
awilliam@10270 403 }
awilliam@10270 404
awilliam@11306 405 printk("Xen command line: %s\n", saved_command_line);
alex@16785 406
alex@17198 407 /*
alex@17198 408 * Test if the boot allocator bitmap will overflow xenheap_size. If
alex@17198 409 * so, continue to bump it up until we have at least a minimum space
alex@17198 410 * for the actual xenheap.
alex@17198 411 */
alex@17198 412 max_page = efi_get_max_addr() >> PAGE_SHIFT;
yamahata@19130 413 while ((max_page >> 3) > xenheap_size - XENHEAP_SIZE_MIN)
alex@17198 414 xenheap_size <<= 1;
alex@17198 415
djm@6458 416 xenheap_phys_end = xen_pstart + xenheap_size;
djm@6458 417 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
awilliam@10270 418 xen_pstart, xenheap_phys_end);
awilliam@10270 419
awilliam@11639 420 xen_patch_kernel();
awilliam@11639 421
awilliam@10270 422 kern_md = md = efi_get_md(xen_pstart);
awilliam@10270 423 md_end = __pa(ia64_imva(&_end));
awilliam@10270 424 relo_start = xenheap_phys_end;
awilliam@10270 425
awilliam@10270 426 /*
awilliam@10270 427 * Scan through the memory descriptors after the kernel
awilliam@10270 428 * image to make sure we have enough room for the xenheap
awilliam@10270 429 * area, pushing out whatever may already be there.
awilliam@10270 430 */
awilliam@10270 431 while (relo_start + relo_size >= md_end) {
awilliam@10270 432 md = efi_get_md(md_end);
awilliam@10270 433
alex@16791 434 if (md == NULL) {
alex@16791 435 printk("no room to move loader data. skip moving loader data\n");
alex@16791 436 goto skip_move;
alex@16791 437 }
alex@16791 438
alex@16791 439 md_end = MD_END(md);
alex@16791 440 if (relo_start < md->phys_addr)
alex@16791 441 relo_start = md->phys_addr;
alex@16791 442
alex@16792 443 if (!is_xenheap_usable_memory(md)) {
alex@16792 444 /* Skip this area */
alex@16792 445 if (md_end > relo_start)
alex@16792 446 relo_start = md_end;
alex@16791 447 continue;
alex@16792 448 }
djm@6458 449
awilliam@10270 450 /*
awilliam@10270 451 * The dom0 kernel or initrd could overlap, reserve space
awilliam@10270 452 * at the end to relocate them later.
awilliam@10270 453 */
awilliam@10270 454 if (md->type == EFI_LOADER_DATA) {
awilliam@10270 455 /* Test for ranges we're not prepared to move */
alex@16791 456 if (!md_overlap_with_boot_param(md))
alex@16791 457 relo_size += MD_SIZE(md);
awilliam@10270 458
awilliam@10270 459 /* If range overlaps the end, push out the relocation start */
awilliam@10270 460 if (md_end > relo_start)
awilliam@10270 461 relo_start = md_end;
awilliam@10270 462 }
awilliam@10270 463 }
awilliam@10270 464 last_md = md;
alex@16791 465 relo_start = md_end - relo_size;
awilliam@10270 466 relo_end = relo_start + relo_size;
djm@6458 467
awilliam@10270 468 md_end = __pa(ia64_imva(&_end));
awilliam@10270 469
awilliam@10270 470 /*
awilliam@10270 471 * Move any relocated data out into the previously found relocation
awilliam@10270 472 * area. Any extra memory descriptrs are moved out to the end
awilliam@10270 473 * and set to zero pages.
awilliam@10270 474 */
awilliam@10270 475 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
alex@16791 476 md_end = MD_END(md);
awilliam@10270 477
alex@16791 478 if (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) {
awilliam@10270 479 unsigned long relo_offset;
awilliam@10270 480
awilliam@10270 481 if (md_overlaps(md, ia64_boot_param->domain_start)) {
awilliam@10270 482 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
awilliam@10270 483 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
awilliam@10270 484 ia64_boot_param->domain_start, relo_start + relo_offset,
awilliam@10270 485 ia64_boot_param->domain_size >> 10);
awilliam@10270 486 ia64_boot_param->domain_start = relo_start + relo_offset;
awilliam@10270 487 }
awilliam@10270 488 if (ia64_boot_param->initrd_size &&
awilliam@10270 489 md_overlaps(md, ia64_boot_param->initrd_start)) {
awilliam@10270 490 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
awilliam@10270 491 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
awilliam@10270 492 ia64_boot_param->initrd_start, relo_start + relo_offset,
awilliam@10270 493 ia64_boot_param->initrd_size >> 10);
awilliam@10270 494 ia64_boot_param->initrd_start = relo_start + relo_offset;
awilliam@10270 495 }
awilliam@10270 496 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
awilliam@10270 497 relo_start += MD_SIZE(md);
awilliam@10270 498 }
awilliam@10270 499
awilliam@10270 500 if (md == last_md)
awilliam@10270 501 break;
djm@7735 502 }
djm@7735 503
awilliam@10270 504 /* Trim the last entry */
alex@16791 505 md->num_pages -= (relo_size >> EFI_PAGE_SHIFT);
djm@6458 506
alex@16791 507 skip_move:
awilliam@10270 508 reserve_memory();
djm@6458 509
djm@6458 510 /* first find highest page frame number */
djm@6458 511 max_page = 0;
djm@6458 512 efi_memmap_walk(find_max_pfn, &max_page);
kfraser@11947 513 printk("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
awilliam@9750 514 efi_print();
alex@15131 515
awilliam@11606 516 xen_heap_start = memguard_init(ia64_imva(&_end));
awilliam@11961 517 printk("Before xen_heap_start: %p\n", xen_heap_start);
awilliam@11606 518 xen_heap_start = __va(init_boot_allocator(__pa(xen_heap_start)));
awilliam@11961 519 printk("After xen_heap_start: %p\n", xen_heap_start);
djm@6458 520
djm@6458 521 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
djm@6458 522 efi_memmap_walk(xen_count_pages, &nr_pages);
djm@6458 523
djm@6458 524 printk("System RAM: %luMB (%lukB)\n",
djm@6458 525 nr_pages >> (20 - PAGE_SHIFT),
djm@6458 526 nr_pages << (PAGE_SHIFT - 10));
awilliam@9773 527 total_pages = nr_pages;
djm@6458 528
djm@6458 529 init_frametable();
djm@6458 530
awilliam@10157 531 trap_init();
awilliam@10157 532
alex@16786 533 /* process SAL system table */
alex@16786 534 /* must be before any pal/sal call */
yamahata@17886 535 BUG_ON(efi.sal_systab == EFI_INVALID_TABLE_ADDR);
yamahata@17886 536 ia64_sal_init(__va(efi.sal_systab));
alex@16786 537
alex@16786 538 /* early_setup_arch() maps PAL code. */
alex@16786 539 identify_vmx_feature();
alex@16786 540 /* If vmx feature is on, do necessary initialization for vmx */
alex@16786 541 if (vmx_enabled)
alex@16786 542 xen_heap_start = vmx_init_env(xen_heap_start, xenheap_phys_end);
alex@16786 543
yamahata@18139 544 /* allocate memory for percpu area
yamahata@18139 545 * per_cpu_init() called from late_set_arch() is called after
yamahata@18139 546 * end_boot_allocate(). It's too late to allocate memory in
yamahata@18139 547 * xenva.
yamahata@18139 548 */
yamahata@18139 549 xen_heap_start = per_cpu_allocate(xen_heap_start, xenheap_phys_end);
yamahata@18139 550
alex@16792 551 heap_desc.xen_heap_start = xen_heap_start;
alex@16792 552 heap_desc.xenheap_phys_end = xenheap_phys_end;
alex@16792 553 heap_desc.kern_md = kern_md;
alex@16792 554 efi_memmap_walk(&init_xenheap_mds, &heap_desc);
alex@16791 555
djm@6458 556 printk("Xen heap: %luMB (%lukB)\n",
alex@16791 557 (xenheap_phys_end-__pa(xen_heap_start)) >> 20,
alex@16791 558 (xenheap_phys_end-__pa(xen_heap_start)) >> 10);
djm@6458 559
keir@19295 560 /* for is_xen_fixed_mfn() */
keir@19295 561 xen_fixed_mfn_start = virt_to_mfn(&_start);
keir@19295 562 xen_fixed_mfn_end = virt_to_mfn(xen_heap_start);
keir@19295 563
alex@15154 564 end_boot_allocator();
alex@15154 565
keir@17444 566 softirq_init();
keir@17444 567
kaf24@11019 568 late_setup_arch(&cmdline);
kaf24@11019 569
kaf24@8552 570 scheduler_init();
kaf24@8552 571 idle_vcpu[0] = (struct vcpu*) ia64_r13;
kfraser@14911 572 idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
keir@19788 573 if ( idle_domain == NULL )
keir@19788 574 BUG();
keir@19788 575 idle_domain->vcpu = idle_vcpu;
keir@19788 576 idle_domain->max_vcpus = NR_CPUS;
keir@19788 577 if ( alloc_vcpu(idle_domain, 0, 0) == NULL )
kfraser@10655 578 BUG();
kaf24@8552 579
awilliam@10151 580 alloc_dom_xen_and_dom_io();
djm@6458 581 setup_per_cpu_areas();
djm@6458 582 mem_init();
djm@6458 583
djm@6458 584 local_irq_disable();
djm@7332 585 init_IRQ ();
djm@6458 586 init_xen_time(); /* initialise the time */
kaf24@8586 587 timer_init();
djm@6458 588
awilliam@13667 589 rcu_init();
awilliam@13667 590
awilliam@13479 591 #ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
awilliam@13479 592 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
awilliam@13479 593 #endif
awilliam@13479 594
djm@6458 595 #ifdef CONFIG_SMP
djm@6458 596 if ( opt_nosmp )
djm@6458 597 {
djm@6458 598 max_cpus = 0;
djm@6458 599 smp_num_siblings = 1;
djm@6458 600 //boot_cpu_data.x86_num_cores = 1;
djm@6458 601 }
djm@6458 602
awilliam@9495 603 /* A vcpu is created for the idle domain on every physical cpu.
awilliam@9495 604 Limit the number of cpus to the maximum number of vcpus. */
awilliam@9495 605 if (max_cpus > MAX_VIRT_CPUS)
awilliam@9495 606 max_cpus = MAX_VIRT_CPUS;
awilliam@9495 607
djm@6458 608 smp_prepare_cpus(max_cpus);
awilliam@9495 609
djm@6458 610 /* We aren't hotplug-capable yet. */
djm@6458 611 for_each_cpu ( i )
djm@6458 612 cpu_set(i, cpu_present_map);
djm@6458 613
djm@7332 614 /* Enable IRQ to receive IPI (needed for ITC sync). */
djm@7332 615 local_irq_enable();
djm@7332 616
djm@6458 617 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
djm@6458 618 for_each_present_cpu ( i )
djm@6458 619 {
djm@6458 620 if ( num_online_cpus() >= max_cpus )
djm@6458 621 break;
djm@6458 622 if ( !cpu_online(i) ) {
awilliam@13667 623 rcu_online_cpu(i);
djm@6458 624 __cpu_up(i);
djm@6458 625 }
djm@6458 626 }
djm@6458 627
djm@7332 628 local_irq_disable();
djm@7332 629
djm@6458 630 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
djm@6458 631 smp_cpus_done(max_cpus);
djm@6458 632 #endif
djm@6458 633
kaf24@9117 634 initialise_gdb(); /* could be moved earlier */
kaf24@9117 635
djm@6458 636 do_initcalls();
djm@6458 637 sort_main_extable();
djm@6458 638
awilliam@9685 639 init_rid_allocator ();
awilliam@9685 640
awilliam@10442 641 local_irq_enable();
awilliam@10442 642
awilliam@10442 643 if (opt_xencons) {
awilliam@10445 644 initialize_keytable();
awilliam@10445 645 if (ns16550_com1_gsi) {
awilliam@10445 646 if (opt_xencons_poll ||
awilliam@10445 647 iosapic_register_intr(ns16550_com1_gsi,
awilliam@10445 648 ns16550_com1_polarity,
awilliam@10445 649 ns16550_com1_trigger) < 0) {
awilliam@10445 650 ns16550_com1.irq = 0;
awilliam@10445 651 ns16550_init(0, &ns16550_com1);
awilliam@10445 652 }
awilliam@10445 653 }
keir@19543 654 console_init_postirq();
awilliam@10442 655 }
awilliam@9685 656
awilliam@11726 657 expose_p2m_init();
awilliam@11726 658
djm@6458 659 /* Create initial domain 0. */
kfraser@14911 660 dom0 = domain_create(0, 0, DOM0_SSIDREF);
awilliam@13434 661 if (dom0 == NULL)
djm@6458 662 panic("Error creating domain 0\n");
alex@16817 663 domain_set_vhpt_size(dom0, dom0_vhpt_size_log2);
keir@19788 664 dom0_vcpu0 = alloc_dom0_vcpu0();
awilliam@13434 665 if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0)
awilliam@13434 666 panic("Cannot allocate dom0 vcpu 0\n");
djm@6458 667
kfraser@12210 668 dom0->is_privileged = 1;
keir@16856 669 dom0->target = NULL;
djm@6458 670
djm@6458 671 /*
djm@6458 672 * We're going to setup domain0 using the module(s) that we stashed safely
djm@6458 673 * above our heap. The second module, if present, is an initrd ramdisk.
djm@6458 674 */
awilliam@10270 675 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
djm@7735 676 dom0_memory_size = ia64_boot_param->domain_size;
awilliam@9864 677 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
djm@7735 678 dom0_initrd_size = ia64_boot_param->initrd_size;
djm@7735 679
djm@7735 680 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
djm@7735 681 dom0_initrd_start,dom0_initrd_size,
djm@7735 682 0) != 0)
djm@6458 683 panic("Could not set up DOM0 guest OS\n");
djm@7332 684
alex@15135 685 if (!running_on_sim && !IS_MEDUSA()) // slow on ski and pages are pre-initialized to zero
djm@6458 686 scrub_heap_pages();
djm@6458 687
djm@6458 688 init_trace_bufs();
djm@6458 689
awilliam@10934 690 if (opt_xencons) {
awilliam@10513 691 console_endboot();
awilliam@10934 692 serial_endboot();
awilliam@10934 693 }
djm@6458 694
djm@7332 695 domain0_ready = 1;
djm@7332 696
djm@6458 697 domain_unpause_by_systemcontroller(dom0);
djm@7332 698
alex@15131 699 init_done();
djm@6458 700 }
djm@6723 701
ian@13763 702 void arch_get_xen_caps(xen_capabilities_info_t *info)
djm@6723 703 {
kfraser@14997 704 /* Interface name is always xen-3.0-* for Xen-3.x. */
kfraser@14997 705 int major = 3, minor = 0;
keir@13754 706 char s[32];
djm@6723 707
ian@13763 708 (*info)[0] = '\0';
keir@13754 709
ian@13763 710 snprintf(s, sizeof(s), "xen-%d.%d-ia64 ", major, minor);
ian@13763 711 safe_strcat(*info, s);
djm@6723 712
awilliam@14037 713 snprintf(s, sizeof(s), "xen-%d.%d-ia64be ", major, minor);
awilliam@14037 714 safe_strcat(*info, s);
awilliam@14037 715
djm@8475 716 if (vmx_enabled)
keir@13754 717 {
keir@13754 718 snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor);
ian@13763 719 safe_strcat(*info, s);
alex@17072 720
alex@17072 721 snprintf(s, sizeof(s), "hvm-%d.%d-ia64-sioemu ", major, minor);
alex@17072 722 safe_strcat(*info, s);
keir@13754 723 }
djm@6723 724 }
djm@6723 725
yamahata@18688 726 int xen_in_range(paddr_t start, paddr_t end)
yamahata@18688 727 {
yamahata@19130 728 paddr_t xs = __pa(&_start);
yamahata@19130 729 paddr_t xe = __pa(&_end);
yamahata@18688 730
yamahata@19130 731 return (start < xe) && (end > xs);
yamahata@18688 732 }