ia64/xen-unstable

view xen/arch/ia64/xensetup.c @ 3843:184c3ab84dc7

bitkeeper revision 1.1211 (42135fc9O6u50eCen5G3SeEPjYjX6w)

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