WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] ia64: nvram setup., Xen patchbot-unstable <=