ia64/xen-unstable

view tools/libxc/xc_ia64_stubs.c @ 9488:0a6f5527ca4b

[IA64] set itv handoff as masked and enable reading irr[0-3]

Set initial vcpu itv handoff state to mask the timer vector.
This seems to match hardware and makes logical sense from a
spurious interrupt perspective. Enable vcpu_get_irr[0-3]
functions as they seem to work and have the proper backing.
This enables the check_sal_cache_flush() in arch/ia64/kernel.sal.c
to work unmodified, allowing us to remove the Xen changes from
the file (and thus the file from the sparse tree).

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Apr 04 09:39:45 2006 -0600 (2006-04-04)
parents 899532500ada
children 827c65c06a66 74ee53209cca
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 uint32_t vcpus,
573 unsigned int store_evtchn,
574 unsigned long *store_mfn)
575 {
576 unsigned long page_array[2];
577 shared_iopage_t *sp;
578 int i;
580 // FIXME: initialize pfn list for a temp hack
581 if (xc_ia64_get_pfn_list(xc_handle, dom, NULL, -1, -1) == -1) {
582 PERROR("Could not allocate continuous memory");
583 goto error_out;
584 }
586 if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {
587 PERROR("Guest firmware size is incorrect [%ld]?", image_size);
588 return -1;
589 }
591 /* Load guest firmware */
592 if( xc_ia64_copy_to_domain_pages( xc_handle, dom,
593 image, 4*MEM_G-image_size, image_size>>PAGE_SHIFT)) {
594 PERROR("Could not load guest firmware into domain");
595 goto error_out;
596 }
598 /* Hand-off state passed to guest firmware */
599 if (xc_ia64_build_hob(xc_handle, dom, memsize) < 0){
600 PERROR("Could not build hob\n");
601 goto error_out;
602 }
604 /* Retrieve special pages like io, xenstore, etc. */
605 if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, IO_PAGE_START>>PAGE_SHIFT, 2) != 2 )
606 {
607 PERROR("Could not get the page frame list");
608 goto error_out;
609 }
611 *store_mfn = page_array[1];
612 if ((sp = (shared_iopage_t *) xc_map_foreign_range(
613 xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
614 page_array[0])) == 0)
615 goto error_out;
616 memset(sp, 0, PAGE_SIZE);
618 for (i = 0; i < vcpus; i++) {
619 uint32_t vp_eport;
621 vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
622 if (vp_eport < 0) {
623 fprintf(stderr, "Couldn't get unbound port from VMX guest.\n");
624 goto error_out;
625 }
626 sp->vcpu_iodata[i].vp_eport = vp_eport;
627 }
629 munmap(sp, PAGE_SIZE);
631 return 0;
633 error_out:
634 return -1;
635 }
637 int xc_hvm_build(int xc_handle,
638 uint32_t domid,
639 int memsize,
640 const char *image_name,
641 unsigned int vcpus,
642 unsigned int pae,
643 unsigned int acpi,
644 unsigned int apic,
645 unsigned int store_evtchn,
646 unsigned long *store_mfn)
647 {
648 dom0_op_t launch_op, op;
649 int rc ;
650 vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
651 char *image = NULL;
652 unsigned long image_size;
653 unsigned long nr_pages;
655 if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 )
656 {
657 PERROR("Could not find total pages for domain");
658 goto error_out;
659 }
661 if ( (image = xc_read_image(image_name, &image_size)) == NULL ){
662 PERROR("Could not read guest firmware image %s",image_name);
663 goto error_out;
664 }
666 image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;
668 if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){
669 PERROR("Unable to mlock ctxt");
670 return 1;
671 }
673 op.cmd = DOM0_GETDOMAININFO;
674 op.u.getdomaininfo.domain = (domid_t)domid;
675 if ( (do_dom0_op(xc_handle, &op) < 0) ||
676 ((uint16_t)op.u.getdomaininfo.domain != domid) ) {
677 PERROR("Could not get info on domain");
678 goto error_out;
679 }
681 memset(ctxt, 0, sizeof(*ctxt));
683 if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image,
684 image_size, vcpus, store_evtchn, store_mfn ) < 0 ){
685 ERROR("Error constructing guest OS");
686 goto error_out;
687 }
689 free(image);
691 ctxt->flags = VGCF_VMX_GUEST;
692 ctxt->regs.cr_iip = 0x80000000ffffffb0UL;
693 ctxt->vcpu.privregs = 0;
695 memset( &launch_op, 0, sizeof(launch_op) );
697 launch_op.u.setvcpucontext.domain = (domid_t)domid;
698 launch_op.u.setvcpucontext.vcpu = 0;
699 launch_op.u.setvcpucontext.ctxt = ctxt;
701 launch_op.cmd = DOM0_SETVCPUCONTEXT;
702 rc = do_dom0_op(xc_handle, &launch_op);
703 return rc;
705 error_out:
706 free(image);
707 return -1;
708 }
710 /*
711 * Local variables:
712 * mode: C
713 * c-set-style: "BSD"
714 * c-basic-offset: 4
715 * tab-width: 4
716 * indent-tabs-mode: nil
717 * End:
718 */