ia64/xen-unstable

view xen/arch/ia64/xensetup.c @ 3940:6a7bbb8b60f4

bitkeeper revision 1.1236.1.30 (42204c4csSlUlMNeJeX9_Mcy3_XPYA)

Merge http://xen-ia64.bkbits.net/xeno-unstable-ia64.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno-unstable-ia64.bk
author kaf24@scramble.cl.cam.ac.uk
date Sat Feb 26 10:15:40 2005 +0000 (2005-02-26)
parents ca98a0eeb6b1 fbb1d8be1f5f
children a6914c2c15cf 6fe925d85cd6 4e765d177de7 205e127344e9
line source
1 /******************************************************************************
2 * kernel.c
3 *
4 * This file should contain architecture-independent bootstrap and low-level
5 * help routines. It's a bit x86/PC specific right now!
6 *
7 * Copyright (c) 2002-2003 K A Fraser
8 */
10 //#include <stdarg.h>
11 #include <xen/config.h>
12 #include <xen/lib.h>
13 #include <xen/errno.h>
14 //#include <xen/spinlock.h>
15 #include <xen/multiboot.h>
16 #include <xen/sched.h>
17 #include <xen/mm.h>
18 //#include <xen/delay.h>
19 #include <xen/compile.h>
20 //#include <xen/console.h>
21 //#include <xen/serial.h>
22 #include <xen/trace.h>
23 //#include <asm/shadow.h>
24 //#include <asm/io.h>
25 //#include <asm/uaccess.h>
26 //#include <asm/domain_page.h>
27 //#include <public/dom0_ops.h>
29 unsigned long xenheap_phys_end;
31 struct exec_domain *idle_task[NR_CPUS] = { &idle0_exec_domain };
33 xmem_cache_t *domain_struct_cachep;
34 #ifdef IA64
35 kmem_cache_t *mm_cachep;
36 kmem_cache_t *vm_area_cachep;
37 #ifdef CLONE_DOMAIN0
38 struct domain *clones[CLONE_DOMAIN0];
39 #endif
40 #endif
41 extern struct domain *dom0;
42 extern unsigned long domain0_ready;
44 #ifndef IA64
45 vm_assist_info_t vm_assist_info[MAX_VMASST_TYPE + 1];
46 #endif
48 #ifndef IA64
49 struct e820entry {
50 unsigned long addr_lo, addr_hi; /* start of memory segment */
51 unsigned long size_lo, size_hi; /* size of memory segment */
52 unsigned long type; /* type of memory segment */
53 };
54 #endif
56 void start_of_day(void);
58 /* opt_console: comma-separated list of console outputs. */
59 #ifdef IA64
60 unsigned char opt_console[30] = "com1";
61 #else
62 unsigned char opt_console[30] = "com1,vga";
63 #endif
64 /* opt_conswitch: a character pair controlling console switching. */
65 /* Char 1: CTRL+<char1> is used to switch console input between Xen and DOM0 */
66 /* Char 2: If this character is 'x', then do not auto-switch to DOM0 when it */
67 /* boots. Any other value, or omitting the char, enables auto-switch */
68 unsigned char opt_conswitch[5] = "a"; /* NB. '`' would disable switching. */
69 /* opt_com[12]: Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
70 unsigned char opt_com1[30] = "", opt_com2[30] = "";
71 /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
72 unsigned int opt_dom0_mem = 16000;
73 /* opt_noht: If true, Hyperthreading is ignored. */
74 int opt_noht=0;
75 /* opt_noacpi: If true, ACPI tables are not parsed. */
76 int opt_noacpi=0;
77 /* opt_nosmp: If true, secondary processors are ignored. */
78 int opt_nosmp=0;
79 /* opt_noreboot: If true, machine will need manual reset on error. */
80 int opt_noreboot=0;
81 /* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */
82 /* NB. This flag implies 'nosmp' and 'noacpi'. */
83 int opt_ignorebiostables=0;
84 /* opt_watchdog: If true, run a watchdog NMI on each processor. */
85 int opt_watchdog=0;
86 /* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */
87 unsigned char opt_pdb[10] = "none";
88 /* opt_tbuf_size: trace buffer size (in pages) */
89 unsigned int opt_tbuf_size = 10;
90 /* opt_sched: scheduler - default to Borrowed Virtual Time */
91 char opt_sched[10] = "bvt";
92 /* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */
93 /* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */
94 char opt_physdev_dom0_hide[200] = "";
95 /* opt_leveltrigger, opt_edgetrigger: Force an IO-APIC-routed IRQ to be */
96 /* level- or edge-triggered. */
97 /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
98 char opt_leveltrigger[30] = "", opt_edgetrigger[30] = "";
99 /*
100 * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
101 * pfn_info table and allocation bitmap.
102 */
103 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
104 /*
105 * opt_nmi: one of 'ignore', 'dom0', or 'fatal'.
106 * fatal: Xen prints diagnostic message and then hangs.
107 * dom0: The NMI is virtualised to DOM0.
108 * ignore: The NMI error is cleared and ignored.
109 */
110 #ifdef NDEBUG
111 char opt_nmi[10] = "dom0";
112 #else
113 char opt_nmi[10] = "fatal";
114 #endif
115 /*
116 * Comma-separated list of hexadecimal page numbers containing bad bytes.
117 * e.g. 'badpage=0x3f45,0x8a321'.
118 */
119 char opt_badpage[100] = "";
121 extern long running_on_sim;
123 void cmain(multiboot_info_t *mbi)
124 {
125 unsigned long max_page;
126 unsigned char *cmdline;
127 module_t *mod = (module_t *)__va(mbi->mods_addr);
128 void *heap_start;
129 int i;
130 unsigned long max_mem;
131 unsigned long dom0_memory_start, dom0_memory_end;
132 unsigned long initial_images_start, initial_images_end;
135 running_on_sim = is_platform_hp_ski();
137 /* Parse the command-line options. */
138 cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
139 cmdline_parse(cmdline);
141 /* Must do this early -- e.g., spinlocks rely on get_current(). */
142 set_current(&idle0_exec_domain);
144 early_setup_arch();
146 /* We initialise the serial devices very early so we can get debugging. */
147 serial_init_stage1();
149 init_console();
150 set_printk_prefix("(XEN) ");
152 #ifdef IA64
153 //set_current(&idle0_exec_domain);
154 { char *cmdline;
155 setup_arch(&cmdline);
156 }
157 setup_per_cpu_areas();
158 build_all_zonelists();
159 mem_init();
160 //show_mem(); // call to dump lots of memory info for debug
161 #else
162 /* We require memory and module information. */
163 if ( (mbi->flags & 9) != 9 )
164 {
165 printk("FATAL ERROR: Bad flags passed by bootloader: 0x%x\n",
166 (unsigned)mbi->flags);
167 for ( ; ; ) ;
168 }
170 if ( mbi->mods_count == 0 )
171 {
172 printk("Require at least one Multiboot module!\n");
173 for ( ; ; ) ;
174 }
176 if ( opt_xenheap_megabytes < 4 )
177 {
178 printk("Xen heap size is too small to safely continue!\n");
179 for ( ; ; ) ;
180 }
182 xenheap_phys_end = opt_xenheap_megabytes << 20;
184 max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
185 #endif
187 #if defined(__i386__)
189 initial_images_start = DIRECTMAP_PHYS_END;
190 initial_images_end = initial_images_start +
191 (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
192 if ( initial_images_end > (max_page << PAGE_SHIFT) )
193 {
194 printk("Not enough memory to stash the DOM0 kernel image.\n");
195 for ( ; ; ) ;
196 }
197 memmove((void *)initial_images_start, /* use low mapping */
198 (void *)mod[0].mod_start, /* use low mapping */
199 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
201 if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
202 {
203 printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
204 XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
205 for ( ; ; ) ;
206 }
208 ASSERT((sizeof(struct pfn_info) << 20) <=
209 (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
211 init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
213 #elif defined(__x86_64__)
215 init_frametable(__va(xenheap_phys_end), max_page);
217 initial_images_start = __pa(frame_table) + frame_table_size;
218 initial_images_end = initial_images_start +
219 (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
220 if ( initial_images_end > (max_page << PAGE_SHIFT) )
221 {
222 printk("Not enough memory to stash the DOM0 kernel image.\n");
223 for ( ; ; ) ;
224 }
225 memmove(__va(initial_images_start),
226 __va(mod[0].mod_start),
227 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
229 #endif
231 #ifndef IA64
232 dom0_memory_start = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
233 dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10);
234 dom0_memory_end = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
236 /* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
237 if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
238 {
239 printk("Not enough memory for DOM0 memory reservation.\n");
240 for ( ; ; ) ;
241 }
242 #endif
244 printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
245 max_page >> (20-PAGE_SHIFT), max_page,
246 max_mem >> (20-PAGE_SHIFT));
248 #ifndef IA64
249 heap_start = memguard_init(&_end);
250 heap_start = __va(init_heap_allocator(__pa(heap_start), max_page));
252 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
253 printk("Xen heap size is %luKB\n",
254 (xenheap_phys_end-__pa(heap_start))/1024 );
256 init_domheap_pages(dom0_memory_end, max_page << PAGE_SHIFT);
257 #endif
259 /* Initialise the slab allocator. */
260 #ifdef IA64
261 kmem_cache_init();
262 #else
263 xmem_cache_init();
264 xmem_cache_sizes_init(max_page);
265 #endif
267 domain_struct_cachep = xmem_cache_create(
268 "domain_cache", sizeof(struct domain),
269 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
270 if ( domain_struct_cachep == NULL )
271 panic("No slab cache for task structs.");
273 #ifdef IA64
274 // following from proc_caches_init in linux/kernel/fork.c
275 vm_area_cachep = kmem_cache_create("vm_area_struct",
276 sizeof(struct vm_area_struct), 0,
277 SLAB_PANIC, NULL, NULL);
278 mm_cachep = kmem_cache_create("mm_struct",
279 sizeof(struct mm_struct), 0,
280 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
281 printk("About to call scheduler_init()\n");
282 scheduler_init();
283 local_irq_disable();
284 printk("About to call time_init()\n");
285 time_init();
286 printk("About to call ac_timer_init()\n");
287 ac_timer_init();
288 // init_xen_time(); ???
289 // schedulers_start(); ???
290 // do_initcalls(); ???
291 #else
292 start_of_day();
294 grant_table_init();
295 #endif
297 /* Create initial domain 0. */
298 printk("About to call do_createdomain()\n");
299 dom0 = do_createdomain(0, 0);
300 printk("About to call init_idle_task()\n");
301 init_task.domain = &idle0_domain;
302 init_task.processor = 0;
303 init_task.mm = &init_mm;
304 // init_task.thread = INIT_THREAD;
305 init_idle_task();
306 //arch_do_createdomain(current);
307 #ifdef CLONE_DOMAIN0
308 {
309 int i;
310 for (i = 0; i < CLONE_DOMAIN0; i++) {
311 clones[i] = do_createdomain(i+1, 0);
312 if ( clones[i] == NULL )
313 panic("Error creating domain0 clone %d\n",i);
314 }
315 }
316 #endif
317 if ( dom0 == NULL )
318 panic("Error creating domain 0\n");
320 set_bit(DF_PRIVILEGED, &dom0->d_flags);
322 //printk("About to call shadow_mode_init()\n");
323 // shadow_mode_init();
325 /* Grab the DOM0 command line. Skip past the image name. */
326 printk("About to process command line\n");
327 #ifndef IA64
328 cmdline = (unsigned char *)(mod[0].string ? __va(mod[0].string) : NULL);
329 if ( cmdline != NULL )
330 {
331 while ( *cmdline == ' ' ) cmdline++;
332 if ( (cmdline = strchr(cmdline, ' ')) != NULL )
333 while ( *cmdline == ' ' ) cmdline++;
334 }
335 #endif
337 /*
338 * We're going to setup domain0 using the module(s) that we stashed safely
339 * above our heap. The second module, if present, is an initrd ramdisk.
340 */
341 #ifdef IA64
342 printk("About to call construct_dom0()\n");
343 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
344 0,
345 0,
346 0) != 0)
347 #else
348 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
349 (char *)initial_images_start,
350 mod[0].mod_end-mod[0].mod_start,
351 (mbi->mods_count == 1) ? 0 :
352 (char *)initial_images_start +
353 (mod[1].mod_start-mod[0].mod_start),
354 (mbi->mods_count == 1) ? 0 :
355 mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
356 cmdline) != 0)
357 #endif
358 panic("Could not set up DOM0 guest OS\n");
359 #ifdef CLONE_DOMAIN0
360 {
361 int i;
362 for (i = 0; i < CLONE_DOMAIN0; i++) {
363 printk("CONSTRUCTING DOMAIN0 CLONE #%d\n",i+1);
364 if ( construct_dom0(clones[i], dom0_memory_start, dom0_memory_end,
365 0,
366 0,
367 0) != 0)
368 panic("Could not set up DOM0 clone %d\n",i);
369 }
370 }
371 #endif
373 /* The stash space for the initial kernel image can now be freed up. */
374 #ifndef IA64
375 init_domheap_pages(__pa(frame_table) + frame_table_size,
376 dom0_memory_start);
378 scrub_heap_pages();
379 #endif
381 printk("About to call init_trace_bufs()\n");
382 init_trace_bufs();
384 /* Give up the VGA console if DOM0 is configured to grab it. */
385 #ifndef IA64
386 console_endboot(cmdline && strstr(cmdline, "tty0"));
387 #endif
389 domain_unpause_by_systemcontroller(current);
390 #ifdef CLONE_DOMAIN0
391 {
392 int i;
393 for (i = 0; i < CLONE_DOMAIN0; i++)
394 domain_unpause_by_systemcontroller(clones[i]);
395 }
396 #endif
397 domain_unpause_by_systemcontroller(dom0);
398 domain0_ready = 1;
399 local_irq_enable();
400 printk("About to call startup_cpu_idle_loop()\n");
401 startup_cpu_idle_loop();
402 }