romstage.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <adainit.h> 4 #include <arch/romstage.h> 5 #include <arch/symbols.h> 6 #include <arch/stack_canary_breakpoint.h> 7 #include <commonlib/helpers.h> 8 #include <console/console.h> 9 #include <cpu/x86/smm.h> 10 #include <program_loading.h> 11 #include <romstage_common.h> 12 #include <security/vboot/vboot_common.h> 13 #include <types.h> 14 15 /* If we do not have a constrained _car_stack region size, use the 16 following as a guideline for acceptable stack usage. */ 17 #define DCACHE_RAM_ROMSTAGE_STACK_SIZE 0x2000 18 19 void __noreturn romstage_main(void) 20 { 21 int i; 22 const int num_guards = 64; 23 const u32 stack_guard = 0xdeadbeef; 24 u32 *stack_base; 25 u32 size; 26 const size_t stack_size = MAX(CONFIG_DCACHE_BSP_STACK_SIZE, 27 DCACHE_RAM_ROMSTAGE_STACK_SIZE); 28 29 /* Size of unallocated CAR. */ 30 size = ALIGN_DOWN(_car_stack_size, 16); 31 32 size = MIN(size, stack_size); 33 if (size < stack_size) 34 printk(BIOS_DEBUG, "Romstage stack size limited to 0x%x!\n", 35 size); 36 37 stack_base = (u32 *)(_ecar_stack - size); 38 39 /* Disable breakpoint since stack is intentionally corrupted */ 40 stack_canary_breakpoint_remove(); 41 42 /* 43 * The "stack guard" and the "stack canary breakpoint" can both detect excessive 44 * stack usage. Excessive stack usage can corrupt data and lead to undefined 45 * (and thus hard to debug) behaviour. 46 * The stack guard will be checked later on, assuming the corruption wasn't to 47 * severe and allowed romstage to run. It's useful to detect problems when 48 * HW breakpoints were disabled. 49 * 50 * When HW breakpoints are used and enabled, the stack canary breakpoint will 51 * report the instruction pointer immediately, which can hint at which function 52 * may be using too much stack. FSP might disable HW breakpoints, though. 53 */ 54 for (i = 0; i < num_guards; i++) 55 stack_base[i] = stack_guard; 56 57 stack_canary_breakpoint_init(); 58 59 if (CONFIG(VBOOT_EARLY_EC_SYNC)) 60 vboot_sync_ec(); 61 62 /* 63 * We can generally jump between C and Ada code back and forth 64 * without trouble. But since we don't have an Ada main() we 65 * have to do some Ada package initializations that GNAT would 66 * do there. This has to be done before calling any Ada code. 67 * 68 * The package initializations should not have any dependen- 69 * cies on C code. So we can call them here early, and don't 70 * have to worry at which point we can start to use Ada. 71 */ 72 romstage_adainit(); 73 74 mainboard_romstage_entry(); 75 76 /* Check the stack. */ 77 for (i = 0; i < num_guards; i++) { 78 if (stack_base[i] == stack_guard) 79 continue; 80 printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n"); 81 } 82 83 if (CONFIG(SMM_TSEG)) 84 smm_list_regions(); 85 86 prepare_and_run_postcar(); 87 /* We do not return here. */ 88 }