public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Kvm: Qemu: save nvram
@ 2008-12-02  2:25 Zhang, Yang
  2008-12-02  5:27 ` Zhang, Yang
  2008-12-02 10:31 ` Daniel P. Berrange
  0 siblings, 2 replies; 14+ messages in thread
From: Zhang, Yang @ 2008-12-02  2:25 UTC (permalink / raw)
  To: kvm-ia64@vger.kernel.org
  Cc: kvm@vger.kernel.org, avi@readhat.com, Zhang, Xiantao

[-- Attachment #1: Type: text/plain, Size: 8909 bytes --]

This patch to save the nvram. It save the nvram by specify the arg of -name.And the saved file named by the arg. If do not specify the arg,it will not save the nvram

>From d3e31cda03ef67efc860eaec2f93153e5535d744 Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 10:02:00 +0800
Subject: [PATCH] Kvm: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   15 ++++++-
 qemu/target-ia64/firmware.c |  107 +++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 ++++++++-
 3 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..cdbd4e0 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;
 
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,12 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;        
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +476,16 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            if((nvram_fd = kvm_ia64_nvram_init()) != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd,g_fw_start);
+                close(nvram_fd);
+            }
+            atexit(kvm_ia64_copy_from_GFW_to_nvram);
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..39c8361 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+#include "sysemu.h"
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start,unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,7 @@ add_max_hob_entry(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) {
@@ -229,6 +233,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +294,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +596,88 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+    char  name[21] ;
+
+    if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+    {
+        if(errno != ENOENT)
+        {
+            goto out;
+        }
+        if(mkdir(nvram_path, 0755) == -1)
+        {
+            goto out;
+        }
+        else
+        {
+            if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+            {    
+                errno = EACCES;
+                goto out;
+            }
+        }
+    }
+    if(strlen(qemu_name) > PATH_MAX)
+    {
+        goto out;
+    }
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".data");
+    if((nvram_fd = open(nvram_path,O_CREAT|O_RDWR,0644)) < 0)
+    {
+        goto out;
+    }
+    if(VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1))
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start)
+{
+    struct stat file_stat;
+    if (( fstat(nvram_fd, &file_stat) < 0 )||( NVRAM_SIZE  != file_stat.st_size)
+        ||(read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE ))
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long * nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    if((nvram_fd = kvm_ia64_nvram_init()) == -1)
+        goto out;
+    if(((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG)
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if(write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr + 
+                        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE )
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..71aef2a 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start; 
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                       uint8_t* fw_start,unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
-- 
1.6.0.rc1


[-- Attachment #2: 0001-Kvm-Qemu-save-nvram.patch --]
[-- Type: application/octet-stream, Size: 8479 bytes --]

From d3e31cda03ef67efc860eaec2f93153e5535d744 Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 10:02:00 +0800
Subject: [PATCH] Kvm: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   15 ++++++-
 qemu/target-ia64/firmware.c |  107 +++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 ++++++++-
 3 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..cdbd4e0 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;
 
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,12 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;        
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +476,16 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            if((nvram_fd = kvm_ia64_nvram_init()) != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd,g_fw_start);
+                close(nvram_fd);
+            }
+            atexit(kvm_ia64_copy_from_GFW_to_nvram);
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..39c8361 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+#include "sysemu.h"
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start,unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,7 @@ add_max_hob_entry(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) {
@@ -229,6 +233,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +294,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +596,88 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+    char  name[21] ;
+
+    if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+    {
+        if(errno != ENOENT)
+        {
+            goto out;
+        }
+        if(mkdir(nvram_path, 0755) == -1)
+        {
+            goto out;
+        }
+        else
+        {
+            if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+            {    
+                errno = EACCES;
+                goto out;
+            }
+        }
+    }
+    if(strlen(qemu_name) > PATH_MAX)
+    {
+        goto out;
+    }
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".data");
+    if((nvram_fd = open(nvram_path,O_CREAT|O_RDWR,0644)) < 0)
+    {
+        goto out;
+    }
+    if(VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1))
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start)
+{
+    struct stat file_stat;
+    if (( fstat(nvram_fd, &file_stat) < 0 )||( NVRAM_SIZE  != file_stat.st_size)
+        ||(read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE ))
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long * nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    if((nvram_fd = kvm_ia64_nvram_init()) == -1)
+        goto out;
+    if(((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG)
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if(write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr + 
+                        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE )
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..71aef2a 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start; 
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                       uint8_t* fw_start,unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
-- 
1.6.0.rc1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-02  2:25 [PATCH] Kvm: Qemu: save nvram Zhang, Yang
@ 2008-12-02  5:27 ` Zhang, Yang
  2008-12-02 10:31 ` Daniel P. Berrange
  1 sibling, 0 replies; 14+ messages in thread
From: Zhang, Yang @ 2008-12-02  5:27 UTC (permalink / raw)
  To: Zhang, Yang, kvm-ia64@vger.kernel.org
  Cc: kvm@vger.kernel.org, avi@redhat.com, Zhang, Xiantao

[-- Attachment #1: Type: text/plain, Size: 18027 bytes --]

Hi:
Please drop the previous one.

From 2fd0c2746a2d07813ad16700ee31c7f6ae78c40a Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 13:05:55 +0800
Subject: [PATCH] KVM: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   19 ++++++++-
 qemu/target-ia64/firmware.c |   94 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 +++++++++-
 3 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..2300ba9 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;

 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;

+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +477,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            nvram_fd = kvm_ia64_nvram_init();
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }

     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..6729cb5 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,9 @@

 #include "firmware.h"

+#include "qemu-common.h"
+#include "sysemu.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +88,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);

 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;

@@ -102,7 +107,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +211,8 @@ add_max_hob_entry(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) {
@@ -229,6 +235,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }

+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+           Hob_Output("Add nvram hob failed, buffer too small");
+           goto err_out;
+       }
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +296,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,73 @@ out_1:
     return NULL;
 }

+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+
+    if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+        if (errno != ENOENT)
+            goto out;
+        if (mkdir(nvram_path, 0755) == -1)
+            goto out;
+        else
+            if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+                errno = EACCES;
+                goto out;
+            }
+    }
+    if (strlen(qemu_name) > PATH_MAX)
+        goto out;
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".dat");
+    nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0644);
+    if (nvram_fd < 0)
+        goto out;
+    if (VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1)) {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init();
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..d632599 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)

-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t* fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);

+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
--
1.6.0.rc1

-----Original Message-----
From: kvm-ia64-owner@vger.kernel.org [mailto:kvm-ia64-owner@vger.kernel.org] On Behalf Of Zhang, Yang
Sent: 2008年12月2日 10:26
To: kvm-ia64@vger.kernel.org
Cc: kvm@vger.kernel.org; avi@readhat.com; Zhang, Xiantao
Subject: [PATCH] Kvm: Qemu: save nvram

This patch to save the nvram. It save the nvram by specify the arg of -name.And the saved file named by the arg. If do not specify the arg,it will not save the nvram

From d3e31cda03ef67efc860eaec2f93153e5535d744 Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 10:02:00 +0800
Subject: [PATCH] Kvm: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   15 ++++++-
 qemu/target-ia64/firmware.c |  107 +++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 ++++++++-
 3 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..cdbd4e0 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;

 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,12 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;

+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +476,16 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            if((nvram_fd = kvm_ia64_nvram_init()) != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd,g_fw_start);
+                close(nvram_fd);
+            }
+            atexit(kvm_ia64_copy_from_GFW_to_nvram);
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }

     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..39c8361 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@

 #include "firmware.h"

+#include "qemu-common.h"
+#include "sysemu.h"
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);

 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start,unsigned long nvram_addr)
 {
     char   *hob_buf;

@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,7 @@ add_max_hob_entry(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) {
@@ -229,6 +233,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }

+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+           Hob_Output("Add nvram hob failed, buffer too small");
+           goto err_out;
+       }
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +294,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +596,88 @@ out_1:
     return NULL;
 }

+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+    char  name[21] ;
+
+    if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+    {
+        if(errno != ENOENT)
+        {
+            goto out;
+        }
+        if(mkdir(nvram_path, 0755) == -1)
+        {
+            goto out;
+        }
+        else
+        {
+            if(access(nvram_path, R_OK|W_OK|X_OK) == -1)
+            {
+                errno = EACCES;
+                goto out;
+            }
+        }
+    }
+    if(strlen(qemu_name) > PATH_MAX)
+    {
+        goto out;
+    }
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".data");
+    if((nvram_fd = open(nvram_path,O_CREAT|O_RDWR,0644)) < 0)
+    {
+        goto out;
+    }
+    if(VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1))
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start)
+{
+    struct stat file_stat;
+    if (( fstat(nvram_fd, &file_stat) < 0 )||( NVRAM_SIZE  != file_stat.st_size)
+        ||(read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE ))
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long * nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    if((nvram_fd = kvm_ia64_nvram_init()) == -1)
+        goto out;
+    if(((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG)
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if(write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+                        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE )
+    {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..71aef2a 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)

-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                       uint8_t* fw_start,unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);

+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,const uint8_t * fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
--
1.6.0.rc1


[-- Attachment #2: 0001-KVM-Qemu-save-nvram.patch --]
[-- Type: application/octet-stream, Size: 8521 bytes --]

From 2fd0c2746a2d07813ad16700ee31c7f6ae78c40a Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 13:05:55 +0800
Subject: [PATCH] KVM: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   19 ++++++++-
 qemu/target-ia64/firmware.c |   94 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 +++++++++-
 3 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..2300ba9 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;
 
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +477,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            nvram_fd = kvm_ia64_nvram_init();
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..6729cb5 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,9 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+#include "sysemu.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +88,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +107,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +211,8 @@ add_max_hob_entry(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) {
@@ -229,6 +235,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +296,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,73 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+
+    if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+        if (errno != ENOENT)
+            goto out;
+        if (mkdir(nvram_path, 0755) == -1)
+            goto out;
+        else
+            if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+                errno = EACCES;
+                goto out;
+            }
+    }    
+    if (strlen(qemu_name) > PATH_MAX)
+        goto out;
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".dat");
+    nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0644);
+    if (nvram_fd < 0)
+        goto out;
+    if (VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1)) {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init();
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr + 
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..d632599 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t* fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
-- 
1.6.0.rc1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kvm: Qemu: save nvram
  2008-12-02  2:25 [PATCH] Kvm: Qemu: save nvram Zhang, Yang
  2008-12-02  5:27 ` Zhang, Yang
@ 2008-12-02 10:31 ` Daniel P. Berrange
  2008-12-02 13:01   ` Avi Kivity
  1 sibling, 1 reply; 14+ messages in thread
From: Daniel P. Berrange @ 2008-12-02 10:31 UTC (permalink / raw)
  To: Zhang, Yang
  Cc: kvm-ia64@vger.kernel.org, kvm@vger.kernel.org, avi@readhat.com,
	Zhang, Xiantao

On Tue, Dec 02, 2008 at 10:25:49AM +0800, Zhang, Yang wrote:
> This patch to save the nvram. It save the nvram by specify the arg of 
> -name.And the saved file named by the arg. If do not specify the arg,
> it will not save the nvram

I think we might be better off having an explicit command line arg for nvram
path rather than hardcoding the directory, because there may well be times
where you want to have nvram saved, but don't want to specify -name, and
vica-verca. 

  -nvram foo.data

could prepend a default directory of $localstatedir/lib/qemu/nvram, where
$localstatedir  is set from 'configure' script, or

  -nvram /some/path/foo.data

would use the explicit path given.

> diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
> index 553a9f9..71aef2a 100644
> --- a/qemu/target-ia64/firmware.h
> +++ b/qemu/target-ia64/firmware.h
> @@ -34,11 +34,27 @@

[..snip...]

> +#define NVRAM_DIR "/usr/local/share/qemu/nvram/"

This is definitely wrong. You cannot assume /usr/local as the install
prefix, and using '$prefix/share' violates the FHS. '$prefix/share' is
for readonly data that can be shared across machines, not variable runtime
state data. I'd expect it to be in $localstatedir/lib/qemu/nvram, which
would normally default to $prefix/var/lib/qemu/nvram, but for distro package
builds typically be overridden to /var/lib/qemu/nvram. 

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kvm: Qemu: save nvram
  2008-12-02 10:31 ` Daniel P. Berrange
@ 2008-12-02 13:01   ` Avi Kivity
  2008-12-02 13:10     ` Daniel P. Berrange
  0 siblings, 1 reply; 14+ messages in thread
From: Avi Kivity @ 2008-12-02 13:01 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Zhang, Yang, kvm-ia64@vger.kernel.org, kvm@vger.kernel.org,
	avi@readhat.com, Zhang, Xiantao

Daniel P. Berrange wrote:
> On Tue, Dec 02, 2008 at 10:25:49AM +0800, Zhang, Yang wrote:
>   
>> This patch to save the nvram. It save the nvram by specify the arg of 
>> -name.And the saved file named by the arg. If do not specify the arg,
>> it will not save the nvram
>>     
>
> I think we might be better off having an explicit command line arg for nvram
> path rather than hardcoding the directory, because there may well be times
> where you want to have nvram saved, but don't want to specify -name, and
> vica-verca. 
>
>   -nvram foo.data
>
> could prepend a default directory of $localstatedir/lib/qemu/nvram, where
> $localstatedir  is set from 'configure' script, or
>
>   -nvram /some/path/foo.data
>
> would use the explicit path given.
>   

I prefer current directory if relative path is given.  Since we 
encourage running qemu as an unprivileged user, and we don't want a 
world-writable directory, each user will have to provide a private 
storage location.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kvm: Qemu: save nvram
  2008-12-02 13:01   ` Avi Kivity
@ 2008-12-02 13:10     ` Daniel P. Berrange
  2008-12-03  6:02       ` Zhang, Xiantao
  0 siblings, 1 reply; 14+ messages in thread
From: Daniel P. Berrange @ 2008-12-02 13:10 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Zhang, Yang, kvm-ia64@vger.kernel.org, kvm@vger.kernel.org,
	avi@readhat.com, Zhang, Xiantao

On Tue, Dec 02, 2008 at 03:01:20PM +0200, Avi Kivity wrote:
> Daniel P. Berrange wrote:
> >On Tue, Dec 02, 2008 at 10:25:49AM +0800, Zhang, Yang wrote:
> >  
> >>This patch to save the nvram. It save the nvram by specify the arg of 
> >>-name.And the saved file named by the arg. If do not specify the arg,
> >>it will not save the nvram
> >>    
> >
> >I think we might be better off having an explicit command line arg for 
> >nvram
> >path rather than hardcoding the directory, because there may well be times
> >where you want to have nvram saved, but don't want to specify -name, and
> >vica-verca. 
> >
> >  -nvram foo.data
> >
> >could prepend a default directory of $localstatedir/lib/qemu/nvram, where
> >$localstatedir  is set from 'configure' script, or
> >
> >  -nvram /some/path/foo.data
> >
> >would use the explicit path given.
> >  
> 
> I prefer current directory if relative path is given.  Since we 
> encourage running qemu as an unprivileged user, and we don't want a 
> world-writable directory, each user will have to provide a private 
> storage location.

Fine by me - avoids needing to embed any path in QEMU code at all then

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-02 13:10     ` Daniel P. Berrange
@ 2008-12-03  6:02       ` Zhang, Xiantao
  2008-12-03  6:12         ` Zhang, Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Xiantao @ 2008-12-03  6:02 UTC (permalink / raw)
  To: Daniel P. Berrange, Avi Kivity
  Cc: Zhang, Yang, kvm-ia64@vger.kernel.org, kvm@vger.kernel.org

Daniel P. Berrange wrote:
> On Tue, Dec 02, 2008 at 03:01:20PM +0200, Avi Kivity wrote:
>> Daniel P. Berrange wrote:
>>> On Tue, Dec 02, 2008 at 10:25:49AM +0800, Zhang, Yang wrote:
>>> 
>>>> This patch to save the nvram. It save the nvram by specify the arg
>>>> of -name.And the saved file named by the arg. If do not specify
>>>> the arg, it will not save the nvram 
>>>> 
>>> 
>>> I think we might be better off having an explicit command line arg
>>> for nvram path rather than hardcoding the directory, because there
>>> may well be times where you want to have nvram saved, but don't
>>> want to specify -name, and vica-verca. 
>>> 
>>>  -nvram foo.data

If acceptable for upstream, it should be the best choice.  

>>> could prepend a default directory of $localstatedir/lib/qemu/nvram,
>>> where $localstatedir  is set from 'configure' script, or
>>> 
>>>  -nvram /some/path/foo.data
>>> 
>>> would use the explicit path given.
>>> 
>> 
>> I prefer current directory if relative path is given.  Since we
>> encourage running qemu as an unprivileged user, and we don't want a
>> world-writable directory, each user will have to provide a private
>> storage location.
> 
> Fine by me - avoids needing to embed any path in QEMU code at all then

So we don't need a default path ? 
Yang, could you address Daniel and Avi's comments in next version ? 

Xiantao


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-03  6:02       ` Zhang, Xiantao
@ 2008-12-03  6:12         ` Zhang, Yang
  2008-12-16  9:21           ` Zhang, Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Yang @ 2008-12-03  6:12 UTC (permalink / raw)
  To: Zhang, Xiantao, Daniel P. Berrange, Avi Kivity
  Cc: kvm-ia64@vger.kernel.org, kvm@vger.kernel.org

Ok, I will save it in current directory and don't read nvram from file, if don't specify -nvram.

Best Regards
--yang
-----Original Message-----
From: Zhang, Xiantao 
Sent: 2008年12月3日 14:02
To: Daniel P. Berrange; Avi Kivity
Cc: Zhang, Yang; kvm-ia64@vger.kernel.org; kvm@vger.kernel.org
Subject: RE: [PATCH] Kvm: Qemu: save nvram

Daniel P. Berrange wrote:
> On Tue, Dec 02, 2008 at 03:01:20PM +0200, Avi Kivity wrote:
>> Daniel P. Berrange wrote:
>>> On Tue, Dec 02, 2008 at 10:25:49AM +0800, Zhang, Yang wrote:
>>> 
>>>> This patch to save the nvram. It save the nvram by specify the arg
>>>> of -name.And the saved file named by the arg. If do not specify
>>>> the arg, it will not save the nvram 
>>>> 
>>> 
>>> I think we might be better off having an explicit command line arg
>>> for nvram path rather than hardcoding the directory, because there
>>> may well be times where you want to have nvram saved, but don't
>>> want to specify -name, and vica-verca. 
>>> 
>>>  -nvram foo.data

If acceptable for upstream, it should be the best choice.  

>>> could prepend a default directory of $localstatedir/lib/qemu/nvram,
>>> where $localstatedir  is set from 'configure' script, or
>>> 
>>>  -nvram /some/path/foo.data
>>> 
>>> would use the explicit path given.
>>> 
>> 
>> I prefer current directory if relative path is given.  Since we
>> encourage running qemu as an unprivileged user, and we don't want a
>> world-writable directory, each user will have to provide a private
>> storage location.
> 
> Fine by me - avoids needing to embed any path in QEMU code at all then

So we don't need a default path ? 
Yang, could you address Daniel and Avi's comments in next version ? 

Xiantao


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-03  6:12         ` Zhang, Yang
@ 2008-12-16  9:21           ` Zhang, Yang
  2008-12-17 18:39             ` Charles Duffy
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Yang @ 2008-12-16  9:21 UTC (permalink / raw)
  To: kvm-ia64@vger.kernel.org; +Cc: kvm@vger.kernel.org, Zhang, Xiantao, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 11422 bytes --]

Hi
Please drop former. 
This is the modify patch for save nvram.
I add the new command line arg of "-nvram file" to specify the location 
Of the file. Without the arg ,it will save the nvram in the current dir 
and named as "nvram.dat". Also, it will read the saved file "nvram.dat" 
from current dir without the arg.

>From 902ac71c035a641ac0c9e0a0859d8198dfbe3319 Mon Sep 17 00:00:00 2001
From: Zhang Yang <yang.zhang@intel.com>
Date: Mon, 15 Dec 2008 23:56:12 +0800
Subject: [PATCH] KVM : Qemu: Save nvram

Save nvram to the file

Signed-off-by: Zhang Yang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   20 +++++++-
 qemu/target-ia64/firmware.c |  110 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   24 +++++++++-
 qemu/vl.c                   |    9 ++++
 4 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 3e24c98..ba3f0b4 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -53,6 +53,7 @@ static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
 
+uint8_t *g_fw_start;
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
     return (uint32_t)(((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3));
@@ -454,9 +455,14 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long type = READ_FROM_NVRAM;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +478,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        
+        nvram_addr = NVRAM_START;
+        nvram_fd = kvm_ia64_nvram_init(type);
+        if (nvram_fd != -1) {
+            kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+            close(nvram_fd);
+        }
+        i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+        if (i != 0)
+            fprintf(stderr, "cannot set exit function\n");
+        
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus,
+                           fw_start, nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..88fcaa8 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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 nvram_addr);
 static int load_hob(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t *fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,8 @@ add_max_hob_entry(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) {
@@ -229,6 +234,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +295,13 @@ 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_NR_NVRAM,
+                   &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,87 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init(unsigned long type)
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX];
+    unsigned long i;
+
+    if (nvram) {
+        if (strlen(nvram) > PATH_MAX) {
+            goto out;
+        }
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+    else {
+        strcpy(nvram_path, "nvram.dat");
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram_path, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram_path, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long type = WRITE_TO_NVRAM;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init(type);
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..47aaa1d 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -37,8 +37,28 @@
 
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE   (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+#define READ_FROM_NVRAM 0
+#define WRITE_TO_NVRAM 1
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern const char *nvram;
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t *fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_copy_from_GFW_to_nvram();
+extern int kvm_ia64_nvram_init(unsigned long type);
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                           const uint8_t *fw_start);
 #endif //__FIRM_WARE_
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605..fe29ecd 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -255,6 +255,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
+const char *nvram = NULL;
 struct drive_opt drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
@@ -3991,6 +3992,9 @@ static void help(int exitcode)
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
+#ifdef TARGET_IA64
+           "-nvram file     use 'file' to save or load nvram image\n"
+#endif
            "-name string    set the name of the guest\n"
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
            "\n"
@@ -4215,6 +4219,7 @@ enum {
     QEMU_OPTION_semihosting,
     QEMU_OPTION_cpu_vendor,
     QEMU_OPTION_name,
+    QEMU_OPTION_nvram,
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
@@ -4345,6 +4350,7 @@ static const QEMUOption qemu_options[] = {
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
     { "kvm-shadow-memory", HAS_ARG, QEMU_OPTION_kvm_shadow_memory },
     { "name", HAS_ARG, QEMU_OPTION_name },
+    { "nvram", HAS_ARG, QEMU_OPTION_nvram },
 #if defined(TARGET_SPARC)
     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
 #endif
@@ -5418,6 +5424,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_incoming:
                 incoming = optarg;
                 break;
+            case QEMU_OPTION_nvram:
+                nvram = optarg;
+                break;
             }
         }
     }
-- 
1.6.0.rc1


[-- Attachment #2: 0001-KVM-Qemu-Save-nvram.patch --]
[-- Type: application/octet-stream, Size: 10778 bytes --]

From 902ac71c035a641ac0c9e0a0859d8198dfbe3319 Mon Sep 17 00:00:00 2001
From: Zhang Yang <yang.zhang@intel.com>
Date: Mon, 15 Dec 2008 23:56:12 +0800
Subject: [PATCH] KVM : Qemu: Save nvram

Save nvram to the file

Signed-off-by: Zhang Yang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   20 +++++++-
 qemu/target-ia64/firmware.c |  110 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   24 +++++++++-
 qemu/vl.c                   |    9 ++++
 4 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 3e24c98..ba3f0b4 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -53,6 +53,7 @@ static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
 
+uint8_t *g_fw_start;
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
     return (uint32_t)(((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3));
@@ -454,9 +455,14 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long type = READ_FROM_NVRAM;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +478,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        
+        nvram_addr = NVRAM_START;
+        nvram_fd = kvm_ia64_nvram_init(type);
+        if (nvram_fd != -1) {
+            kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+            close(nvram_fd);
+        }
+        i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+        if (i != 0)
+            fprintf(stderr, "cannot set exit function\n");
+        
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus,
+                           fw_start, nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..88fcaa8 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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 nvram_addr);
 static int load_hob(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t *fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,8 @@ add_max_hob_entry(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) {
@@ -229,6 +234,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +295,13 @@ 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_NR_NVRAM,
+                   &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,87 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init(unsigned long type)
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX];
+    unsigned long i;
+
+    if (nvram) {
+        if (strlen(nvram) > PATH_MAX) {
+            goto out;
+        }
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+    else {
+        strcpy(nvram_path, "nvram.dat");
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram_path, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram_path, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long type = WRITE_TO_NVRAM;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init(type);
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..47aaa1d 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -37,8 +37,28 @@
 
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE   (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+#define READ_FROM_NVRAM 0
+#define WRITE_TO_NVRAM 1
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern const char *nvram;
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t *fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_copy_from_GFW_to_nvram();
+extern int kvm_ia64_nvram_init(unsigned long type);
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                           const uint8_t *fw_start);
 #endif //__FIRM_WARE_
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605..fe29ecd 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -255,6 +255,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
+const char *nvram = NULL;
 struct drive_opt drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
@@ -3991,6 +3992,9 @@ static void help(int exitcode)
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
+#ifdef TARGET_IA64
+           "-nvram file     use 'file' to save or load nvram image\n"
+#endif
            "-name string    set the name of the guest\n"
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
            "\n"
@@ -4215,6 +4219,7 @@ enum {
     QEMU_OPTION_semihosting,
     QEMU_OPTION_cpu_vendor,
     QEMU_OPTION_name,
+    QEMU_OPTION_nvram,
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
@@ -4345,6 +4350,7 @@ static const QEMUOption qemu_options[] = {
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
     { "kvm-shadow-memory", HAS_ARG, QEMU_OPTION_kvm_shadow_memory },
     { "name", HAS_ARG, QEMU_OPTION_name },
+    { "nvram", HAS_ARG, QEMU_OPTION_nvram },
 #if defined(TARGET_SPARC)
     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
 #endif
@@ -5418,6 +5424,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_incoming:
                 incoming = optarg;
                 break;
+            case QEMU_OPTION_nvram:
+                nvram = optarg;
+                break;
             }
         }
     }
-- 
1.6.0.rc1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kvm: Qemu: save nvram
  2008-12-16  9:21           ` Zhang, Yang
@ 2008-12-17 18:39             ` Charles Duffy
  2008-12-18  5:30               ` Zhang, Xiantao
  0 siblings, 1 reply; 14+ messages in thread
From: Charles Duffy @ 2008-12-17 18:39 UTC (permalink / raw)
  To: kvm

Zhang, Yang wrote:
> Hi
> Please drop former. 
> This is the modify patch for save nvram.
> I add the new command line arg of "-nvram file" to specify the location 
> Of the file. Without the arg ,it will save the nvram in the current dir 
> and named as "nvram.dat". Also, it will read the saved file "nvram.dat" 
> from current dir without the arg.

Speaking with my end-user hat on, this seems to violate the principal of 
least surprise:

I would expect NVRAM contents to be discarded, not saved to a file in 
the current working directory, if no relevant option were given on the 
command line.

Likewise, I would expect NVRAM contents to be initialized exactly as 
they are right now (even if that means no initialization at all) if no 
path were given.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-17 18:39             ` Charles Duffy
@ 2008-12-18  5:30               ` Zhang, Xiantao
  2008-12-18 18:00                 ` Charles Duffy
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Xiantao @ 2008-12-18  5:30 UTC (permalink / raw)
  To: Charles Duffy, kvm@vger.kernel.org

Charles Duffy wrote:
> Zhang, Yang wrote:
>> Hi
>> Please drop former.
>> This is the modify patch for save nvram.
>> I add the new command line arg of "-nvram file" to specify the
>> location Of the file. Without the arg ,it will save the nvram in the
>> current dir and named as "nvram.dat". Also, it will read the saved
>> file "nvram.dat" from current dir without the arg.
> 
> Speaking with my end-user hat on, this seems to violate the principal
> of least surprise:
> 
> I would expect NVRAM contents to be discarded, not saved to a file in
> the current working directory, if no relevant option were given on the
> command line.

Maybe better to generate a temporary file to save the data instead of discarding it?

> Likewise, I would expect NVRAM contents to be initialized exactly as
> they are right now (even if that means no initialization at all) if no
> path were given. 

Since the NVRAM is saved by BIOS(eg. EFI), and only BIOS can recognize the data format, so it is almost impossible to initialize it to a fixed right states.  In addition, since different VMs running with difffernt OS,  and needs different NVRAMs, so can't configre them with a fixed nvram as well.

Xiantao

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kvm: Qemu: save nvram
  2008-12-18  5:30               ` Zhang, Xiantao
@ 2008-12-18 18:00                 ` Charles Duffy
  2008-12-19  1:56                   ` Zhang, Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Charles Duffy @ 2008-12-18 18:00 UTC (permalink / raw)
  To: kvm

Zhang, Xiantao wrote:
> Charles Duffy wrote:
>> Speaking with my end-user hat on, this seems to violate the principal
>> of least surprise:
>>
>> I would expect NVRAM contents to be discarded, not saved to a file in
>> the current working directory, if no relevant option were given on the
>> command line.
> 
> Maybe better to generate a temporary file to save the data instead of discarding it?

An unlinked temporary file as default behavior makes good sense -- it 
doesn't leave anything sitting around the user didn't ask for or doesn't 
expect, so it wouldn't be surprising behavior to me as an end-user, but 
provides a method for persisting nvram contents during a single session.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-18 18:00                 ` Charles Duffy
@ 2008-12-19  1:56                   ` Zhang, Yang
  2008-12-24  5:27                     ` Zhang, Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Yang @ 2008-12-19  1:56 UTC (permalink / raw)
  To: Charles Duffy, kvm@vger.kernel.org

Charles Duffy wrote:
>An unlinked temporary file as default behavior makes good sense -- it
>doesn't leave anything sitting around the user didn't ask for or doesn't
>expect, so it wouldn't be surprising behavior to me as an end-user, but
>provides a method for persisting nvram contents during a single session.

Ok, seems you are right. I will modify the patch.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-19  1:56                   ` Zhang, Yang
@ 2008-12-24  5:27                     ` Zhang, Yang
  2008-12-24  5:34                       ` Zhang, Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Yang @ 2008-12-24  5:27 UTC (permalink / raw)
  To: kvm-ia64@vger.kernel.org
  Cc: kvm@vger.kernel.org, Avi Kivity, Zhang, Xiantao, Charles Duffy

[-- Attachment #1: Type: text/plain, Size: 9231 bytes --]

>Charles Duffy wrote:
>>An unlinked temporary file as default behavior makes good sense -- it
>>doesn't leave anything sitting around the user didn't ask for or doesn't
>>expect, so it wouldn't be surprising behavior to me as an end-user, but
>>provides a method for persisting nvram contents during a single session.
>
>Ok, seems you are right. I will modify the patch.
The patch is modified. Without the arg of nvram, the patch will do nothing

>From 2fd0c2746a2d07813ad16700ee31c7f6ae78c40a Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 13:05:55 +0800
Subject: [PATCH] KVM: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   19 ++++++++-
 qemu/target-ia64/firmware.c |   94 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 +++++++++-
 3 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..2300ba9 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;
 
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +477,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            nvram_fd = kvm_ia64_nvram_init();
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..6729cb5 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,9 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+#include "sysemu.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +88,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +107,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +211,8 @@ add_max_hob_entry(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) {
@@ -229,6 +235,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +296,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,73 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+
+    if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+        if (errno != ENOENT)
+            goto out;
+        if (mkdir(nvram_path, 0755) == -1)
+            goto out;
+        else
+            if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+                errno = EACCES;
+                goto out;
+            }
+    }    
+    if (strlen(qemu_name) > PATH_MAX)
+        goto out;
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".dat");
+    nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0644);
+    if (nvram_fd < 0)
+        goto out;
+    if (VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1)) {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init();
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr + 
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..d632599 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t* fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
-- 
1.6.0.rc1



[-- Attachment #2: 0001-KVM-Qemu-save-nvram.patch --]
[-- Type: application/octet-stream, Size: 8521 bytes --]

From 2fd0c2746a2d07813ad16700ee31c7f6ae78c40a Mon Sep 17 00:00:00 2001
From: Yang Zhang <yang.zhang@intel.com>
Date: Tue, 2 Dec 2008 13:05:55 +0800
Subject: [PATCH] KVM: Qemu: save nvram

support to save nvram to the file

Signed-off-by: Yang Zhang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   19 ++++++++-
 qemu/target-ia64/firmware.c |   94 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   22 +++++++++-
 3 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 337c854..2300ba9 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -51,6 +51,7 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
+uint8_t *g_fw_start;
 
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
@@ -454,9 +455,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +477,19 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        if (qemu_name) {
+            nvram_addr = NVRAM_START;
+            nvram_fd = kvm_ia64_nvram_init();
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size,smp_cpus,fw_start,
+                           nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..6729cb5 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,9 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+#include "sysemu.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +88,16 @@ 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 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(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t* fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +107,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +211,8 @@ add_max_hob_entry(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) {
@@ -229,6 +235,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +296,12 @@ 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_NR_NVRAM, &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,73 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init()
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+
+    if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+        if (errno != ENOENT)
+            goto out;
+        if (mkdir(nvram_path, 0755) == -1)
+            goto out;
+        else
+            if (access(nvram_path, R_OK|W_OK|X_OK) == -1) {
+                errno = EACCES;
+                goto out;
+            }
+    }    
+    if (strlen(qemu_name) > PATH_MAX)
+        goto out;
+    strcat(nvram_path, qemu_name);
+    strcat(nvram_path, ".dat");
+    nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0644);
+    if (nvram_fd < 0)
+        goto out;
+    if (VALIDATE_NVRAM_FD(nvram_fd) == (uint64_t)(-1)) {
+        close(nvram_fd);
+        goto out;
+    }
+    return nvram_fd;
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init();
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr + 
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..d632599 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -34,11 +34,27 @@
 #define GFW_HOB_START           ((4UL<<30) - (14UL<<20))    // 4G - 14M
 #define GFW_HOB_SIZE            (1UL<<20)                 // 1M
 #define HOB_OFFSET              (GFW_HOB_START-GFW_START)
-
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE    (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define NVRAM_DIR "/usr/local/share/qemu/nvram/"
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t* fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_nvram_init();
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd, const uint8_t *fw_start);
+extern int kvm_ia64_copy_from_GFW_to_nvram();
 #endif //__FIRM_WARE_
-- 
1.6.0.rc1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* RE: [PATCH] Kvm: Qemu: save nvram
  2008-12-24  5:27                     ` Zhang, Yang
@ 2008-12-24  5:34                       ` Zhang, Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Zhang, Yang @ 2008-12-24  5:34 UTC (permalink / raw)
  To: kvm-ia64@vger.kernel.org
  Cc: kvm@vger.kernel.org, Avi Kivity, Zhang, Xiantao, Charles Duffy

[-- Attachment #1: Type: text/plain, Size: 11360 bytes --]

Zhang, Yang wrote:
>The patch is modified. Without the arg of nvram, the patch will do nothing

Sorry, I has upload the wrong patch. Please drop it.
This is the right one.
Please review it.


>From 3cce00ce9ac25c723dec34226991c61d89f79e70 Mon Sep 17 00:00:00 2001
From: Zhang Yang <yang.zhang@intel.com>
Date: Wed, 24 Dec 2008 11:54:38 +0800
Subject: [PATCH] KVM : Qemu: Save nvram

Save nvram to the file

Signed-off-by: Zhang Yang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   21 ++++++++-
 qemu/target-ia64/firmware.c |  110 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   24 +++++++++-
 qemu/vl.c                   |    9 ++++
 4 files changed, 155 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 3e24c98..4e9b052 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -53,6 +53,7 @@ static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
 
+uint8_t *g_fw_start;
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
     return (uint32_t)(((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3));
@@ -454,9 +455,14 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long type = READ_FROM_NVRAM;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +478,20 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        
+        nvram_addr = NVRAM_START;
+        if (nvram) {
+            nvram_fd = kvm_ia64_nvram_init(type);
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }        
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus,
+                           fw_start, nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..88fcaa8 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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 nvram_addr);
 static int load_hob(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t *fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,8 @@ add_max_hob_entry(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) {
@@ -229,6 +234,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +295,13 @@ 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_NR_NVRAM,
+                   &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,87 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init(unsigned long type)
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX];
+    unsigned long i;
+
+    if (nvram) {
+        if (strlen(nvram) > PATH_MAX) {
+            goto out;
+        }
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+    else {
+        strcpy(nvram_path, "nvram.dat");
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram_path, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram_path, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long type = WRITE_TO_NVRAM;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init(type);
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..47aaa1d 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -37,8 +37,28 @@
 
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE   (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+#define READ_FROM_NVRAM 0
+#define WRITE_TO_NVRAM 1
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern const char *nvram;
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t *fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_copy_from_GFW_to_nvram();
+extern int kvm_ia64_nvram_init(unsigned long type);
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                           const uint8_t *fw_start);
 #endif //__FIRM_WARE_
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605..fe29ecd 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -255,6 +255,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
+const char *nvram = NULL;
 struct drive_opt drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
@@ -3991,6 +3992,9 @@ static void help(int exitcode)
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
+#ifdef TARGET_IA64
+           "-nvram file     use 'file' to save or load nvram image\n"
+#endif
            "-name string    set the name of the guest\n"
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
            "\n"
@@ -4215,6 +4219,7 @@ enum {
     QEMU_OPTION_semihosting,
     QEMU_OPTION_cpu_vendor,
     QEMU_OPTION_name,
+    QEMU_OPTION_nvram,
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
@@ -4345,6 +4350,7 @@ static const QEMUOption qemu_options[] = {
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
     { "kvm-shadow-memory", HAS_ARG, QEMU_OPTION_kvm_shadow_memory },
     { "name", HAS_ARG, QEMU_OPTION_name },
+    { "nvram", HAS_ARG, QEMU_OPTION_nvram },
 #if defined(TARGET_SPARC)
     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
 #endif
@@ -5418,6 +5424,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_incoming:
                 incoming = optarg;
                 break;
+            case QEMU_OPTION_nvram:
+                nvram = optarg;
+                break;
             }
         }
     }
-- 
1.6.0.rc1


[-- Attachment #2: 0001-KVM-Qemu-Save-nvram.patch --]
[-- Type: application/octet-stream, Size: 10842 bytes --]

From 3cce00ce9ac25c723dec34226991c61d89f79e70 Mon Sep 17 00:00:00 2001
From: Zhang Yang <yang.zhang@intel.com>
Date: Wed, 24 Dec 2008 11:54:38 +0800
Subject: [PATCH] KVM : Qemu: Save nvram

Save nvram to the file

Signed-off-by: Zhang Yang <yang.zhang@intel.com>
---
 qemu/hw/ipf.c               |   21 ++++++++-
 qemu/target-ia64/firmware.c |  110 ++++++++++++++++++++++++++++++++++++++++--
 qemu/target-ia64/firmware.h |   24 +++++++++-
 qemu/vl.c                   |    9 ++++
 4 files changed, 155 insertions(+), 9 deletions(-)

diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c
index 3e24c98..4e9b052 100644
--- a/qemu/hw/ipf.c
+++ b/qemu/hw/ipf.c
@@ -53,6 +53,7 @@ static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PCIDevice *i440fx_state;
 
+uint8_t *g_fw_start;
 static uint32_t ipf_to_legacy_io(target_phys_addr_t addr)
 {
     return (uint32_t)(((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3));
@@ -454,9 +455,14 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         unsigned long  image_size;
         char *image = NULL;
         uint8_t *fw_image_start;
+        unsigned long nvram_addr = 0;
+        unsigned long nvram_fd = 0;
+        unsigned long type = READ_FROM_NVRAM;
+        unsigned long i = 0;
         ram_addr_t fw_offset = qemu_ram_alloc(GFW_SIZE);
         uint8_t *fw_start = phys_ram_base + fw_offset;
 
+        g_fw_start = fw_start;
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, FW_FILENAME);
         image = read_image(buf, &image_size );
         if (NULL == image || !image_size) {
@@ -472,7 +478,20 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size,
         free(image);
         flush_icache_range((unsigned long)fw_image_start,
                            (unsigned long)fw_image_start + image_size);
-        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start);
+        
+        nvram_addr = NVRAM_START;
+        if (nvram) {
+            nvram_fd = kvm_ia64_nvram_init(type);
+            if (nvram_fd != -1) {
+                kvm_ia64_copy_from_nvram_to_GFW(nvram_fd, g_fw_start);
+                close(nvram_fd);
+            }
+            i = atexit(kvm_ia64_copy_from_GFW_to_nvram);
+            if (i != 0)
+                fprintf(stderr, "cannot set exit function\n");
+        }        
+        kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus,
+                           fw_start, nvram_addr);
     }
 
     /*Register legacy io address space, size:64M*/
diff --git a/qemu/target-ia64/firmware.c b/qemu/target-ia64/firmware.c
index bac2721..88fcaa8 100644
--- a/qemu/target-ia64/firmware.c
+++ b/qemu/target-ia64/firmware.c
@@ -31,6 +31,8 @@
 
 #include "firmware.h"
 
+#include "qemu-common.h"
+
 typedef struct {
     unsigned long signature;
     unsigned int  type;
@@ -85,14 +87,16 @@ 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 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 nvram_addr);
 static int load_hob(void *hob_buf,
                     unsigned long dom_mem_size, void* hob_start);
 
 int
-kvm_ia64_build_hob(unsigned long memsize,
-                   unsigned long vcpus, uint8_t* fw_start)
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                   uint8_t *fw_start, unsigned long nvram_addr)
 {
     char   *hob_buf;
 
@@ -102,7 +106,7 @@ kvm_ia64_build_hob(unsigned long memsize,
         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);
         Hob_Output("Could not build hob");
         return -1;
@@ -206,7 +210,8 @@ add_max_hob_entry(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) {
@@ -229,6 +234,11 @@ build_hob(void* hob_buf, unsigned long hob_buf_size,
         goto err_out;
     }
 
+    if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+	    Hob_Output("Add nvram hob failed, buffer too small");
+	    goto err_out;
+	}
+
     if (add_max_hob_entry(hob_buf) < 0) {
         Hob_Output("Add max hob entry failed, buffer too small");
         goto err_out;
@@ -285,6 +295,13 @@ 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_NR_NVRAM,
+                   &nvram_addr, sizeof(nvram_addr));
+}
+
 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
@@ -581,6 +598,87 @@ out_1:
     return NULL;
 }
 
+int kvm_ia64_nvram_init(unsigned long type)
+{
+    unsigned long nvram_fd;
+    char nvram_path[PATH_MAX];
+    unsigned long i;
+
+    if (nvram) {
+        if (strlen(nvram) > PATH_MAX) {
+            goto out;
+        }
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+    else {
+        strcpy(nvram_path, "nvram.dat");
+        if (type == READ_FROM_NVRAM) {
+            if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
+                goto out;
+            nvram_fd = open(nvram_path, O_RDONLY);
+            return nvram_fd;
+        }
+        else { /* write from gfw to nvram file */
+            i = access(nvram_path, R_OK | W_OK | X_OK);
+            if ((i == -1) && (errno != ENOENT))
+               goto out;
+            nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
+            return nvram_fd;
+        }
+    }
+out:
+    return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                const uint8_t *fw_start)
+{
+    struct stat file_stat;
+    if ((fstat(nvram_fd, &file_stat) < 0) ||
+        (NVRAM_SIZE  != file_stat.st_size) ||
+        (read(nvram_fd, fw_start + NVRAM_OFFSET, NVRAM_SIZE) != NVRAM_SIZE))
+        return -1;
+    return 0;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+    unsigned long nvram_fd;
+    unsigned long type = WRITE_TO_NVRAM;
+    unsigned long *nvram_addr = (unsigned long *)(g_fw_start + NVRAM_OFFSET);
+    nvram_fd = kvm_ia64_nvram_init(type);
+    if (nvram_fd  == -1)
+        goto out;
+    if (((struct nvram_save_addr *)nvram_addr)->signature != NVRAM_VALID_SIG) {
+        close(nvram_fd);
+        goto out;
+    }
+    lseek(nvram_fd, 0, SEEK_SET);
+    if (write(nvram_fd, ((void *)(((struct nvram_save_addr *)nvram_addr)->addr +
+        (char *)phys_ram_base)), NVRAM_SIZE) != NVRAM_SIZE) {
+        close(nvram_fd);
+        goto out;
+    }
+    close(nvram_fd);
+    return 0;
+out:
+    return -1;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/qemu/target-ia64/firmware.h b/qemu/target-ia64/firmware.h
index 553a9f9..47aaa1d 100644
--- a/qemu/target-ia64/firmware.h
+++ b/qemu/target-ia64/firmware.h
@@ -37,8 +37,28 @@
 
 #define Hob_Output(s)           fprintf(stderr, s)
 
-extern int kvm_ia64_build_hob(unsigned long memsize,
-                              unsigned long vcpus, uint8_t* fw_start);
+#define NVRAM_START  (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE   (64 * (1UL << 10))
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+#define READ_FROM_NVRAM 0
+#define WRITE_TO_NVRAM 1
+
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+extern const char *nvram;
+extern uint8_t *g_fw_start;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+                              uint8_t *fw_start, unsigned long nvram_addr);
 extern char *read_image(const char *filename, unsigned long *size);
 
+extern int kvm_ia64_copy_from_GFW_to_nvram();
+extern int kvm_ia64_nvram_init(unsigned long type);
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd,
+                                           const uint8_t *fw_start);
 #endif //__FIRM_WARE_
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605..fe29ecd 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -255,6 +255,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
+const char *nvram = NULL;
 struct drive_opt drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
@@ -3991,6 +3992,9 @@ static void help(int exitcode)
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
+#ifdef TARGET_IA64
+           "-nvram file     use 'file' to save or load nvram image\n"
+#endif
            "-name string    set the name of the guest\n"
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
            "\n"
@@ -4215,6 +4219,7 @@ enum {
     QEMU_OPTION_semihosting,
     QEMU_OPTION_cpu_vendor,
     QEMU_OPTION_name,
+    QEMU_OPTION_nvram,
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
@@ -4345,6 +4350,7 @@ static const QEMUOption qemu_options[] = {
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
     { "kvm-shadow-memory", HAS_ARG, QEMU_OPTION_kvm_shadow_memory },
     { "name", HAS_ARG, QEMU_OPTION_name },
+    { "nvram", HAS_ARG, QEMU_OPTION_nvram },
 #if defined(TARGET_SPARC)
     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
 #endif
@@ -5418,6 +5424,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_incoming:
                 incoming = optarg;
                 break;
+            case QEMU_OPTION_nvram:
+                nvram = optarg;
+                break;
             }
         }
     }
-- 
1.6.0.rc1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-12-24  5:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-02  2:25 [PATCH] Kvm: Qemu: save nvram Zhang, Yang
2008-12-02  5:27 ` Zhang, Yang
2008-12-02 10:31 ` Daniel P. Berrange
2008-12-02 13:01   ` Avi Kivity
2008-12-02 13:10     ` Daniel P. Berrange
2008-12-03  6:02       ` Zhang, Xiantao
2008-12-03  6:12         ` Zhang, Yang
2008-12-16  9:21           ` Zhang, Yang
2008-12-17 18:39             ` Charles Duffy
2008-12-18  5:30               ` Zhang, Xiantao
2008-12-18 18:00                 ` Charles Duffy
2008-12-19  1:56                   ` Zhang, Yang
2008-12-24  5:27                     ` Zhang, Yang
2008-12-24  5:34                       ` Zhang, Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox