# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID dab0a5650e6df87ce202ef7375ae1e34ad3578ba
# Parent dc26ac2f77180521d9523e917a19d974d2459b89
[IA64] 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 <tristan.gingold@xxxxxxxx>
[whitespace cleanups in new files]
Signed-off-by: Alex Williamson <alex.williamson@xxxxxx>
---
tools/libxc/xc_ia64_stubs.c | 755 -----------------------------------
tools/libxc/Makefile | 5
tools/libxc/ia64/Makefile | 3
tools/libxc/ia64/xc_ia64_hvm_build.c | 673 +++++++++++++++++++++++++++++++
tools/libxc/ia64/xc_ia64_stubs.c | 124 +++++
tools/libxc/xc_private.c | 2
tools/libxc/xenctrl.h | 3
7 files changed, 806 insertions(+), 759 deletions(-)
diff -r dc26ac2f7718 -r dab0a5650e6d tools/libxc/Makefile
--- a/tools/libxc/Makefile Mon Jul 10 14:14:11 2006 -0600
+++ b/tools/libxc/Makefile Tue Jul 11 11:29:25 2006 -0600
@@ -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 dc26ac2f7718 -r dab0a5650e6d tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Mon Jul 10 14:14:11 2006 -0600
+++ b/tools/libxc/xc_private.c Tue Jul 11 11:29:25 2006 -0600
@@ -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 dc26ac2f7718 -r dab0a5650e6d tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon Jul 10 14:14:11 2006 -0600
+++ b/tools/libxc/xenctrl.h Tue Jul 11 11:29:25 2006 -0600
@@ -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 dc26ac2f7718 -r dab0a5650e6d tools/libxc/ia64/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/ia64/Makefile Tue Jul 11 11:29:25 2006 -0600
@@ -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 dc26ac2f7718 -r dab0a5650e6d 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 Tue Jul 11 11:29:25 2006 -0600
@@ -0,0 +1,673 @@
+#include "xg_private.h"
+#include "xenguest.h"
+#include "xc_private.h"
+#include "xc_elf.h"
+#include <stdlib.h>
+#include <zlib.h>
+#include "xen/arch-ia64.h"
+#include <xen/hvm/ioreq.h>
+
+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;
+
+ page_array = malloc(nr_pages * sizeof(xen_pfn_t));
+ if (page_array == 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;
+
+ hob_size = get_hob_size(hob_buf);
+ if (hob_size < 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 < sizeof(hob_batch)/sizeof(hob_batch_t); i++) {
+ if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data,
+ hob_batch[i].size) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
+ char *image, unsigned long image_size, uint32_t vcpus,
+ unsigned int store_evtchn, unsigned long *store_mfn)
+{
+ unsigned long page_array[2];
+ shared_iopage_t *sp;
+ int i;
+ unsigned long dom_memsize = (memsize << 20);
+ DECLARE_DOM0_OP;
+
+ if ((image_size > 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];
+ sp = (shared_iopage_t *)xc_map_foreign_range(xc_handle, dom,
+ PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
+ if (sp == 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;
+
+ nr_pages = xc_get_max_pages(xc_handle, domid);
+ if (nr_pages < 0) {
+ PERROR("Could not find total pages for domain");
+ goto error_out;
+ }
+
+ image = xc_read_image(image_name, &image_size);
+ if (image == 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 dc26ac2f7718 -r dab0a5650e6d 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 Tue Jul 11 11:29:25 2006 -0600
@@ -0,0 +1,124 @@
+#include "xg_private.h"
+#include "xenguest.h"
+#include "xc_private.h"
+#include "xc_elf.h"
+#include <stdlib.h>
+#include <zlib.h>
+#include "xen/arch-ia64.h"
+#include <xen/hvm/ioreq.h>
+
+/* 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 <asm/fpu.h>
+#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 dc26ac2f7718 -r dab0a5650e6d tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c Mon Jul 10 14:14:11 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 <stdlib.h>
-#include <zlib.h>
-#include "xen/arch-ia64.h"
-#include <xen/hvm/ioreq.h>
-
-/* 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 <asm/fpu.h>
-#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<sizeof(hob_batch)/sizeof(hob_batch_t); i++){
- if (hob_add(hob_buf, hob_batch[i].type,
- hob_batch[i].data,
- hob_batch[i].size)<0)
- return -1;
- }
- return 0;
-}
-
-static int setup_guest( int xc_handle,
- uint32_t dom, unsigned long memsize,
- char *image, unsigned long image_size,
- uint32_t vcpus,
- unsigned int store_evtchn,
- unsigned long *store_mfn)
-{
- unsigned long page_array[2];
- shared_iopage_t *sp;
- int i;
- unsigned long dom_memsize = (memsize << 20);
- DECLARE_DOM0_OP;
-
- if ((image_size > 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:
- */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|