* RE: FW: [PATCH] Kvm: Qemu: save nvram
[not found] ` <496C601C.9000304@redhat.com>
@ 2009-01-15 6:57 ` Zhang, Yang
2009-01-15 9:57 ` Avi Kivity
0 siblings, 1 reply; 2+ messages in thread
From: Zhang, Yang @ 2009-01-15 6:57 UTC (permalink / raw)
To: kvm-ia64@vger.kernel.org, Avi Kivity; +Cc: Zhang, Xiantao, kvm@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 502 bytes --]
Hi
This is refreshed patch.
Please review it.
Best Regards
--yang
>-----Original Message-----
>From: Avi Kivity [mailto:avi@redhat.com]
>Sent: 2009年1月13日 17:34
>To: Zhang, Xiantao
>Cc: Zhang, Yang
>Subject: Re: FW: [PATCH] Kvm: Qemu: save nvram
>
>Zhang, Xiantao wrote:
>> Avi,
>> Could you help to commit this patch ?
>>
>
>Doesn't apply, please refresh.
>
>(Yang, sorry for dropping it previously).
>
>
>--
>error compiling committee.c: too many arguments to function
[-- Attachment #2: 0001-KVM-Qemu-Save-nvram.patch --]
[-- Type: application/octet-stream, Size: 10872 bytes --]
From 966de0bed4f18f856f58a626b9d7337e03e6ed28 Mon Sep 17 00:00:00 2001
From: Yang <yang.zhang@intel.com>
Date: Thu, 15 Jan 2009 13:03:53 +0800
Subject: [PATCH] KVM : Qemu: Save nvram
Save nvram to the file
Signed-off-by: Yang Zhang <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 7a36870..e81ae21 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -249,6 +249,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;
@@ -4005,6 +4006,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"
@@ -4235,6 +4239,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,
@@ -4368,6 +4373,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) || defined(TARGET_PPC)
{ "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
#endif
@@ -5461,6 +5467,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_incoming:
incoming = optarg;
break;
+ case QEMU_OPTION_nvram:
+ nvram = optarg;
+ break;
}
}
}
--
1.6.0.rc1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: FW: [PATCH] Kvm: Qemu: save nvram
2009-01-15 6:57 ` FW: [PATCH] Kvm: Qemu: save nvram Zhang, Yang
@ 2009-01-15 9:57 ` Avi Kivity
0 siblings, 0 replies; 2+ messages in thread
From: Avi Kivity @ 2009-01-15 9:57 UTC (permalink / raw)
To: Zhang, Yang; +Cc: kvm-ia64@vger.kernel.org, Zhang, Xiantao, kvm@vger.kernel.org
Zhang, Yang wrote:
> Hi
> This is refreshed patch.
> Please review it.
>
Applied, thanks.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-01-15 9:57 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <706158FABBBA044BAD4FE898A02E4BC21C9A0616@pdsmsx503.ccr.corp.intel.com>
[not found] ` <496C601C.9000304@redhat.com>
2009-01-15 6:57 ` FW: [PATCH] Kvm: Qemu: save nvram Zhang, Yang
2009-01-15 9:57 ` Avi Kivity
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox