diff options
author | 2009-01-15 13:03:53 +0800 | |
---|---|---|
committer | 2009-01-15 11:57:31 +0200 | |
commit | 28007f15ebfd76c426efc06d05b883db072f9a9c (patch) | |
tree | e964b85c5f73f7b7c481db2a01517009fa40cded /target-ia64 | |
parent | kvm: libkvm: Fix typo in the documentation header (diff) | |
download | qemu-kvm-28007f15ebfd76c426efc06d05b883db072f9a9c.tar.gz qemu-kvm-28007f15ebfd76c426efc06d05b883db072f9a9c.tar.bz2 qemu-kvm-28007f15ebfd76c426efc06d05b883db072f9a9c.zip |
Save ia64 nvram
Save nvram to a file given by a command line parameter.
Signed-off-by: Yang Zhang <yang.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'target-ia64')
-rw-r--r-- | target-ia64/firmware.c | 110 | ||||
-rw-r--r-- | target-ia64/firmware.h | 24 |
2 files changed, 126 insertions, 8 deletions
diff --git a/target-ia64/firmware.c b/target-ia64/firmware.c index bac2721f2..88fcaa874 100644 --- a/target-ia64/firmware.c +++ b/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/target-ia64/firmware.h b/target-ia64/firmware.h index 553a9f9fb..47aaa1d8b 100644 --- a/target-ia64/firmware.h +++ b/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_ |