ia64/xen-unstable

view xen/arch/ia64/xensetup.c @ 5797:ca44d2dbb273

Intel's pre-bk->hg transition patches
Signed-off-by Eddie Dong <Eddie.dong@intel.com>
Signed-off-by Anthony Xu <Anthony.xu@intel.com>
Signed-off-by Kevin Tian <Kevin.tian@intel.com>
author djm@kirby.fc.hp.com
date Sat Jul 09 07:58:56 2005 -0700 (2005-07-09)
parents ca1fb1af953d
children 8328317e60ab
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 void start_kernel(void)
134 {
135 unsigned char *cmdline;
136 void *heap_start;
137 int i;
138 unsigned long max_mem, nr_pages, firsthole_start;
139 unsigned long dom0_memory_start, dom0_memory_end;
140 unsigned long initial_images_start, initial_images_end;
142 running_on_sim = is_platform_hp_ski();
143 /* Kernel may be relocated by EFI loader */
144 xen_pstart = ia64_tpa(KERNEL_START);
146 /* Must do this early -- e.g., spinlocks rely on get_current(). */
147 //set_current(&idle0_vcpu);
148 ia64_r13 = (void *)&idle0_vcpu;
149 idle0_vcpu.domain = &idle0_domain;
151 early_setup_arch(&cmdline);
153 /* We initialise the serial devices very early so we can get debugging. */
154 if (running_on_sim) hpsim_serial_init();
155 else ns16550_init();
156 serial_init_preirq();
158 init_console();
159 set_printk_prefix("(XEN) ");
161 /* xenheap should be in same TR-covered range with xen image */
162 xenheap_phys_end = xen_pstart + xenheap_size;
163 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
164 xen_pstart, xenheap_phys_end);
166 #ifdef CONFIG_VTI
167 /* If we want to enable vhpt for all regions, related initialization
168 * for HV TLB must be done earlier before first TLB miss
169 */
170 #endif // CONFIG_VTI
171 /* Find next hole */
172 firsthole_start = 0;
173 efi_memmap_walk(xen_find_first_hole, &firsthole_start);
175 initial_images_start = xenheap_phys_end;
176 initial_images_end = initial_images_start + ia64_boot_param->initrd_size;
178 /* Later may find another memory trunk, even away from xen image... */
179 if (initial_images_end > firsthole_start) {
180 printk("Not enough memory to stash the DOM0 kernel image.\n");
181 printk("First hole:0x%lx, relocation end: 0x%lx\n",
182 firsthole_start, initial_images_end);
183 for ( ; ; );
184 }
186 /* This copy is time consuming, but elilo may load Dom0 image
187 * within xenheap range */
188 printk("ready to move Dom0 to 0x%lx...", initial_images_start);
189 memmove(__va(initial_images_start),
190 __va(ia64_boot_param->initrd_start),
191 ia64_boot_param->initrd_size);
192 ia64_boot_param->initrd_start = initial_images_start;
193 printk("Done\n");
195 /* first find highest page frame number */
196 max_page = 0;
197 efi_memmap_walk(find_max_pfn, &max_page);
198 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
200 heap_start = memguard_init(ia64_imva(&_end));
201 printf("Before heap_start: 0x%lx\n", heap_start);
202 heap_start = __va(init_boot_allocator(__pa(heap_start)));
203 printf("After heap_start: 0x%lx\n", heap_start);
205 reserve_memory();
207 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
208 efi_memmap_walk(xen_count_pages, &nr_pages);
210 printk("System RAM: %luMB (%lukB)\n",
211 nr_pages >> (20 - PAGE_SHIFT),
212 nr_pages << (PAGE_SHIFT - 10));
214 init_frametable();
216 ia64_fph_enable();
217 __ia64_init_fpu();
219 alloc_dom0();
220 #ifdef DOMU_BUILD_STAGING
221 alloc_domU_staging();
222 #endif
224 end_boot_allocator();
226 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
227 printk("Xen heap: %luMB (%lukB)\n",
228 (xenheap_phys_end-__pa(heap_start)) >> 20,
229 (xenheap_phys_end-__pa(heap_start)) >> 10);
231 late_setup_arch(&cmdline);
232 setup_per_cpu_areas();
233 mem_init();
235 printk("About to call scheduler_init()\n");
236 scheduler_init();
237 local_irq_disable();
238 printk("About to call xen_time_init()\n");
239 xen_time_init();
240 #ifdef CONFIG_VTI
241 init_xen_time(); /* initialise the time */
242 #endif // CONFIG_VTI
243 printk("About to call ac_timer_init()\n");
244 ac_timer_init();
245 // init_xen_time(); ???
246 schedulers_start();
247 do_initcalls();
248 printk("About to call sort_main_extable()\n");
249 sort_main_extable();
251 /* Create initial domain 0. */
252 printk("About to call do_createdomain()\n");
253 dom0 = do_createdomain(0, 0);
254 init_task.domain = &idle0_domain;
255 init_task.processor = 0;
256 // init_task.mm = &init_mm;
257 init_task.domain->arch.mm = &init_mm;
258 // init_task.thread = INIT_THREAD;
259 //arch_do_createdomain(current);
260 #ifdef CLONE_DOMAIN0
261 {
262 int i;
263 for (i = 0; i < CLONE_DOMAIN0; i++) {
264 clones[i] = do_createdomain(i+1, 0);
265 if ( clones[i] == NULL )
266 panic("Error creating domain0 clone %d\n",i);
267 }
268 }
269 #endif
270 if ( dom0 == NULL )
271 panic("Error creating domain 0\n");
273 set_bit(_DOMF_privileged, &dom0->domain_flags);
275 /*
276 * We're going to setup domain0 using the module(s) that we stashed safely
277 * above our heap. The second module, if present, is an initrd ramdisk.
278 */
279 printk("About to call construct_dom0()\n");
280 dom0_memory_start = __va(ia64_boot_param->initrd_start);
281 dom0_memory_end = ia64_boot_param->initrd_size;
282 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
283 0,
284 0,
285 0) != 0)
286 panic("Could not set up DOM0 guest OS\n");
287 #ifdef CLONE_DOMAIN0
288 {
289 int i;
290 dom0_memory_start = __va(ia64_boot_param->initrd_start);
291 dom0_memory_end = ia64_boot_param->initrd_size;
292 for (i = 0; i < CLONE_DOMAIN0; i++) {
293 printk("CONSTRUCTING DOMAIN0 CLONE #%d\n",i+1);
294 if ( construct_domU(clones[i], dom0_memory_start, dom0_memory_end,
295 0,
296 0,
297 0) != 0)
298 panic("Could not set up DOM0 clone %d\n",i);
299 }
300 }
301 #endif
303 /* The stash space for the initial kernel image can now be freed up. */
304 init_domheap_pages(ia64_boot_param->initrd_start,
305 ia64_boot_param->initrd_start + ia64_boot_param->initrd_size);
306 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
307 scrub_heap_pages();
309 printk("About to call init_trace_bufs()\n");
310 init_trace_bufs();
312 /* Give up the VGA console if DOM0 is configured to grab it. */
313 #ifndef IA64
314 console_endboot(cmdline && strstr(cmdline, "tty0"));
315 #endif
317 #ifdef CLONE_DOMAIN0
318 {
319 int i;
320 for (i = 0; i < CLONE_DOMAIN0; i++)
321 domain_unpause_by_systemcontroller(clones[i]);
322 }
323 #endif
324 domain_unpause_by_systemcontroller(dom0);
325 domain0_ready = 1;
326 local_irq_enable();
327 printk("About to call startup_cpu_idle_loop()\n");
328 startup_cpu_idle_loop();
329 }