# HG changeset patch # User gingold@virtu10 # Node ID aa8dd442a257fd61bad67b62a1d33f5574e192f9 # Parent a1482fd7453049806fb1eabd7320615405ca7910 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 diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/Makefile --- a/tools/libxc/Makefile Sun Jul 09 22:50:43 2006 -0600 +++ b/tools/libxc/Makefile Mon Jul 10 13:06:46 2006 +0200 @@ -30,9 +30,11 @@ GUEST_SRCS-y += xc_load_bin.c GUEST_SRCS-y += xc_load_bin.c GUEST_SRCS-y += xc_load_elf.c GUEST_SRCS-y += xg_private.c -GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c + +# This Makefile only adds files if CONFIG_IA64 is y. +include ia64/Makefile CFLAGS += -Werror CFLAGS += -fno-strict-aliasing @@ -98,6 +100,7 @@ TAGS: .PHONY: clean clean: rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen + rm -rf ia64/*.o ia64/*.opic .PHONY: rpm rpm: build diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Sun Jul 09 22:50:43 2006 -0600 +++ b/tools/libxc/xc_private.c Mon Jul 10 13:06:46 2006 +0200 @@ -262,6 +262,7 @@ long long xc_domain_get_cpu_usage( int x } +#ifndef __ia64__ int xc_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, @@ -305,6 +306,7 @@ int xc_get_pfn_list(int xc_handle, return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } +#endif long xc_get_tot_pages(int xc_handle, uint32_t domid) { diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Sun Jul 09 22:50:43 2006 -0600 +++ b/tools/libxc/xenctrl.h Mon Jul 10 13:06:46 2006 +0200 @@ -519,9 +519,6 @@ int xc_clear_domain_page(int xc_handle, int xc_clear_domain_page(int xc_handle, uint32_t domid, unsigned long dst_pfn); -int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, - void* src_page, unsigned long dst_pfn, int nr_pages); - long xc_get_max_pages(int xc_handle, uint32_t domid); int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/ia64/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/Makefile Mon Jul 10 13:06:46 2006 +0200 @@ -0,0 +1,3 @@ +CTRL_SRCS-$(CONFIG_IA64) += ia64/xc_ia64_stubs.c + +GUEST_SRCS-$(CONFIG_IA64) += ia64/xc_ia64_hvm_build.c diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/ia64/xc_ia64_hvm_build.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jul 10 13:06:46 2006 +0200 @@ -0,0 +1,657 @@ +#include "xg_private.h" +#include "xenguest.h" +#include "xc_private.h" +#include "xc_elf.h" +#include +#include +#include "xen/arch-ia64.h" +#include + +static int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, + void* src_page, unsigned long dst_pfn, int nr_pages) +{ + // N.B. gva should be page aligned + + xen_pfn_t *page_array = NULL; + int i; + + if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ){ + PERROR("Could not allocate memory"); + goto error_out; + } + if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, + dst_pfn, nr_pages) != nr_pages ){ + PERROR("Could not get the page frame list"); + goto error_out; + } + + for ( i=0; i< nr_pages; i++ ){ + if (xc_copy_to_domain_page(xc_handle, domid, page_array[i], + src_page + (i << PAGE_SHIFT))) + goto error_out; + } + free(page_array); + return 0; + +error_out: + free(page_array); + return -1; +} + + +#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" +#define GFW_HOB_START ((4UL<<30)-(14UL<<20)) // 4G - 14M +#define GFW_HOB_SIZE (1UL<<20) // 1M + +typedef struct { + unsigned long signature; + unsigned int type; + unsigned int length; +} HOB_GENERIC_HEADER; + +/* + * INFO HOB is the first data data in one HOB list + * it contains the control information of the HOB list + */ +typedef struct { + HOB_GENERIC_HEADER header; + unsigned long length; // current length of hob + unsigned long cur_pos; // current poisiton of hob + unsigned long buf_size; // size of hob buffer +}HOB_INFO; + +typedef struct{ + unsigned long start; + unsigned long size; +}hob_mem_t; + +typedef enum { + HOB_TYPE_INFO=0, + HOB_TYPE_TERMINAL, + HOB_TYPE_MEM, + HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + HOB_TYPE_PAL_CACHE_SUMMARY, + HOB_TYPE_PAL_MEM_ATTRIB, + HOB_TYPE_PAL_CACHE_INFO, + HOB_TYPE_PAL_CACHE_PROT_INFO, + HOB_TYPE_PAL_DEBUG_INFO, + HOB_TYPE_PAL_FIXED_ADDR, + HOB_TYPE_PAL_FREQ_BASE, + HOB_TYPE_PAL_FREQ_RATIOS, + HOB_TYPE_PAL_HALT_INFO, + HOB_TYPE_PAL_PERF_MON_INFO, + HOB_TYPE_PAL_PROC_GET_FEATURES, + HOB_TYPE_PAL_PTCE_INFO, + HOB_TYPE_PAL_REGISTER_INFO, + HOB_TYPE_PAL_RSE_INFO, + HOB_TYPE_PAL_TEST_INFO, + HOB_TYPE_PAL_VM_SUMMARY, + HOB_TYPE_PAL_VM_INFO, + HOB_TYPE_PAL_VM_PAGE_SIZE, + HOB_TYPE_NR_VCPU, + HOB_TYPE_MAX +}hob_type_t; + +static int hob_init( void *buffer ,unsigned long buf_size); +static int add_pal_hob(void* hob_buf); +static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size); +static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu); +static int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size, unsigned long vcpus); +static int load_hob(int xc_handle,uint32_t dom, void *hob_buf, + unsigned long dom_mem_size); + +static int xc_ia64_build_hob(int xc_handle, uint32_t dom, + unsigned long memsize, unsigned long vcpus) +{ + char *hob_buf; + + hob_buf = malloc (GFW_HOB_SIZE); + if (hob_buf == NULL) { + PERROR("Could not allocate hob"); + return -1; + } + + if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize, vcpus) < 0){ + free (hob_buf); + PERROR("Could not build hob"); + return -1; + } + + if ( load_hob( xc_handle, dom, hob_buf, memsize) < 0){ + free (hob_buf); + PERROR("Could not load hob"); + return -1; + } + free (hob_buf); + return 0; + +} + +static int +hob_init( void *buffer ,unsigned long buf_size) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *terminal; + + if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){ + // buffer too small + return -1; + } + + phit = (HOB_INFO*)buffer; + phit->header.signature = HOB_SIGNATURE; + phit->header.type = HOB_TYPE_INFO; + phit->header.length = sizeof(HOB_INFO); + phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER); + phit->cur_pos = 0; + phit->buf_size = buf_size; + + terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO)); + terminal->signature= HOB_SIGNATURE; + terminal->type = HOB_TYPE_TERMINAL; + terminal->length = sizeof(HOB_GENERIC_HEADER); + + return 0; +} + +/* + * Add a new HOB to the HOB List. + * + * hob_start - start address of hob buffer + * type - type of the hob to be added + * data - data of the hob to be added + * data_size - size of the data + */ +static int +hob_add( + void* hob_start, + int type, + void* data, + int data_size +) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *newhob,*tail; + + phit = (HOB_INFO*)hob_start; + + if (phit->length + data_size > phit->buf_size){ + // no space for new hob + return -1; + } + + //append new HOB + newhob = (HOB_GENERIC_HEADER*) + (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER)); + newhob->signature = HOB_SIGNATURE; + newhob->type = type; + newhob->length = data_size + sizeof(HOB_GENERIC_HEADER); + memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size); + + // append terminal HOB + tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size); + tail->signature = HOB_SIGNATURE; + tail->type = HOB_TYPE_TERMINAL; + tail->length = sizeof(HOB_GENERIC_HEADER); + + // adjust HOB list length + phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size; + + return 0; + +} + +static int get_hob_size(void* hob_buf) +{ + HOB_INFO *phit = (HOB_INFO*)hob_buf; + + if (phit->header.signature != HOB_SIGNATURE){ + PERROR("xc_get_hob_size:Incorrect signature"); + return -1; + } + return phit->length; +} + +static int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size, unsigned long vcpus) +{ + //Init HOB List + if (hob_init (hob_buf, hob_buf_size)<0){ + PERROR("buffer too small"); + goto err_out; + } + + if ( add_mem_hob( hob_buf,dom_mem_size) < 0){ + PERROR("Add memory hob failed, buffer too small"); + goto err_out; + } + + if ( add_vcpus_hob(hob_buf, vcpus)<0){ + PERROR("Add NR_VCPU hob failed, buffer too small"); + goto err_out; + } + + if ( add_pal_hob( hob_buf ) < 0 ){ + PERROR("Add PAL hob failed, buffer too small"); + goto err_out; + } + + return 0; + +err_out: + return -1; +} + +static int +load_hob(int xc_handle, uint32_t dom, void *hob_buf, + unsigned long dom_mem_size) +{ + // hob_buf should be page aligned + int hob_size; + int nr_pages; + + if ((hob_size = get_hob_size(hob_buf)) < 0){ + PERROR("Invalid hob data"); + return -1; + } + + if (hob_size > GFW_HOB_SIZE){ + PERROR("No enough memory for hob data"); + return -1; + } + + nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; + + return xc_ia64_copy_to_domain_pages(xc_handle, dom, + hob_buf, GFW_HOB_START>>PAGE_SHIFT, nr_pages ); +} + +#define MIN(x, y) ((x) < (y)) ? (x) : (y) +static int +add_mem_hob(void* hob_buf, unsigned long dom_mem_size){ + hob_mem_t memhob; + + // less than 3G + memhob.start = 0; + memhob.size = MIN(dom_mem_size, 0xC0000000); + + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){ + return -1; + } + + if (dom_mem_size > 0xC0000000) { + // 4G ~ 4G+remain + memhob.start = 0x100000000; //4G + memhob.size = dom_mem_size - 0xC0000000; + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0) + return -1; + } + return 0; +} + +static int +add_vcpus_hob(void* hob_buf, unsigned long vcpus) +{ + return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus)); +} + +static const unsigned char config_pal_bus_get_features_data[24] = { + 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_cache_summary[16] = { + 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned char config_pal_mem_attrib[8] = { + 241, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_cache_info[152] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12, + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1, + 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0, + 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, + 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255, + 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9, + 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0 +}; +static const unsigned char config_pal_cache_prot_info[200] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, + 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, + 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160, + 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; +static const unsigned char config_pal_debug_info[16] = { + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_fixed_addr[8] = { + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_freq_base[8] = { + 109, 219, 182, 13, 0, 0, 0, 0 +}; +static const unsigned char config_pal_freq_ratios[24] = { + 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 7, 0, 0, 0 +}; +static const unsigned char config_pal_halt_info[64] = { + 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_perf_mon_info[136] = { + 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_proc_get_features[104] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_ptce_info[24] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_register_info[64] = { + 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, + 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, + 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255 +}; +static const unsigned char config_pal_rse_info[16] = { + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_test_info[48] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_vm_summary[16] = { + 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_vm_info[104] = { + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, + 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0 +}; +static const unsigned char config_pal_vm_page_size[16] = { + 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0 +}; + +typedef struct{ + hob_type_t type; + void* data; + unsigned long size; +}hob_batch_t; + +static const hob_batch_t hob_batch[]={ + { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + &config_pal_bus_get_features_data, + sizeof(config_pal_bus_get_features_data) + }, + { HOB_TYPE_PAL_CACHE_SUMMARY, + &config_pal_cache_summary, + sizeof(config_pal_cache_summary) + }, + { HOB_TYPE_PAL_MEM_ATTRIB, + &config_pal_mem_attrib, + sizeof(config_pal_mem_attrib) + }, + { HOB_TYPE_PAL_CACHE_INFO, + &config_pal_cache_info, + sizeof(config_pal_cache_info) + }, + { HOB_TYPE_PAL_CACHE_PROT_INFO, + &config_pal_cache_prot_info, + sizeof(config_pal_cache_prot_info) + }, + { HOB_TYPE_PAL_DEBUG_INFO, + &config_pal_debug_info, + sizeof(config_pal_debug_info) + }, + { HOB_TYPE_PAL_FIXED_ADDR, + &config_pal_fixed_addr, + sizeof(config_pal_fixed_addr) + }, + { HOB_TYPE_PAL_FREQ_BASE, + &config_pal_freq_base, + sizeof(config_pal_freq_base) + }, + { HOB_TYPE_PAL_FREQ_RATIOS, + &config_pal_freq_ratios, + sizeof(config_pal_freq_ratios) + }, + { HOB_TYPE_PAL_HALT_INFO, + &config_pal_halt_info, + sizeof(config_pal_halt_info) + }, + { HOB_TYPE_PAL_PERF_MON_INFO, + &config_pal_perf_mon_info, + sizeof(config_pal_perf_mon_info) + }, + { HOB_TYPE_PAL_PROC_GET_FEATURES, + &config_pal_proc_get_features, + sizeof(config_pal_proc_get_features) + }, + { HOB_TYPE_PAL_PTCE_INFO, + &config_pal_ptce_info, + sizeof(config_pal_ptce_info) + }, + { HOB_TYPE_PAL_REGISTER_INFO, + &config_pal_register_info, + sizeof(config_pal_register_info) + }, + { HOB_TYPE_PAL_RSE_INFO, + &config_pal_rse_info, + sizeof(config_pal_rse_info) + }, + { HOB_TYPE_PAL_TEST_INFO, + &config_pal_test_info, + sizeof(config_pal_test_info) + }, + { HOB_TYPE_PAL_VM_SUMMARY, + &config_pal_vm_summary, + sizeof(config_pal_vm_summary) + }, + { HOB_TYPE_PAL_VM_INFO, + &config_pal_vm_info, + sizeof(config_pal_vm_info) + }, + { HOB_TYPE_PAL_VM_PAGE_SIZE, + &config_pal_vm_page_size, + sizeof(config_pal_vm_page_size) + }, +}; + +static int add_pal_hob(void* hob_buf){ + int i; + for (i=0; i 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { + PERROR("Guest firmware size is incorrect [%ld]?", image_size); + return -1; + } + + /* This will creates the physmap. */ + op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest; + op.u.domain_setup.domain = (domid_t)dom; + op.u.domain_setup.bp = 0; + op.u.domain_setup.maxmem = 0; + + op.cmd = DOM0_DOMAIN_SETUP; + if ( xc_dom0_op(xc_handle, &op) ) + goto error_out; + + /* Load guest firmware */ + if( xc_ia64_copy_to_domain_pages(xc_handle, dom, image, + (GFW_START+GFW_SIZE-image_size)>>PAGE_SHIFT, image_size>>PAGE_SHIFT)) { + PERROR("Could not load guest firmware into domain"); + goto error_out; + } + + /* Hand-off state passed to guest firmware */ + if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, (unsigned long)vcpus) < 0){ + PERROR("Could not build hob\n"); + goto error_out; + } + + /* Retrieve special pages like io, xenstore, etc. */ + if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, + IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) + { + PERROR("Could not get the page frame list"); + goto error_out; + } + + *store_mfn = page_array[1]; + if ((sp = (shared_iopage_t *) xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, + page_array[0])) == 0) + goto error_out; + memset(sp, 0, PAGE_SIZE); + + for (i = 0; i < vcpus; i++) { + uint32_t vp_eport; + + vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0); + if (vp_eport < 0) { + DPRINTF("Couldn't get unbound port from VMX guest.\n"); + goto error_out; + } + sp->vcpu_iodata[i].vp_eport = vp_eport; + } + + munmap(sp, PAGE_SIZE); + + return 0; + + error_out: + return -1; +} + +int xc_hvm_build(int xc_handle, + uint32_t domid, + int memsize, + const char *image_name, + unsigned int vcpus, + unsigned int pae, + unsigned int acpi, + unsigned int apic, + unsigned int store_evtchn, + unsigned long *store_mfn) +{ + dom0_op_t launch_op, op; + int rc ; + vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; + char *image = NULL; + unsigned long image_size; + unsigned long nr_pages; + + if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 ) + { + PERROR("Could not find total pages for domain"); + goto error_out; + } + + if ( (image = xc_read_image(image_name, &image_size)) == NULL ){ + PERROR("Could not read guest firmware image %s",image_name); + goto error_out; + } + + image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK; + + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){ + PERROR("Unable to mlock ctxt"); + return 1; + } + + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + if ( (do_dom0_op(xc_handle, &op) < 0) || + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { + PERROR("Could not get info on domain"); + goto error_out; + } + + memset(ctxt, 0, sizeof(*ctxt)); + + if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, + image_size, vcpus, store_evtchn, store_mfn ) < 0 ){ + ERROR("Error constructing guest OS"); + goto error_out; + } + + free(image); + + ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL; + + memset( &launch_op, 0, sizeof(launch_op) ); + + launch_op.u.setvcpucontext.domain = (domid_t)domid; + launch_op.u.setvcpucontext.vcpu = 0; + set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt); + + launch_op.cmd = DOM0_SETVCPUCONTEXT; + rc = do_dom0_op(xc_handle, &launch_op); + return rc; + + error_out: + free(image); + return -1; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/ia64/xc_ia64_stubs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_ia64_stubs.c Mon Jul 10 13:06:46 2006 +0200 @@ -0,0 +1,125 @@ +#include "xg_private.h" +#include "xenguest.h" +#include "xc_private.h" +#include "xc_elf.h" +#include +#include +#include "xen/arch-ia64.h" +#include + +/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is + * mysteriously declared in two places: /usr/include/asm/fpu.h and + * /usr/include/bits/sigcontext.h. The former also defines FPSR_DEFAULT, + * the latter doesn't but is included (indirectly) by xg_private.h */ +#define __ASSEMBLY__ +#include +#undef __IA64_UL +#define __IA64_UL(x) ((unsigned long)(x)) +#undef __ASSEMBLY__ + +unsigned long xc_ia64_fpsr_default(void) +{ + return FPSR_DEFAULT; +} + +int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, + uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, + int (*suspend)(int domid)) +{ + PERROR("xc_linux_save not implemented\n"); + return -1; +} + +int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, + unsigned int store_evtchn, unsigned long *store_mfn, + unsigned int console_evtchn, unsigned long *console_mfn) +{ + PERROR("xc_linux_restore not implemented\n"); + return -1; +} + +/* + VMM uses put_user to copy pfn_list to guest buffer, this maybe fail, + VMM doesn't handle this now. + This method will touch guest buffer to make sure the buffer's mapping + is tracked by VMM, + */ +int xc_ia64_get_pfn_list(int xc_handle, + uint32_t domid, + xen_pfn_t *pfn_buf, + unsigned int start_page, + unsigned int nr_pages) +{ + dom0_op_t op; + int num_pfns,ret; + unsigned int __start_page, __nr_pages; + unsigned long max_pfns; + xen_pfn_t *__pfn_buf; + + __start_page = start_page; + __nr_pages = nr_pages; + __pfn_buf = pfn_buf; + + while(__nr_pages){ + max_pfns = ((unsigned long)__start_page << 32) | __nr_pages; + op.cmd = DOM0_GETMEMLIST; + op.u.getmemlist.domain = (domid_t)domid; + op.u.getmemlist.max_pfns = max_pfns; + op.u.getmemlist.num_pfns = 0; + set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf); + + if ( (max_pfns != -1UL) + && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0 ) + { + PERROR("Could not lock pfn list buffer"); + return -1; + } + + ret = do_dom0_op(xc_handle, &op); + + if (max_pfns != -1UL) + (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)); + + if (max_pfns == -1UL) + return 0; + + num_pfns = op.u.getmemlist.num_pfns; + __start_page += num_pfns; + __nr_pages -= num_pfns; + __pfn_buf += num_pfns; + + if (ret < 0) + // dummy write to make sure this tlb mapping is tracked by VMM + *__pfn_buf = 0; + else + return nr_pages; + } + return nr_pages; +} + +int xc_get_pfn_list(int xc_handle, + uint32_t domid, + xen_pfn_t *pfn_buf, + unsigned long max_pfns) +{ + return xc_ia64_get_pfn_list (xc_handle, domid, pfn_buf, 0, max_pfns); +} + +long xc_get_max_pages(int xc_handle, uint32_t domid) +{ + dom0_op_t op; + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + return (do_dom0_op(xc_handle, &op) < 0) ? + -1 : op.u.getdomaininfo.max_pages; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r a1482fd74530 -r aa8dd442a257 tools/libxc/xc_ia64_stubs.c --- a/tools/libxc/xc_ia64_stubs.c Sun Jul 09 22:50:43 2006 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,755 +0,0 @@ -#include "xg_private.h" -#include "xenguest.h" -#include "xc_private.h" -#include "xc_elf.h" -#include -#include -#include "xen/arch-ia64.h" -#include - -/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is - * mysteriously declared in two places: /usr/include/asm/fpu.h and - * /usr/include/bits/sigcontext.h. The former also defines FPSR_DEFAULT, - * the latter doesn't but is included (indirectly) by xg_private.h */ -#define __ASSEMBLY__ -#include -#undef __IA64_UL -#define __IA64_UL(x) ((unsigned long)(x)) -#undef __ASSEMBLY__ - -unsigned long xc_ia64_fpsr_default(void) -{ - return FPSR_DEFAULT; -} - -int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, - uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, - int (*suspend)(int domid)) -{ - PERROR("xc_linux_save not implemented\n"); - return -1; -} - -int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, - unsigned int store_evtchn, unsigned long *store_mfn, - unsigned int console_evtchn, unsigned long *console_mfn) -{ - PERROR("xc_linux_restore not implemented\n"); - return -1; -} - -/* - VMM uses put_user to copy pfn_list to guest buffer, this maybe fail, - VMM doesn't handle this now. - This method will touch guest buffer to make sure the buffer's mapping - is tracked by VMM, - */ -int xc_ia64_get_pfn_list(int xc_handle, - uint32_t domid, - xen_pfn_t *pfn_buf, - unsigned int start_page, - unsigned int nr_pages) -{ - dom0_op_t op; - int num_pfns,ret; - unsigned int __start_page, __nr_pages; - unsigned long max_pfns; - xen_pfn_t *__pfn_buf; - - __start_page = start_page; - __nr_pages = nr_pages; - __pfn_buf = pfn_buf; - - while(__nr_pages){ - max_pfns = ((unsigned long)__start_page << 32) | __nr_pages; - op.cmd = DOM0_GETMEMLIST; - op.u.getmemlist.domain = (domid_t)domid; - op.u.getmemlist.max_pfns = max_pfns; - op.u.getmemlist.num_pfns = 0; - set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf); - - if ( (max_pfns != -1UL) - && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0 ) - { - PERROR("Could not lock pfn list buffer"); - return -1; - } - - ret = do_dom0_op(xc_handle, &op); - - if (max_pfns != -1UL) - (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)); - - if (max_pfns == -1UL) - return 0; - - num_pfns = op.u.getmemlist.num_pfns; - __start_page += num_pfns; - __nr_pages -= num_pfns; - __pfn_buf += num_pfns; - - if (ret < 0) - // dummy write to make sure this tlb mapping is tracked by VMM - *__pfn_buf = 0; - else - return nr_pages; - } - return nr_pages; -} - -long xc_get_max_pages(int xc_handle, uint32_t domid) -{ - dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - return (do_dom0_op(xc_handle, &op) < 0) ? - -1 : op.u.getdomaininfo.max_pages; -} - -int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, - void* src_page, unsigned long dst_pfn, int nr_pages) -{ - // N.B. gva should be page aligned - - xen_pfn_t *page_array = NULL; - int i; - - if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ){ - PERROR("Could not allocate memory"); - goto error_out; - } - if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, - dst_pfn, nr_pages) != nr_pages ){ - PERROR("Could not get the page frame list"); - goto error_out; - } - - for ( i=0; i< nr_pages; i++ ){ - if (xc_copy_to_domain_page(xc_handle, domid, page_array[i], - src_page + (i << PAGE_SHIFT))) - goto error_out; - } - free(page_array); - return 0; - -error_out: - free(page_array); - return -1; -} - - -#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" -#define GFW_HOB_START ((4UL<<30)-(14UL<<20)) // 4G - 14M -#define GFW_HOB_SIZE (1UL<<20) // 1M - -typedef struct { - unsigned long signature; - unsigned int type; - unsigned int length; -} HOB_GENERIC_HEADER; - -/* - * INFO HOB is the first data data in one HOB list - * it contains the control information of the HOB list - */ -typedef struct { - HOB_GENERIC_HEADER header; - unsigned long length; // current length of hob - unsigned long cur_pos; // current poisiton of hob - unsigned long buf_size; // size of hob buffer -}HOB_INFO; - -typedef struct{ - unsigned long start; - unsigned long size; -}hob_mem_t; - -typedef enum { - HOB_TYPE_INFO=0, - HOB_TYPE_TERMINAL, - HOB_TYPE_MEM, - HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, - HOB_TYPE_PAL_CACHE_SUMMARY, - HOB_TYPE_PAL_MEM_ATTRIB, - HOB_TYPE_PAL_CACHE_INFO, - HOB_TYPE_PAL_CACHE_PROT_INFO, - HOB_TYPE_PAL_DEBUG_INFO, - HOB_TYPE_PAL_FIXED_ADDR, - HOB_TYPE_PAL_FREQ_BASE, - HOB_TYPE_PAL_FREQ_RATIOS, - HOB_TYPE_PAL_HALT_INFO, - HOB_TYPE_PAL_PERF_MON_INFO, - HOB_TYPE_PAL_PROC_GET_FEATURES, - HOB_TYPE_PAL_PTCE_INFO, - HOB_TYPE_PAL_REGISTER_INFO, - HOB_TYPE_PAL_RSE_INFO, - HOB_TYPE_PAL_TEST_INFO, - HOB_TYPE_PAL_VM_SUMMARY, - HOB_TYPE_PAL_VM_INFO, - HOB_TYPE_PAL_VM_PAGE_SIZE, - HOB_TYPE_NR_VCPU, - HOB_TYPE_MAX -}hob_type_t; - -static int hob_init( void *buffer ,unsigned long buf_size); -static int add_pal_hob(void* hob_buf); -static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size); -static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu); -static int build_hob (void* hob_buf, unsigned long hob_buf_size, - unsigned long dom_mem_size, unsigned long vcpus); -static int load_hob(int xc_handle,uint32_t dom, void *hob_buf, - unsigned long dom_mem_size); - -int xc_ia64_build_hob(int xc_handle, uint32_t dom, unsigned long memsize, - unsigned long vcpus){ - - char *hob_buf; - - hob_buf = malloc (GFW_HOB_SIZE); - if (hob_buf == NULL) { - PERROR("Could not allocate hob"); - return -1; - } - - if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize, vcpus) < 0){ - free (hob_buf); - PERROR("Could not build hob"); - return -1; - } - - if ( load_hob( xc_handle, dom, hob_buf, memsize) < 0){ - free (hob_buf); - PERROR("Could not load hob"); - return -1; - } - free (hob_buf); - return 0; - -} -static int -hob_init( void *buffer ,unsigned long buf_size) -{ - HOB_INFO *phit; - HOB_GENERIC_HEADER *terminal; - - if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){ - // buffer too small - return -1; - } - - phit = (HOB_INFO*)buffer; - phit->header.signature = HOB_SIGNATURE; - phit->header.type = HOB_TYPE_INFO; - phit->header.length = sizeof(HOB_INFO); - phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER); - phit->cur_pos = 0; - phit->buf_size = buf_size; - - terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO)); - terminal->signature= HOB_SIGNATURE; - terminal->type = HOB_TYPE_TERMINAL; - terminal->length = sizeof(HOB_GENERIC_HEADER); - - return 0; -} - -/* - * Add a new HOB to the HOB List. - * - * hob_start - start address of hob buffer - * type - type of the hob to be added - * data - data of the hob to be added - * data_size - size of the data - */ -static int -hob_add( - void* hob_start, - int type, - void* data, - int data_size -) -{ - HOB_INFO *phit; - HOB_GENERIC_HEADER *newhob,*tail; - - phit = (HOB_INFO*)hob_start; - - if (phit->length + data_size > phit->buf_size){ - // no space for new hob - return -1; - } - - //append new HOB - newhob = (HOB_GENERIC_HEADER*) - (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER)); - newhob->signature = HOB_SIGNATURE; - newhob->type = type; - newhob->length = data_size + sizeof(HOB_GENERIC_HEADER); - memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size); - - // append terminal HOB - tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size); - tail->signature = HOB_SIGNATURE; - tail->type = HOB_TYPE_TERMINAL; - tail->length = sizeof(HOB_GENERIC_HEADER); - - // adjust HOB list length - phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size; - - return 0; - -} - -int get_hob_size(void* hob_buf){ - - HOB_INFO *phit = (HOB_INFO*)hob_buf; - - if (phit->header.signature != HOB_SIGNATURE){ - PERROR("xc_get_hob_size:Incorrect signature"); - return -1; - } - return phit->length; -} - -int build_hob (void* hob_buf, unsigned long hob_buf_size, - unsigned long dom_mem_size, unsigned long vcpus) -{ - //Init HOB List - if (hob_init (hob_buf, hob_buf_size)<0){ - PERROR("buffer too small"); - goto err_out; - } - - if ( add_mem_hob( hob_buf,dom_mem_size) < 0){ - PERROR("Add memory hob failed, buffer too small"); - goto err_out; - } - - if ( add_vcpus_hob(hob_buf, vcpus)<0){ - PERROR("Add NR_VCPU hob failed, buffer too small"); - goto err_out; - } - - if ( add_pal_hob( hob_buf ) < 0 ){ - PERROR("Add PAL hob failed, buffer too small"); - goto err_out; - } - - return 0; - -err_out: - return -1; -} - -static int -load_hob(int xc_handle, uint32_t dom, void *hob_buf, - unsigned long dom_mem_size) -{ - // hob_buf should be page aligned - int hob_size; - int nr_pages; - - if ((hob_size = get_hob_size(hob_buf)) < 0){ - PERROR("Invalid hob data"); - return -1; - } - - if (hob_size > GFW_HOB_SIZE){ - PERROR("No enough memory for hob data"); - return -1; - } - - nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; - - return xc_ia64_copy_to_domain_pages(xc_handle, dom, - hob_buf, GFW_HOB_START>>PAGE_SHIFT, nr_pages ); -} - -#define MIN(x, y) ((x) < (y)) ? (x) : (y) -static int -add_mem_hob(void* hob_buf, unsigned long dom_mem_size){ - hob_mem_t memhob; - - // less than 3G - memhob.start = 0; - memhob.size = MIN(dom_mem_size, 0xC0000000); - - if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){ - return -1; - } - - if (dom_mem_size > 0xC0000000) { - // 4G ~ 4G+remain - memhob.start = 0x100000000; //4G - memhob.size = dom_mem_size - 0xC0000000; - if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0) - return -1; - } - return 0; -} - -static int -add_vcpus_hob(void* hob_buf, unsigned long vcpus) -{ - return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus)); -} - -unsigned char config_pal_bus_get_features_data[24] = { - 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_cache_summary[16] = { - 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0}; -unsigned char config_pal_mem_attrib[8] = { - 241, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_cache_info[152] = { - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12, - 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1, - 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0, - 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, - 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255, - 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9, - 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0 -}; -unsigned char config_pal_cache_prot_info[200] = { - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, - 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, - 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, - 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160, - 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0 -}; -unsigned char config_pal_debug_info[16] = { - 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_fixed_addr[8] = { - 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_freq_base[8] = { - 109, 219, 182, 13, 0, 0, 0, 0 -}; -unsigned char config_pal_freq_ratios[24] = { - 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4, - 0, 0, 0, 7, 0, 0, 0 -}; -unsigned char config_pal_halt_info[64] = { - 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_perf_mon_info[136] = { - 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_proc_get_features[104] = { - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, - 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, - 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_ptce_info[24] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_register_info[64] = { - 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, - 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, - 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255 -}; -unsigned char config_pal_rse_info[16] = { - 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_test_info[48] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_vm_summary[16] = { - 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_vm_info[104] = { - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, - 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, - 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0 -}; -unsigned char config_pal_vm_page_size[16] = { - 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0 -}; - -typedef struct{ - hob_type_t type; - void* data; - unsigned long size; -}hob_batch_t; - -hob_batch_t hob_batch[]={ - { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, - &config_pal_bus_get_features_data, - sizeof(config_pal_bus_get_features_data) - }, - { HOB_TYPE_PAL_CACHE_SUMMARY, - &config_pal_cache_summary, - sizeof(config_pal_cache_summary) - }, - { HOB_TYPE_PAL_MEM_ATTRIB, - &config_pal_mem_attrib, - sizeof(config_pal_mem_attrib) - }, - { HOB_TYPE_PAL_CACHE_INFO, - &config_pal_cache_info, - sizeof(config_pal_cache_info) - }, - { HOB_TYPE_PAL_CACHE_PROT_INFO, - &config_pal_cache_prot_info, - sizeof(config_pal_cache_prot_info) - }, - { HOB_TYPE_PAL_DEBUG_INFO, - &config_pal_debug_info, - sizeof(config_pal_debug_info) - }, - { HOB_TYPE_PAL_FIXED_ADDR, - &config_pal_fixed_addr, - sizeof(config_pal_fixed_addr) - }, - { HOB_TYPE_PAL_FREQ_BASE, - &config_pal_freq_base, - sizeof(config_pal_freq_base) - }, - { HOB_TYPE_PAL_FREQ_RATIOS, - &config_pal_freq_ratios, - sizeof(config_pal_freq_ratios) - }, - { HOB_TYPE_PAL_HALT_INFO, - &config_pal_halt_info, - sizeof(config_pal_halt_info) - }, - { HOB_TYPE_PAL_PERF_MON_INFO, - &config_pal_perf_mon_info, - sizeof(config_pal_perf_mon_info) - }, - { HOB_TYPE_PAL_PROC_GET_FEATURES, - &config_pal_proc_get_features, - sizeof(config_pal_proc_get_features) - }, - { HOB_TYPE_PAL_PTCE_INFO, - &config_pal_ptce_info, - sizeof(config_pal_ptce_info) - }, - { HOB_TYPE_PAL_REGISTER_INFO, - &config_pal_register_info, - sizeof(config_pal_register_info) - }, - { HOB_TYPE_PAL_RSE_INFO, - &config_pal_rse_info, - sizeof(config_pal_rse_info) - }, - { HOB_TYPE_PAL_TEST_INFO, - &config_pal_test_info, - sizeof(config_pal_test_info) - }, - { HOB_TYPE_PAL_VM_SUMMARY, - &config_pal_vm_summary, - sizeof(config_pal_vm_summary) - }, - { HOB_TYPE_PAL_VM_INFO, - &config_pal_vm_info, - sizeof(config_pal_vm_info) - }, - { HOB_TYPE_PAL_VM_PAGE_SIZE, - &config_pal_vm_page_size, - sizeof(config_pal_vm_page_size) - }, -}; - -static int add_pal_hob(void* hob_buf){ - int i; - for (i=0; i 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { - PERROR("Guest firmware size is incorrect [%ld]?", image_size); - return -1; - } - - /* This will creates the physmap. */ - op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest; - op.u.domain_setup.domain = (domid_t)dom; - op.u.domain_setup.bp = 0; - op.u.domain_setup.maxmem = 0; - - op.cmd = DOM0_DOMAIN_SETUP; - if ( xc_dom0_op(xc_handle, &op) ) - goto error_out; - - /* Load guest firmware */ - if( xc_ia64_copy_to_domain_pages(xc_handle, dom, image, - (GFW_START+GFW_SIZE-image_size)>>PAGE_SHIFT, image_size>>PAGE_SHIFT)) { - PERROR("Could not load guest firmware into domain"); - goto error_out; - } - - /* Hand-off state passed to guest firmware */ - if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, (unsigned long)vcpus) < 0){ - PERROR("Could not build hob\n"); - goto error_out; - } - - /* Retrieve special pages like io, xenstore, etc. */ - if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, - IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) - { - PERROR("Could not get the page frame list"); - goto error_out; - } - - *store_mfn = page_array[1]; - if ((sp = (shared_iopage_t *) xc_map_foreign_range( - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, - page_array[0])) == 0) - goto error_out; - memset(sp, 0, PAGE_SIZE); - - for (i = 0; i < vcpus; i++) { - uint32_t vp_eport; - - vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0); - if (vp_eport < 0) { - DPRINTF("Couldn't get unbound port from VMX guest.\n"); - goto error_out; - } - sp->vcpu_iodata[i].vp_eport = vp_eport; - } - - munmap(sp, PAGE_SIZE); - - return 0; - - error_out: - return -1; -} - -int xc_hvm_build(int xc_handle, - uint32_t domid, - int memsize, - const char *image_name, - unsigned int vcpus, - unsigned int pae, - unsigned int acpi, - unsigned int apic, - unsigned int store_evtchn, - unsigned long *store_mfn) -{ - dom0_op_t launch_op, op; - int rc ; - vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; - char *image = NULL; - unsigned long image_size; - unsigned long nr_pages; - - if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 ) - { - PERROR("Could not find total pages for domain"); - goto error_out; - } - - if ( (image = xc_read_image(image_name, &image_size)) == NULL ){ - PERROR("Could not read guest firmware image %s",image_name); - goto error_out; - } - - image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK; - - if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){ - PERROR("Unable to mlock ctxt"); - return 1; - } - - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - if ( (do_dom0_op(xc_handle, &op) < 0) || - ((uint16_t)op.u.getdomaininfo.domain != domid) ) { - PERROR("Could not get info on domain"); - goto error_out; - } - - memset(ctxt, 0, sizeof(*ctxt)); - - if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, - image_size, vcpus, store_evtchn, store_mfn ) < 0 ){ - ERROR("Error constructing guest OS"); - goto error_out; - } - - free(image); - - ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL; - - memset( &launch_op, 0, sizeof(launch_op) ); - - launch_op.u.setvcpucontext.domain = (domid_t)domid; - launch_op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt); - - launch_op.cmd = DOM0_SETVCPUCONTEXT; - rc = do_dom0_op(xc_handle, &launch_op); - return rc; - - error_out: - free(image); - return -1; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */