ia64/xen-unstable

annotate xen/arch/ia64/xen/xensetup.c @ 10890:b786bfb058eb

[XEN] Hide compile-time information values behind a
functional interface, so that the values are contained
within a single object file.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Aug 01 15:28:09 2006 +0100 (2006-08-01)
parents c4af6e854010
children c3e20511c745 e8bdf6a8b74a
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/spinlock.h>
djm@6458 11 #include <xen/multiboot.h>
djm@6458 12 #include <xen/sched.h>
djm@6458 13 #include <xen/mm.h>
djm@6723 14 #include <public/version.h>
kaf24@9117 15 #include <xen/gdbstub.h>
kfraser@10890 16 #include <xen/version.h>
awilliam@9005 17 #include <xen/console.h>
awilliam@10664 18 #include <xen/domain.h>
djm@6458 19 #include <xen/serial.h>
djm@6458 20 #include <xen/trace.h>
djm@6458 21 #include <asm/meminit.h>
djm@6458 22 #include <asm/page.h>
djm@6458 23 #include <asm/setup.h>
djm@6458 24 #include <xen/string.h>
djm@8475 25 #include <asm/vmx.h>
awilliam@9005 26 #include <linux/efi.h>
awilliam@10445 27 #include <asm/iosapic.h>
djm@6458 28
awilliam@10667 29 /* Be sure the struct shared_info size is <= XSI_SIZE. */
awilliam@10667 30 #if SHARED_INFO_SIZE > XSI_SIZE
awilliam@10667 31 #error "struct shared_info bigger than XSI_SIZE"
awilliam@9495 32 #endif
awilliam@9495 33
awilliam@9773 34 unsigned long xenheap_phys_end, total_pages;
djm@6458 35
djm@6458 36 char saved_command_line[COMMAND_LINE_SIZE];
awilliam@9270 37 char dom0_command_line[COMMAND_LINE_SIZE];
djm@6458 38
djm@6458 39 cpumask_t cpu_present_map;
djm@6458 40
djm@6458 41 extern unsigned long domain0_ready;
djm@6458 42
djm@6458 43 int find_max_pfn (unsigned long, unsigned long, void *);
djm@6458 44
awilliam@9005 45 /* FIXME: which header these declarations should be there ? */
awilliam@10442 46 extern void initialize_keytable(void);
awilliam@9005 47 extern long is_platform_hp_ski(void);
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 alloc_dom0(void);
awilliam@9005 52 extern void setup_per_cpu_areas(void);
awilliam@9005 53 extern void mem_init(void);
awilliam@9005 54 extern void init_IRQ(void);
awilliam@10157 55 extern void trap_init(void);
awilliam@9005 56
djm@6458 57 /* opt_nosmp: If true, secondary processors are ignored. */
djm@6458 58 static int opt_nosmp = 0;
djm@6458 59 boolean_param("nosmp", opt_nosmp);
djm@6458 60
djm@6458 61 /* maxcpus: maximum number of CPUs to activate. */
djm@6458 62 static unsigned int max_cpus = NR_CPUS;
djm@6458 63 integer_param("maxcpus", max_cpus);
djm@6458 64
awilliam@10442 65 /* xencons: if true enable 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). */
awilliam@10694 68 static int opt_xencons = 1;
awilliam@10698 69 integer_param("xencons", opt_xencons);
awilliam@10442 70
awilliam@10445 71 /* Toggle to allow non-legacy xencons UARTs to run in polling mode */
awilliam@10445 72 static int opt_xencons_poll = 0;
awilliam@10445 73 boolean_param("xencons_poll", opt_xencons_poll);
awilliam@10445 74
djm@6458 75 /*
djm@6458 76 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
djm@6458 77 * xen image
djm@6458 78 * bootmap bits
djm@6458 79 * xen heap
djm@6458 80 * Note: To allow xenheap size configurable, the prerequisite is
djm@6458 81 * to configure elilo allowing relocation defaultly. Then since
djm@6458 82 * elilo chooses 256M as alignment when relocating, alignment issue
djm@6458 83 * on IPF can be addressed.
djm@6458 84 */
djm@6458 85 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
djm@6458 86 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
djm@6458 87 extern long running_on_sim;
djm@6458 88 unsigned long xen_pstart;
djm@6458 89
djm@6458 90 static int
djm@6458 91 xen_count_pages(u64 start, u64 end, void *arg)
djm@6458 92 {
djm@6458 93 unsigned long *count = arg;
djm@6458 94
djm@6458 95 /* FIXME: do we need consider difference between DMA-usable memory and
djm@6458 96 * normal memory? Seems that HV has no requirement to operate DMA which
djm@6458 97 * is owned by Dom0? */
djm@6458 98 *count += (end - start) >> PAGE_SHIFT;
djm@6458 99 return 0;
djm@6458 100 }
djm@6458 101
djm@6458 102 static void __init do_initcalls(void)
djm@6458 103 {
djm@6458 104 initcall_t *call;
djm@6458 105 for ( call = &__initcall_start; call < &__initcall_end; call++ )
djm@6458 106 (*call)();
djm@6458 107 }
djm@6458 108
djm@6458 109 /*
djm@6458 110 * IPF loader only supports one commaind line currently, for
djm@6458 111 * both xen and guest kernel. This function provides pre-parse
djm@6458 112 * to mixed command line, to split it into two parts.
djm@6458 113 *
djm@6458 114 * User should split the parameters by "--", with strings after
djm@6458 115 * spliter for guest kernel. Missing "--" means whole line belongs
djm@6458 116 * to guest. Example:
djm@6458 117 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
djm@6458 118 * root=/dev/sda3 ro"
djm@6458 119 */
djm@6458 120 static char null[4] = { 0 };
djm@6458 121
djm@6458 122 void early_cmdline_parse(char **cmdline_p)
djm@6458 123 {
djm@6458 124 char *guest_cmd;
awilliam@9270 125 static const char * const split = "--";
djm@6458 126
djm@6458 127 if (*cmdline_p == NULL) {
djm@6458 128 *cmdline_p = &null[0];
djm@6458 129 saved_command_line[0] = '\0';
awilliam@9270 130 dom0_command_line[0] = '\0';
djm@6458 131 return;
djm@6458 132 }
djm@6458 133
djm@6458 134 guest_cmd = strstr(*cmdline_p, split);
djm@6458 135 /* If no spliter, whole line is for guest */
djm@6458 136 if (guest_cmd == NULL) {
djm@6458 137 guest_cmd = *cmdline_p;
djm@6458 138 *cmdline_p = &null[0];
djm@6458 139 } else {
djm@6458 140 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
djm@6458 141 guest_cmd += strlen(split);
djm@6458 142 while (*guest_cmd == ' ') guest_cmd++;
djm@6458 143 }
djm@6458 144
awilliam@9270 145 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
awilliam@9270 146 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
djm@6458 147 return;
djm@6458 148 }
djm@6458 149
djm@6458 150 struct ns16550_defaults ns16550_com1 = {
djm@6458 151 .baud = BAUD_AUTO,
djm@6458 152 .data_bits = 8,
djm@6458 153 .parity = 'n',
djm@6458 154 .stop_bits = 1
djm@6458 155 };
djm@6458 156
awilliam@10445 157 unsigned int ns16550_com1_gsi;
awilliam@10445 158 unsigned int ns16550_com1_polarity;
awilliam@10445 159 unsigned int ns16550_com1_trigger;
awilliam@10445 160
djm@6458 161 struct ns16550_defaults ns16550_com2 = {
djm@6458 162 .baud = BAUD_AUTO,
djm@6458 163 .data_bits = 8,
djm@6458 164 .parity = 'n',
djm@6458 165 .stop_bits = 1
djm@6458 166 };
djm@6458 167
awilliam@9750 168 /* efi_print: print efi table at boot */
awilliam@9750 169 static int opt_efi_print = 0;
awilliam@9750 170 boolean_param("efi_print", opt_efi_print);
awilliam@9750 171
awilliam@9750 172 /* print EFI memory map: */
awilliam@9750 173 static void
awilliam@9750 174 efi_print(void)
awilliam@9750 175 {
awilliam@9750 176 void *efi_map_start, *efi_map_end;
awilliam@9750 177 u64 efi_desc_size;
awilliam@9750 178
awilliam@9750 179 efi_memory_desc_t *md;
awilliam@9750 180 void *p;
awilliam@9750 181 int i;
awilliam@9750 182
awilliam@9750 183 if (!opt_efi_print)
awilliam@9750 184 return;
awilliam@9750 185
awilliam@9750 186 efi_map_start = __va(ia64_boot_param->efi_memmap);
awilliam@9750 187 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
awilliam@9750 188 efi_desc_size = ia64_boot_param->efi_memdesc_size;
awilliam@9750 189
awilliam@9750 190 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
awilliam@9750 191 md = p;
awilliam@9750 192 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
awilliam@9750 193 i, md->type, md->attribute, md->phys_addr,
awilliam@9750 194 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
awilliam@9750 195 md->num_pages >> (20 - EFI_PAGE_SHIFT));
awilliam@9750 196 }
awilliam@9750 197 }
awilliam@9750 198
awilliam@10270 199 /*
awilliam@10270 200 * These functions are utility functions for getting and
awilliam@10270 201 * testing memory descriptors for allocating the xenheap area.
awilliam@10270 202 */
awilliam@10270 203 static efi_memory_desc_t *
awilliam@10270 204 efi_get_md (unsigned long phys_addr)
awilliam@10270 205 {
awilliam@10270 206 void *efi_map_start, *efi_map_end, *p;
awilliam@10270 207 efi_memory_desc_t *md;
awilliam@10270 208 u64 efi_desc_size;
awilliam@10270 209
awilliam@10270 210 efi_map_start = __va(ia64_boot_param->efi_memmap);
awilliam@10270 211 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
awilliam@10270 212 efi_desc_size = ia64_boot_param->efi_memdesc_size;
awilliam@10270 213
awilliam@10270 214 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
awilliam@10270 215 md = p;
awilliam@10270 216 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
awilliam@10270 217 return md;
awilliam@10270 218 }
awilliam@10270 219 return 0;
awilliam@10270 220 }
awilliam@10270 221
awilliam@10270 222 static int
awilliam@10270 223 is_xenheap_usable_memory(efi_memory_desc_t *md)
awilliam@10270 224 {
awilliam@10270 225 if (!(md->attribute & EFI_MEMORY_WB))
awilliam@10270 226 return 0;
awilliam@10270 227
awilliam@10270 228 switch (md->type) {
awilliam@10270 229 case EFI_LOADER_CODE:
awilliam@10270 230 case EFI_LOADER_DATA:
awilliam@10270 231 case EFI_BOOT_SERVICES_CODE:
awilliam@10270 232 case EFI_BOOT_SERVICES_DATA:
awilliam@10270 233 case EFI_CONVENTIONAL_MEMORY:
awilliam@10270 234 return 1;
awilliam@10270 235 }
awilliam@10270 236 return 0;
awilliam@10270 237 }
awilliam@10270 238
awilliam@10270 239 static inline int
awilliam@10270 240 md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr)
awilliam@10270 241 {
awilliam@10270 242 return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));
awilliam@10270 243 }
awilliam@10270 244
awilliam@10270 245 #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)
awilliam@10270 246
djm@6458 247 void start_kernel(void)
djm@6458 248 {
awilliam@10442 249 char *cmdline;
djm@6458 250 void *heap_start;
awilliam@10270 251 unsigned long nr_pages;
djm@7735 252 unsigned long dom0_memory_start, dom0_memory_size;
djm@7735 253 unsigned long dom0_initrd_start, dom0_initrd_size;
awilliam@10270 254 unsigned long md_end, relo_start, relo_end, relo_size = 0;
kaf24@8552 255 struct domain *idle_domain;
awilliam@10270 256 efi_memory_desc_t *kern_md, *last_md, *md;
awilliam@9314 257 #ifdef CONFIG_SMP
awilliam@9314 258 int i;
awilliam@9314 259 #endif
djm@6458 260
djm@6458 261 running_on_sim = is_platform_hp_ski();
djm@6458 262 /* Kernel may be relocated by EFI loader */
djm@6458 263 xen_pstart = ia64_tpa(KERNEL_START);
djm@6458 264
awilliam@10442 265 early_setup_arch(&cmdline);
djm@6458 266
djm@6458 267 /* We initialise the serial devices very early so we can get debugging. */
djm@6458 268 if (running_on_sim) hpsim_serial_init();
djm@6458 269 else {
djm@6458 270 ns16550_init(0, &ns16550_com1);
djm@6458 271 /* Also init com2 for Tiger4. */
djm@6458 272 ns16550_com2.io_base = 0x2f8;
djm@6458 273 ns16550_com2.irq = 3;
djm@6458 274 ns16550_init(1, &ns16550_com2);
djm@6458 275 }
djm@6458 276 serial_init_preirq();
djm@6458 277
djm@6458 278 init_console();
djm@6458 279 set_printk_prefix("(XEN) ");
djm@6458 280
awilliam@10270 281 if (running_on_sim || ia64_boot_param->domain_start == 0 ||
awilliam@10270 282 ia64_boot_param->domain_size == 0) {
awilliam@10270 283 /* This is possible only with the old elilo, which does not support
awilliam@10270 284 a vmm. Fix now, and continue without initrd. */
awilliam@10270 285 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
awilliam@10270 286 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
awilliam@10270 287 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
awilliam@10270 288 ia64_boot_param->initrd_start = 0;
awilliam@10270 289 ia64_boot_param->initrd_size = 0;
awilliam@10270 290 }
awilliam@10270 291
djm@6458 292 /* xenheap should be in same TR-covered range with xen image */
djm@6458 293 xenheap_phys_end = xen_pstart + xenheap_size;
djm@6458 294 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
awilliam@10270 295 xen_pstart, xenheap_phys_end);
awilliam@10270 296
awilliam@10270 297 kern_md = md = efi_get_md(xen_pstart);
awilliam@10270 298 md_end = __pa(ia64_imva(&_end));
awilliam@10270 299 relo_start = xenheap_phys_end;
awilliam@10270 300
awilliam@10270 301 /*
awilliam@10270 302 * Scan through the memory descriptors after the kernel
awilliam@10270 303 * image to make sure we have enough room for the xenheap
awilliam@10270 304 * area, pushing out whatever may already be there.
awilliam@10270 305 */
awilliam@10270 306 while (relo_start + relo_size >= md_end) {
awilliam@10270 307 md = efi_get_md(md_end);
awilliam@10270 308
awilliam@10270 309 BUG_ON(!md);
awilliam@10270 310 BUG_ON(!is_xenheap_usable_memory(md));
djm@6458 311
awilliam@10270 312 md_end = md->phys_addr + MD_SIZE(md);
awilliam@10270 313 /*
awilliam@10270 314 * The dom0 kernel or initrd could overlap, reserve space
awilliam@10270 315 * at the end to relocate them later.
awilliam@10270 316 */
awilliam@10270 317 if (md->type == EFI_LOADER_DATA) {
awilliam@10270 318 /* Test for ranges we're not prepared to move */
awilliam@10270 319 BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) ||
awilliam@10270 320 md_overlaps(md, ia64_boot_param->efi_memmap) ||
awilliam@10270 321 md_overlaps(md, ia64_boot_param->command_line));
awilliam@10270 322
awilliam@10270 323 relo_size += MD_SIZE(md);
awilliam@10270 324 /* If range overlaps the end, push out the relocation start */
awilliam@10270 325 if (md_end > relo_start)
awilliam@10270 326 relo_start = md_end;
awilliam@10270 327 }
awilliam@10270 328 }
awilliam@10270 329 last_md = md;
awilliam@10270 330 relo_end = relo_start + relo_size;
djm@6458 331
awilliam@10270 332 md_end = __pa(ia64_imva(&_end));
awilliam@10270 333
awilliam@10270 334 /*
awilliam@10270 335 * Move any relocated data out into the previously found relocation
awilliam@10270 336 * area. Any extra memory descriptrs are moved out to the end
awilliam@10270 337 * and set to zero pages.
awilliam@10270 338 */
awilliam@10270 339 for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) {
awilliam@10270 340 md_end = md->phys_addr + MD_SIZE(md);
awilliam@10270 341
awilliam@10270 342 if (md->type == EFI_LOADER_DATA) {
awilliam@10270 343 unsigned long relo_offset;
awilliam@10270 344
awilliam@10270 345 if (md_overlaps(md, ia64_boot_param->domain_start)) {
awilliam@10270 346 relo_offset = ia64_boot_param->domain_start - md->phys_addr;
awilliam@10270 347 printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n",
awilliam@10270 348 ia64_boot_param->domain_start, relo_start + relo_offset,
awilliam@10270 349 ia64_boot_param->domain_size >> 10);
awilliam@10270 350 ia64_boot_param->domain_start = relo_start + relo_offset;
awilliam@10270 351 }
awilliam@10270 352 if (ia64_boot_param->initrd_size &&
awilliam@10270 353 md_overlaps(md, ia64_boot_param->initrd_start)) {
awilliam@10270 354 relo_offset = ia64_boot_param->initrd_start - md->phys_addr;
awilliam@10270 355 printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n",
awilliam@10270 356 ia64_boot_param->initrd_start, relo_start + relo_offset,
awilliam@10270 357 ia64_boot_param->initrd_size >> 10);
awilliam@10270 358 ia64_boot_param->initrd_start = relo_start + relo_offset;
awilliam@10270 359 }
awilliam@10270 360 memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md));
awilliam@10270 361 relo_start += MD_SIZE(md);
awilliam@10270 362 }
awilliam@10270 363
awilliam@10270 364 if (md == kern_md)
awilliam@10270 365 continue;
awilliam@10270 366 if (md == last_md)
awilliam@10270 367 break;
awilliam@10270 368
awilliam@10270 369 md->phys_addr = relo_end;
awilliam@10270 370 md->num_pages = 0;
djm@7735 371 }
djm@7735 372
awilliam@10270 373 /* Trim the last entry */
awilliam@10270 374 md->phys_addr = relo_end;
awilliam@10270 375 md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT;
djm@6458 376
awilliam@10270 377 /*
awilliam@10270 378 * Expand the new kernel/xenheap (and maybe dom0/initrd) out to
awilliam@10270 379 * the full size. This range will already be type EFI_LOADER_DATA,
awilliam@10270 380 * therefore the xenheap area is now protected being allocated for
awilliam@10270 381 * use by find_memmap_space() in efi.c
awilliam@10270 382 */
awilliam@10270 383 kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT;
djm@7735 384
awilliam@10270 385 reserve_memory();
djm@6458 386
djm@6458 387 /* first find highest page frame number */
djm@6458 388 max_page = 0;
djm@6458 389 efi_memmap_walk(find_max_pfn, &max_page);
djm@6458 390 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
awilliam@9758 391 #ifndef CONFIG_XEN_IA64_DOM0_VP
djm@8374 392 /* this is a bad hack. see dom_fw.c creation of EFI map for dom0 */
djm@8374 393 max_page = (GRANULEROUNDDOWN(max_page << PAGE_SHIFT)
djm@8374 394 - IA64_GRANULE_SIZE) >> PAGE_SHIFT;
djm@8374 395 printf("find_memory: last granule reserved for dom0; xen max_page=%lx\n",
djm@8374 396 max_page);
awilliam@9758 397 #endif
awilliam@9750 398 efi_print();
djm@6458 399
djm@6458 400 heap_start = memguard_init(ia64_imva(&_end));
awilliam@9005 401 printf("Before heap_start: %p\n", heap_start);
djm@6458 402 heap_start = __va(init_boot_allocator(__pa(heap_start)));
awilliam@9005 403 printf("After heap_start: %p\n", heap_start);
djm@6458 404
djm@6458 405 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
djm@6458 406 efi_memmap_walk(xen_count_pages, &nr_pages);
djm@6458 407
djm@6458 408 printk("System RAM: %luMB (%lukB)\n",
djm@6458 409 nr_pages >> (20 - PAGE_SHIFT),
djm@6458 410 nr_pages << (PAGE_SHIFT - 10));
awilliam@9773 411 total_pages = nr_pages;
djm@6458 412
djm@6458 413 init_frametable();
djm@6458 414
awilliam@10157 415 trap_init();
awilliam@10157 416
djm@6458 417 alloc_dom0();
djm@6458 418
djm@6458 419 end_boot_allocator();
djm@6458 420
djm@6458 421 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
djm@6458 422 printk("Xen heap: %luMB (%lukB)\n",
djm@6458 423 (xenheap_phys_end-__pa(heap_start)) >> 20,
djm@6458 424 (xenheap_phys_end-__pa(heap_start)) >> 10);
djm@6458 425
kaf24@8552 426 scheduler_init();
kaf24@8552 427 idle_vcpu[0] = (struct vcpu*) ia64_r13;
kfraser@10655 428 idle_domain = domain_create(IDLE_DOMAIN_ID);
kfraser@10655 429 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
kfraser@10655 430 BUG();
kaf24@8552 431
awilliam@10442 432 late_setup_arch(&cmdline);
awilliam@10151 433 alloc_dom_xen_and_dom_io();
djm@6458 434 setup_per_cpu_areas();
djm@6458 435 mem_init();
djm@6458 436
djm@6458 437 local_irq_disable();
djm@7332 438 init_IRQ ();
djm@6458 439 init_xen_time(); /* initialise the time */
kaf24@8586 440 timer_init();
djm@6458 441
djm@6458 442 #ifdef CONFIG_SMP
djm@6458 443 if ( opt_nosmp )
djm@6458 444 {
djm@6458 445 max_cpus = 0;
djm@6458 446 smp_num_siblings = 1;
djm@6458 447 //boot_cpu_data.x86_num_cores = 1;
djm@6458 448 }
djm@6458 449
awilliam@9495 450 /* A vcpu is created for the idle domain on every physical cpu.
awilliam@9495 451 Limit the number of cpus to the maximum number of vcpus. */
awilliam@9495 452 if (max_cpus > MAX_VIRT_CPUS)
awilliam@9495 453 max_cpus = MAX_VIRT_CPUS;
awilliam@9495 454
djm@6458 455 smp_prepare_cpus(max_cpus);
awilliam@9495 456
djm@6458 457 /* We aren't hotplug-capable yet. */
djm@6458 458 for_each_cpu ( i )
djm@6458 459 cpu_set(i, cpu_present_map);
djm@6458 460
djm@7332 461 /* Enable IRQ to receive IPI (needed for ITC sync). */
djm@7332 462 local_irq_enable();
djm@7332 463
djm@6458 464 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
djm@6458 465 for_each_present_cpu ( i )
djm@6458 466 {
djm@6458 467 if ( num_online_cpus() >= max_cpus )
djm@6458 468 break;
djm@6458 469 if ( !cpu_online(i) ) {
djm@6458 470 __cpu_up(i);
djm@6458 471 }
djm@6458 472 }
djm@6458 473
djm@7332 474 local_irq_disable();
djm@7332 475
djm@6458 476 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
djm@6458 477 smp_cpus_done(max_cpus);
djm@6458 478 #endif
djm@6458 479
kaf24@9117 480 initialise_gdb(); /* could be moved earlier */
kaf24@9117 481
djm@6458 482 do_initcalls();
djm@6458 483 sort_main_extable();
djm@6458 484
awilliam@9685 485 init_rid_allocator ();
awilliam@9685 486
awilliam@10442 487 local_irq_enable();
awilliam@10442 488
awilliam@10442 489 if (opt_xencons) {
awilliam@10445 490 initialize_keytable();
awilliam@10445 491 if (ns16550_com1_gsi) {
awilliam@10445 492 if (opt_xencons_poll ||
awilliam@10445 493 iosapic_register_intr(ns16550_com1_gsi,
awilliam@10445 494 ns16550_com1_polarity,
awilliam@10445 495 ns16550_com1_trigger) < 0) {
awilliam@10445 496 ns16550_com1.irq = 0;
awilliam@10445 497 ns16550_init(0, &ns16550_com1);
awilliam@10445 498 }
awilliam@10445 499 }
awilliam@10445 500 serial_init_postirq();
awilliam@10445 501
awilliam@10445 502 /* Hide the HCDP table from dom0 */
awilliam@10445 503 efi.hcdp = NULL;
awilliam@10442 504 }
awilliam@9685 505
djm@6458 506 /* Create initial domain 0. */
kfraser@10655 507 dom0 = domain_create(0);
kfraser@10655 508 if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
djm@6458 509 panic("Error creating domain 0\n");
djm@6458 510
djm@6458 511 set_bit(_DOMF_privileged, &dom0->domain_flags);
djm@6458 512
djm@6458 513 /*
djm@6458 514 * We're going to setup domain0 using the module(s) that we stashed safely
djm@6458 515 * above our heap. The second module, if present, is an initrd ramdisk.
djm@6458 516 */
awilliam@10270 517 dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start);
djm@7735 518 dom0_memory_size = ia64_boot_param->domain_size;
awilliam@9864 519 dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start);
djm@7735 520 dom0_initrd_size = ia64_boot_param->initrd_size;
djm@7735 521
djm@7735 522 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
djm@7735 523 dom0_initrd_start,dom0_initrd_size,
djm@7735 524 0) != 0)
djm@6458 525 panic("Could not set up DOM0 guest OS\n");
djm@7332 526
djm@7332 527 /* PIN domain0 on CPU 0. */
kaf24@8511 528 dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
djm@7332 529
djm@6458 530 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
djm@6458 531 scrub_heap_pages();
djm@6458 532
djm@6458 533 init_trace_bufs();
djm@6458 534
awilliam@10442 535 if (opt_xencons)
awilliam@10513 536 console_endboot();
djm@6458 537
djm@7332 538 domain0_ready = 1;
djm@7332 539
djm@7332 540 schedulers_start();
djm@7332 541
djm@6458 542 domain_unpause_by_systemcontroller(dom0);
djm@7332 543
djm@6458 544 startup_cpu_idle_loop();
djm@6458 545 }
djm@6723 546
djm@6797 547 void arch_get_xen_caps(xen_capabilities_info_t info)
djm@6723 548 {
djm@6797 549 char *p=info;
kfraser@10890 550 int major = xen_major_version();
kfraser@10890 551 int minor = xen_minor_version();
djm@6723 552
kfraser@10890 553 p += sprintf(p,"xen-%d.%d-ia64 ", major, minor);
djm@6723 554
djm@8475 555 if (vmx_enabled)
kfraser@10890 556 p += sprintf(p,"hvm-%d.%d-ia64 ", major, minor);
djm@6723 557
djm@6797 558 *(p-1) = 0;
djm@6723 559
djm@6797 560 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
djm@6797 561
djm@6723 562 }
djm@6723 563