ia64/xen-unstable

view tools/libxc/ia64/xc_ia64_hvm_build.c @ 10691:dab0a5650e6d

[IA64] Creates tools/libxc/ia64 directory.

Split and move xc_ia64_stubs.c into ia64/xc_ia64_hvm_build.c and
ia64/xc_ia64_stubs.c
Creates ia64/Makefile.
Clean up (static in const) in xc_ia64_hvm_build.c

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
[whitespace cleanups in new files]
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Jul 11 11:29:25 2006 -0600 (2006-07-11)
parents
children 111936ef4291
line source
1 #include "xg_private.h"
2 #include "xenguest.h"
3 #include "xc_private.h"
4 #include "xc_elf.h"
5 #include <stdlib.h>
6 #include <zlib.h>
7 #include "xen/arch-ia64.h"
8 #include <xen/hvm/ioreq.h>
10 static int
11 xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, void* src_page,
12 unsigned long dst_pfn, int nr_pages)
13 {
14 // N.B. gva should be page aligned
16 xen_pfn_t *page_array = NULL;
17 int i;
19 page_array = malloc(nr_pages * sizeof(xen_pfn_t));
20 if (page_array == NULL) {
21 PERROR("Could not allocate memory");
22 goto error_out;
23 }
24 if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
25 dst_pfn, nr_pages) != nr_pages) {
26 PERROR("Could not get the page frame list");
27 goto error_out;
28 }
30 for (i = 0; i < nr_pages; i++) {
31 if (xc_copy_to_domain_page(xc_handle, domid, page_array[i],
32 src_page + (i << PAGE_SHIFT)))
33 goto error_out;
34 }
35 free(page_array);
36 return 0;
38 error_out:
39 free(page_array);
40 return -1;
41 }
44 #define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64"
45 #define GFW_HOB_START ((4UL<<30)-(14UL<<20)) // 4G - 14M
46 #define GFW_HOB_SIZE (1UL<<20) // 1M
48 typedef struct {
49 unsigned long signature;
50 unsigned int type;
51 unsigned int length;
52 } HOB_GENERIC_HEADER;
54 /*
55 * INFO HOB is the first data data in one HOB list
56 * it contains the control information of the HOB list
57 */
58 typedef struct {
59 HOB_GENERIC_HEADER header;
60 unsigned long length; // current length of hob
61 unsigned long cur_pos; // current poisiton of hob
62 unsigned long buf_size; // size of hob buffer
63 } HOB_INFO;
65 typedef struct{
66 unsigned long start;
67 unsigned long size;
68 } hob_mem_t;
70 typedef enum {
71 HOB_TYPE_INFO=0,
72 HOB_TYPE_TERMINAL,
73 HOB_TYPE_MEM,
74 HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
75 HOB_TYPE_PAL_CACHE_SUMMARY,
76 HOB_TYPE_PAL_MEM_ATTRIB,
77 HOB_TYPE_PAL_CACHE_INFO,
78 HOB_TYPE_PAL_CACHE_PROT_INFO,
79 HOB_TYPE_PAL_DEBUG_INFO,
80 HOB_TYPE_PAL_FIXED_ADDR,
81 HOB_TYPE_PAL_FREQ_BASE,
82 HOB_TYPE_PAL_FREQ_RATIOS,
83 HOB_TYPE_PAL_HALT_INFO,
84 HOB_TYPE_PAL_PERF_MON_INFO,
85 HOB_TYPE_PAL_PROC_GET_FEATURES,
86 HOB_TYPE_PAL_PTCE_INFO,
87 HOB_TYPE_PAL_REGISTER_INFO,
88 HOB_TYPE_PAL_RSE_INFO,
89 HOB_TYPE_PAL_TEST_INFO,
90 HOB_TYPE_PAL_VM_SUMMARY,
91 HOB_TYPE_PAL_VM_INFO,
92 HOB_TYPE_PAL_VM_PAGE_SIZE,
93 HOB_TYPE_NR_VCPU,
94 HOB_TYPE_MAX
95 } hob_type_t;
97 static int hob_init(void *buffer ,unsigned long buf_size);
98 static int add_pal_hob(void* hob_buf);
99 static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size);
100 static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu);
101 static int build_hob(void* hob_buf, unsigned long hob_buf_size,
102 unsigned long dom_mem_size, unsigned long vcpus);
103 static int load_hob(int xc_handle,uint32_t dom, void *hob_buf,
104 unsigned long dom_mem_size);
106 static int
107 xc_ia64_build_hob(int xc_handle, uint32_t dom,
108 unsigned long memsize, unsigned long vcpus)
109 {
110 char *hob_buf;
112 hob_buf = malloc(GFW_HOB_SIZE);
113 if (hob_buf == NULL) {
114 PERROR("Could not allocate hob");
115 return -1;
116 }
118 if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus) < 0) {
119 free(hob_buf);
120 PERROR("Could not build hob");
121 return -1;
122 }
124 if (load_hob(xc_handle, dom, hob_buf, memsize) < 0) {
125 free(hob_buf);
126 PERROR("Could not load hob");
127 return -1;
128 }
129 free(hob_buf);
130 return 0;
132 }
134 static int
135 hob_init(void *buffer, unsigned long buf_size)
136 {
137 HOB_INFO *phit;
138 HOB_GENERIC_HEADER *terminal;
140 if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size) {
141 // buffer too small
142 return -1;
143 }
145 phit = (HOB_INFO*)buffer;
146 phit->header.signature = HOB_SIGNATURE;
147 phit->header.type = HOB_TYPE_INFO;
148 phit->header.length = sizeof(HOB_INFO);
149 phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER);
150 phit->cur_pos = 0;
151 phit->buf_size = buf_size;
153 terminal = (HOB_GENERIC_HEADER*)(buffer + sizeof(HOB_INFO));
154 terminal->signature = HOB_SIGNATURE;
155 terminal->type = HOB_TYPE_TERMINAL;
156 terminal->length = sizeof(HOB_GENERIC_HEADER);
158 return 0;
159 }
161 /*
162 * Add a new HOB to the HOB List.
163 *
164 * hob_start - start address of hob buffer
165 * type - type of the hob to be added
166 * data - data of the hob to be added
167 * data_size - size of the data
168 */
169 static int
170 hob_add(void* hob_start, int type, void* data, int data_size)
171 {
172 HOB_INFO *phit;
173 HOB_GENERIC_HEADER *newhob, *tail;
175 phit = (HOB_INFO*)hob_start;
177 if (phit->length + data_size > phit->buf_size) {
178 // no space for new hob
179 return -1;
180 }
182 //append new HOB
183 newhob = (HOB_GENERIC_HEADER*)(hob_start + phit->length -
184 sizeof(HOB_GENERIC_HEADER));
185 newhob->signature = HOB_SIGNATURE;
186 newhob->type = type;
187 newhob->length = data_size + sizeof(HOB_GENERIC_HEADER);
188 memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size);
190 // append terminal HOB
191 tail = (HOB_GENERIC_HEADER*)(hob_start + phit->length + data_size);
192 tail->signature = HOB_SIGNATURE;
193 tail->type = HOB_TYPE_TERMINAL;
194 tail->length = sizeof(HOB_GENERIC_HEADER);
196 // adjust HOB list length
197 phit->length += sizeof(HOB_GENERIC_HEADER) + data_size;
199 return 0;
200 }
202 static int
203 get_hob_size(void* hob_buf)
204 {
205 HOB_INFO *phit = (HOB_INFO*)hob_buf;
207 if (phit->header.signature != HOB_SIGNATURE) {
208 PERROR("xc_get_hob_size:Incorrect signature");
209 return -1;
210 }
211 return phit->length;
212 }
214 static int
215 build_hob(void* hob_buf, unsigned long hob_buf_size,
216 unsigned long dom_mem_size, unsigned long vcpus)
217 {
218 //Init HOB List
219 if (hob_init(hob_buf, hob_buf_size) < 0) {
220 PERROR("buffer too small");
221 goto err_out;
222 }
224 if (add_mem_hob(hob_buf,dom_mem_size) < 0) {
225 PERROR("Add memory hob failed, buffer too small");
226 goto err_out;
227 }
229 if (add_vcpus_hob(hob_buf, vcpus) < 0) {
230 PERROR("Add NR_VCPU hob failed, buffer too small");
231 goto err_out;
232 }
234 if (add_pal_hob( hob_buf ) < 0) {
235 PERROR("Add PAL hob failed, buffer too small");
236 goto err_out;
237 }
239 return 0;
241 err_out:
242 return -1;
243 }
245 static int
246 load_hob(int xc_handle, uint32_t dom, void *hob_buf,
247 unsigned long dom_mem_size)
248 {
249 // hob_buf should be page aligned
250 int hob_size;
251 int nr_pages;
253 hob_size = get_hob_size(hob_buf);
254 if (hob_size < 0) {
255 PERROR("Invalid hob data");
256 return -1;
257 }
259 if (hob_size > GFW_HOB_SIZE) {
260 PERROR("No enough memory for hob data");
261 return -1;
262 }
264 nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT;
266 return xc_ia64_copy_to_domain_pages(xc_handle, dom, hob_buf,
267 GFW_HOB_START >> PAGE_SHIFT, nr_pages);
268 }
270 #define MIN(x, y) ((x) < (y)) ? (x) : (y)
271 static int
272 add_mem_hob(void* hob_buf, unsigned long dom_mem_size)
273 {
274 hob_mem_t memhob;
276 // less than 3G
277 memhob.start = 0;
278 memhob.size = MIN(dom_mem_size, 0xC0000000);
280 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
281 return -1;
283 if (dom_mem_size > 0xC0000000) {
284 // 4G ~ 4G+remain
285 memhob.start = 0x100000000; //4G
286 memhob.size = dom_mem_size - 0xC0000000;
287 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
288 return -1;
289 }
290 return 0;
291 }
293 static int
294 add_vcpus_hob(void* hob_buf, unsigned long vcpus)
295 {
296 return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus));
297 }
299 static const unsigned char config_pal_bus_get_features_data[24] = {
300 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
302 };
304 static const unsigned char config_pal_cache_summary[16] = {
305 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
306 };
308 static const unsigned char config_pal_mem_attrib[8] = {
309 241, 0, 0, 0, 0, 0, 0, 0
310 };
312 static const unsigned char config_pal_cache_info[152] = {
313 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
315 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
316 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
318 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
319 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
320 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
321 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
323 };
325 static const unsigned char config_pal_cache_prot_info[200] = {
326 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
327 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
331 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
333 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
335 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
337 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0
339 };
341 static const unsigned char config_pal_debug_info[16] = {
342 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
343 };
345 static const unsigned char config_pal_fixed_addr[8] = {
346 0, 0, 0, 0, 0, 0, 0, 0
347 };
349 static const unsigned char config_pal_freq_base[8] = {
350 109, 219, 182, 13, 0, 0, 0, 0
351 };
353 static const unsigned char config_pal_freq_ratios[24] = {
354 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
355 0, 0, 0, 7, 0, 0, 0
356 };
358 static const unsigned char config_pal_halt_info[64] = {
359 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
362 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
363 };
365 static const unsigned char config_pal_perf_mon_info[136] = {
366 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
368 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
369 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
370 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
371 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
372 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
373 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
374 0, 0, 0, 0, 0, 0, 0, 0
375 };
377 static const unsigned char config_pal_proc_get_features[104] = {
378 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
381 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
382 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
383 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
384 0, 0, 0, 0, 0, 0, 0, 0
385 };
387 static const unsigned char config_pal_ptce_info[24] = {
388 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0
390 };
392 static const unsigned char config_pal_register_info[64] = {
393 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
394 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
395 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
396 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
397 };
399 static const unsigned char config_pal_rse_info[16] = {
400 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
401 };
403 static const unsigned char config_pal_test_info[48] = {
404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
407 };
409 static const unsigned char config_pal_vm_summary[16] = {
410 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
411 };
413 static const unsigned char config_pal_vm_info[104] = {
414 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
415 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
417 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
418 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
419 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
420 };
422 static const unsigned char config_pal_vm_page_size[16] = {
423 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
424 };
426 typedef struct{
427 hob_type_t type;
428 void* data;
429 unsigned long size;
430 } hob_batch_t;
432 static const hob_batch_t hob_batch[]={
433 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
434 &config_pal_bus_get_features_data,
435 sizeof(config_pal_bus_get_features_data)
436 },
437 { HOB_TYPE_PAL_CACHE_SUMMARY,
438 &config_pal_cache_summary,
439 sizeof(config_pal_cache_summary)
440 },
441 { HOB_TYPE_PAL_MEM_ATTRIB,
442 &config_pal_mem_attrib,
443 sizeof(config_pal_mem_attrib)
444 },
445 { HOB_TYPE_PAL_CACHE_INFO,
446 &config_pal_cache_info,
447 sizeof(config_pal_cache_info)
448 },
449 { HOB_TYPE_PAL_CACHE_PROT_INFO,
450 &config_pal_cache_prot_info,
451 sizeof(config_pal_cache_prot_info)
452 },
453 { HOB_TYPE_PAL_DEBUG_INFO,
454 &config_pal_debug_info,
455 sizeof(config_pal_debug_info)
456 },
457 { HOB_TYPE_PAL_FIXED_ADDR,
458 &config_pal_fixed_addr,
459 sizeof(config_pal_fixed_addr)
460 },
461 { HOB_TYPE_PAL_FREQ_BASE,
462 &config_pal_freq_base,
463 sizeof(config_pal_freq_base)
464 },
465 { HOB_TYPE_PAL_FREQ_RATIOS,
466 &config_pal_freq_ratios,
467 sizeof(config_pal_freq_ratios)
468 },
469 { HOB_TYPE_PAL_HALT_INFO,
470 &config_pal_halt_info,
471 sizeof(config_pal_halt_info)
472 },
473 { HOB_TYPE_PAL_PERF_MON_INFO,
474 &config_pal_perf_mon_info,
475 sizeof(config_pal_perf_mon_info)
476 },
477 { HOB_TYPE_PAL_PROC_GET_FEATURES,
478 &config_pal_proc_get_features,
479 sizeof(config_pal_proc_get_features)
480 },
481 { HOB_TYPE_PAL_PTCE_INFO,
482 &config_pal_ptce_info,
483 sizeof(config_pal_ptce_info)
484 },
485 { HOB_TYPE_PAL_REGISTER_INFO,
486 &config_pal_register_info,
487 sizeof(config_pal_register_info)
488 },
489 { HOB_TYPE_PAL_RSE_INFO,
490 &config_pal_rse_info,
491 sizeof(config_pal_rse_info)
492 },
493 { HOB_TYPE_PAL_TEST_INFO,
494 &config_pal_test_info,
495 sizeof(config_pal_test_info)
496 },
497 { HOB_TYPE_PAL_VM_SUMMARY,
498 &config_pal_vm_summary,
499 sizeof(config_pal_vm_summary)
500 },
501 { HOB_TYPE_PAL_VM_INFO,
502 &config_pal_vm_info,
503 sizeof(config_pal_vm_info)
504 },
505 { HOB_TYPE_PAL_VM_PAGE_SIZE,
506 &config_pal_vm_page_size,
507 sizeof(config_pal_vm_page_size)
508 },
509 };
511 static int
512 add_pal_hob(void* hob_buf)
513 {
514 int i;
515 for (i = 0; i < sizeof(hob_batch)/sizeof(hob_batch_t); i++) {
516 if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data,
517 hob_batch[i].size) < 0)
518 return -1;
519 }
520 return 0;
521 }
523 static int
524 setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
525 char *image, unsigned long image_size, uint32_t vcpus,
526 unsigned int store_evtchn, unsigned long *store_mfn)
527 {
528 unsigned long page_array[2];
529 shared_iopage_t *sp;
530 int i;
531 unsigned long dom_memsize = (memsize << 20);
532 DECLARE_DOM0_OP;
534 if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {
535 PERROR("Guest firmware size is incorrect [%ld]?", image_size);
536 return -1;
537 }
539 /* This will creates the physmap. */
540 op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest;
541 op.u.domain_setup.domain = (domid_t)dom;
542 op.u.domain_setup.bp = 0;
543 op.u.domain_setup.maxmem = 0;
545 op.cmd = DOM0_DOMAIN_SETUP;
546 if (xc_dom0_op(xc_handle, &op))
547 goto error_out;
549 /* Load guest firmware */
550 if (xc_ia64_copy_to_domain_pages(xc_handle, dom, image,
551 (GFW_START + GFW_SIZE - image_size) >> PAGE_SHIFT,
552 image_size >> PAGE_SHIFT)) {
553 PERROR("Could not load guest firmware into domain");
554 goto error_out;
555 }
557 /* Hand-off state passed to guest firmware */
558 if (xc_ia64_build_hob(xc_handle, dom, dom_memsize,
559 (unsigned long)vcpus) < 0) {
560 PERROR("Could not build hob\n");
561 goto error_out;
562 }
564 /* Retrieve special pages like io, xenstore, etc. */
565 if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
566 IO_PAGE_START>>PAGE_SHIFT, 2) != 2) {
567 PERROR("Could not get the page frame list");
568 goto error_out;
569 }
571 *store_mfn = page_array[1];
572 sp = (shared_iopage_t *)xc_map_foreign_range(xc_handle, dom,
573 PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
574 if (sp == 0)
575 goto error_out;
577 memset(sp, 0, PAGE_SIZE);
579 for (i = 0; i < vcpus; i++) {
580 uint32_t vp_eport;
582 vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
583 if (vp_eport < 0) {
584 DPRINTF("Couldn't get unbound port from VMX guest.\n");
585 goto error_out;
586 }
587 sp->vcpu_iodata[i].vp_eport = vp_eport;
588 }
590 munmap(sp, PAGE_SIZE);
592 return 0;
594 error_out:
595 return -1;
596 }
598 int
599 xc_hvm_build(int xc_handle, uint32_t domid, int memsize,
600 const char *image_name, unsigned int vcpus, unsigned int pae,
601 unsigned int acpi, unsigned int apic, unsigned int store_evtchn,
602 unsigned long *store_mfn)
603 {
604 dom0_op_t launch_op, op;
605 int rc;
606 vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
607 char *image = NULL;
608 unsigned long image_size;
609 unsigned long nr_pages;
611 nr_pages = xc_get_max_pages(xc_handle, domid);
612 if (nr_pages < 0) {
613 PERROR("Could not find total pages for domain");
614 goto error_out;
615 }
617 image = xc_read_image(image_name, &image_size);
618 if (image == NULL) {
619 PERROR("Could not read guest firmware image %s", image_name);
620 goto error_out;
621 }
623 image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;
625 if (mlock(&st_ctxt, sizeof(st_ctxt))) {
626 PERROR("Unable to mlock ctxt");
627 return 1;
628 }
630 op.cmd = DOM0_GETDOMAININFO;
631 op.u.getdomaininfo.domain = (domid_t)domid;
632 if (do_dom0_op(xc_handle, &op) < 0 ||
633 (uint16_t)op.u.getdomaininfo.domain != domid) {
634 PERROR("Could not get info on domain");
635 goto error_out;
636 }
638 memset(ctxt, 0, sizeof(*ctxt));
640 if (setup_guest(xc_handle, domid, (unsigned long)memsize, image,
641 image_size, vcpus, store_evtchn, store_mfn) < 0) {
642 ERROR("Error constructing guest OS");
643 goto error_out;
644 }
646 free(image);
648 ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL;
650 memset(&launch_op, 0, sizeof(launch_op));
652 launch_op.u.setvcpucontext.domain = (domid_t)domid;
653 launch_op.u.setvcpucontext.vcpu = 0;
654 set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt);
656 launch_op.cmd = DOM0_SETVCPUCONTEXT;
657 rc = do_dom0_op(xc_handle, &launch_op);
658 return rc;
660 error_out:
661 free(image);
662 return -1;
663 }
665 /*
666 * Local variables:
667 * mode: C
668 * c-set-style: "BSD"
669 * c-basic-offset: 4
670 * tab-width: 4
671 * indent-tabs-mode: nil
672 * End:
673 */