summaryrefslogtreecommitdiffstats
path: root/target-ia64
diff options
context:
space:
mode:
authorYang <[email protected]>2009-01-15 13:03:53 +0800
committerAvi Kivity <[email protected]>2009-01-15 11:57:31 +0200
commit28007f15ebfd76c426efc06d05b883db072f9a9c (patch)
treee964b85c5f73f7b7c481db2a01517009fa40cded /target-ia64
parent3685b8ffbfaca0885cc1b3fd21be07f7a6f97704 (diff)
downloadqemu-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 <[email protected]> Signed-off-by: Avi Kivity <[email protected]>
Diffstat (limited to 'target-ia64')
-rw-r--r--target-ia64/firmware.c110
-rw-r--r--target-ia64/firmware.h24
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_