Merge commit 'a62acdc0cc5308706e2503557a09828979b59a12' into upstream-merge
[qemu-kvm/fedora.git] / target-ia64 / firmware.c
blob79f846421764fa56661e4f98f6a63a60f4eefdf8
1 /*
2 * firmware.c : Firmware build logic for ia64 platform.
4 * Ported from Xen 3.0 Source.
5 * Copyright (c) 2007, Intel Corporation.
6 * Zhang Xiantao <xiantao.zhang@intel.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place - Suite 330, Boston, MA 02111-1307 USA.
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <zlib.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
30 #include "cpu.h"
32 #include "firmware.h"
34 #include "qemu-common.h"
36 typedef struct {
37 unsigned long signature;
38 unsigned int type;
39 unsigned int length;
40 } HOB_GENERIC_HEADER;
43 * INFO HOB is the first data data in one HOB list
44 * it contains the control information of the HOB list
46 typedef struct {
47 HOB_GENERIC_HEADER header;
48 unsigned long length; // current length of hob
49 unsigned long cur_pos; // current poisiton of hob
50 unsigned long buf_size; // size of hob buffer
51 } HOB_INFO;
53 typedef struct{
54 unsigned long start;
55 unsigned long size;
56 } hob_mem_t;
58 typedef enum {
59 HOB_TYPE_INFO=0,
60 HOB_TYPE_TERMINAL,
61 HOB_TYPE_MEM,
62 HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
63 HOB_TYPE_PAL_CACHE_SUMMARY,
64 HOB_TYPE_PAL_MEM_ATTRIB,
65 HOB_TYPE_PAL_CACHE_INFO,
66 HOB_TYPE_PAL_CACHE_PROT_INFO,
67 HOB_TYPE_PAL_DEBUG_INFO,
68 HOB_TYPE_PAL_FIXED_ADDR,
69 HOB_TYPE_PAL_FREQ_BASE,
70 HOB_TYPE_PAL_FREQ_RATIOS,
71 HOB_TYPE_PAL_HALT_INFO,
72 HOB_TYPE_PAL_PERF_MON_INFO,
73 HOB_TYPE_PAL_PROC_GET_FEATURES,
74 HOB_TYPE_PAL_PTCE_INFO,
75 HOB_TYPE_PAL_REGISTER_INFO,
76 HOB_TYPE_PAL_RSE_INFO,
77 HOB_TYPE_PAL_TEST_INFO,
78 HOB_TYPE_PAL_VM_SUMMARY,
79 HOB_TYPE_PAL_VM_INFO,
80 HOB_TYPE_PAL_VM_PAGE_SIZE,
81 HOB_TYPE_NR_VCPU,
82 HOB_TYPE_NR_NVRAM,
83 HOB_TYPE_MAX
84 } hob_type_t;
86 static int hob_init(void *buffer ,unsigned long buf_size);
87 static int add_pal_hob(void* hob_buf);
88 static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size);
89 static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu);
90 static int add_nvram_hob(void *hob_buf, unsigned long nvram_addr);
91 static int build_hob(void *hob_buf, unsigned long hob_buf_size,
92 unsigned long dom_mem_size, unsigned long vcpus,
93 unsigned long nvram_addr);
94 static int load_hob(void *hob_buf, unsigned long dom_mem_size);
96 int
97 kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
98 unsigned long nvram_addr)
100 char *hob_buf;
102 hob_buf = malloc(GFW_HOB_SIZE);
103 if (hob_buf == NULL) {
104 Hob_Output("Hob: Could not allocate hob");
105 return -1;
108 if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus, nvram_addr) < 0) {
109 free(hob_buf);
110 Hob_Output("Could not build hob");
111 return -1;
114 if (load_hob(hob_buf, memsize) < 0) {
115 free(hob_buf);
116 Hob_Output("Could not load hob");
117 return -1;
119 free(hob_buf);
121 return 0;
124 static int
125 hob_init(void *buffer, unsigned long buf_size)
127 HOB_INFO *phit;
128 HOB_GENERIC_HEADER *terminal;
130 if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size) {
131 // buffer too small
132 return -1;
135 phit = (HOB_INFO*)buffer;
136 phit->header.signature = HOB_SIGNATURE;
137 phit->header.type = HOB_TYPE_INFO;
138 phit->header.length = sizeof(HOB_INFO);
139 phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER);
140 phit->cur_pos = 0;
141 phit->buf_size = buf_size;
143 terminal = (HOB_GENERIC_HEADER*)(buffer + sizeof(HOB_INFO));
144 terminal->signature = HOB_SIGNATURE;
145 terminal->type = HOB_TYPE_TERMINAL;
146 terminal->length = sizeof(HOB_GENERIC_HEADER);
148 return 0;
152 * Add a new HOB to the HOB List.
154 * hob_start - start address of hob buffer
155 * type - type of the hob to be added
156 * data - data of the hob to be added
157 * data_size - size of the data
159 static int
160 hob_add(void* hob_start, int type, void* data, int data_size)
162 HOB_INFO *phit;
163 HOB_GENERIC_HEADER *newhob, *tail;
165 phit = (HOB_INFO*)hob_start;
167 if (phit->length + data_size > phit->buf_size) {
168 // no space for new hob
169 return -1;
172 //append new HOB
173 newhob = (HOB_GENERIC_HEADER*)(hob_start + phit->length -
174 sizeof(HOB_GENERIC_HEADER));
175 newhob->signature = HOB_SIGNATURE;
176 newhob->type = type;
177 newhob->length = data_size + sizeof(HOB_GENERIC_HEADER);
178 memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size);
180 // append terminal HOB
181 tail = (HOB_GENERIC_HEADER*)(hob_start + phit->length + data_size);
182 tail->signature = HOB_SIGNATURE;
183 tail->type = HOB_TYPE_TERMINAL;
184 tail->length = sizeof(HOB_GENERIC_HEADER);
186 // adjust HOB list length
187 phit->length += sizeof(HOB_GENERIC_HEADER) + data_size;
189 return 0;
192 static int
193 get_hob_size(void* hob_buf)
195 HOB_INFO *phit = (HOB_INFO*)hob_buf;
197 if (phit->header.signature != HOB_SIGNATURE) {
198 Hob_Output("xc_get_hob_size:Incorrect signature");
199 return -1;
201 return phit->length;
204 static int
205 add_max_hob_entry(void* hob_buf)
207 long max_hob = 0;
208 return hob_add(hob_buf, HOB_TYPE_MAX, &max_hob, sizeof(long));
211 static int
212 build_hob(void* hob_buf, unsigned long hob_buf_size,
213 unsigned long dom_mem_size, unsigned long vcpus,
214 unsigned long nvram_addr)
216 //Init HOB List
217 if (hob_init(hob_buf, hob_buf_size) < 0) {
218 Hob_Output("buffer too small");
219 goto err_out;
222 if (add_mem_hob(hob_buf,dom_mem_size) < 0) {
223 Hob_Output("Add memory hob failed, buffer too small");
224 goto err_out;
227 if (add_vcpus_hob(hob_buf, vcpus) < 0) {
228 Hob_Output("Add NR_VCPU hob failed, buffer too small");
229 goto err_out;
232 if (add_pal_hob(hob_buf) < 0) {
233 Hob_Output("Add PAL hob failed, buffer too small");
234 goto err_out;
237 if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
238 Hob_Output("Add nvram hob failed, buffer too small");
239 goto err_out;
242 if (add_max_hob_entry(hob_buf) < 0) {
243 Hob_Output("Add max hob entry failed, buffer too small");
244 goto err_out;
246 return 0;
248 err_out:
249 return -1;
251 static int
252 load_hob(void *hob_buf, unsigned long dom_mem_size)
254 int hob_size;
256 hob_size = get_hob_size(hob_buf);
257 if (hob_size < 0) {
258 Hob_Output("Invalid hob data");
259 return -1;
262 if (hob_size > GFW_HOB_SIZE) {
263 Hob_Output("No enough memory for hob data");
264 return -1;
267 cpu_physical_memory_write(GFW_HOB_START, hob_buf, hob_size);
269 return 0;
272 static int
273 add_mem_hob(void* hob_buf, unsigned long dom_mem_size)
275 hob_mem_t memhob;
277 // less than 3G
278 memhob.start = 0;
279 memhob.size = MIN(dom_mem_size, 0xC0000000);
281 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
282 return -1;
284 if (dom_mem_size > 0xC0000000) {
285 // 4G ~ 4G+remain
286 memhob.start = 0x100000000; //4G
287 memhob.size = dom_mem_size - 0xC0000000;
288 if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
289 return -1;
291 return 0;
294 static int
295 add_vcpus_hob(void* hob_buf, unsigned long vcpus)
297 return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus));
300 static int
301 add_nvram_hob(void *hob_buf, unsigned long nvram_addr)
303 return hob_add(hob_buf, HOB_TYPE_NR_NVRAM,
304 &nvram_addr, sizeof(nvram_addr));
307 static const unsigned char config_pal_bus_get_features_data[24] = {
308 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
312 static const unsigned char config_pal_cache_summary[16] = {
313 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
316 static const unsigned char config_pal_mem_attrib[8] = {
317 241, 0, 0, 0, 0, 0, 0, 0
320 static const unsigned char config_pal_cache_info[152] = {
321 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
323 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
324 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
325 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
326 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
327 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
328 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
329 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
333 static const unsigned char config_pal_cache_prot_info[200] = {
334 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
339 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
341 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
343 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
345 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
346 0, 0, 0
349 static const unsigned char config_pal_debug_info[16] = {
350 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
353 static const unsigned char config_pal_fixed_addr[8] = {
354 0, 0, 0, 0, 0, 0, 0, 0
357 static const unsigned char config_pal_freq_base[8] = {
358 109, 219, 182, 13, 0, 0, 0, 0
361 static const unsigned char config_pal_freq_ratios[24] = {
362 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
363 0, 0, 0, 7, 0, 0, 0
366 static const unsigned char config_pal_halt_info[64] = {
367 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
369 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
373 static const unsigned char config_pal_perf_mon_info[136] = {
374 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
376 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
382 0, 0, 0, 0, 0, 0, 0, 0
385 static const unsigned char config_pal_proc_get_features[104] = {
386 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
388 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
389 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
391 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0
395 static const unsigned char config_pal_ptce_info[24] = {
396 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0
400 static const unsigned char config_pal_register_info[64] = {
401 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
402 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
403 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
404 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
407 static const unsigned char config_pal_rse_info[16] = {
408 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
411 static const unsigned char config_pal_test_info[48] = {
412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
417 static const unsigned char config_pal_vm_summary[16] = {
418 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
421 static const unsigned char config_pal_vm_info[104] = {
422 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
423 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
424 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
425 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
426 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
427 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
430 static const unsigned char config_pal_vm_page_size[16] = {
431 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
434 typedef struct{
435 hob_type_t type;
436 void* data;
437 unsigned long size;
438 } hob_batch_t;
440 static const hob_batch_t hob_batch[]={
441 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
442 &config_pal_bus_get_features_data,
443 sizeof(config_pal_bus_get_features_data)
445 { HOB_TYPE_PAL_CACHE_SUMMARY,
446 &config_pal_cache_summary,
447 sizeof(config_pal_cache_summary)
449 { HOB_TYPE_PAL_MEM_ATTRIB,
450 &config_pal_mem_attrib,
451 sizeof(config_pal_mem_attrib)
453 { HOB_TYPE_PAL_CACHE_INFO,
454 &config_pal_cache_info,
455 sizeof(config_pal_cache_info)
457 { HOB_TYPE_PAL_CACHE_PROT_INFO,
458 &config_pal_cache_prot_info,
459 sizeof(config_pal_cache_prot_info)
461 { HOB_TYPE_PAL_DEBUG_INFO,
462 &config_pal_debug_info,
463 sizeof(config_pal_debug_info)
465 { HOB_TYPE_PAL_FIXED_ADDR,
466 &config_pal_fixed_addr,
467 sizeof(config_pal_fixed_addr)
469 { HOB_TYPE_PAL_FREQ_BASE,
470 &config_pal_freq_base,
471 sizeof(config_pal_freq_base)
473 { HOB_TYPE_PAL_FREQ_RATIOS,
474 &config_pal_freq_ratios,
475 sizeof(config_pal_freq_ratios)
477 { HOB_TYPE_PAL_HALT_INFO,
478 &config_pal_halt_info,
479 sizeof(config_pal_halt_info)
481 { HOB_TYPE_PAL_PERF_MON_INFO,
482 &config_pal_perf_mon_info,
483 sizeof(config_pal_perf_mon_info)
485 { HOB_TYPE_PAL_PROC_GET_FEATURES,
486 &config_pal_proc_get_features,
487 sizeof(config_pal_proc_get_features)
489 { HOB_TYPE_PAL_PTCE_INFO,
490 &config_pal_ptce_info,
491 sizeof(config_pal_ptce_info)
493 { HOB_TYPE_PAL_REGISTER_INFO,
494 &config_pal_register_info,
495 sizeof(config_pal_register_info)
497 { HOB_TYPE_PAL_RSE_INFO,
498 &config_pal_rse_info,
499 sizeof(config_pal_rse_info)
501 { HOB_TYPE_PAL_TEST_INFO,
502 &config_pal_test_info,
503 sizeof(config_pal_test_info)
505 { HOB_TYPE_PAL_VM_SUMMARY,
506 &config_pal_vm_summary,
507 sizeof(config_pal_vm_summary)
509 { HOB_TYPE_PAL_VM_INFO,
510 &config_pal_vm_info,
511 sizeof(config_pal_vm_info)
513 { HOB_TYPE_PAL_VM_PAGE_SIZE,
514 &config_pal_vm_page_size,
515 sizeof(config_pal_vm_page_size)
519 static int
520 add_pal_hob(void* hob_buf)
522 int i;
523 for (i = 0; i < sizeof(hob_batch)/sizeof(hob_batch_t); i++) {
524 if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data,
525 hob_batch[i].size) < 0)
526 return -1;
528 return 0;
531 uint8_t *read_image(const char *filename, unsigned long *size)
533 int kernel_fd = -1;
534 gzFile kernel_gfd = NULL;
535 uint8_t *image = NULL, *tmp;
536 unsigned int bytes;
538 if ((filename == NULL) || (size == NULL))
539 return NULL;
541 kernel_fd = open(filename, O_RDONLY);
542 if (kernel_fd < 0) {
543 Hob_Output("Could not open kernel image\n");
544 goto out_1;
547 if ((kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL) {
548 Hob_Output("Could not allocate decompression state for state file\n");
549 goto out_1;
552 *size = 0;
554 #define CHUNK 1*1024*1024
555 while(1)
557 if ((tmp = realloc(image, *size + CHUNK)) == NULL) {
558 Hob_Output("Could not allocate memory for kernel image");
559 free(image);
560 image = NULL;
561 goto out;
563 image = tmp;
565 bytes = gzread(kernel_gfd, image + *size, CHUNK);
566 switch (bytes) {
567 case -1:
568 Hob_Output("Error reading kernel image");
569 free(image);
570 image = NULL;
571 goto out;
572 case 0: /* EOF */
573 goto out;
574 default:
575 *size += bytes;
576 break;
579 #undef CHUNK
581 out:
582 if (*size == 0) {
583 Hob_Output("Could not read kernel image");
584 free(image);
585 image = NULL;
586 } else if (image) {
587 /* Shrink allocation to fit image. */
588 tmp = realloc(image, *size);
589 if (tmp)
590 image = tmp;
593 if (kernel_gfd != NULL)
594 gzclose(kernel_gfd);
595 else if (kernel_fd >= 0)
596 close(kernel_fd);
597 return image;
599 out_1:
600 return NULL;
603 int kvm_ia64_nvram_init(unsigned long type)
605 unsigned long nvram_fd;
606 char nvram_path[PATH_MAX];
607 unsigned long i;
609 if (nvram) {
610 if (strlen(nvram) > PATH_MAX) {
611 goto out;
613 if (type == READ_FROM_NVRAM) {
614 if (access(nvram, R_OK | W_OK | X_OK) == -1)
615 goto out;
616 nvram_fd = open(nvram, O_RDONLY);
617 return nvram_fd;
619 else { /* write from gfw to nvram file */
620 i = access(nvram, R_OK | W_OK | X_OK);
621 if ((i == -1) && (errno != ENOENT))
622 goto out;
623 nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
624 return nvram_fd;
627 else {
628 strcpy(nvram_path, "nvram.dat");
629 if (type == READ_FROM_NVRAM) {
630 if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
631 goto out;
632 nvram_fd = open(nvram_path, O_RDONLY);
633 return nvram_fd;
635 else { /* write from gfw to nvram file */
636 i = access(nvram_path, R_OK | W_OK | X_OK);
637 if ((i == -1) && (errno != ENOENT))
638 goto out;
639 nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
640 return nvram_fd;
643 out:
644 return -1;
648 kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd)
650 struct stat file_stat;
651 uint8_t *nvram_buf;
652 int r = 0;
654 nvram_buf = malloc(NVRAM_SIZE);
656 if ((fstat(nvram_fd, &file_stat) < 0) ||
657 (NVRAM_SIZE != file_stat.st_size) ||
658 (read(nvram_fd, nvram_buf, NVRAM_SIZE) != NVRAM_SIZE)) {
659 r = -1;
660 goto out;
663 cpu_physical_memory_write(NVRAM_START, nvram_buf, NVRAM_SIZE);
665 out:
666 free(nvram_buf);
667 return r;
671 kvm_ia64_copy_from_GFW_to_nvram()
673 struct nvram_save_addr nvram_addr_buf;
674 uint8_t *nvram_buf;
675 unsigned long nvram_fd;
676 unsigned long type = WRITE_TO_NVRAM;
677 int ret = -1;
679 nvram_buf = malloc(NVRAM_SIZE);
680 if (!nvram_buf)
681 goto out_free;
683 cpu_physical_memory_read(NVRAM_START, (uint8_t *)&nvram_addr_buf,
684 sizeof(struct nvram_save_addr));
685 if (nvram_addr_buf.signature != NVRAM_VALID_SIG) {
686 goto out_free;
689 cpu_physical_memory_read(nvram_addr_buf.addr, nvram_buf, NVRAM_SIZE);
691 nvram_fd = kvm_ia64_nvram_init(type);
692 if (nvram_fd == -1)
693 goto out;
695 lseek(nvram_fd, 0, SEEK_SET);
696 if (write(nvram_fd, nvram_buf, NVRAM_SIZE) != NVRAM_SIZE)
697 goto out;
699 ret = 0;
700 out:
701 close(nvram_fd);
702 out_free:
703 free(nvram_buf);
704 return ret;
708 * Local variables:
709 * mode: C
710 * c-set-style: "BSD"
711 * c-basic-offset: 4
712 * tab-width: 4
713 * indent-tabs-mode: nil
714 * End: