ia64/xen-unstable

view xen/arch/ia64/xensetup.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 f46bb706a38d
children 99914b54f7bf
line source
1 /******************************************************************************
2 * xensetup.c
3 * Copyright (c) 2004-2005 Hewlett-Packard Co
4 * Dan Magenheimer <dan.magenheimer@hp.com>
5 */
7 #include <xen/config.h>
8 #include <xen/lib.h>
9 #include <xen/errno.h>
10 //#include <xen/spinlock.h>
11 #include <xen/multiboot.h>
12 #include <xen/sched.h>
13 #include <xen/mm.h>
14 //#include <xen/delay.h>
15 #include <xen/compile.h>
16 //#include <xen/console.h>
17 #include <xen/serial.h>
18 #include <xen/trace.h>
19 #include <asm/meminit.h>
20 #include <asm/page.h>
21 #include <asm/setup.h>
22 #include <xen/string.h>
24 unsigned long xenheap_phys_end;
26 char saved_command_line[COMMAND_LINE_SIZE];
28 struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
30 #ifdef CLONE_DOMAIN0
31 struct domain *clones[CLONE_DOMAIN0];
32 #endif
33 extern unsigned long domain0_ready;
35 int find_max_pfn (unsigned long, unsigned long, void *);
36 void start_of_day(void);
38 /* opt_nosmp: If true, secondary processors are ignored. */
39 static int opt_nosmp = 0;
40 boolean_param("nosmp", opt_nosmp);
42 /* maxcpus: maximum number of CPUs to activate. */
43 static unsigned int max_cpus = NR_CPUS;
44 integer_param("maxcpus", max_cpus);
46 /*
47 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
48 * xen image
49 * bootmap bits
50 * xen heap
51 * Note: To allow xenheap size configurable, the prerequisite is
52 * to configure elilo allowing relocation defaultly. Then since
53 * elilo chooses 256M as alignment when relocating, alignment issue
54 * on IPF can be addressed.
55 */
56 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
57 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
58 extern long running_on_sim;
59 unsigned long xen_pstart;
61 static int
62 xen_count_pages(u64 start, u64 end, void *arg)
63 {
64 unsigned long *count = arg;
66 /* FIXME: do we need consider difference between DMA-usable memory and
67 * normal memory? Seems that HV has no requirement to operate DMA which
68 * is owned by Dom0? */
69 *count += (end - start) >> PAGE_SHIFT;
70 return 0;
71 }
73 /* Find first hole after trunk for xen image */
74 static int
75 xen_find_first_hole(u64 start, u64 end, void *arg)
76 {
77 unsigned long *first_hole = arg;
79 if ((*first_hole) == 0) {
80 if ((start <= KERNEL_START) && (KERNEL_START < end))
81 *first_hole = __pa(end);
82 }
84 return 0;
85 }
87 static void __init do_initcalls(void)
88 {
89 initcall_t *call;
90 for ( call = &__initcall_start; call < &__initcall_end; call++ )
91 (*call)();
92 }
94 /*
95 * IPF loader only supports one commaind line currently, for
96 * both xen and guest kernel. This function provides pre-parse
97 * to mixed command line, to split it into two parts.
98 *
99 * User should split the parameters by "--", with strings after
100 * spliter for guest kernel. Missing "--" means whole line belongs
101 * to guest. Example:
102 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
103 * root=/dev/sda3 ro"
104 */
105 static char null[4] = { 0 };
107 void early_cmdline_parse(char **cmdline_p)
108 {
109 char *guest_cmd;
110 char *split = "--";
112 if (*cmdline_p == NULL) {
113 *cmdline_p = &null[0];
114 saved_command_line[0] = '\0';
115 return;
116 }
118 guest_cmd = strstr(*cmdline_p, split);
119 /* If no spliter, whole line is for guest */
120 if (guest_cmd == NULL) {
121 guest_cmd = *cmdline_p;
122 *cmdline_p = &null[0];
123 } else {
124 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
125 guest_cmd += strlen(split);
126 while (*guest_cmd == ' ') guest_cmd++;
127 }
129 strlcpy(saved_command_line, guest_cmd, COMMAND_LINE_SIZE);
130 return;
131 }
133 struct ns16550_defaults ns16550_com1 = {
134 .baud = BAUD_AUTO,
135 .data_bits = 8,
136 .parity = 'n',
137 .stop_bits = 1
138 };
140 struct ns16550_defaults ns16550_com2 = {
141 .baud = BAUD_AUTO,
142 .data_bits = 8,
143 .parity = 'n',
144 .stop_bits = 1
145 };
147 void start_kernel(void)
148 {
149 unsigned char *cmdline;
150 void *heap_start;
151 int i;
152 unsigned long max_mem, nr_pages, firsthole_start;
153 unsigned long dom0_memory_start, dom0_memory_end;
154 unsigned long initial_images_start, initial_images_end;
156 running_on_sim = is_platform_hp_ski();
157 /* Kernel may be relocated by EFI loader */
158 xen_pstart = ia64_tpa(KERNEL_START);
160 /* Must do this early -- e.g., spinlocks rely on get_current(). */
161 //set_current(&idle0_vcpu);
162 ia64_r13 = (void *)&idle0_vcpu;
163 idle0_vcpu.domain = &idle0_domain;
165 early_setup_arch(&cmdline);
167 /* We initialise the serial devices very early so we can get debugging. */
168 if (running_on_sim) hpsim_serial_init();
169 else {
170 ns16550_init(0, &ns16550_com1);
171 /* Also init com2 for Tiger4. */
172 ns16550_com2.io_base = 0x2f8;
173 ns16550_com2.irq = 3;
174 ns16550_init(1, &ns16550_com2);
175 }
176 serial_init_preirq();
178 init_console();
179 set_printk_prefix("(XEN) ");
181 /* xenheap should be in same TR-covered range with xen image */
182 xenheap_phys_end = xen_pstart + xenheap_size;
183 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
184 xen_pstart, xenheap_phys_end);
186 #ifdef CONFIG_VTI
187 /* If we want to enable vhpt for all regions, related initialization
188 * for HV TLB must be done earlier before first TLB miss
189 */
190 #endif // CONFIG_VTI
191 /* Find next hole */
192 firsthole_start = 0;
193 efi_memmap_walk(xen_find_first_hole, &firsthole_start);
195 initial_images_start = xenheap_phys_end;
196 initial_images_end = initial_images_start + ia64_boot_param->initrd_size;
198 /* Later may find another memory trunk, even away from xen image... */
199 if (initial_images_end > firsthole_start) {
200 printk("Not enough memory to stash the DOM0 kernel image.\n");
201 printk("First hole:0x%lx, relocation end: 0x%lx\n",
202 firsthole_start, initial_images_end);
203 for ( ; ; );
204 }
206 /* This copy is time consuming, but elilo may load Dom0 image
207 * within xenheap range */
208 printk("ready to move Dom0 to 0x%lx...", initial_images_start);
209 memmove(__va(initial_images_start),
210 __va(ia64_boot_param->initrd_start),
211 ia64_boot_param->initrd_size);
212 ia64_boot_param->initrd_start = initial_images_start;
213 printk("Done\n");
215 /* first find highest page frame number */
216 max_page = 0;
217 efi_memmap_walk(find_max_pfn, &max_page);
218 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
220 heap_start = memguard_init(ia64_imva(&_end));
221 printf("Before heap_start: 0x%lx\n", heap_start);
222 heap_start = __va(init_boot_allocator(__pa(heap_start)));
223 printf("After heap_start: 0x%lx\n", heap_start);
225 reserve_memory();
227 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
228 efi_memmap_walk(xen_count_pages, &nr_pages);
230 printk("System RAM: %luMB (%lukB)\n",
231 nr_pages >> (20 - PAGE_SHIFT),
232 nr_pages << (PAGE_SHIFT - 10));
234 init_frametable();
236 ia64_fph_enable();
237 __ia64_init_fpu();
239 alloc_dom0();
240 #ifdef DOMU_BUILD_STAGING
241 alloc_domU_staging();
242 #endif
244 end_boot_allocator();
246 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
247 printk("Xen heap: %luMB (%lukB)\n",
248 (xenheap_phys_end-__pa(heap_start)) >> 20,
249 (xenheap_phys_end-__pa(heap_start)) >> 10);
251 late_setup_arch(&cmdline);
252 setup_per_cpu_areas();
253 mem_init();
255 printk("About to call scheduler_init()\n");
256 scheduler_init();
257 local_irq_disable();
258 printk("About to call xen_time_init()\n");
259 xen_time_init();
260 #ifdef CONFIG_VTI
261 init_xen_time(); /* initialise the time */
262 #endif // CONFIG_VTI
263 printk("About to call ac_timer_init()\n");
264 ac_timer_init();
265 // init_xen_time(); ???
266 schedulers_start();
267 do_initcalls();
268 printk("About to call sort_main_extable()\n");
269 sort_main_extable();
271 /* Create initial domain 0. */
272 printk("About to call do_createdomain()\n");
273 dom0 = do_createdomain(0, 0);
274 init_task.domain = &idle0_domain;
275 init_task.processor = 0;
276 // init_task.mm = &init_mm;
277 init_task.domain->arch.mm = &init_mm;
278 // init_task.thread = INIT_THREAD;
279 //arch_do_createdomain(current);
280 #ifdef CLONE_DOMAIN0
281 {
282 int i;
283 for (i = 0; i < CLONE_DOMAIN0; i++) {
284 clones[i] = do_createdomain(i+1, 0);
285 if ( clones[i] == NULL )
286 panic("Error creating domain0 clone %d\n",i);
287 }
288 }
289 #endif
290 if ( dom0 == NULL )
291 panic("Error creating domain 0\n");
293 set_bit(_DOMF_privileged, &dom0->domain_flags);
295 /*
296 * We're going to setup domain0 using the module(s) that we stashed safely
297 * above our heap. The second module, if present, is an initrd ramdisk.
298 */
299 printk("About to call construct_dom0()\n");
300 dom0_memory_start = __va(ia64_boot_param->initrd_start);
301 dom0_memory_end = ia64_boot_param->initrd_size;
302 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
303 0,
304 0,
305 0) != 0)
306 panic("Could not set up DOM0 guest OS\n");
307 #ifdef CLONE_DOMAIN0
308 {
309 int i;
310 dom0_memory_start = __va(ia64_boot_param->initrd_start);
311 dom0_memory_end = ia64_boot_param->initrd_size;
312 for (i = 0; i < CLONE_DOMAIN0; i++) {
313 printk("CONSTRUCTING DOMAIN0 CLONE #%d\n",i+1);
314 if ( construct_domU(clones[i], dom0_memory_start, dom0_memory_end,
315 0,
316 0,
317 0) != 0)
318 panic("Could not set up DOM0 clone %d\n",i);
319 }
320 }
321 #endif
323 /* The stash space for the initial kernel image can now be freed up. */
324 init_domheap_pages(ia64_boot_param->initrd_start,
325 ia64_boot_param->initrd_start + ia64_boot_param->initrd_size);
326 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
327 scrub_heap_pages();
329 printk("About to call init_trace_bufs()\n");
330 init_trace_bufs();
332 /* Give up the VGA console if DOM0 is configured to grab it. */
333 #ifndef IA64
334 console_endboot(cmdline && strstr(cmdline, "tty0"));
335 #endif
337 #ifdef CLONE_DOMAIN0
338 {
339 int i;
340 for (i = 0; i < CLONE_DOMAIN0; i++)
341 domain_unpause_by_systemcontroller(clones[i]);
342 }
343 #endif
344 domain_unpause_by_systemcontroller(dom0);
345 domain0_ready = 1;
346 local_irq_enable();
347 printk("About to call startup_cpu_idle_loop()\n");
348 startup_cpu_idle_loop();
349 }