direct-io.hg

view tools/libxc/ia64/xc_ia64_hvm_build.c @ 11329:3fdc31e91384

[IA64] Modify xc_ia64_hvm_build for using the new Xen event channels

Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Wed Aug 23 13:21:02 2006 -0600 (2006-08-23)
parents 111936ef4291
children c4ea8d4d2ae1
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>
9 #include <xen/hvm/params.h>
11 static int
12 xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, void* src_page,
13 unsigned long dst_pfn, int nr_pages)
14 {
15 // N.B. gva should be page aligned
17 xen_pfn_t *page_array = NULL;
18 int i;
20 page_array = malloc(nr_pages * sizeof(xen_pfn_t));
21 if (page_array == NULL) {
22 PERROR("Could not allocate memory");
23 goto error_out;
24 }
25 if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
26 dst_pfn, nr_pages) != nr_pages) {
27 PERROR("Could not get the page frame list");
28 goto error_out;
29 }
31 for (i = 0; i < nr_pages; i++) {
32 if (xc_copy_to_domain_page(xc_handle, domid, page_array[i],
33 src_page + (i << PAGE_SHIFT)))
34 goto error_out;
35 }
36 free(page_array);
37 return 0;
39 error_out:
40 free(page_array);
41 return -1;
42 }
44 static void
45 xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
46 {
47 DECLARE_HYPERCALL;
48 xen_hvm_param_t arg;
49 int rc;
51 hypercall.op = __HYPERVISOR_hvm_op;
52 hypercall.arg[0] = HVMOP_set_param;
53 hypercall.arg[1] = (unsigned long)&arg;
55 arg.domid = dom;
56 arg.index = param;
57 arg.value = value;
59 if (mlock(&arg, sizeof(arg)) != 0) {
60 PERROR("Could not lock memory for set parameter");
61 return;
62 }
64 rc = do_xen_hypercall(handle, &hypercall);
65 safe_munlock(&arg, sizeof(arg));
66 if (rc < 0)
67 PERROR("set HVM parameter failed (%d)", rc);
68 }
70 #define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64"
71 #define GFW_HOB_START ((4UL<<30)-(14UL<<20)) // 4G - 14M
72 #define GFW_HOB_SIZE (1UL<<20) // 1M
74 typedef struct {
75 unsigned long signature;
76 unsigned int type;
77 unsigned int length;
78 } HOB_GENERIC_HEADER;
80 /*
81 * INFO HOB is the first data data in one HOB list
82 * it contains the control information of the HOB list
83 */
84 typedef struct {
85 HOB_GENERIC_HEADER header;
86 unsigned long length; // current length of hob
87 unsigned long cur_pos; // current poisiton of hob
88 unsigned long buf_size; // size of hob buffer
89 } HOB_INFO;
91 typedef struct{
92 unsigned long start;
93 unsigned long size;
94 } hob_mem_t;
96 typedef enum {
97 HOB_TYPE_INFO=0,
98 HOB_TYPE_TERMINAL,
99 HOB_TYPE_MEM,
100 HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
101 HOB_TYPE_PAL_CACHE_SUMMARY,
102 HOB_TYPE_PAL_MEM_ATTRIB,
103 HOB_TYPE_PAL_CACHE_INFO,
104 HOB_TYPE_PAL_CACHE_PROT_INFO,
105 HOB_TYPE_PAL_DEBUG_INFO,
106 HOB_TYPE_PAL_FIXED_ADDR,
107 HOB_TYPE_PAL_FREQ_BASE,
108 HOB_TYPE_PAL_FREQ_RATIOS,
109 HOB_TYPE_PAL_HALT_INFO,
110 HOB_TYPE_PAL_PERF_MON_INFO,
111 HOB_TYPE_PAL_PROC_GET_FEATURES,
112 HOB_TYPE_PAL_PTCE_INFO,
113 HOB_TYPE_PAL_REGISTER_INFO,
114 HOB_TYPE_PAL_RSE_INFO,
115 HOB_TYPE_PAL_TEST_INFO,
116 HOB_TYPE_PAL_VM_SUMMARY,
117 HOB_TYPE_PAL_VM_INFO,
118 HOB_TYPE_PAL_VM_PAGE_SIZE,
119 HOB_TYPE_NR_VCPU,
120 HOB_TYPE_MAX
121 } hob_type_t;
123 static int hob_init(void *buffer ,unsigned long buf_size);
124 static int add_pal_hob(void* hob_buf);
125 static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size);
126 static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu);
127 static int build_hob(void* hob_buf, unsigned long hob_buf_size,
128 unsigned long dom_mem_size, unsigned long vcpus);
129 static int load_hob(int xc_handle,uint32_t dom, void *hob_buf,
130 unsigned long dom_mem_size);
132 static int
133 xc_ia64_build_hob(int xc_handle, uint32_t dom,
134 unsigned long memsize, unsigned long vcpus)
135 {
136 char *hob_buf;
138 hob_buf = malloc(GFW_HOB_SIZE);
139 if (hob_buf == NULL) {
140 PERROR("Could not allocate hob");
141 return -1;
142 }
144 if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus) < 0) {
145 free(hob_buf);
146 PERROR("Could not build hob");
147 return -1;
148 }
150 if (load_hob(xc_handle, dom, hob_buf, memsize) < 0) {
151 free(hob_buf);
152 PERROR("Could not load hob");
153 return -1;
154 }
155 free(hob_buf);
156 return 0;
158 }
160 static int
161 hob_init(void *buffer, unsigned long buf_size)
162 {
163 HOB_INFO *phit;
164 HOB_GENERIC_HEADER *terminal;
166 if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size) {
167 // buffer too small
168 return -1;
169 }
171 phit = (HOB_INFO*)buffer;
172 phit->header.signature = HOB_SIGNATURE;
173 phit->header.type = HOB_TYPE_INFO;
174 phit->header.length = sizeof(HOB_INFO);
175 phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER);
176 phit->cur_pos = 0;
177 phit->buf_size = buf_size;
179 terminal = (HOB_GENERIC_HEADER*)(buffer + sizeof(HOB_INFO));
180 terminal->signature = HOB_SIGNATURE;
181 terminal->type = HOB_TYPE_TERMINAL;
182 terminal->length = sizeof(HOB_GENERIC_HEADER);
184 return 0;
185 }
187 /*
188 * Add a new HOB to the HOB List.
189 *
190 * hob_start - start address of hob buffer
191 * type - type of the hob to be added
192 * data - data of the hob to be added
193 * data_size - size of the data
194 */
195 static int
196 hob_add(void* hob_start, int type, void* data, int data_size)
197 {
198 HOB_INFO *phit;
199 HOB_GENERIC_HEADER *newhob, *tail;
201 phit = (HOB_INFO*)hob_start;
203 if (phit->length + data_size > phit->buf_size) {
204 // no space for new hob
205 return -1;
206 }
208 //append new HOB
209 newhob = (HOB_GENERIC_HEADER*)(hob_start + phit->length -
210 sizeof(HOB_GENERIC_HEADER));
211 newhob->signature = HOB_SIGNATURE;
212 newhob->type = type;
213 newhob->length = data_size + sizeof(HOB_GENERIC_HEADER);
214 memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size);
216 // append terminal HOB
217 tail = (HOB_GENERIC_HEADER*)(hob_start + phit->length + data_size);
218 tail->signature = HOB_SIGNATURE;
219 tail->type = HOB_TYPE_TERMINAL;
220 tail->length = sizeof(HOB_GENERIC_HEADER);
222 // adjust HOB list length
223 phit->length += sizeof(HOB_GENERIC_HEADER) + data_size;
225 return 0;
226 }
228 static int
229 get_hob_size(void* hob_buf)
230 {
231 HOB_INFO *phit = (HOB_INFO*)hob_buf;
233 if (phit->header.signature != HOB_SIGNATURE) {
234 PERROR("xc_get_hob_size:Incorrect signature");
235 return -1;
236 }
237 return phit->length;
238 }
240 static int
241 build_hob(void* hob_buf, unsigned long hob_buf_size,
242 unsigned long dom_mem_size, unsigned long vcpus)
243 {
244 //Init HOB List
245 if (hob_init(hob_buf, hob_buf_size) < 0) {
246 PERROR("buffer too small");
247 goto err_out;
248 }
250 if (add_mem_hob(hob_buf,dom_mem_size) < 0) {
251 PERROR("Add memory hob failed, buffer too small");
252 goto err_out;
253 }
255 if (add_vcpus_hob(hob_buf, vcpus) < 0) {
256 PERROR("Add NR_VCPU hob failed, buffer too small");
257 goto err_out;
258 }
260 if (add_pal_hob( hob_buf ) < 0) {
261 PERROR("Add PAL hob failed, buffer too small");
262 goto err_out;
263 }
265 return 0;
267 err_out:
268 return -1;
269 }
271 static int
272 load_hob(int xc_handle, uint32_t dom, void *hob_buf,
273 unsigned long dom_mem_size)
274 {
275 // hob_buf should be page aligned
276 int hob_size;
277 int nr_pages;
279 hob_size = get_hob_size(hob_buf);
280 if (hob_size < 0) {
281 PERROR("Invalid hob data");
282 return -1;
283 }
285 if (hob_size > GFW_HOB_SIZE) {
286 PERROR("No enough memory for hob data");
287 return -1;
288 }
290 nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT;
292 return xc_ia64_copy_to_domain_pages(xc_handle, dom, hob_buf,
293 GFW_HOB_START >> PAGE_SHIFT, nr_pages);
294 }
296 #define MIN(x, y) ((x) < (y)) ? (x) : (y)
297 static int
298 add_mem_hob(void* hob_buf, unsigned long dom_mem_size)
299 {
300 hob_mem_t memhob;
302 // less than 3G
303 memhob.start = 0;
304 memhob.size = MIN(dom_mem_size, 0xC0000000);
306 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
307 return -1;
309 if (dom_mem_size > 0xC0000000) {
310 // 4G ~ 4G+remain
311 memhob.start = 0x100000000; //4G
312 memhob.size = dom_mem_size - 0xC0000000;
313 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
314 return -1;
315 }
316 return 0;
317 }
319 static int
320 add_vcpus_hob(void* hob_buf, unsigned long vcpus)
321 {
322 return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus));
323 }
325 static const unsigned char config_pal_bus_get_features_data[24] = {
326 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
328 };
330 static const unsigned char config_pal_cache_summary[16] = {
331 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
332 };
334 static const unsigned char config_pal_mem_attrib[8] = {
335 241, 0, 0, 0, 0, 0, 0, 0
336 };
338 static const unsigned char config_pal_cache_info[152] = {
339 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
341 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
342 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
344 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
345 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
346 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
347 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
349 };
351 static const unsigned char config_pal_cache_prot_info[200] = {
352 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
357 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
359 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
361 32, 0, 112, 12, 0, 79, 124, 76, 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, 255, 0, 160,
363 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
364 0, 0, 0
365 };
367 static const unsigned char config_pal_debug_info[16] = {
368 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
369 };
371 static const unsigned char config_pal_fixed_addr[8] = {
372 0, 0, 0, 0, 0, 0, 0, 0
373 };
375 static const unsigned char config_pal_freq_base[8] = {
376 109, 219, 182, 13, 0, 0, 0, 0
377 };
379 static const unsigned char config_pal_freq_ratios[24] = {
380 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
381 0, 0, 0, 7, 0, 0, 0
382 };
384 static const unsigned char config_pal_halt_info[64] = {
385 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
389 };
391 static const unsigned char config_pal_perf_mon_info[136] = {
392 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
400 0, 0, 0, 0, 0, 0, 0, 0
401 };
403 static const unsigned char config_pal_proc_get_features[104] = {
404 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
407 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
408 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
409 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
410 0, 0, 0, 0, 0, 0, 0, 0
411 };
413 static const unsigned char config_pal_ptce_info[24] = {
414 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
415 0, 0, 0, 0, 0, 0, 0, 0
416 };
418 static const unsigned char config_pal_register_info[64] = {
419 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
420 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
421 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
422 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
423 };
425 static const unsigned char config_pal_rse_info[16] = {
426 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
427 };
429 static const unsigned char config_pal_test_info[48] = {
430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
433 };
435 static const unsigned char config_pal_vm_summary[16] = {
436 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
437 };
439 static const unsigned char config_pal_vm_info[104] = {
440 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
441 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
442 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
443 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
444 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
445 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
446 };
448 static const unsigned char config_pal_vm_page_size[16] = {
449 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
450 };
452 typedef struct{
453 hob_type_t type;
454 void* data;
455 unsigned long size;
456 } hob_batch_t;
458 static const hob_batch_t hob_batch[]={
459 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
460 &config_pal_bus_get_features_data,
461 sizeof(config_pal_bus_get_features_data)
462 },
463 { HOB_TYPE_PAL_CACHE_SUMMARY,
464 &config_pal_cache_summary,
465 sizeof(config_pal_cache_summary)
466 },
467 { HOB_TYPE_PAL_MEM_ATTRIB,
468 &config_pal_mem_attrib,
469 sizeof(config_pal_mem_attrib)
470 },
471 { HOB_TYPE_PAL_CACHE_INFO,
472 &config_pal_cache_info,
473 sizeof(config_pal_cache_info)
474 },
475 { HOB_TYPE_PAL_CACHE_PROT_INFO,
476 &config_pal_cache_prot_info,
477 sizeof(config_pal_cache_prot_info)
478 },
479 { HOB_TYPE_PAL_DEBUG_INFO,
480 &config_pal_debug_info,
481 sizeof(config_pal_debug_info)
482 },
483 { HOB_TYPE_PAL_FIXED_ADDR,
484 &config_pal_fixed_addr,
485 sizeof(config_pal_fixed_addr)
486 },
487 { HOB_TYPE_PAL_FREQ_BASE,
488 &config_pal_freq_base,
489 sizeof(config_pal_freq_base)
490 },
491 { HOB_TYPE_PAL_FREQ_RATIOS,
492 &config_pal_freq_ratios,
493 sizeof(config_pal_freq_ratios)
494 },
495 { HOB_TYPE_PAL_HALT_INFO,
496 &config_pal_halt_info,
497 sizeof(config_pal_halt_info)
498 },
499 { HOB_TYPE_PAL_PERF_MON_INFO,
500 &config_pal_perf_mon_info,
501 sizeof(config_pal_perf_mon_info)
502 },
503 { HOB_TYPE_PAL_PROC_GET_FEATURES,
504 &config_pal_proc_get_features,
505 sizeof(config_pal_proc_get_features)
506 },
507 { HOB_TYPE_PAL_PTCE_INFO,
508 &config_pal_ptce_info,
509 sizeof(config_pal_ptce_info)
510 },
511 { HOB_TYPE_PAL_REGISTER_INFO,
512 &config_pal_register_info,
513 sizeof(config_pal_register_info)
514 },
515 { HOB_TYPE_PAL_RSE_INFO,
516 &config_pal_rse_info,
517 sizeof(config_pal_rse_info)
518 },
519 { HOB_TYPE_PAL_TEST_INFO,
520 &config_pal_test_info,
521 sizeof(config_pal_test_info)
522 },
523 { HOB_TYPE_PAL_VM_SUMMARY,
524 &config_pal_vm_summary,
525 sizeof(config_pal_vm_summary)
526 },
527 { HOB_TYPE_PAL_VM_INFO,
528 &config_pal_vm_info,
529 sizeof(config_pal_vm_info)
530 },
531 { HOB_TYPE_PAL_VM_PAGE_SIZE,
532 &config_pal_vm_page_size,
533 sizeof(config_pal_vm_page_size)
534 },
535 };
537 static int
538 add_pal_hob(void* hob_buf)
539 {
540 int i;
541 for (i = 0; i < sizeof(hob_batch)/sizeof(hob_batch_t); i++) {
542 if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data,
543 hob_batch[i].size) < 0)
544 return -1;
545 }
546 return 0;
547 }
549 static int
550 setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
551 char *image, unsigned long image_size, uint32_t vcpus,
552 unsigned int store_evtchn, unsigned long *store_mfn)
553 {
554 unsigned long page_array[2];
555 shared_iopage_t *sp;
556 unsigned long dom_memsize = (memsize << 20);
557 DECLARE_DOM0_OP;
559 if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {
560 PERROR("Guest firmware size is incorrect [%ld]?", image_size);
561 return -1;
562 }
564 /* This will creates the physmap. */
565 op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest;
566 op.u.domain_setup.domain = (domid_t)dom;
567 op.u.domain_setup.bp = 0;
568 op.u.domain_setup.maxmem = 0;
570 op.cmd = DOM0_DOMAIN_SETUP;
571 if (xc_dom0_op(xc_handle, &op))
572 goto error_out;
574 /* Load guest firmware */
575 if (xc_ia64_copy_to_domain_pages(xc_handle, dom, image,
576 (GFW_START + GFW_SIZE - image_size) >> PAGE_SHIFT,
577 image_size >> PAGE_SHIFT)) {
578 PERROR("Could not load guest firmware into domain");
579 goto error_out;
580 }
582 /* Hand-off state passed to guest firmware */
583 if (xc_ia64_build_hob(xc_handle, dom, dom_memsize,
584 (unsigned long)vcpus) < 0) {
585 PERROR("Could not build hob\n");
586 goto error_out;
587 }
589 /* Retrieve special pages like io, xenstore, etc. */
590 if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
591 IO_PAGE_START>>PAGE_SHIFT, 2) != 2) {
592 PERROR("Could not get the page frame list");
593 goto error_out;
594 }
596 xc_set_hvm_param(xc_handle, dom,
597 HVM_PARAM_STORE_PFN, STORE_PAGE_START>>PAGE_SHIFT);
598 xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
600 *store_mfn = page_array[1];
601 sp = (shared_iopage_t *)xc_map_foreign_range(xc_handle, dom,
602 PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
603 if (sp == 0)
604 goto error_out;
606 memset(sp, 0, PAGE_SIZE);
607 munmap(sp, PAGE_SIZE);
609 return 0;
611 error_out:
612 return -1;
613 }
615 int
616 xc_hvm_build(int xc_handle, uint32_t domid, int memsize,
617 const char *image_name, unsigned int vcpus, unsigned int pae,
618 unsigned int acpi, unsigned int apic, unsigned int store_evtchn,
619 unsigned long *store_mfn)
620 {
621 dom0_op_t launch_op, op;
622 int rc;
623 vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
624 char *image = NULL;
625 unsigned long image_size;
626 unsigned long nr_pages;
628 nr_pages = xc_get_max_pages(xc_handle, domid);
629 if (nr_pages < 0) {
630 PERROR("Could not find total pages for domain");
631 goto error_out;
632 }
634 image = xc_read_image(image_name, &image_size);
635 if (image == NULL) {
636 PERROR("Could not read guest firmware image %s", image_name);
637 goto error_out;
638 }
640 image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;
642 if (mlock(&st_ctxt, sizeof(st_ctxt))) {
643 PERROR("Unable to mlock ctxt");
644 return 1;
645 }
647 op.cmd = DOM0_GETDOMAININFO;
648 op.u.getdomaininfo.domain = (domid_t)domid;
649 if (do_dom0_op(xc_handle, &op) < 0 ||
650 (uint16_t)op.u.getdomaininfo.domain != domid) {
651 PERROR("Could not get info on domain");
652 goto error_out;
653 }
655 memset(ctxt, 0, sizeof(*ctxt));
657 if (setup_guest(xc_handle, domid, (unsigned long)memsize, image,
658 image_size, vcpus, store_evtchn, store_mfn) < 0) {
659 ERROR("Error constructing guest OS");
660 goto error_out;
661 }
663 free(image);
665 ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL;
667 memset(&launch_op, 0, sizeof(launch_op));
669 launch_op.u.setvcpucontext.domain = (domid_t)domid;
670 launch_op.u.setvcpucontext.vcpu = 0;
671 set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt);
673 launch_op.cmd = DOM0_SETVCPUCONTEXT;
674 rc = do_dom0_op(xc_handle, &launch_op);
675 return rc;
677 error_out:
678 free(image);
679 return -1;
680 }
682 /*
683 * Local variables:
684 * mode: C
685 * c-set-style: "BSD"
686 * c-basic-offset: 4
687 * tab-width: 4
688 * indent-tabs-mode: nil
689 * End:
690 */