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.
25 #include <sys/types.h>
34 unsigned long signature
;
40 * INFO HOB is the first data data in one HOB list
41 * it contains the control information of the HOB list
44 HOB_GENERIC_HEADER header
;
45 unsigned long length
; // current length of hob
46 unsigned long cur_pos
; // current poisiton of hob
47 unsigned long buf_size
; // size of hob buffer
59 HOB_TYPE_PAL_BUS_GET_FEATURES_DATA
,
60 HOB_TYPE_PAL_CACHE_SUMMARY
,
61 HOB_TYPE_PAL_MEM_ATTRIB
,
62 HOB_TYPE_PAL_CACHE_INFO
,
63 HOB_TYPE_PAL_CACHE_PROT_INFO
,
64 HOB_TYPE_PAL_DEBUG_INFO
,
65 HOB_TYPE_PAL_FIXED_ADDR
,
66 HOB_TYPE_PAL_FREQ_BASE
,
67 HOB_TYPE_PAL_FREQ_RATIOS
,
68 HOB_TYPE_PAL_HALT_INFO
,
69 HOB_TYPE_PAL_PERF_MON_INFO
,
70 HOB_TYPE_PAL_PROC_GET_FEATURES
,
71 HOB_TYPE_PAL_PTCE_INFO
,
72 HOB_TYPE_PAL_REGISTER_INFO
,
73 HOB_TYPE_PAL_RSE_INFO
,
74 HOB_TYPE_PAL_TEST_INFO
,
75 HOB_TYPE_PAL_VM_SUMMARY
,
77 HOB_TYPE_PAL_VM_PAGE_SIZE
,
83 static int hob_init(void *buffer
,unsigned long buf_size
);
84 static int add_pal_hob(void* hob_buf
);
85 static int add_mem_hob(void* hob_buf
, unsigned long dom_mem_size
);
86 static int add_vcpus_hob(void* hob_buf
, unsigned long nr_vcpu
);
87 static int build_hob(void* hob_buf
, unsigned long hob_buf_size
,
88 unsigned long dom_mem_size
, unsigned long vcpus
);
89 static int load_hob(void *hob_buf
,
90 unsigned long dom_mem_size
, void* hob_start
);
93 kvm_ia64_build_hob(unsigned long memsize
,
94 unsigned long vcpus
, uint8_t* fw_start
)
98 hob_buf
= malloc(GFW_HOB_SIZE
);
99 if (hob_buf
== NULL
) {
100 Hob_Output("Hob: Could not allocate hob");
104 if (build_hob(hob_buf
, GFW_HOB_SIZE
, memsize
, vcpus
) < 0) {
106 Hob_Output("Could not build hob");
109 if (load_hob(hob_buf
, memsize
, fw_start
+ HOB_OFFSET
) < 0) {
111 Hob_Output("Could not load hob");
120 hob_init(void *buffer
, unsigned long buf_size
)
123 HOB_GENERIC_HEADER
*terminal
;
125 if (sizeof(HOB_INFO
) + sizeof(HOB_GENERIC_HEADER
) > buf_size
) {
130 phit
= (HOB_INFO
*)buffer
;
131 phit
->header
.signature
= HOB_SIGNATURE
;
132 phit
->header
.type
= HOB_TYPE_INFO
;
133 phit
->header
.length
= sizeof(HOB_INFO
);
134 phit
->length
= sizeof(HOB_INFO
) + sizeof(HOB_GENERIC_HEADER
);
136 phit
->buf_size
= buf_size
;
138 terminal
= (HOB_GENERIC_HEADER
*)(buffer
+ sizeof(HOB_INFO
));
139 terminal
->signature
= HOB_SIGNATURE
;
140 terminal
->type
= HOB_TYPE_TERMINAL
;
141 terminal
->length
= sizeof(HOB_GENERIC_HEADER
);
147 * Add a new HOB to the HOB List.
149 * hob_start - start address of hob buffer
150 * type - type of the hob to be added
151 * data - data of the hob to be added
152 * data_size - size of the data
155 hob_add(void* hob_start
, int type
, void* data
, int data_size
)
158 HOB_GENERIC_HEADER
*newhob
, *tail
;
160 phit
= (HOB_INFO
*)hob_start
;
162 if (phit
->length
+ data_size
> phit
->buf_size
) {
163 // no space for new hob
168 newhob
= (HOB_GENERIC_HEADER
*)(hob_start
+ phit
->length
-
169 sizeof(HOB_GENERIC_HEADER
));
170 newhob
->signature
= HOB_SIGNATURE
;
172 newhob
->length
= data_size
+ sizeof(HOB_GENERIC_HEADER
);
173 memcpy((void*)newhob
+ sizeof(HOB_GENERIC_HEADER
), data
, data_size
);
175 // append terminal HOB
176 tail
= (HOB_GENERIC_HEADER
*)(hob_start
+ phit
->length
+ data_size
);
177 tail
->signature
= HOB_SIGNATURE
;
178 tail
->type
= HOB_TYPE_TERMINAL
;
179 tail
->length
= sizeof(HOB_GENERIC_HEADER
);
181 // adjust HOB list length
182 phit
->length
+= sizeof(HOB_GENERIC_HEADER
) + data_size
;
188 get_hob_size(void* hob_buf
)
190 HOB_INFO
*phit
= (HOB_INFO
*)hob_buf
;
192 if (phit
->header
.signature
!= HOB_SIGNATURE
) {
193 Hob_Output("xc_get_hob_size:Incorrect signature");
200 add_max_hob_entry(void* hob_buf
)
203 return hob_add(hob_buf
, HOB_TYPE_MAX
, &max_hob
, sizeof(long));
207 build_hob(void* hob_buf
, unsigned long hob_buf_size
,
208 unsigned long dom_mem_size
, unsigned long vcpus
)
211 if (hob_init(hob_buf
, hob_buf_size
) < 0) {
212 Hob_Output("buffer too small");
216 if (add_mem_hob(hob_buf
,dom_mem_size
) < 0) {
217 Hob_Output("Add memory hob failed, buffer too small");
221 if (add_vcpus_hob(hob_buf
, vcpus
) < 0) {
222 Hob_Output("Add NR_VCPU hob failed, buffer too small");
226 if (add_pal_hob( hob_buf
) < 0) {
227 Hob_Output("Add PAL hob failed, buffer too small");
231 if (add_max_hob_entry(hob_buf
) < 0) {
232 Hob_Output("Add max hob entry failed, buffer too small");
241 load_hob(void *hob_buf
,
242 unsigned long dom_mem_size
, void* hob_start
)
246 hob_size
= get_hob_size(hob_buf
);
248 Hob_Output("Invalid hob data");
252 if (hob_size
> GFW_HOB_SIZE
) {
253 Hob_Output("No enough memory for hob data");
256 memcpy (hob_start
, hob_buf
, hob_size
);
261 add_mem_hob(void* hob_buf
, unsigned long dom_mem_size
)
267 memhob
.size
= MIN(dom_mem_size
, 0xC0000000);
269 if (hob_add(hob_buf
, HOB_TYPE_MEM
, &memhob
, sizeof(memhob
)) < 0)
272 if (dom_mem_size
> 0xC0000000) {
274 memhob
.start
= 0x100000000; //4G
275 memhob
.size
= dom_mem_size
- 0xC0000000;
276 if (hob_add(hob_buf
, HOB_TYPE_MEM
, &memhob
, sizeof(memhob
)) < 0)
283 add_vcpus_hob(void* hob_buf
, unsigned long vcpus
)
285 return hob_add(hob_buf
, HOB_TYPE_NR_VCPU
, &vcpus
, sizeof(vcpus
));
288 static const unsigned char config_pal_bus_get_features_data
[24] = {
289 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
293 static const unsigned char config_pal_cache_summary
[16] = {
294 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
297 static const unsigned char config_pal_mem_attrib
[8] = {
298 241, 0, 0, 0, 0, 0, 0, 0
301 static const unsigned char config_pal_cache_info
[152] = {
302 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
304 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
305 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
307 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
308 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
309 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
310 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
314 static const unsigned char config_pal_cache_prot_info
[200] = {
315 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
320 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
322 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
323 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
324 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
326 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 static const unsigned char config_pal_debug_info
[16] = {
331 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
334 static const unsigned char config_pal_fixed_addr
[8] = {
335 0, 0, 0, 0, 0, 0, 0, 0
338 static const unsigned char config_pal_freq_base
[8] = {
339 109, 219, 182, 13, 0, 0, 0, 0
342 static const unsigned char config_pal_freq_ratios
[24] = {
343 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
347 static const unsigned char config_pal_halt_info
[64] = {
348 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
354 static const unsigned char config_pal_perf_mon_info
[136] = {
355 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
357 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
359 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
362 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
363 0, 0, 0, 0, 0, 0, 0, 0
366 static const unsigned char config_pal_proc_get_features
[104] = {
367 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
368 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
369 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
370 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
371 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
372 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
373 0, 0, 0, 0, 0, 0, 0, 0
376 static const unsigned char config_pal_ptce_info
[24] = {
377 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0
381 static const unsigned char config_pal_register_info
[64] = {
382 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
383 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
384 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
385 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
388 static const unsigned char config_pal_rse_info
[16] = {
389 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
392 static const unsigned char config_pal_test_info
[48] = {
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
398 static const unsigned char config_pal_vm_summary
[16] = {
399 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
402 static const unsigned char config_pal_vm_info
[104] = {
403 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
404 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
406 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
407 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
411 static const unsigned char config_pal_vm_page_size
[16] = {
412 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
421 static const hob_batch_t hob_batch
[]={
422 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA
,
423 &config_pal_bus_get_features_data
,
424 sizeof(config_pal_bus_get_features_data
)
426 { HOB_TYPE_PAL_CACHE_SUMMARY
,
427 &config_pal_cache_summary
,
428 sizeof(config_pal_cache_summary
)
430 { HOB_TYPE_PAL_MEM_ATTRIB
,
431 &config_pal_mem_attrib
,
432 sizeof(config_pal_mem_attrib
)
434 { HOB_TYPE_PAL_CACHE_INFO
,
435 &config_pal_cache_info
,
436 sizeof(config_pal_cache_info
)
438 { HOB_TYPE_PAL_CACHE_PROT_INFO
,
439 &config_pal_cache_prot_info
,
440 sizeof(config_pal_cache_prot_info
)
442 { HOB_TYPE_PAL_DEBUG_INFO
,
443 &config_pal_debug_info
,
444 sizeof(config_pal_debug_info
)
446 { HOB_TYPE_PAL_FIXED_ADDR
,
447 &config_pal_fixed_addr
,
448 sizeof(config_pal_fixed_addr
)
450 { HOB_TYPE_PAL_FREQ_BASE
,
451 &config_pal_freq_base
,
452 sizeof(config_pal_freq_base
)
454 { HOB_TYPE_PAL_FREQ_RATIOS
,
455 &config_pal_freq_ratios
,
456 sizeof(config_pal_freq_ratios
)
458 { HOB_TYPE_PAL_HALT_INFO
,
459 &config_pal_halt_info
,
460 sizeof(config_pal_halt_info
)
462 { HOB_TYPE_PAL_PERF_MON_INFO
,
463 &config_pal_perf_mon_info
,
464 sizeof(config_pal_perf_mon_info
)
466 { HOB_TYPE_PAL_PROC_GET_FEATURES
,
467 &config_pal_proc_get_features
,
468 sizeof(config_pal_proc_get_features
)
470 { HOB_TYPE_PAL_PTCE_INFO
,
471 &config_pal_ptce_info
,
472 sizeof(config_pal_ptce_info
)
474 { HOB_TYPE_PAL_REGISTER_INFO
,
475 &config_pal_register_info
,
476 sizeof(config_pal_register_info
)
478 { HOB_TYPE_PAL_RSE_INFO
,
479 &config_pal_rse_info
,
480 sizeof(config_pal_rse_info
)
482 { HOB_TYPE_PAL_TEST_INFO
,
483 &config_pal_test_info
,
484 sizeof(config_pal_test_info
)
486 { HOB_TYPE_PAL_VM_SUMMARY
,
487 &config_pal_vm_summary
,
488 sizeof(config_pal_vm_summary
)
490 { HOB_TYPE_PAL_VM_INFO
,
492 sizeof(config_pal_vm_info
)
494 { HOB_TYPE_PAL_VM_PAGE_SIZE
,
495 &config_pal_vm_page_size
,
496 sizeof(config_pal_vm_page_size
)
501 add_pal_hob(void* hob_buf
)
504 for (i
= 0; i
< sizeof(hob_batch
)/sizeof(hob_batch_t
); i
++) {
505 if (hob_add(hob_buf
, hob_batch
[i
].type
, hob_batch
[i
].data
,
506 hob_batch
[i
].size
) < 0)
511 char *read_image(const char *filename
, unsigned long *size
)
514 gzFile kernel_gfd
= NULL
;
515 char *image
= NULL
, *tmp
;
518 if ( (filename
== NULL
) || (size
== NULL
) )
521 kernel_fd
= open(filename
, O_RDONLY
);
524 Hob_Output("Could not open kernel image\n");
528 if ( (kernel_gfd
= gzdopen(kernel_fd
, "rb")) == NULL
)
530 Hob_Output("Could not allocate decompression state for state file\n");
536 #define CHUNK 1*1024*1024
539 if ( (tmp
= realloc(image
, *size
+ CHUNK
)) == NULL
)
541 Hob_Output("Could not allocate memory for kernel image");
548 bytes
= gzread(kernel_gfd
, image
+ *size
, CHUNK
);
552 Hob_Output("Error reading kernel image");
568 Hob_Output("Could not read kernel image");
574 /* Shrink allocation to fit image. */
575 tmp
= realloc(image
, *size
);
580 if ( kernel_gfd
!= NULL
)
582 else if ( kernel_fd
>= 0 )
596 * indent-tabs-mode: nil