direct-io.hg

view tools/libxc/ia64/xc_ia64_hvm_build.c @ 12429:6f3b4d6b04f5

[IA64] fix VTI boot

workaroud patch for memory initial interface

Signed-off-by: zhang xiantao <xiantao.zhang@intel.com>
Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
author awilliam@xenbuild.aw
date Fri Nov 10 11:14:51 2006 -0700 (2006-11-10)
parents 2368e779f89f
children 357a3c90d67b
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[3];
555 shared_iopage_t *sp;
556 void *ioreq_buffer_page;
557 // memsize = required memsize(in configure file) + 16M
558 // dom_memsize will pass to xc_ia64_build_hob(), so must be subbed 16M
559 unsigned long dom_memsize = ((memsize - 16) << 20);
560 unsigned long nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
561 int rc;
562 DECLARE_DOMCTL;
564 // ROM size for guest firmware, ioreq page and xenstore page
565 nr_pages += 3;
567 if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {
568 PERROR("Guest firmware size is incorrect [%ld]?", image_size);
569 return -1;
570 }
572 rc = xc_domain_memory_increase_reservation(xc_handle, dom, nr_pages,
573 0, 0, NULL);
574 if (rc != 0) {
575 PERROR("Could not allocate memory for HVM guest.\n");
576 goto error_out;
577 }
579 /* This will creates the physmap. */
580 domctl.u.arch_setup.flags = XEN_DOMAINSETUP_hvm_guest;
581 domctl.u.arch_setup.bp = 0;
582 domctl.u.arch_setup.maxmem = 0;
583 domctl.cmd = XEN_DOMCTL_arch_setup;
584 domctl.domain = (domid_t)dom;
585 if (xc_domctl(xc_handle, &domctl))
586 goto error_out;
588 /* Load guest firmware */
589 if (xc_ia64_copy_to_domain_pages(xc_handle, dom, image,
590 (GFW_START + GFW_SIZE - image_size) >> PAGE_SHIFT,
591 image_size >> PAGE_SHIFT)) {
592 PERROR("Could not load guest firmware into domain");
593 goto error_out;
594 }
596 /* Hand-off state passed to guest firmware */
597 if (xc_ia64_build_hob(xc_handle, dom, dom_memsize,
598 (unsigned long)vcpus) < 0) {
599 PERROR("Could not build hob\n");
600 goto error_out;
601 }
603 /* Retrieve special pages like io, xenstore, etc. */
604 if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
605 IO_PAGE_START>>PAGE_SHIFT, 3) != 3) {
606 PERROR("Could not get the page frame list");
607 goto error_out;
608 }
610 xc_set_hvm_param(xc_handle, dom,
611 HVM_PARAM_STORE_PFN, STORE_PAGE_START>>PAGE_SHIFT);
612 xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
614 *store_mfn = page_array[1];
615 sp = (shared_iopage_t *)xc_map_foreign_range(xc_handle, dom,
616 PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
617 if (sp == 0)
618 goto error_out;
620 memset(sp, 0, PAGE_SIZE);
621 munmap(sp, PAGE_SIZE);
622 ioreq_buffer_page = xc_map_foreign_range(xc_handle, dom,
623 PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[2]);
624 memset(ioreq_buffer_page,0,PAGE_SIZE);
625 munmap(ioreq_buffer_page, PAGE_SIZE);
626 return 0;
628 error_out:
629 return -1;
630 }
632 int
633 xc_hvm_build(int xc_handle, uint32_t domid, int memsize,
634 const char *image_name, unsigned int vcpus, unsigned int pae,
635 unsigned int acpi, unsigned int store_evtchn,
636 unsigned long *store_mfn)
637 {
638 struct xen_domctl launch_domctl, domctl;
639 int rc;
640 vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
641 char *image = NULL;
642 unsigned long image_size;
643 unsigned long nr_pages;
645 nr_pages = xc_get_max_pages(xc_handle, domid);
646 if (nr_pages < 0) {
647 PERROR("Could not find total pages for domain");
648 goto error_out;
649 }
651 image = xc_read_image(image_name, &image_size);
652 if (image == NULL) {
653 PERROR("Could not read guest firmware image %s", image_name);
654 goto error_out;
655 }
657 image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;
659 if (mlock(&st_ctxt, sizeof(st_ctxt))) {
660 PERROR("Unable to mlock ctxt");
661 return 1;
662 }
664 domctl.cmd = XEN_DOMCTL_getdomaininfo;
665 domctl.domain = (domid_t)domid;
666 if (do_domctl(xc_handle, &domctl) < 0 ||
667 (uint16_t)domctl.domain != domid) {
668 PERROR("Could not get info on domain");
669 goto error_out;
670 }
672 memset(ctxt, 0, sizeof(*ctxt));
674 if (setup_guest(xc_handle, domid, (unsigned long)memsize, image,
675 image_size, vcpus, store_evtchn, store_mfn) < 0) {
676 ERROR("Error constructing guest OS");
677 goto error_out;
678 }
680 free(image);
682 ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL;
684 memset(&launch_domctl, 0, sizeof(launch_domctl));
686 launch_domctl.domain = (domid_t)domid;
687 launch_domctl.u.vcpucontext.vcpu = 0;
688 set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
690 launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
691 rc = do_domctl(xc_handle, &launch_domctl);
692 return rc;
694 error_out:
695 free(image);
696 return -1;
697 }
699 /*
700 * Local variables:
701 * mode: C
702 * c-set-style: "BSD"
703 * c-basic-offset: 4
704 * tab-width: 4
705 * indent-tabs-mode: nil
706 * End:
707 */