[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] ia64: nvram setup.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1179996843 -3600 # Node ID 17f6163ae930c007d13abc1e3dbc06a624fb5a21 # Parent 1e097a48db065457e84647641097b7b55f86d9b1 ia64: nvram setup. From: "Zhang, Xing Z" <xing.z.zhang@xxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/libxc/ia64/xc_ia64_hvm_build.c | 214 +++++++++++++++++++++++++++++++- tools/libxc/xenctrl.h | 9 + tools/python/xen/lowlevel/xc/xc.c | 48 ++++++- tools/python/xen/xend/XendDomainInfo.py | 1 tools/python/xen/xend/image.py | 4 xen/include/public/arch-ia64.h | 5 xen/include/public/hvm/params.h | 5 7 files changed, 275 insertions(+), 11 deletions(-) diff -r 1e097a48db06 -r 17f6163ae930 tools/libxc/ia64/xc_ia64_hvm_build.c --- a/tools/libxc/ia64/xc_ia64_hvm_build.c Thu May 24 09:15:58 2007 +0100 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Thu May 24 09:54:03 2007 +0100 @@ -122,6 +122,7 @@ typedef enum { HOB_TYPE_PAL_VM_INFO, HOB_TYPE_PAL_VM_PAGE_SIZE, HOB_TYPE_NR_VCPU, + HOB_TYPE_NVRAM, HOB_TYPE_MAX } hob_type_t; @@ -129,14 +130,17 @@ static int add_pal_hob(void* hob_buf); 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 add_nvram_hob(void* hob_buf, unsigned long nvram_addr); static int build_hob(void* hob_buf, unsigned long hob_buf_size, - unsigned long dom_mem_size, unsigned long vcpus); + unsigned long dom_mem_size, unsigned long vcpus, + unsigned long nvram_addr); 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) + unsigned long memsize, unsigned long vcpus, + unsigned long nvram_addr) { char *hob_buf; @@ -146,7 +150,7 @@ xc_ia64_build_hob(int xc_handle, uint32_ return -1; } - if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus) < 0) { + if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus, nvram_addr) < 0) { free(hob_buf); PERROR("Could not build hob"); return -1; @@ -244,7 +248,8 @@ get_hob_size(void* hob_buf) static int build_hob(void* hob_buf, unsigned long hob_buf_size, - unsigned long dom_mem_size, unsigned long vcpus) + unsigned long dom_mem_size, unsigned long vcpus, + unsigned long nvram_addr) { //Init HOB List if (hob_init(hob_buf, hob_buf_size) < 0) { @@ -266,6 +271,11 @@ build_hob(void* hob_buf, unsigned long h PERROR("Add PAL hob failed, buffer too small"); goto err_out; } + + if (add_nvram_hob( hob_buf, nvram_addr ) < 0) { + PERROR("Add nvram hob failed, buffer too small"); + goto err_out; + } return 0; @@ -325,6 +335,12 @@ add_vcpus_hob(void* hob_buf, unsigned lo add_vcpus_hob(void* hob_buf, unsigned long vcpus) { return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus)); +} + +static int +add_nvram_hob(void *hob_buf, unsigned long nvram_addr) +{ + return hob_add(hob_buf, HOB_TYPE_NVRAM, &nvram_addr, sizeof(nvram_addr)); } static const unsigned char config_pal_bus_get_features_data[24] = { @@ -551,6 +567,184 @@ add_pal_hob(void* hob_buf) return 0; } +// The most significant bit of nvram file descriptor: +// 1: valid; 0: invalid +#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x) +#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1)) +static uint64_t +nvram_init(const char *nvram_path) +{ + uint64_t fd = 0; + fd = open(nvram_path, O_CREAT|O_RDWR, 0666); + + if ( fd < 0 ) + { + PERROR("Nvram open failed at %s. Guest will boot without" + " nvram support!\n", nvram_path); + return -1; + } + + return VALIDATE_NVRAM_FD(fd); +} + +static int +copy_from_nvram_to_GFW(int xc_handle, uint32_t dom, int nvram_fd) +{ + unsigned int nr_pages = NVRAM_SIZE >> PAGE_SHIFT; + struct stat file_stat; + char buf[NVRAM_SIZE] = {0}; + + if ( fstat(nvram_fd, &file_stat) < 0 ) + { + PERROR("Cannot get Nvram file info! Guest will boot without " + "nvram support!\n"); + return -1; + } + + if ( 0 == file_stat.st_size ) + { + DPRINTF("Nvram file create successful!\n"); + return 0; + } + + if ( read(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE ) + { + PERROR("Load nvram fail. guest will boot without" + " nvram support!\n"); + return -1; + } + + return xc_ia64_copy_to_domain_pages(xc_handle, dom, buf, + NVRAM_START >> PAGE_SHIFT, + nr_pages); +} + + +/* + * GFW use 4k page. when doing foreign map, we should 16k align + * the address and map one more page to guarantee all 64k nvram data + * can be got. + */ +static int +copy_from_GFW_to_nvram(int xc_handle, uint32_t dom, int nvram_fd) +{ + xen_pfn_t *pfn_list = NULL; + char *tmp_ptr = NULL; + unsigned int nr_pages = 0; + uint64_t addr_from_GFW_4k_align = 0; + uint32_t offset = 0; + uint64_t nvram_base_addr = 0; + char buf[NVRAM_SIZE] = {0}; + int i; + + + // map one more page + nr_pages = (NVRAM_SIZE + PAGE_SIZE) >> PAGE_SHIFT; + pfn_list = (xen_pfn_t *)malloc(sizeof(xen_pfn_t) * nr_pages); + if ( NULL == pfn_list ) + { + PERROR("Cannot allocate memory for nvram save!\n"); + close(nvram_fd); + return -1; + } + + /* + * GFW allocate memory dynamicly to save nvram data + * and save address of the dynamic memory at NVRAM_START. + * To save nvram data to file, we must get the dynamic + * memory address first. + */ + pfn_list[0] = NVRAM_START >> PAGE_SHIFT; + tmp_ptr = (char *)xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, pfn_list[0]); + + if ( NULL == tmp_ptr ) + { + PERROR("Cannot get nvram data from GFW!\n"); + free(pfn_list); + close(nvram_fd); + return -1; + } + + addr_from_GFW_4k_align = *((uint64_t *)tmp_ptr); + munmap(tmp_ptr, PAGE_SIZE); + + // align address to 16k + offset = addr_from_GFW_4k_align % ( 16 * MEM_K ); + addr_from_GFW_4k_align = addr_from_GFW_4k_align - offset; + for ( i=0; i<nr_pages; i++ ) + pfn_list[i] = (addr_from_GFW_4k_align >> PAGE_SHIFT) + i; + + tmp_ptr = (char *)xc_map_foreign_batch(xc_handle, dom, + PROT_READ | PROT_WRITE, pfn_list, nr_pages); + if ( NULL == tmp_ptr ) + { + PERROR("Cannot get nvram data from GFW!\n"); + free(pfn_list); + close(nvram_fd); + return -1; + } + + // calculate nvram data base addrees + nvram_base_addr = (uint64_t)(tmp_ptr + offset); + + memcpy(buf, (void *)nvram_base_addr, NVRAM_SIZE); + free(pfn_list); + munmap(tmp_ptr, NVRAM_SIZE + PAGE_SIZE); + + lseek(nvram_fd, 0, SEEK_SET); + if ( write(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE ) + { + PERROR("Save to nvram fail!\n"); + return -1; + } + + close(nvram_fd); + + DPRINTF("Nvram save successful!\n"); + + return 0; +} + +int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom) +{ + uint64_t nvram_fd = 0; + xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd); + + if ( !IS_VALID_NVRAM_FD(nvram_fd) ) + { + PERROR("Nvram not be initialized. Nvram save fail!\n"); + return -1; + } + return copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd); +} + +#define NVRAM_FILE_PATH "/usr/lib/xen/boot/nvram_" +int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom) +{ + int file_path_len = strlen(NVRAM_FILE_PATH); + uint64_t nvram_fd = 0; + char nvram_path[100] = {0}; + + strncpy(nvram_path, NVRAM_FILE_PATH, file_path_len); + if ( file_path_len + strlen(dom_name) + 1 > sizeof(nvram_path) ) + { + PERROR("Nvram file path is too long!\n"); + return -1; + } + strcpy(nvram_path + file_path_len, dom_name); + + nvram_fd = nvram_init(nvram_path); + if ( nvram_fd == (uint64_t)(-1) ) + { + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, 0); + return -1; + } + + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, nvram_fd); + return 0; +} + #define GFW_PAGES (GFW_SIZE >> PAGE_SHIFT) #define VGA_START_PAGE (VGA_IO_START >> PAGE_SHIFT) #define VGA_END_PAGE ((VGA_IO_START + VGA_IO_SIZE) >> PAGE_SHIFT) @@ -573,6 +767,7 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long dom_memsize = memsize << 20; unsigned long nr_pages = memsize << (20 - PAGE_SHIFT); unsigned long vcpus; + unsigned long nvram_start = NVRAM_START, nvram_fd = 0; int rc; long i; DECLARE_DOMCTL; @@ -627,7 +822,7 @@ setup_guest(int xc_handle, uint32_t dom, goto error_out; } - pfn_list[0] = IO_PAGE_START >> PAGE_SHIFT; + pfn_list[0] = IO_PAGE_START >> PAGE_SHIFT; pfn_list[1] = STORE_PAGE_START >> PAGE_SHIFT; pfn_list[2] = BUFFER_IO_PAGE_START >> PAGE_SHIFT; pfn_list[3] = BUFFER_PIO_PAGE_START >> PAGE_SHIFT; @@ -662,10 +857,17 @@ setup_guest(int xc_handle, uint32_t dom, goto error_out; } + xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd); + if ( !IS_VALID_NVRAM_FD(nvram_fd) ) + nvram_start = 0; + else + if ( copy_from_nvram_to_GFW(xc_handle, dom, (int)nvram_fd ) == -1 ) + nvram_start = 0; + vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1; // Hand-off state passed to guest firmware - if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus) < 0) { + if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus, nvram_start) < 0) { PERROR("Could not build hob\n"); goto error_out; } diff -r 1e097a48db06 -r 17f6163ae930 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu May 24 09:15:58 2007 +0100 +++ b/tools/libxc/xenctrl.h Thu May 24 09:54:03 2007 +0100 @@ -847,4 +847,11 @@ int xc_alloc_real_mode_area(int xc_handl int xc_alloc_real_mode_area(int xc_handle, uint32_t domid, unsigned int log); -#endif + +/* IA64 specific, nvram save */ +int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom); + +/* IA64 specific, nvram init */ +int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom); + +#endif /* XENCTRL_H */ diff -r 1e097a48db06 -r 17f6163ae930 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu May 24 09:15:58 2007 +0100 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu May 24 09:54:03 2007 +0100 @@ -54,9 +54,9 @@ static PyObject *pyxc_error_to_exception return PyErr_SetFromErrno(xc_error_obj); if ( err->message[0] != '\0' ) - pyerr = Py_BuildValue("(iss)", err->code, desc, err->message); + pyerr = Py_BuildValue("(iss)", err->code, desc, err->message); else - pyerr = Py_BuildValue("(is)", err->code, desc); + pyerr = Py_BuildValue("(is)", err->code, desc); xc_clear_last_error(); @@ -161,6 +161,16 @@ static PyObject *pyxc_domain_unpause(XcO static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args) { return dom_op(self, args, xc_domain_unpause); +} + +static PyObject *pyxc_domain_destroy_hook(XcObject *self, PyObject *args) +{ +#ifdef __ia64__ + dom_op(self, args, xc_ia64_save_to_nvram); +#endif + + Py_INCREF(zero); + return zero; } static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args) @@ -426,7 +436,7 @@ static PyObject *pyxc_linux_build(XcObje xc_dom_loginit(); if (!(dom = xc_dom_allocate(cmdline, features))) - return pyxc_error_to_exception(); + return pyxc_error_to_exception(); if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image, ramdisk, flags, store_evtchn, &store_mfn, @@ -497,6 +507,23 @@ static PyObject *pyxc_get_hvm_param(XcOb return Py_BuildValue("i", value); } + +#ifdef __ia64__ +static PyObject *pyxc_nvram_init(XcObject *self, + PyObject *args) +{ + char *dom_name; + uint32_t dom; + + if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) ) + return NULL; + + xc_ia64_nvram_init(self->xc_handle, dom_name, dom); + + Py_INCREF(zero); + return zero; +} +#endif /* __ia64__ */ static PyObject *pyxc_hvm_build(XcObject *self, PyObject *args, @@ -1153,6 +1180,13 @@ static PyMethodDef pyxc_methods[] = { (PyCFunction)pyxc_domain_destroy, METH_VARARGS, "\n" "Destroy a domain.\n" + " dom [int]: Identifier of domain to be destroyed.\n\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_destroy_hook", + (PyCFunction)pyxc_domain_destroy_hook, + METH_VARARGS, "\n" + "Add a hook for arch stuff before destroy a domain.\n" " dom [int]: Identifier of domain to be destroyed.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, @@ -1397,7 +1431,13 @@ static PyMethodDef pyxc_methods[] = { " dom [int]: Identifier of domain.\n" " mem_kb [long]: .\n" "Returns: [int] 0 on success; -1 on error.\n" }, - +#ifdef __ia64__ + { "nvram_init", + (PyCFunction)pyxc_nvram_init, + METH_VARARGS, "\n" + "Init nvram in IA64 platform\n" + "Returns: [int] 0 on success; -1 on error.\n" }, +#endif /* __ia64__ */ { "domain_ioport_permission", (PyCFunction)pyxc_domain_ioport_permission, METH_VARARGS | METH_KEYWORDS, "\n" diff -r 1e097a48db06 -r 17f6163ae930 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu May 24 09:15:58 2007 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu May 24 09:54:03 2007 +0100 @@ -1666,6 +1666,7 @@ class XendDomainInfo: self._cleanupVm() if self.dompath is not None: + xc.domain_destroy_hook(self.domid) self.destroyDomain() self._cleanup_phantom_devs(paths) diff -r 1e097a48db06 -r 17f6163ae930 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Thu May 24 09:15:58 2007 +0100 +++ b/tools/python/xen/xend/image.py Thu May 24 09:54:03 2007 +0100 @@ -469,6 +469,10 @@ class HVMImageHandler(ImageHandler): class IA64_HVM_ImageHandler(HVMImageHandler): + def buildDomain(self): + xc.nvram_init(self.vm.getName(), self.vm.getDomid()) + return HVMImageHandler.buildDomain(self) + def getRequiredAvailableMemory(self, mem_kb): page_kb = 16 # ROM size for guest firmware, ioreq page, pio page and xenstore page diff -r 1e097a48db06 -r 17f6163ae930 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Thu May 24 09:15:58 2007 +0100 +++ b/xen/include/public/arch-ia64.h Thu May 24 09:54:03 2007 +0100 @@ -77,6 +77,7 @@ typedef unsigned long xen_ulong_t; #define MEM_G (1UL << 30) #define MEM_M (1UL << 20) +#define MEM_K (1UL << 10) #define MMIO_START (3 * MEM_G) #define MMIO_SIZE (512 * MEM_M) @@ -107,6 +108,10 @@ typedef unsigned long xen_ulong_t; #define GFW_START (4*MEM_G -16*MEM_M) #define GFW_SIZE (16*MEM_M) + +/* Nvram belongs to GFW memory space */ +#define NVRAM_SIZE (MEM_K * 64) +#define NVRAM_START (GFW_START + 10 * MEM_M) struct pt_fpreg { union { diff -r 1e097a48db06 -r 17f6163ae930 xen/include/public/hvm/params.h --- a/xen/include/public/hvm/params.h Thu May 24 09:15:58 2007 +0100 +++ b/xen/include/public/hvm/params.h Thu May 24 09:54:03 2007 +0100 @@ -50,6 +50,11 @@ #define HVM_PARAM_BUFIOREQ_PFN 6 +#ifdef __ia64__ +#define HVM_PARAM_NVRAM_FD 7 +#define HVM_NR_PARAMS 8 +#else #define HVM_NR_PARAMS 7 +#endif #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |