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
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.
26 #include <sys/types.h>
34 #include "qemu-common.h"
37 unsigned long signature
;
43 * INFO HOB is the first data data in one HOB list
44 * it contains the control information of the HOB list
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
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
,
80 HOB_TYPE_PAL_VM_PAGE_SIZE
,
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
);
97 kvm_ia64_build_hob(unsigned long memsize
, unsigned long vcpus
,
98 unsigned long nvram_addr
)
102 hob_buf
= malloc(GFW_HOB_SIZE
);
103 if (hob_buf
== NULL
) {
104 Hob_Output("Hob: Could not allocate hob");
108 if (build_hob(hob_buf
, GFW_HOB_SIZE
, memsize
, vcpus
, nvram_addr
) < 0) {
110 Hob_Output("Could not build hob");
114 if (load_hob(hob_buf
, memsize
) < 0) {
116 Hob_Output("Could not load hob");
125 hob_init(void *buffer
, unsigned long buf_size
)
128 HOB_GENERIC_HEADER
*terminal
;
130 if (sizeof(HOB_INFO
) + sizeof(HOB_GENERIC_HEADER
) > buf_size
) {
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
);
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
);
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
160 hob_add(void* hob_start
, int type
, void* data
, int data_size
)
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
173 newhob
= (HOB_GENERIC_HEADER
*)(hob_start
+ phit
->length
-
174 sizeof(HOB_GENERIC_HEADER
));
175 newhob
->signature
= HOB_SIGNATURE
;
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
;
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");
205 add_max_hob_entry(void* hob_buf
)
208 return hob_add(hob_buf
, HOB_TYPE_MAX
, &max_hob
, sizeof(long));
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
)
217 if (hob_init(hob_buf
, hob_buf_size
) < 0) {
218 Hob_Output("buffer too small");
222 if (add_mem_hob(hob_buf
,dom_mem_size
) < 0) {
223 Hob_Output("Add memory hob failed, buffer too small");
227 if (add_vcpus_hob(hob_buf
, vcpus
) < 0) {
228 Hob_Output("Add NR_VCPU hob failed, buffer too small");
232 if (add_pal_hob(hob_buf
) < 0) {
233 Hob_Output("Add PAL hob failed, buffer too small");
237 if (add_nvram_hob(hob_buf
, nvram_addr
) < 0) {
238 Hob_Output("Add nvram hob failed, buffer too small");
242 if (add_max_hob_entry(hob_buf
) < 0) {
243 Hob_Output("Add max hob entry failed, buffer too small");
252 load_hob(void *hob_buf
, unsigned long dom_mem_size
)
256 hob_size
= get_hob_size(hob_buf
);
258 Hob_Output("Invalid hob data");
262 if (hob_size
> GFW_HOB_SIZE
) {
263 Hob_Output("No enough memory for hob data");
267 cpu_physical_memory_write(GFW_HOB_START
, hob_buf
, hob_size
);
273 add_mem_hob(void* hob_buf
, unsigned long dom_mem_size
)
279 memhob
.size
= MIN(dom_mem_size
, 0xC0000000);
281 if (hob_add(hob_buf
, HOB_TYPE_MEM
, &memhob
, sizeof(memhob
)) < 0)
284 if (dom_mem_size
> 0xC0000000) {
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)
295 add_vcpus_hob(void* hob_buf
, unsigned long vcpus
)
297 return hob_add(hob_buf
, HOB_TYPE_NR_VCPU
, &vcpus
, sizeof(vcpus
));
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,
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,
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
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
,
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
)
520 add_pal_hob(void* hob_buf
)
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)
531 uint8_t *read_image(const char *filename
, unsigned long *size
)
534 gzFile kernel_gfd
= NULL
;
535 uint8_t *image
= NULL
, *tmp
;
538 if ((filename
== NULL
) || (size
== NULL
))
541 kernel_fd
= open(filename
, O_RDONLY
);
543 Hob_Output("Could not open kernel image\n");
547 if ((kernel_gfd
= gzdopen(kernel_fd
, "rb")) == NULL
) {
548 Hob_Output("Could not allocate decompression state for state file\n");
554 #define CHUNK 1*1024*1024
557 if ((tmp
= realloc(image
, *size
+ CHUNK
)) == NULL
) {
558 Hob_Output("Could not allocate memory for kernel image");
565 bytes
= gzread(kernel_gfd
, image
+ *size
, CHUNK
);
568 Hob_Output("Error reading kernel image");
583 Hob_Output("Could not read kernel image");
587 /* Shrink allocation to fit image. */
588 tmp
= realloc(image
, *size
);
593 if (kernel_gfd
!= NULL
)
595 else if (kernel_fd
>= 0)
603 int kvm_ia64_nvram_init(unsigned long type
)
605 unsigned long nvram_fd
;
606 char nvram_path
[PATH_MAX
];
610 if (strlen(nvram
) > PATH_MAX
) {
613 if (type
== READ_FROM_NVRAM
) {
614 if (access(nvram
, R_OK
| W_OK
| X_OK
) == -1)
616 nvram_fd
= open(nvram
, O_RDONLY
);
619 else { /* write from gfw to nvram file */
620 i
= access(nvram
, R_OK
| W_OK
| X_OK
);
621 if ((i
== -1) && (errno
!= ENOENT
))
623 nvram_fd
= open(nvram
, O_CREAT
|O_RDWR
, 0777);
628 strcpy(nvram_path
, "nvram.dat");
629 if (type
== READ_FROM_NVRAM
) {
630 if (access(nvram_path
, R_OK
| W_OK
| X_OK
) == -1)
632 nvram_fd
= open(nvram_path
, O_RDONLY
);
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
))
639 nvram_fd
= open(nvram_path
, O_CREAT
|O_RDWR
, 0777);
648 kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd
)
650 struct stat file_stat
;
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
)) {
663 cpu_physical_memory_write(NVRAM_START
, nvram_buf
, NVRAM_SIZE
);
671 kvm_ia64_copy_from_GFW_to_nvram()
673 struct nvram_save_addr nvram_addr_buf
;
675 unsigned long nvram_fd
;
676 unsigned long type
= WRITE_TO_NVRAM
;
679 nvram_buf
= malloc(NVRAM_SIZE
);
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
) {
689 cpu_physical_memory_read(nvram_addr_buf
.addr
, nvram_buf
, NVRAM_SIZE
);
691 nvram_fd
= kvm_ia64_nvram_init(type
);
695 lseek(nvram_fd
, 0, SEEK_SET
);
696 if (write(nvram_fd
, nvram_buf
, NVRAM_SIZE
) != NVRAM_SIZE
)
713 * indent-tabs-mode: nil