Hi: Please drop the previous one. From 2fd0c2746a2d07813ad16700ee31c7f6ae78c40a Mon Sep 17 00:00:00 2001 From: Yang Zhang <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>
---
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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Zhang, Yang
Sent: 2008年12月2日 10:26
To: [EMAIL PROTECTED]
Cc: [email protected]; [EMAIL PROTECTED]; 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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
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
0001-KVM-Qemu-save-nvram.patch
Description: 0001-KVM-Qemu-save-nvram.patch
