aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'xen/arch/x86/setup.c')
-rw-r--r--xen/arch/x86/setup.c192
1 files changed, 191 insertions, 1 deletions
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index d69ff860ff..6d2541d702 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -7,6 +7,9 @@
#include <xen/serial.h>
#include <xen/softirq.h>
#include <xen/acpi.h>
+#include <xen/console.h>
+#include <xen/trace.h>
+#include <xen/multiboot.h>
#include <asm/bitops.h>
#include <asm/smp.h>
#include <asm/processor.h>
@@ -15,6 +18,18 @@
#include <asm/desc.h>
#include <asm/domain_page.h>
#include <asm/pdb.h>
+#include <asm/shadow.h>
+
+/* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
+static unsigned int opt_dom0_mem = 16000;
+integer_param("dom0_mem", opt_dom0_mem);
+
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * pfn_info table and allocation bitmap.
+ */
+static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
/* opt_noht: If true, Hyperthreading is ignored. */
int opt_noht = 0;
@@ -37,6 +52,8 @@ boolean_param("ignorebiostables", opt_ignorebiostables);
static int opt_watchdog = 0;
boolean_param("watchdog", opt_watchdog);
+unsigned long xenheap_phys_end;
+
extern void arch_init_memory(void);
extern void init_IRQ(void);
extern void trap_init(void);
@@ -330,7 +347,7 @@ static void __init do_initcalls(void)
unsigned long pci_mem_start = 0x10000000;
-void __init start_of_day(void)
+static void __init start_of_day(void)
{
unsigned long low_mem_size;
@@ -440,3 +457,176 @@ void __init start_of_day(void)
watchdog_on = 1;
}
+
+void __init __start_xen(multiboot_info_t *mbi)
+{
+ unsigned long max_page;
+ unsigned char *cmdline;
+ module_t *mod = (module_t *)__va(mbi->mods_addr);
+ void *heap_start;
+ unsigned long max_mem;
+ unsigned long dom0_memory_start, dom0_memory_end;
+ unsigned long initial_images_start, initial_images_end;
+
+ /* Parse the command-line options. */
+ cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
+ cmdline_parse(cmdline);
+
+ /* Must do this early -- e.g., spinlocks rely on get_current(). */
+ set_current(&idle0_task);
+
+ /* We initialise the serial devices very early so we can get debugging. */
+ serial_init_stage1();
+
+ init_console();
+
+ /* We require memory and module information. */
+ if ( (mbi->flags & 9) != 9 )
+ {
+ printk("FATAL ERROR: Bad flags passed by bootloader: 0x%x\n",
+ (unsigned)mbi->flags);
+ for ( ; ; ) ;
+ }
+
+ if ( mbi->mods_count == 0 )
+ {
+ printk("Require at least one Multiboot module!\n");
+ for ( ; ; ) ;
+ }
+
+ if ( opt_xenheap_megabytes < 4 )
+ {
+ printk("Xen heap size is too small to safely continue!\n");
+ for ( ; ; ) ;
+ }
+
+ xenheap_phys_end = opt_xenheap_megabytes << 20;
+
+ max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
+
+#if defined(__i386__)
+
+ initial_images_start = DIRECTMAP_PHYS_END;
+ initial_images_end = initial_images_start +
+ (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+ if ( initial_images_end > (max_page << PAGE_SHIFT) )
+ {
+ printk("Not enough memory to stash the DOM0 kernel image.\n");
+ for ( ; ; ) ;
+ }
+ memmove((void *)initial_images_start, /* use low mapping */
+ (void *)mod[0].mod_start, /* use low mapping */
+ mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+ if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
+ {
+ printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
+ XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
+ for ( ; ; ) ;
+ }
+
+ ASSERT((sizeof(struct pfn_info) << 20) <=
+ (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
+
+ init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
+
+#elif defined(__x86_64__)
+
+ init_frametable(__va(xenheap_phys_end), max_page);
+
+ initial_images_start = __pa(frame_table) + frame_table_size;
+ initial_images_end = initial_images_start +
+ (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+ if ( initial_images_end > (max_page << PAGE_SHIFT) )
+ {
+ printk("Not enough memory to stash the DOM0 kernel image.\n");
+ for ( ; ; ) ;
+ }
+ memmove(__va(initial_images_start),
+ __va(mod[0].mod_start),
+ mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+#endif
+
+ dom0_memory_start = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
+ dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10);
+ dom0_memory_end = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
+
+ /* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
+ if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
+ {
+ printk("Not enough memory for DOM0 memory reservation.\n");
+ for ( ; ; ) ;
+ }
+
+ printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
+ max_page >> (20-PAGE_SHIFT), max_page,
+ max_mem >> (20-PAGE_SHIFT));
+
+ heap_start = memguard_init(&_end);
+ heap_start = __va(init_heap_allocator(__pa(heap_start), max_page));
+
+ init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
+ printk("Xen heap size is %luKB\n",
+ (xenheap_phys_end-__pa(heap_start))/1024 );
+
+ init_domheap_pages(dom0_memory_end, max_page << PAGE_SHIFT);
+
+ /* Initialise the slab allocator. */
+ xmem_cache_init();
+ xmem_cache_sizes_init(max_page);
+
+ domain_startofday();
+
+ start_of_day();
+
+ grant_table_init();
+
+ shadow_mode_init();
+
+ /* Create initial domain 0. */
+ dom0 = do_createdomain(0, 0);
+ if ( dom0 == NULL )
+ panic("Error creating domain 0\n");
+
+ set_bit(DF_PRIVILEGED, &dom0->flags);
+
+ /* Grab the DOM0 command line. Skip past the image name. */
+ cmdline = (unsigned char *)(mod[0].string ? __va(mod[0].string) : NULL);
+ if ( cmdline != NULL )
+ {
+ while ( *cmdline == ' ' ) cmdline++;
+ if ( (cmdline = strchr(cmdline, ' ')) != NULL )
+ while ( *cmdline == ' ' ) cmdline++;
+ }
+
+ /*
+ * We're going to setup domain0 using the module(s) that we stashed safely
+ * above our heap. The second module, if present, is an initrd ramdisk.
+ */
+ if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
+ (char *)initial_images_start,
+ mod[0].mod_end-mod[0].mod_start,
+ (mbi->mods_count == 1) ? 0 :
+ (char *)initial_images_start +
+ (mod[1].mod_start-mod[0].mod_start),
+ (mbi->mods_count == 1) ? 0 :
+ mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
+ cmdline) != 0)
+ panic("Could not set up DOM0 guest OS\n");
+
+ /* The stash space for the initial kernel image can now be freed up. */
+ init_domheap_pages(__pa(frame_table) + frame_table_size,
+ dom0_memory_start);
+
+ scrub_heap_pages();
+
+ init_trace_bufs();
+
+ /* Give up the VGA console if DOM0 is configured to grab it. */
+ console_endboot(cmdline && strstr(cmdline, "tty0"));
+
+ domain_unpause_by_systemcontroller(current);
+ domain_unpause_by_systemcontroller(dom0);
+ startup_cpu_idle_loop();
+}