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
, unsigned long dom_mem_size
, void* hob_start
)
245 hob_size
= get_hob_size(hob_buf
);
247 Hob_Output("Invalid hob data");
251 if (hob_size
> GFW_HOB_SIZE
) {
252 Hob_Output("No enough memory for hob data");
255 memcpy (hob_start
, hob_buf
, hob_size
);
260 add_mem_hob(void* hob_buf
, unsigned long dom_mem_size
)
266 memhob
.size
= MIN(dom_mem_size
, 0xC0000000);
268 if (hob_add(hob_buf
, HOB_TYPE_MEM
, &memhob
, sizeof(memhob
)) < 0)
271 if (dom_mem_size
> 0xC0000000) {
273 memhob
.start
= 0x100000000; //4G
274 memhob
.size
= dom_mem_size
- 0xC0000000;
275 if (hob_add(hob_buf
, HOB_TYPE_MEM
, &memhob
, sizeof(memhob
)) < 0)
282 add_vcpus_hob(void* hob_buf
, unsigned long vcpus
)
284 return hob_add(hob_buf
, HOB_TYPE_NR_VCPU
, &vcpus
, sizeof(vcpus
));
287 static const unsigned char config_pal_bus_get_features_data
[24] = {
288 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
292 static const unsigned char config_pal_cache_summary
[16] = {
293 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
296 static const unsigned char config_pal_mem_attrib
[8] = {
297 241, 0, 0, 0, 0, 0, 0, 0
300 static const unsigned char config_pal_cache_info
[152] = {
301 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
303 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
304 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
306 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
307 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
308 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
309 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
313 static const unsigned char config_pal_cache_prot_info
[200] = {
314 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
319 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
321 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
323 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
325 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329 static const unsigned char config_pal_debug_info
[16] = {
330 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
333 static const unsigned char config_pal_fixed_addr
[8] = {
334 0, 0, 0, 0, 0, 0, 0, 0
337 static const unsigned char config_pal_freq_base
[8] = {
338 109, 219, 182, 13, 0, 0, 0, 0
341 static const unsigned char config_pal_freq_ratios
[24] = {
342 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
346 static const unsigned char config_pal_halt_info
[64] = {
347 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 0, 0, 0, 0, 0, 0, 0, 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
353 static const unsigned char config_pal_perf_mon_info
[136] = {
354 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
358 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
359 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
362 0, 0, 0, 0, 0, 0, 0, 0
365 static const unsigned char config_pal_proc_get_features
[104] = {
366 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
367 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
368 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
369 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
370 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
371 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
372 0, 0, 0, 0, 0, 0, 0, 0
375 static const unsigned char config_pal_ptce_info
[24] = {
376 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0
380 static const unsigned char config_pal_register_info
[64] = {
381 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
382 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
383 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
384 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
387 static const unsigned char config_pal_rse_info
[16] = {
388 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
391 static const unsigned char config_pal_test_info
[48] = {
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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
397 static const unsigned char config_pal_vm_summary
[16] = {
398 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
401 static const unsigned char config_pal_vm_info
[104] = {
402 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
403 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
404 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
405 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
406 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
410 static const unsigned char config_pal_vm_page_size
[16] = {
411 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
420 static const hob_batch_t hob_batch
[]={
421 { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA
,
422 &config_pal_bus_get_features_data
,
423 sizeof(config_pal_bus_get_features_data
)
425 { HOB_TYPE_PAL_CACHE_SUMMARY
,
426 &config_pal_cache_summary
,
427 sizeof(config_pal_cache_summary
)
429 { HOB_TYPE_PAL_MEM_ATTRIB
,
430 &config_pal_mem_attrib
,
431 sizeof(config_pal_mem_attrib
)
433 { HOB_TYPE_PAL_CACHE_INFO
,
434 &config_pal_cache_info
,
435 sizeof(config_pal_cache_info
)
437 { HOB_TYPE_PAL_CACHE_PROT_INFO
,
438 &config_pal_cache_prot_info
,
439 sizeof(config_pal_cache_prot_info
)
441 { HOB_TYPE_PAL_DEBUG_INFO
,
442 &config_pal_debug_info
,
443 sizeof(config_pal_debug_info
)
445 { HOB_TYPE_PAL_FIXED_ADDR
,
446 &config_pal_fixed_addr
,
447 sizeof(config_pal_fixed_addr
)
449 { HOB_TYPE_PAL_FREQ_BASE
,
450 &config_pal_freq_base
,
451 sizeof(config_pal_freq_base
)
453 { HOB_TYPE_PAL_FREQ_RATIOS
,
454 &config_pal_freq_ratios
,
455 sizeof(config_pal_freq_ratios
)
457 { HOB_TYPE_PAL_HALT_INFO
,
458 &config_pal_halt_info
,
459 sizeof(config_pal_halt_info
)
461 { HOB_TYPE_PAL_PERF_MON_INFO
,
462 &config_pal_perf_mon_info
,
463 sizeof(config_pal_perf_mon_info
)
465 { HOB_TYPE_PAL_PROC_GET_FEATURES
,
466 &config_pal_proc_get_features
,
467 sizeof(config_pal_proc_get_features
)
469 { HOB_TYPE_PAL_PTCE_INFO
,
470 &config_pal_ptce_info
,
471 sizeof(config_pal_ptce_info
)
473 { HOB_TYPE_PAL_REGISTER_INFO
,
474 &config_pal_register_info
,
475 sizeof(config_pal_register_info
)
477 { HOB_TYPE_PAL_RSE_INFO
,
478 &config_pal_rse_info
,
479 sizeof(config_pal_rse_info
)
481 { HOB_TYPE_PAL_TEST_INFO
,
482 &config_pal_test_info
,
483 sizeof(config_pal_test_info
)
485 { HOB_TYPE_PAL_VM_SUMMARY
,
486 &config_pal_vm_summary
,
487 sizeof(config_pal_vm_summary
)
489 { HOB_TYPE_PAL_VM_INFO
,
491 sizeof(config_pal_vm_info
)
493 { HOB_TYPE_PAL_VM_PAGE_SIZE
,
494 &config_pal_vm_page_size
,
495 sizeof(config_pal_vm_page_size
)
500 add_pal_hob(void* hob_buf
)
503 for (i
= 0; i
< sizeof(hob_batch
)/sizeof(hob_batch_t
); i
++) {
504 if (hob_add(hob_buf
, hob_batch
[i
].type
, hob_batch
[i
].data
,
505 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
);
523 Hob_Output("Could not open kernel image\n");
527 if ((kernel_gfd
= gzdopen(kernel_fd
, "rb")) == NULL
) {
528 Hob_Output("Could not allocate decompression state for state file\n");
534 #define CHUNK 1*1024*1024
537 if ((tmp
= realloc(image
, *size
+ CHUNK
)) == NULL
) {
538 Hob_Output("Could not allocate memory for kernel image");
545 bytes
= gzread(kernel_gfd
, image
+ *size
, CHUNK
);
548 Hob_Output("Error reading kernel image");
563 Hob_Output("Could not read kernel image");
567 /* Shrink allocation to fit image. */
568 tmp
= realloc(image
, *size
);
573 if (kernel_gfd
!= NULL
)
575 else if (kernel_fd
>= 0)
589 * indent-tabs-mode: nil