forked from wolfSSL/wolfBoot
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathboot_x86_fsp.c
More file actions
674 lines (602 loc) · 22.1 KB
/
boot_x86_fsp.c
File metadata and controls
674 lines (602 loc) · 22.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
/* boot_x86_fsp.c
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <printf.h>
#include <string.h>
#include <x86/fsp/FspCommon.h>
#include <x86/common.h>
#include <x86/fsp.h>
#include <uart_drv.h>
#include <x86/hob.h>
#include <x86/paging.h>
#include <pci.h>
#include <target.h>
#include <stage2_params.h>
#include "wolfboot/wolfboot.h"
#include "image.h"
#ifdef WOLFBOOT_TPM
#include <loader.h>
#include <tpm.h>
#endif
#define WOLFBOOT_X86_STACK_SIZE 0x10000
#ifndef STAGE1_AUTH
/* When STAGE1_AUTH is disabled, create dummy images to fill
* the space used by wolfBoot manifest headers to authenticate FSPs
*/
#define HEADER_SIZE IMAGE_HEADER_SIZE
const uint8_t __attribute__((section(".sig_fsp_s")))
empty_sig_fsp_s[HEADER_SIZE] = {};
const uint8_t __attribute__((section(".sig_wolfboot_raw")))
empty_sig_wolfboot_raw[HEADER_SIZE] = {};
#endif
/* info can be retrieved from the CfgRegionSize of FSP info header. we need to
* know this at compile time because to make things simpler we want to use the
* stack to store the parameters and we don't want to include machine specific
* code here */
#ifndef FSP_M_UDP_MAX_SIZE
/* #define FSP_M_UDP_MAX_SIZE 0x80 */
#define FSP_M_UDP_MAX_SIZE 0x978
#endif
/* Amount of car memory to provide to FSP-M, machine dependent, find the value
* in the integration guide */
#ifndef FSP_M_CAR_MEM_SIZE
#define FSP_M_CAR_MEM_SIZE 0x50000
#endif
/* offset of the header from the base image */
#define FSP_INFO_HEADER_OFFSET 0x94
#define EFI_SUCCESS 0x0
#define FSP_STATUS_RESET_REQUIRED_COLD 0x40000001
#define FSP_STATUS_RESET_REQUIRED_WARM 0x40000002
#define MEMORY_4GB (4ULL * 1024 * 1024 * 1024)
#define ENDLINE "\r\n"
/* Standard PCI capabilities live in conventional config space at 0x40-0xFC,
* on 4-byte alignment, so there are at most 48 distinct capability headers. */
#define PCI_MAX_STANDARD_CAPABILITIES 48
/* compile time alignment checks */
#define ALIGN_CHECK(value, alignment) ((value) & ((alignment)-1)) == 0
#if !ALIGN_CHECK(WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE, 16)
#error "WOLFBOOT_LOAD_BASE must be aligned on a 16 bytes boundary"
#endif
typedef uint32_t (*memory_init_cb)(void *udp, struct efi_hob **HobList);
/* need to be implemented by machine dependent code */
int fsp_machine_update_m_parameters(uint8_t *default_m_params,
uint32_t mem_base, uint32_t mem_size);
int fsp_machine_update_s_parameters(uint8_t *default_s_params);
int post_temp_ram_init_cb(void);
int fsp_pre_mem_init_cb(void);
int fsp_pre_silicon_init_cb(void);
/* from the linker */
extern uint8_t _start_fsp_t[];
extern uint8_t _start_fsp_m[];
extern uint8_t _end_fsp_m[];
extern uint8_t _wolfboot_flash_start[];
extern uint8_t _wolfboot_flash_end[];
extern uint8_t wb_end_bss[], wb_start_bss[];
extern uint8_t _stored_data[], _start_data[], _end_data[];
extern uint8_t _start_bss[], _end_bss[];
extern const uint8_t _start_policy[], _end_policy[];
extern const uint32_t _policy_size_u32[];
extern const uint8_t _start_keystore[];
/* wolfboot symbol */
extern int main(void);
/*!
* \brief Get the top address from the EFI HOB (Hand-Off Block) list.
*
* This function retrieves the top address from the EFI Hand-Off Block (HOB) list
* and stores it in the 'top' parameter.
*
* \param top Pointer to a variable where the top address will be stored.
* \param hoblist Pointer to the EFI HOB list.
* \return 0 if the top address is successfully retrieved, -1 otherwise.
*/
static int get_top_address(uint64_t *top, struct efi_hob *hoblist)
{
struct efi_hob_resource_descriptor *fsp_reserved;
fsp_reserved = hob_find_fsp_reserved(hoblist);
if (fsp_reserved == NULL)
return -1;
*top = fsp_reserved->physical_start;
wolfBoot_printf("top reserved %x_%xh" ENDLINE, (uint32_t)(*top>>32),
(uint32_t)*top);
return 0;
}
/*!
* \brief Change the stack and invoke a function with the new stack.
*
* This function changes the stack to the specified 'new_stack' value and then
* calls the function pointed to by 'other_func', passing the 'ptr' parameter as an argument.
*
* \param new_stack The new stack address.
* \param other_func Pointer to the function to be invoked with the new stack.
* \param ptr Pointer to the parameter to be passed to the invoked function.
*/
static void change_stack_and_invoke(uint32_t new_stack,
void (*other_func)(void))
{
__asm__ volatile("movl %0, %%eax\n"
"mov %%eax, %%esp\n"
"call *%1\n"
:
: "r"(new_stack), "r"(other_func)
: "%eax");
}
static int range_overlaps(uint32_t start1, uint32_t end1, uint32_t start2,
uint32_t end2)
{
return !(end1 <= start2 || end2 <= start1);
}
static int check_memory_ranges()
{
uint32_t wb_start, wb_end;
wb_start = (uint32_t)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE;
wb_end = wb_start + (_wolfboot_flash_end - _wolfboot_flash_start);
if (range_overlaps(wb_start, wb_end, (uint32_t)_start_data,
(uint32_t)_end_data))
return -1;
if (range_overlaps(wb_start, wb_end, (uint32_t)_start_bss,
(uint32_t)_end_bss))
return -1;
if (range_overlaps((uint32_t)wb_start_bss,
(uint32_t)wb_end_bss,
(uint32_t)_start_data,
(uint32_t)_end_data))
return -1;
if (range_overlaps((uint32_t)wb_start_bss,
(uint32_t)wb_end_bss,
(uint32_t)_start_bss,
(uint32_t)_end_bss))
return -1;
return 0;
}
/*!
* \brief Load the WolfBoot bootloader into memory.
*
* This static function loads the WolfBoot bootloader into memory at the specified
* address (WOLFBOOT_LOAD_BASE) from the flash memory.
*/
static void load_wolfboot(void)
{
size_t wolfboot_size, bss_size;
uint32_t wolfboot_start;
if (check_memory_ranges() != 0) {
wolfBoot_printf("wolfboot overlaps with loader data...stop" ENDLINE);
panic();
}
wolfboot_start = (uint32_t)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE;
wolfboot_size = _wolfboot_flash_end - _wolfboot_flash_start;
x86_log_memory_load(wolfboot_start, wolfboot_start + wolfboot_size,
"wolfboot");
memcpy((uint8_t*)wolfboot_start,_wolfboot_flash_start, wolfboot_size);
bss_size = wb_end_bss - wb_start_bss;
x86_log_memory_load((uint32_t)(uintptr_t)wb_start_bss,
(uint32_t)(uintptr_t)(wb_start_bss + bss_size),
"wolfboot .bss");
memset(wb_start_bss, 0, bss_size);
wolfBoot_printf("load wolfboot end" ENDLINE);
}
#ifdef WOLFBOOT_64BIT
/*!
* \brief Jump into the WolfBoot bootloader.
*
* This static function transfers control to the WolfBoot bootloader by calling
* the main() function or switch_to_long_mode() for 64-bit systems.
*/
static void jump_into_wolfboot(void)
{
struct stage2_parameter *params;
int ret;
params = stage2_get_parameters();
ret = x86_paging_build_identity_mapping(MEMORY_4GB,
(uint8_t*)(uintptr_t)params->page_table);
if (ret != 0) {
wolfBoot_printf("can't build identity mapping\r\n");
panic();
}
stage2_copy_parameter(params);
wolfBoot_printf("starting wolfboot 64bit\r\n");
switch_to_long_mode((uint64_t*)&main, params->page_table);
panic();
}
#else
static void jump_into_wolfboot(void)
{
struct stage2_parameter *params = stage2_get_parameters();
stage2_copy_parameter(params);
main();
}
#endif /* WOLFBOOT_64BIT */
#if defined(WOLFBOOT_MEASURED_BOOT)
/* The image needs to be already verified */
int wolfBoot_image_measure(uint8_t *image)
{
struct wolfBoot_image img;
int ret;
memset(&img, 0, sizeof(img));
ret = wolfBoot_open_image_address(&img, image);
if (ret != 0) {
return ret;
}
ret = wolfBoot_verify_integrity(&img);
if (ret != 0 || img.sha_hash == NULL) {
return -1;
}
wolfBoot_print_hexstr(img.sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, 0);
return wolfBoot_tpm2_extend(WOLFBOOT_MEASURED_PCR_A, img.sha_hash,
__LINE__);
}
#endif /* WOLFBOOT_MEASURED_BOOT */
/*!
* \brief Check if the payload is valid.
*
* This static function checks if the given payload is valid by verifying
* its signature.
*
* \param base_addr Pointer to the payload
* \return 0 if the payload is successfully retrieved, -1 otherwise.
*/
static inline int verify_payload(uint8_t *base_addr)
{
int ret = -1;
struct wolfBoot_image wb_img;
memset(&wb_img, 0, sizeof(struct wolfBoot_image));
ret = wolfBoot_open_image_address(&wb_img, base_addr);
if (ret < 0) {
wolfBoot_printf("verify_payload: Failed to open image" ENDLINE);
panic();
}
wolfBoot_printf("verify_payload: image open successfully." ENDLINE);
ret = wolfBoot_verify_integrity(&wb_img);
if (ret < 0) {
wolfBoot_printf("verify_payload: Failed integrity check" ENDLINE);
panic();
}
wolfBoot_printf("verify_payload: integrity OK. Checking signature." ENDLINE);
ret = wolfBoot_verify_authenticity(&wb_img);
if (ret < 0) {
wolfBoot_printf("verify_payload: Failed signature check" ENDLINE);
panic();
}
return ret;
}
/*!
* \brief Initialization of .data and .bss sections after memory initialization.
*
* This static function copies initial values for .data to the corresponding
* section in the linker script, and initializes the .bss section to zero.
*
* This function is called after memory initialization is completed and the stack
* has been remapped.
*
*/
static inline void memory_init_data_bss(void)
{
uint32_t *datamem_p;
uint32_t *dataflash_p;
x86_log_memory_load((uint32_t)(uintptr_t)_start_data,
(uint32_t)(uintptr_t)_end_data, "stage1 .data");
datamem_p = (uint32_t *)_start_data;
dataflash_p = (uint32_t *)_stored_data;
while(datamem_p < (uint32_t *)_end_data) {
*(datamem_p++) = *(dataflash_p++);
}
x86_log_memory_load((uint32_t)(uintptr_t)_start_bss,
(uint32_t)(uintptr_t)_end_bss, "stage1 .bss");
memset(_start_bss, 0, (_end_bss - _start_bss));
}
static int pci_get_capability(uint8_t bus, uint8_t dev, uint8_t fun,
uint8_t cap_id, uint8_t *cap_off)
{
uint8_t r8, id;
uint8_t cap_count = 0;
uint32_t r32;
r32 = pci_config_read16(bus, dev, fun, PCI_STATUS_OFFSET);
if (!(r32 & PCI_STATUS_CAP_LIST))
return -1;
r8 = pci_config_read8(bus, dev, fun, PCI_CAP_OFFSET);
while ((r8 != 0) && (cap_count < PCI_MAX_STANDARD_CAPABILITIES)) {
id = pci_config_read8(bus, dev, fun, r8);
if (id == cap_id) {
*cap_off = r8;
return 0;
}
r8 = pci_config_read8(bus, dev, fun, r8 + 1);
cap_count++;
}
return -1;
}
#if defined(TARGET_x86_fsp_qemu) && defined(WOLFBOOT_MEASURED_BOOT)
/*!
* \brief Extend the PCR with stage1 compoments
*
* This function calculates the SHA-256 hash differents compoment of the
* bootloader: keystore, stage1 code, reset vector, FSP_T, FSP_M and FSP_S. The
* layout of these components in the flash is consecutive, it start at keystore
* up to the end of the flash, that is at 4GB.
*
*
* \return 0 on success, error code on failure
*/
static int self_extend_pcr(void)
{
uint8_t hash[SHA256_DIGEST_SIZE];
uint32_t blksz, position = 0;
wc_Sha256 sha256_ctx;
uint32_t sz;
uintptr_t p;
p = (uintptr_t)_start_keystore;
/* The flash is memory mapped so that it ends at 4GB */
sz = ((MEMORY_4GB) - (uint64_t)p);
wc_InitSha256(&sha256_ctx);
do {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (position + blksz > sz)
blksz = sz - position;
wc_Sha256Update(&sha256_ctx, (uint8_t*)p, blksz);
position += blksz;
p += blksz;
} while (position < sz);
wc_Sha256Final(&sha256_ctx, hash);
wolfBoot_print_hexstr(hash, SHA256_DIGEST_SIZE, 0);
return wolfBoot_tpm2_extend(WOLFBOOT_MEASURED_PCR_A, hash, __LINE__);
}
#endif
/*!
* \brief Entry point after memory initialization.
*
* This static function serves as the entry point for further execution after the
* memory initialization is completed and the stack has been remapped.
*
*/
static void memory_ready_entry(uint32_t new_stack)
{
struct fsp_info_header *fsp_info;
uint8_t *fsp_s_base;
uint8_t *fsp_m_base;
uint32_t cpu_info[4];
uint32_t status;
int ret;
/* Confirmed memory initialization complete.
*
* Copy .data section to RAM and initialize .bss
*/
memory_init_data_bss();
#if (defined(WOLFBOOT_MEASURED_BOOT)) || \
(defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY))
wolfBoot_printf("Initializing WOLFBOOT_TPM" ENDLINE);
ret = wolfBoot_tpm2_init();
if (ret != 0) {
wolfBoot_printf("tpm init failed" ENDLINE);
panic();
}
ret = wolfBoot_tpm_self_test();
if (ret != 0) {
wolfBoot_printf("tpm self test failed" ENDLINE);
panic();
}
#endif
#if (defined(TARGET_x86_fsp_qemu) && defined(WOLFBOOT_MEASURED_BOOT))
ret = self_extend_pcr();
if (ret != 0)
wolfBoot_printf("fail to extend PCR" ENDLINE);
#endif
/* Get CPUID */
cpuid(0, &cpu_info[0], &cpu_info[1], &cpu_info[2], NULL);
wolfBoot_printf("CPUID(0):%x %x %x\r\n", cpu_info[0], cpu_info[1], cpu_info[2]);
/* Load stage2 wolfBoot to RAM */
load_wolfboot();
#ifdef STAGE1_AUTH
/* Verify stage2 wolfBoot */
wolfBoot_printf("Authenticating wolfboot at %x..." ENDLINE,
WOLFBOOT_LOAD_BASE);
if (verify_payload((uint8_t *)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE) == 0)
wolfBoot_printf("wolfBoot: verified OK." ENDLINE);
else {
panic();
}
#endif
#if defined(WOLFBOOT_MEASURED_BOOT)
ret = wolfBoot_image_measure((uint8_t*)WOLFBOOT_LOAD_BASE
- IMAGE_HEADER_SIZE);
if (ret != 0) {
wolfBoot_printf("Fail to measure WOLFBOOT image\r\n");
panic();
}
#endif /* WOLFBOOT_MEASURED_BOOT */
#if (defined(WOLFBOOT_MEASURED_BOOT)) || \
(defined(STAGE1_AUTH) && defined (WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY))
wolfBoot_tpm2_deinit();
#endif
/* change_stack_and_invoke() never returns.
*
* Execution here is eventually transferred to jump_into_wolfboot, that
* will transfer the execution to stage2 after the stack has been remapped.
*/
change_stack_and_invoke(new_stack, jump_into_wolfboot);
}
static void print_ucode_revision(void)
{
#if !defined(TARGET_x86_fsp_qemu)
/* incomplete */
struct ucode_header {
uint32_t header_version;
uint32_t update_revision;
uint32_t date;
/* other fields not needed */
} __attribute__((packed));
struct ucode_header *h;
h = (struct ucode_header *)UCODE0_ADDRESS;
wolfBoot_printf("microcode revision: %x, date: %x-%x-%x\r\n",
(int)h->update_revision,
(int)((h->date >> 24) & 0xff), /* month */
(int)((h->date >> 16) & 0xff), /* day */
(int)(h->date & 0xffff)); /* year */
#else
wolfBoot_printf("no microcode for QEMU target\r\n");
#endif
}
/*!
* \brief Entry point for the FSP-M (Firmware Support Package - Memory) module.
*
* This function serves as the entry point for the FSP-M module, which is executed
* during the boot process. It takes the stack base, stack top, timestamp, and BIST
* (Built-In Self Test) as input arguments.
*
* \param stack_base The base address of the stack.
* \param stack_top The top address of the stack.
* \param timestamp A timestamp value.
* \param bist Built-In Self Test value.
*/
void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp,
uint32_t bist)
{
uint8_t udp_m_parameter[FSP_M_UDP_MAX_SIZE], *udp_m_default;
struct stage2_ptr_holder *mem_stage2_holder;
struct fsp_info_header *fsp_m_info_header;
struct stage2_parameter *stage2_params;
struct stage2_ptr_holder stage2_holder;
struct stage2_parameter temp_params;
uint8_t *fsp_m_base, done = 0;
struct efi_hob *hobList, *it;
memory_init_cb MemoryInit;
uint64_t top_address = MEMORY_4GB;
uint32_t new_stack;
uint32_t status;
uint16_t type;
uint32_t esp;
#ifdef STAGE1_AUTH
int ret;
struct wolfBoot_image fsp_m;
#endif
(void)stack_top;
(void)timestamp;
(void)bist;
fsp_m_base = (uint8_t *)(_start_fsp_m);
status = post_temp_ram_init_cb();
if (status != 0) {
wolfBoot_printf("post temp ram init cb failed" ENDLINE);
panic();
}
memset(&temp_params, 0, sizeof(temp_params));
stage2_set_parameters(&temp_params, &stage2_holder);
wolfBoot_printf("Cache-as-RAM initialized" ENDLINE);
wolfBoot_printf("FSP-T:");
print_fsp_image_revision((struct fsp_info_header *)
(_start_fsp_t + FSP_INFO_HEADER_OFFSET));
wolfBoot_printf("FSP-M:");
print_fsp_image_revision((struct fsp_info_header *)
(_start_fsp_m + FSP_INFO_HEADER_OFFSET));
print_ucode_revision();
fsp_m_info_header =
(struct fsp_info_header *)(fsp_m_base + FSP_INFO_HEADER_OFFSET);
udp_m_default = fsp_m_base + fsp_m_info_header->CfgRegionOffset;
if (!fsp_info_header_is_ok(fsp_m_info_header)) {
wolfBoot_printf("invalid FSP_INFO_HEADER" ENDLINE);
panic();
}
if (fsp_m_info_header->CfgRegionSize > sizeof(udp_m_parameter)) {
wolfBoot_printf("FSP-M UDP size is bigger than FSP_M_UDP_MAX_SIZE" ENDLINE);
panic();
}
memcpy(udp_m_parameter, udp_m_default, fsp_m_info_header->CfgRegionSize);
status = fsp_machine_update_m_parameters(udp_m_parameter, stack_base + 0x4,
FSP_M_CAR_MEM_SIZE);
if (status != 0) {
panic();
}
#if defined(WOLFBOOT_DUMP_FSP_UPD)
wolfBoot_printf("Dumping fspm udp (%d bytes)" ENDLINE, (int)fsp_m_info_header->CfgRegionSize);
wolfBoot_print_hexstr(udp_m_parameter, fsp_m_info_header->CfgRegionSize, 16);
#endif
status = fsp_pre_mem_init_cb();
if (status != 0) {
wolfBoot_printf("pre mem init cb returns %d", status);
panic();
}
wolfBoot_printf("calling FspMemInit..." ENDLINE);
MemoryInit = (memory_init_cb)(fsp_m_base +
fsp_m_info_header->FspMemoryInitEntryOffset);
status = MemoryInit((void *)udp_m_parameter, &hobList);
if (status == FSP_STATUS_RESET_REQUIRED_WARM) {
wolfBoot_printf("warm reset required" ENDLINE);
reset(1);
}
else if (status == FSP_STATUS_RESET_REQUIRED_COLD) {
wolfBoot_printf("cold reset required" ENDLINE);
reset(0);
}
else if (status != EFI_SUCCESS) {
wolfBoot_printf("failed: 0x%x" ENDLINE, status);
panic();
}
wolfBoot_printf("success" ENDLINE);
status = get_top_address(&top_address, hobList);
if (status != 0) {
panic();
}
#ifdef DEBUG
hob_dump_memory_map(hobList);
#endif /* DEBUG */
if (top_address >= MEMORY_4GB) {
panic();
}
new_stack = top_address;
x86_log_memory_load(new_stack - WOLFBOOT_X86_STACK_SIZE, new_stack, "stack");
x86_log_memory_load(new_stack - WOLFBOOT_X86_STACK_SIZE - sizeof(struct stage2_parameter),
new_stack - WOLFBOOT_X86_STACK_SIZE, "stage2 parameter");
top_address =
new_stack - WOLFBOOT_X86_STACK_SIZE - sizeof(struct stage2_parameter);
stage2_params = (struct stage2_parameter *)(uint32_t)top_address;
memcpy((uint8_t *)stage2_params, (uint8_t*)&temp_params, sizeof(struct stage2_parameter));
wolfBoot_printf("hoblist@0x%x" ENDLINE, (uint32_t)hobList);
stage2_params->hobList = (uint32_t)hobList;
#ifdef WOLFBOOT_64BIT
stage2_params->page_table = ((uint32_t)(top_address) -
x86_paging_get_page_table_size());
stage2_params->page_table = (((uint32_t)stage2_params->page_table) & ~((1 << 12) - 1));
x86_log_memory_load(stage2_params->page_table, top_address, "page tables");
memset((uint8_t*)stage2_params->page_table, 0, x86_paging_get_page_table_size());
wolfBoot_printf("page table @ 0x%x [length: %x]" ENDLINE, (uint32_t)stage2_params->page_table, x86_paging_get_page_table_size());
top_address = stage2_params->page_table;
#endif /* WOLFBOOT_64BIT */
x86_log_memory_load(top_address - sizeof(struct stage2_ptr_holder), top_address, "stage2 ptr holder");
top_address = top_address - sizeof(struct stage2_ptr_holder);
mem_stage2_holder = (struct stage2_ptr_holder*)(uintptr_t)top_address;
stage2_params->tolum = top_address;
#ifdef WOLFBOOT_TPM_SEAL
stage2_params->tpm_policy = (uint32_t)_start_policy;
stage2_params->tpm_policy_size = *_policy_size_u32;
if (stage2_params->tpm_policy_size > _end_policy - _start_policy)
stage2_params->tpm_policy_size = 0;
wolfBoot_printf("setting policy @%x (%d bytes)\r\n",
(uint32_t)(uintptr_t)stage2_params->tpm_policy,
stage2_params->tpm_policy_size);
#endif
stage2_set_parameters(stage2_params, mem_stage2_holder);
wolfBoot_printf("TOLUM: 0x%x\r\n", stage2_params->tolum);
memory_ready_entry(new_stack);
/* Returning from change_stack_and_invoke() implies a fatal error
*/
wolfBoot_printf("FAIL" ENDLINE);
panic();
}