ia64/xen-unstable

view xen/arch/ia64/xensetup.c @ 4146:f2d61710e4d9

bitkeeper revision 1.1236.25.24 (42366e9aQ71LQ8uCB-Y1IwVNqx5eqA)

Merge djm@kirby.fc.hp.com://home/djm/src/xen/xeno-unstable-ia64.bk
into sportsman.spdomain:/home/djm/xeno-unstable-ia64.bk
author djm@sportsman.spdomain
date Tue Mar 15 05:11:54 2005 +0000 (2005-03-15)
parents f8026d38aa87 0c846e77cca4
children 2f89618be8d4
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);
143 idle0_exec_domain.domain = &idle0_domain;
145 early_setup_arch();
147 /* We initialise the serial devices very early so we can get debugging. */
148 serial_init_stage1();
150 init_console();
151 set_printk_prefix("(XEN) ");
153 #ifdef IA64
154 //set_current(&idle0_exec_domain);
155 { char *cmdline;
156 setup_arch(&cmdline);
157 }
158 setup_per_cpu_areas();
159 build_all_zonelists();
160 mem_init();
161 //show_mem(); // call to dump lots of memory info for debug
162 #else
163 /* We require memory and module information. */
164 if ( (mbi->flags & 9) != 9 )
165 {
166 printk("FATAL ERROR: Bad flags passed by bootloader: 0x%x\n",
167 (unsigned)mbi->flags);
168 for ( ; ; ) ;
169 }
171 if ( mbi->mods_count == 0 )
172 {
173 printk("Require at least one Multiboot module!\n");
174 for ( ; ; ) ;
175 }
177 if ( opt_xenheap_megabytes < 4 )
178 {
179 printk("Xen heap size is too small to safely continue!\n");
180 for ( ; ; ) ;
181 }
183 xenheap_phys_end = opt_xenheap_megabytes << 20;
185 max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
186 #endif
188 #if defined(__i386__)
190 initial_images_start = DIRECTMAP_PHYS_END;
191 initial_images_end = initial_images_start +
192 (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
193 if ( initial_images_end > (max_page << PAGE_SHIFT) )
194 {
195 printk("Not enough memory to stash the DOM0 kernel image.\n");
196 for ( ; ; ) ;
197 }
198 memmove((void *)initial_images_start, /* use low mapping */
199 (void *)mod[0].mod_start, /* use low mapping */
200 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
202 if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
203 {
204 printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
205 XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
206 for ( ; ; ) ;
207 }
209 ASSERT((sizeof(struct pfn_info) << 20) <=
210 (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
212 init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
214 #elif defined(__x86_64__)
216 init_frametable(__va(xenheap_phys_end), max_page);
218 initial_images_start = __pa(frame_table) + frame_table_size;
219 initial_images_end = initial_images_start +
220 (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
221 if ( initial_images_end > (max_page << PAGE_SHIFT) )
222 {
223 printk("Not enough memory to stash the DOM0 kernel image.\n");
224 for ( ; ; ) ;
225 }
226 memmove(__va(initial_images_start),
227 __va(mod[0].mod_start),
228 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
230 #endif
232 #ifndef IA64
233 dom0_memory_start = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
234 dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10);
235 dom0_memory_end = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
237 /* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
238 if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
239 {
240 printk("Not enough memory for DOM0 memory reservation.\n");
241 for ( ; ; ) ;
242 }
243 #endif
245 printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
246 max_page >> (20-PAGE_SHIFT), max_page,
247 max_mem >> (20-PAGE_SHIFT));
249 #ifndef IA64
250 heap_start = memguard_init(&_end);
251 heap_start = __va(init_heap_allocator(__pa(heap_start), max_page));
253 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
254 printk("Xen heap size is %luKB\n",
255 (xenheap_phys_end-__pa(heap_start))/1024 );
257 init_domheap_pages(dom0_memory_end, max_page << PAGE_SHIFT);
258 #endif
260 /* Initialise the slab allocator. */
261 #ifdef IA64
262 kmem_cache_init();
263 #else
264 xmem_cache_init();
265 xmem_cache_sizes_init(max_page);
266 #endif
268 domain_struct_cachep = xmem_cache_create(
269 "domain_cache", sizeof(struct domain),
270 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
271 if ( domain_struct_cachep == NULL )
272 panic("No slab cache for task structs.");
274 #ifdef IA64
275 // following from proc_caches_init in linux/kernel/fork.c
276 vm_area_cachep = kmem_cache_create("vm_area_struct",
277 sizeof(struct vm_area_struct), 0,
278 SLAB_PANIC, NULL, NULL);
279 mm_cachep = kmem_cache_create("mm_struct",
280 sizeof(struct mm_struct), 0,
281 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
282 printk("About to call scheduler_init()\n");
283 scheduler_init();
284 local_irq_disable();
285 printk("About to call time_init()\n");
286 time_init();
287 printk("About to call ac_timer_init()\n");
288 ac_timer_init();
289 // init_xen_time(); ???
290 schedulers_start();
291 // do_initcalls(); ???
292 printk("About to call sort_main_extable()\n");
293 sort_main_extable();
294 #else
295 start_of_day();
297 grant_table_init();
298 #endif
300 /* Create initial domain 0. */
301 printk("About to call do_createdomain()\n");
302 dom0 = do_createdomain(0, 0);
303 printk("About to call init_idle_task()\n");
304 init_task.domain = &idle0_domain;
305 init_task.processor = 0;
306 init_task.mm = &init_mm;
307 // init_task.thread = INIT_THREAD;
308 init_idle_task();
309 //arch_do_createdomain(current);
310 #ifdef CLONE_DOMAIN0
311 {
312 int i;
313 for (i = 0; i < CLONE_DOMAIN0; i++) {
314 clones[i] = do_createdomain(i+1, 0);
315 if ( clones[i] == NULL )
316 panic("Error creating domain0 clone %d\n",i);
317 }
318 }
319 #endif
320 if ( dom0 == NULL )
321 panic("Error creating domain 0\n");
323 set_bit(DF_PRIVILEGED, &dom0->d_flags);
325 //printk("About to call shadow_mode_init()\n");
326 // shadow_mode_init();
328 /* Grab the DOM0 command line. Skip past the image name. */
329 printk("About to process command line\n");
330 #ifndef IA64
331 cmdline = (unsigned char *)(mod[0].string ? __va(mod[0].string) : NULL);
332 if ( cmdline != NULL )
333 {
334 while ( *cmdline == ' ' ) cmdline++;
335 if ( (cmdline = strchr(cmdline, ' ')) != NULL )
336 while ( *cmdline == ' ' ) cmdline++;
337 }
338 #endif
340 /*
341 * We're going to setup domain0 using the module(s) that we stashed safely
342 * above our heap. The second module, if present, is an initrd ramdisk.
343 */
344 #ifdef IA64
345 printk("About to call construct_dom0()\n");
346 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
347 0,
348 0,
349 0) != 0)
350 #else
351 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
352 (char *)initial_images_start,
353 mod[0].mod_end-mod[0].mod_start,
354 (mbi->mods_count == 1) ? 0 :
355 (char *)initial_images_start +
356 (mod[1].mod_start-mod[0].mod_start),
357 (mbi->mods_count == 1) ? 0 :
358 mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
359 cmdline) != 0)
360 #endif
361 panic("Could not set up DOM0 guest OS\n");
362 #ifdef CLONE_DOMAIN0
363 {
364 int i;
365 for (i = 0; i < CLONE_DOMAIN0; i++) {
366 printk("CONSTRUCTING DOMAIN0 CLONE #%d\n",i+1);
367 if ( construct_dom0(clones[i], dom0_memory_start, dom0_memory_end,
368 0,
369 0,
370 0) != 0)
371 panic("Could not set up DOM0 clone %d\n",i);
372 }
373 }
374 #endif
376 /* The stash space for the initial kernel image can now be freed up. */
377 #ifndef IA64
378 init_domheap_pages(__pa(frame_table) + frame_table_size,
379 dom0_memory_start);
381 scrub_heap_pages();
382 #endif
384 printk("About to call init_trace_bufs()\n");
385 init_trace_bufs();
387 /* Give up the VGA console if DOM0 is configured to grab it. */
388 #ifndef IA64
389 console_endboot(cmdline && strstr(cmdline, "tty0"));
390 #endif
392 domain_unpause_by_systemcontroller(current->domain);
393 #ifdef CLONE_DOMAIN0
394 {
395 int i;
396 for (i = 0; i < CLONE_DOMAIN0; i++)
397 domain_unpause_by_systemcontroller(clones[i]);
398 }
399 #endif
400 domain_unpause_by_systemcontroller(dom0);
401 domain0_ready = 1;
402 local_irq_enable();
403 printk("About to call startup_cpu_idle_loop()\n");
404 startup_cpu_idle_loop();
405 }