ia64/xen-unstable

view tools/libxc/xc_ia64_stubs.c @ 8964:8946b6dcd49e

Fix x86_64 Xen build.

event_callback_cs and failsafe_callback_cs are x86_32 only.

Signed-off-by: Ian Campbell <Ian.Campbell@XenSource.com>
author Ian.Campbell@xensource.com
date Wed Feb 22 17:26:39 2006 +0000 (2006-02-22)
parents 991c4d62d392
children 0349fb4de335
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 /* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
11 * mysteriously declared in two places: /usr/include/asm/fpu.h and
12 * /usr/include/bits/sigcontext.h. The former also defines FPSR_DEFAULT,
13 * the latter doesn't but is included (indirectly) by xg_private.h */
14 #define __ASSEMBLY__
15 #include <asm/fpu.h>
16 #undef __IA64_UL
17 #define __IA64_UL(x) ((unsigned long)(x))
18 #undef __ASSEMBLY__
20 unsigned long xc_ia64_fpsr_default(void)
21 {
22 return FPSR_DEFAULT;
23 }
25 int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
26 uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
27 int (*suspend)(int domid))
28 {
29 PERROR("xc_linux_save not implemented\n");
30 return -1;
31 }
33 int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns,
34 unsigned int store_evtchn, unsigned long *store_mfn,
35 unsigned int console_evtchn, unsigned long *console_mfn)
36 {
37 PERROR("xc_linux_restore not implemented\n");
38 return -1;
39 }
41 int
42 xc_plan9_build(int xc_handle,
43 uint32_t domid,
44 const char *image_name,
45 const char *cmdline,
46 unsigned int control_evtchn, unsigned long flags)
47 {
48 PERROR("xc_plan9_build not implemented\n");
49 return -1;
50 }
52 int xc_ia64_get_pfn_list(int xc_handle,
53 uint32_t domid,
54 unsigned long *pfn_buf,
55 unsigned int start_page,
56 unsigned int nr_pages)
57 {
58 dom0_op_t op;
59 int ret;
60 unsigned long max_pfns = ((unsigned long)start_page << 32) | nr_pages;
62 op.cmd = DOM0_GETMEMLIST;
63 op.u.getmemlist.domain = (domid_t)domid;
64 op.u.getmemlist.max_pfns = max_pfns;
65 op.u.getmemlist.buffer = pfn_buf;
67 if ( (max_pfns != -1UL)
68 && mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 )
69 {
70 PERROR("Could not lock pfn list buffer");
71 return -1;
72 }
74 ret = do_dom0_op(xc_handle, &op);
76 if (max_pfns != -1UL)
77 (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long));
79 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
80 }
82 long xc_get_max_pages(int xc_handle, uint32_t domid)
83 {
84 dom0_op_t op;
85 op.cmd = DOM0_GETDOMAININFO;
86 op.u.getdomaininfo.domain = (domid_t)domid;
87 return (do_dom0_op(xc_handle, &op) < 0) ?
88 -1 : op.u.getdomaininfo.max_pages;
89 }
91 int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid,
92 void* src_page, unsigned long dst_pfn, int nr_pages)
93 {
94 // N.B. gva should be page aligned
96 unsigned long *page_array = NULL;
97 int i;
99 if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){
100 PERROR("Could not allocate memory");
101 goto error_out;
102 }
103 if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array,
104 dst_pfn>>PAGE_SHIFT, nr_pages) != nr_pages ){
105 PERROR("Could not get the page frame list");
106 goto error_out;
107 }
109 for ( i=0; i< nr_pages; i++ ){
110 if (xc_copy_to_domain_page(xc_handle, domid, page_array[i],
111 src_page + (i << PAGE_SHIFT)))
112 goto error_out;
113 }
114 free(page_array);
115 return 0;
117 error_out:
118 free(page_array);
119 return -1;
120 }
123 #define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64"
124 #define GFW_HOB_START ((4UL<<30)-(14UL<<20)) //4G -14M
125 #define GFW_HOB_SIZE (1UL<<20) //1M
126 #define MEM_G (1UL << 30)
127 #define MEM_M (1UL << 20)
129 typedef struct {
130 unsigned long signature;
131 unsigned int type;
132 unsigned int length;
133 } HOB_GENERIC_HEADER;
135 /*
136 * INFO HOB is the first data data in one HOB list
137 * it contains the control information of the HOB list
138 */
139 typedef struct {
140 HOB_GENERIC_HEADER header;
141 unsigned long length; // current length of hob
142 unsigned long cur_pos; // current poisiton of hob
143 unsigned long buf_size; // size of hob buffer
144 }HOB_INFO;
146 typedef struct{
147 unsigned long start;
148 unsigned long size;
149 }hob_mem_t;
151 typedef enum {
152 HOB_TYPE_INFO=0,
153 HOB_TYPE_TERMINAL,
154 HOB_TYPE_MEM,
155 HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
156 HOB_TYPE_PAL_CACHE_SUMMARY,
157 HOB_TYPE_PAL_MEM_ATTRIB,
158 HOB_TYPE_PAL_CACHE_INFO,
159 HOB_TYPE_PAL_CACHE_PROT_INFO,
160 HOB_TYPE_PAL_DEBUG_INFO,
161 HOB_TYPE_PAL_FIXED_ADDR,
162 HOB_TYPE_PAL_FREQ_BASE,
163 HOB_TYPE_PAL_FREQ_RATIOS,
164 HOB_TYPE_PAL_HALT_INFO,
165 HOB_TYPE_PAL_PERF_MON_INFO,
166 HOB_TYPE_PAL_PROC_GET_FEATURES,
167 HOB_TYPE_PAL_PTCE_INFO,
168 HOB_TYPE_PAL_REGISTER_INFO,
169 HOB_TYPE_PAL_RSE_INFO,
170 HOB_TYPE_PAL_TEST_INFO,
171 HOB_TYPE_PAL_VM_SUMMARY,
172 HOB_TYPE_PAL_VM_INFO,
173 HOB_TYPE_PAL_VM_PAGE_SIZE,
174 HOB_TYPE_MAX
175 }hob_type_t;
177 static int hob_init( void *buffer ,unsigned long buf_size);
178 static int add_pal_hob(void* hob_buf);
179 static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size);
180 static int build_hob (void* hob_buf, unsigned long hob_buf_size,
181 unsigned long dom_mem_size);
182 static int load_hob(int xc_handle,uint32_t dom, void *hob_buf);
184 int xc_ia64_build_hob(int xc_handle, uint32_t dom, unsigned long memsize){
186 char *hob_buf;
188 hob_buf = malloc (GFW_HOB_SIZE);
189 if (hob_buf == NULL) {
190 PERROR("Could not allocate hob");
191 return -1;
192 }
194 if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize<<20) < 0){
195 free (hob_buf);
196 PERROR("Could not build hob");
197 return -1;
198 }
200 if ( load_hob( xc_handle, dom, hob_buf) <0){
201 free (hob_buf);
202 PERROR("Could not load hob");
203 return -1;
204 }
205 free (hob_buf);
206 return 0;
208 }
209 static int
210 hob_init( void *buffer ,unsigned long buf_size)
211 {
212 HOB_INFO *phit;
213 HOB_GENERIC_HEADER *terminal;
215 if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){
216 // buffer too small
217 return -1;
218 }
220 phit = (HOB_INFO*)buffer;
221 phit->header.signature = HOB_SIGNATURE;
222 phit->header.type = HOB_TYPE_INFO;
223 phit->header.length = sizeof(HOB_INFO);
224 phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER);
225 phit->cur_pos = 0;
226 phit->buf_size = buf_size;
228 terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO));
229 terminal->signature= HOB_SIGNATURE;
230 terminal->type = HOB_TYPE_TERMINAL;
231 terminal->length = sizeof(HOB_GENERIC_HEADER);
233 return 0;
234 }
236 /*
237 * Add a new HOB to the HOB List.
238 *
239 * hob_start - start address of hob buffer
240 * type - type of the hob to be added
241 * data - data of the hob to be added
242 * data_size - size of the data
243 */
244 static int
245 hob_add(
246 void* hob_start,
247 int type,
248 void* data,
249 int data_size
250 )
251 {
252 HOB_INFO *phit;
253 HOB_GENERIC_HEADER *newhob,*tail;
255 phit = (HOB_INFO*)hob_start;
257 if (phit->length + data_size > phit->buf_size){
258 // no space for new hob
259 return -1;
260 }
262 //append new HOB
263 newhob = (HOB_GENERIC_HEADER*)
264 (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER));
265 newhob->signature = HOB_SIGNATURE;
266 newhob->type = type;
267 newhob->length = data_size + sizeof(HOB_GENERIC_HEADER);
268 memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size);
270 // append terminal HOB
271 tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size);
272 tail->signature = HOB_SIGNATURE;
273 tail->type = HOB_TYPE_TERMINAL;
274 tail->length = sizeof(HOB_GENERIC_HEADER);
276 // adjust HOB list length
277 phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size;
279 return 0;
281 }
283 int get_hob_size(void* hob_buf){
285 HOB_INFO *phit = (HOB_INFO*)hob_buf;
287 if (phit->header.signature != HOB_SIGNATURE){
288 PERROR("xc_get_hob_size:Incorrect signature");
289 return -1;
290 }
291 return phit->length;
292 }
294 int build_hob (void* hob_buf, unsigned long hob_buf_size,
295 unsigned long dom_mem_size)
296 {
297 //Init HOB List
298 if (hob_init (hob_buf, hob_buf_size)<0){
299 PERROR("buffer too small");
300 goto err_out;
301 }
303 if ( add_mem_hob( hob_buf,dom_mem_size) < 0){
304 PERROR("Add memory hob failed, buffer too small");
305 goto err_out;
306 }
308 if ( add_pal_hob( hob_buf ) < 0 ){
309 PERROR("Add PAL hob failed, buffer too small");
310 goto err_out;
311 }
313 return 0;
315 err_out:
316 return -1;
317 }
319 static int
320 load_hob(int xc_handle, uint32_t dom, void *hob_buf)
321 {
322 // hob_buf should be page aligned
323 int hob_size;
324 int nr_pages;
326 if ((hob_size = get_hob_size(hob_buf)) < 0){
327 PERROR("Invalid hob data");
328 return -1;
329 }
331 if (hob_size > GFW_HOB_SIZE){
332 PERROR("No enough memory for hob data");
333 return -1;
334 }
336 nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT;
338 return xc_ia64_copy_to_domain_pages(xc_handle, dom,
339 hob_buf, GFW_HOB_START, nr_pages );
340 }
342 #define MIN(x, y) ((x) < (y)) ? (x) : (y)
343 static int
344 add_mem_hob(void* hob_buf, unsigned long dom_mem_size){
345 hob_mem_t memhob;
347 // less than 3G
348 memhob.start = 0;
349 memhob.size = MIN(dom_mem_size, 0xC0000000);
351 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){
352 return -1;
353 }
355 if (dom_mem_size > 0xC0000000) {
356 // 4G ~ 4G+remain
357 memhob.start = 0x100000000; //4G
358 memhob.size = dom_mem_size - 0xC0000000;
359 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
360 return -1;
361 }
362 return 0;
363 }
365 unsigned char config_pal_bus_get_features_data[24] = {
366 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
368 };
369 unsigned char config_pal_cache_summary[16] = {
370 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0};
371 unsigned char config_pal_mem_attrib[8] = {
372 241, 0, 0, 0, 0, 0, 0, 0
373 };
374 unsigned char config_pal_cache_info[152] = {
375 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
376 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
377 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
378 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
380 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
381 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
382 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
383 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
384 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
385 };
386 unsigned char config_pal_cache_prot_info[200] = {
387 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
390 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
391 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
392 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
394 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
396 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
398 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
399 0, 0, 0
400 };
401 unsigned char config_pal_debug_info[16] = {
402 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
403 };
404 unsigned char config_pal_fixed_addr[8] = {
405 0, 0, 0, 0, 0, 0, 0, 0
406 };
407 unsigned char config_pal_freq_base[8] = {
408 109, 219, 182, 13, 0, 0, 0, 0
409 };
410 unsigned char config_pal_freq_ratios[24] = {
411 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
412 0, 0, 0, 7, 0, 0, 0
413 };
414 unsigned char config_pal_halt_info[64] = {
415 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
418 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
419 };
420 unsigned char config_pal_perf_mon_info[136] = {
421 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
422 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
423 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
424 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
425 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
427 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
428 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
429 0, 0, 0, 0, 0, 0, 0, 0
430 };
431 unsigned char config_pal_proc_get_features[104] = {
432 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
433 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
434 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
435 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
436 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
437 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
438 0, 0, 0, 0, 0, 0, 0, 0
439 };
440 unsigned char config_pal_ptce_info[24] = {
441 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
442 0, 0, 0, 0, 0, 0, 0, 0
443 };
444 unsigned char config_pal_register_info[64] = {
445 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
446 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
447 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
448 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
449 };
450 unsigned char config_pal_rse_info[16] = {
451 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
452 };
453 unsigned char config_pal_test_info[48] = {
454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
455 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
456 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
457 };
458 unsigned char config_pal_vm_summary[16] = {
459 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
460 };
461 unsigned char config_pal_vm_info[104] = {
462 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
463 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
464 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
465 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
466 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
467 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
468 };
469 unsigned char config_pal_vm_page_size[16] = {
470 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
471 };
473 typedef struct{
474 hob_type_t type;
475 void* data;
476 unsigned long size;
477 }hob_batch_t;
479 hob_batch_t hob_batch[]={
480 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
481 &config_pal_bus_get_features_data,
482 sizeof(config_pal_bus_get_features_data)
483 },
484 { HOB_TYPE_PAL_CACHE_SUMMARY,
485 &config_pal_cache_summary,
486 sizeof(config_pal_cache_summary)
487 },
488 { HOB_TYPE_PAL_MEM_ATTRIB,
489 &config_pal_mem_attrib,
490 sizeof(config_pal_mem_attrib)
491 },
492 { HOB_TYPE_PAL_CACHE_INFO,
493 &config_pal_cache_info,
494 sizeof(config_pal_cache_info)
495 },
496 { HOB_TYPE_PAL_CACHE_PROT_INFO,
497 &config_pal_cache_prot_info,
498 sizeof(config_pal_cache_prot_info)
499 },
500 { HOB_TYPE_PAL_DEBUG_INFO,
501 &config_pal_debug_info,
502 sizeof(config_pal_debug_info)
503 },
504 { HOB_TYPE_PAL_FIXED_ADDR,
505 &config_pal_fixed_addr,
506 sizeof(config_pal_fixed_addr)
507 },
508 { HOB_TYPE_PAL_FREQ_BASE,
509 &config_pal_freq_base,
510 sizeof(config_pal_freq_base)
511 },
512 { HOB_TYPE_PAL_FREQ_RATIOS,
513 &config_pal_freq_ratios,
514 sizeof(config_pal_freq_ratios)
515 },
516 { HOB_TYPE_PAL_HALT_INFO,
517 &config_pal_halt_info,
518 sizeof(config_pal_halt_info)
519 },
520 { HOB_TYPE_PAL_PERF_MON_INFO,
521 &config_pal_perf_mon_info,
522 sizeof(config_pal_perf_mon_info)
523 },
524 { HOB_TYPE_PAL_PROC_GET_FEATURES,
525 &config_pal_proc_get_features,
526 sizeof(config_pal_proc_get_features)
527 },
528 { HOB_TYPE_PAL_PTCE_INFO,
529 &config_pal_ptce_info,
530 sizeof(config_pal_ptce_info)
531 },
532 { HOB_TYPE_PAL_REGISTER_INFO,
533 &config_pal_register_info,
534 sizeof(config_pal_register_info)
535 },
536 { HOB_TYPE_PAL_RSE_INFO,
537 &config_pal_rse_info,
538 sizeof(config_pal_rse_info)
539 },
540 { HOB_TYPE_PAL_TEST_INFO,
541 &config_pal_test_info,
542 sizeof(config_pal_test_info)
543 },
544 { HOB_TYPE_PAL_VM_SUMMARY,
545 &config_pal_vm_summary,
546 sizeof(config_pal_vm_summary)
547 },
548 { HOB_TYPE_PAL_VM_INFO,
549 &config_pal_vm_info,
550 sizeof(config_pal_vm_info)
551 },
552 { HOB_TYPE_PAL_VM_PAGE_SIZE,
553 &config_pal_vm_page_size,
554 sizeof(config_pal_vm_page_size)
555 },
556 };
558 static int add_pal_hob(void* hob_buf){
559 int i;
560 for (i=0; i<sizeof(hob_batch)/sizeof(hob_batch_t); i++){
561 if (hob_add(hob_buf, hob_batch[i].type,
562 hob_batch[i].data,
563 hob_batch[i].size)<0)
564 return -1;
565 }
566 return 0;
567 }
569 static int setup_guest( int xc_handle,
570 uint32_t dom, unsigned long memsize,
571 char *image, unsigned long image_size,
572 unsigned int control_evtchn,
573 unsigned int store_evtchn,
574 unsigned long *store_mfn)
575 {
576 unsigned long page_array[2];
577 shared_iopage_t *sp;
578 // FIXME: initialize pfn list for a temp hack
579 if (xc_ia64_get_pfn_list(xc_handle, dom, NULL, -1, -1) == -1) {
580 PERROR("Could not allocate continuous memory");
581 goto error_out;
582 }
584 if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {
585 PERROR("Guest firmware size is incorrect [%ld]?", image_size);
586 return -1;
587 }
589 /* Load guest firmware */
590 if( xc_ia64_copy_to_domain_pages( xc_handle, dom,
591 image, 4*MEM_G-image_size, 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, memsize) < 0){
598 PERROR("Could not build hob\n");
599 goto error_out;
600 }
602 /* Retrieve special pages like io, xenstore, etc. */
603 if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, IO_PAGE_START>>PAGE_SHIFT, 2) != 2 )
604 {
605 PERROR("Could not get the page frame list");
606 goto error_out;
607 }
609 *store_mfn = page_array[1];
610 if ((sp = (shared_iopage_t *) xc_map_foreign_range(
611 xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
612 page_array[0])) == 0)
613 goto error_out;
614 memset(sp, 0, PAGE_SIZE);
615 sp->sp_global.eport = control_evtchn;
616 munmap(sp, PAGE_SIZE);
618 return 0;
620 error_out:
621 return -1;
622 }
624 int xc_hvm_build(int xc_handle,
625 uint32_t domid,
626 int memsize,
627 const char *image_name,
628 unsigned int control_evtchn,
629 unsigned int vcpus,
630 unsigned int pae,
631 unsigned int acpi,
632 unsigned int apic,
633 unsigned int store_evtchn,
634 unsigned long *store_mfn)
635 {
636 dom0_op_t launch_op, op;
637 int rc ;
638 vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
639 char *image = NULL;
640 unsigned long image_size;
641 unsigned long nr_pages;
643 if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 )
644 {
645 PERROR("Could not find total pages for domain");
646 goto error_out;
647 }
649 if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){
650 PERROR("Could not read guest firmware image %s",image_name);
651 goto error_out;
652 }
654 image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;
656 if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){
657 PERROR("Unable to mlock ctxt");
658 return 1;
659 }
661 op.cmd = DOM0_GETDOMAININFO;
662 op.u.getdomaininfo.domain = (domid_t)domid;
663 if ( (do_dom0_op(xc_handle, &op) < 0) ||
664 ((uint16_t)op.u.getdomaininfo.domain != domid) ) {
665 PERROR("Could not get info on domain");
666 goto error_out;
667 }
669 memset(ctxt, 0, sizeof(*ctxt));
671 if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, image_size,
672 control_evtchn, store_evtchn, store_mfn ) < 0 ){
673 ERROR("Error constructing guest OS");
674 goto error_out;
675 }
677 free(image);
679 ctxt->flags = VGCF_VMX_GUEST;
680 ctxt->regs.cr_iip = 0x80000000ffffffb0UL;
681 ctxt->vcpu.privregs = 0;
683 memset( &launch_op, 0, sizeof(launch_op) );
685 launch_op.u.setvcpucontext.domain = (domid_t)domid;
686 launch_op.u.setvcpucontext.vcpu = 0;
687 launch_op.u.setvcpucontext.ctxt = ctxt;
689 launch_op.cmd = DOM0_SETVCPUCONTEXT;
690 rc = do_dom0_op(xc_handle, &launch_op);
691 return rc;
693 error_out:
694 free(image);
695 return -1;
696 }
698 /*
699 * Local variables:
700 * mode: C
701 * c-set-style: "BSD"
702 * c-basic-offset: 4
703 * tab-width: 4
704 * indent-tabs-mode: nil
705 * End:
706 */