Patch set updated for coreboot: ce412c1 Add an alternative bootblock implementation.
Denis Carikli (GNUtoo@no-log.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3549 -gerrit commit ce412c14d773e34fa25639d50e0398e524f4457d Author: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> Date: Fri Jun 21 23:32:19 2013 +0200 Add an alternative bootblock implementation. Change-Id: I1109c49c7c84461bb056b36ee5d07391c2392176 Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> --- src/arch/x86/Kconfig | 13 ++++++ src/arch/x86/include/arch/cbfs.h | 8 ++++ src/arch/x86/init/bootblock_failboot.c | 53 ++++++++++++++++++++++ src/cpu/amd/agesa/cache_as_ram.inc | 9 +++- src/cpu/amd/car/cache_as_ram.inc | 9 +++- src/cpu/amd/geode_gx2/cache_as_ram.inc | 11 +++++ src/cpu/amd/geode_lx/cache_as_ram.inc | 11 +++++ src/cpu/intel/car/cache_as_ram.inc | 9 ++++ src/cpu/intel/car/cache_as_ram_ht.inc | 12 +++++ src/cpu/intel/haswell/cache_as_ram.inc | 11 +++++ src/cpu/intel/model_2065x/cache_as_ram.inc | 9 ++++ src/cpu/intel/model_206ax/cache_as_ram.inc | 9 ++++ src/cpu/intel/model_6ex/cache_as_ram.inc | 9 ++++ src/cpu/via/car/cache_as_ram.inc | 8 ++++ src/cpu/x86/16bit/entry16.inc | 8 ++++ src/cpu/x86/32bit/entry32.inc | 10 +++- src/cpu/x86/fpu_enable.inc | 9 +++- src/cpu/x86/sse_enable.inc | 9 +++- src/drivers/pc80/mc146818rtc_early.c | 11 +++++ .../emulation/qemu-i440fx/cache_as_ram.inc | 10 ++++ src/northbridge/intel/i5000/halt_second_bsp.S | 9 ++++ 21 files changed, 241 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index 69cdc8a..8942a66 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -54,12 +54,25 @@ config X86_BOOTBLOCK_SIMPLE config X86_BOOTBLOCK_NORMAL bool "Switch to normal if CMOS says so" +config X86_BOOTBLOCK_FAILBOOT + bool "Switch to Fallback if it fails to boot" + help + Switch to Fallback after failling to boot. + Coreboot will reset boot_option to Fallback + as early as possible, If the user has + a Fallback and a Normal image in cbfs, + and wants to boot on the Normal image, + he must reset the boot_option to Normal + after successfully booting(like trough the OS + boot scripts that would run something like: + "nvramtool -w boot_option=Normal". endchoice config BOOTBLOCK_SOURCE string default "bootblock_simple.c" if X86_BOOTBLOCK_SIMPLE default "bootblock_normal.c" if X86_BOOTBLOCK_NORMAL + default "bootblock_failboot.c" if X86_BOOTBLOCK_FAILBOOT config UPDATE_IMAGE bool "Update existing coreboot.rom image" diff --git a/src/arch/x86/include/arch/cbfs.h b/src/arch/x86/include/arch/cbfs.h index 8a61d6e..b6df10b 100644 --- a/src/arch/x86/include/arch/cbfs.h +++ b/src/arch/x86/include/arch/cbfs.h @@ -45,4 +45,12 @@ static inline void call(unsigned long addr, unsigned long bist) { asm volatile ("jmp *%0\n\t" : : "r" (addr), "a" (bist)); } + +#if CONFIG_X86_BOOTBLOCK_FAILBOOT +static inline void call_cmos_stage(unsigned long addr, unsigned long bist, int normal) +{ + asm volatile ("jmp *%0\n\t" : : "r" (addr), "a" (bist),"b" (normal)); +} +#endif + #endif diff --git a/src/arch/x86/init/bootblock_failboot.c b/src/arch/x86/init/bootblock_failboot.c new file mode 100644 index 0000000..17e5ee3 --- /dev/null +++ b/src/arch/x86/init/bootblock_failboot.c @@ -0,0 +1,53 @@ +#include <bootblock_common.h> +#include <pc80/mc146818rtc.h> + +static const char *get_fallback(const char *stagelist) { + while (*stagelist) stagelist++; + return ++stagelist; +} + +static void main(unsigned long bist) +{ + unsigned long entry; + int boot_mode; + const char *default_filenames = "normal/romstage\0fallback/romstage"; + + if (boot_cpu()) { + bootblock_mainboard_init(); + +#if CONFIG_USE_OPTION_TABLE + sanitize_cmos(); +#endif + boot_mode = last_boot_normal(); + } else { + + /* Questionable single byte read from CMOS. + * Do not add any other CMOS access in the + * bootblock for AP CPUs. + */ + boot_mode = last_boot_normal(); + } + + char *filenames = (char *)walkcbfs("coreboot-stages"); + if (!filenames) { + filenames = default_filenames; + } + char *normal_candidate = filenames; + + if (boot_mode) + entry = findstage(normal_candidate); + else + entry = findstage(get_fallback(normal_candidate)); + + /* reset nvram to fallback */ + set_boot_fallback(); + + if (entry) call_cmos_stage(entry, bist, boot_mode); + + /* run fallback if normal can't be found */ + entry = findstage(get_fallback(normal_candidate)); + if (entry) call_cmos_stage(entry, bist, boot_mode); + + /* duh. we're stuck */ + asm volatile ("1:\n\thlt\n\tjmp 1b\n\t"); +} diff --git a/src/cpu/amd/agesa/cache_as_ram.inc b/src/cpu/amd/agesa/cache_as_ram.inc index c645a1e..780add6 100755 --- a/src/cpu/amd/agesa/cache_as_ram.inc +++ b/src/cpu/amd/agesa/cache_as_ram.inc @@ -57,7 +57,10 @@ cache_as_ram_setup: /* Save the BIST result */ cvtsi2sd %ebp, %xmm0 - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Not implemented for AGESA" +#endif /* for normal part %ebx already contain cpu_init_detected from fallback call */ /* Save the cpu_init_detected */ @@ -70,6 +73,10 @@ cache_as_ram_setup: /* Restore the BIST result */ cvtsd2si %xmm0, %edx +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Not implemented for AGESA" +#endif /* Restore the cpu_init_detected */ cvtsd2si %xmm1, %ebx diff --git a/src/cpu/amd/car/cache_as_ram.inc b/src/cpu/amd/car/cache_as_ram.inc index 7070cf9..c8d6177 100644 --- a/src/cpu/amd/car/cache_as_ram.inc +++ b/src/cpu/amd/car/cache_as_ram.inc @@ -45,6 +45,10 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif /* * For normal part %ebx already contain cpu_init_detected @@ -408,7 +412,10 @@ CAR_FAM10_ap_out: /* Restore the BIST result. */ movl %ebp, %eax - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif /* We need to set EBP? No need. */ movl %esp, %ebp pushl %ebx /* Init detected. */ diff --git a/src/cpu/amd/geode_gx2/cache_as_ram.inc b/src/cpu/amd/geode_gx2/cache_as_ram.inc index 6a107fe..28c3f16 100644 --- a/src/cpu/amd/geode_gx2/cache_as_ram.inc +++ b/src/cpu/amd/geode_gx2/cache_as_ram.inc @@ -38,6 +38,11 @@ /** /***************************************************************************/ DCacheSetup: +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers for Geode GX2" + //movl %ebx, ??? +#endif /* Save the BIST result */ movl %eax, %ebx @@ -154,6 +159,12 @@ DCacheSetupGood: /* Restore the BIST result */ movl %ebx, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers for Geode GX2" + //movl ??? , %ebx ??? +#endif + movl %esp, %ebp pushl %eax diff --git a/src/cpu/amd/geode_lx/cache_as_ram.inc b/src/cpu/amd/geode_lx/cache_as_ram.inc index 45fd166..16a19e0 100644 --- a/src/cpu/amd/geode_lx/cache_as_ram.inc +++ b/src/cpu/amd/geode_lx/cache_as_ram.inc @@ -35,6 +35,11 @@ /** /***************************************************************************/ DCacheSetup: +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers available for Geode LX" + //movl %ebx, %??? +#endif /* Save the BIST result */ movl %eax, %ebx @@ -180,6 +185,12 @@ DCacheSetupGood: /* Restore the BIST result */ movl %ebx, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers available for Geode LX" + //movl ??? , %ebx ??? +#endif + movl %esp, %ebp pushl %eax diff --git a/src/cpu/intel/car/cache_as_ram.inc b/src/cpu/intel/car/cache_as_ram.inc index 1ea50b8..a3a9c29 100644 --- a/src/cpu/intel/car/cache_as_ram.inc +++ b/src/cpu/intel/car/cache_as_ram.inc @@ -32,6 +32,10 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %ebp +#endif CacheAsRam: /* Check whether the processor has HT capability. */ @@ -319,10 +323,15 @@ clear_fixed_var_mtrr_out: lout: /* Restore the BIST result. */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif /* We need to set EBP? No need. */ movl %esp, %ebp pushl %eax /* BIST */ + // pushl %ebx /* nvram's boot_option */ ??? No ebp used after that... call main /* We don't need CAR from now on. */ diff --git a/src/cpu/intel/car/cache_as_ram_ht.inc b/src/cpu/intel/car/cache_as_ram_ht.inc index 8a845e9..954114f 100644 --- a/src/cpu/intel/car/cache_as_ram_ht.inc +++ b/src/cpu/intel/car/cache_as_ram_ht.inc @@ -35,6 +35,12 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers available in src/cpu/intel/car/cache_as_ram_ht.inc" + //movl %ebx, %??? /* %esp and %ebx are used later... */ +#endif + cache_as_ram: post_code(0x20) @@ -343,6 +349,12 @@ no_msr_11e: /* Restore the BIST result. */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers for Geode src/cpu/intel/car/cache_as_ram_ht.inc" + //movl ??? , %ebx ??? +#endif + movl %esp, %ebp pushl %eax diff --git a/src/cpu/intel/haswell/cache_as_ram.inc b/src/cpu/intel/haswell/cache_as_ram.inc index 8601f46..7688a50 100644 --- a/src/cpu/intel/haswell/cache_as_ram.inc +++ b/src/cpu/intel/haswell/cache_as_ram.inc @@ -43,6 +43,11 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers available for haswell" + //movl %ebx, ??? /* %esp and %ebx are used later... */ +#endif cache_as_ram: post_code(0x20) @@ -170,6 +175,12 @@ clear_mtrrs: andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax movl %eax, %cr0 +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + #error "CONFIG_X86_BOOTBLOCK_FAILBOOT Fixme: Not enough registers available for haswell" + //movl ??? , %ebx ??? +#endif + /* Setup the stack. */ movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax movl %eax, %esp diff --git a/src/cpu/intel/model_2065x/cache_as_ram.inc b/src/cpu/intel/model_2065x/cache_as_ram.inc index db0eaae..2893ea7 100644 --- a/src/cpu/intel/model_2065x/cache_as_ram.inc +++ b/src/cpu/intel/model_2065x/cache_as_ram.inc @@ -38,6 +38,11 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + /* Nothing to do, since %esp is used and %ebx not */ + /* Do not clobber %ebx */ +#endif cache_as_ram: post_code(0x20) @@ -174,6 +179,10 @@ clear_mtrrs: movl %ebp, %eax movl %esp, %ebp pushl %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + /* should I push %ebx in the stack? */ +#endif before_romstage: post_code(0x29) diff --git a/src/cpu/intel/model_206ax/cache_as_ram.inc b/src/cpu/intel/model_206ax/cache_as_ram.inc index 2652cb7..d9fb482 100644 --- a/src/cpu/intel/model_206ax/cache_as_ram.inc +++ b/src/cpu/intel/model_206ax/cache_as_ram.inc @@ -38,6 +38,11 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + /* Nothing to do, since %esp is used and %ebx not */ + /* Do not clobber %ebx */ +#endif cache_as_ram: post_code(0x20) @@ -174,6 +179,10 @@ clear_mtrrs: movl %ebp, %eax movl %esp, %ebp pushl %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + /* should I push %ebx in the stack? */ +#endif before_romstage: post_code(0x29) diff --git a/src/cpu/intel/model_6ex/cache_as_ram.inc b/src/cpu/intel/model_6ex/cache_as_ram.inc index 50fab35..ed25ef8 100644 --- a/src/cpu/intel/model_6ex/cache_as_ram.inc +++ b/src/cpu/intel/model_6ex/cache_as_ram.inc @@ -30,6 +30,11 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + /* Nothing to do, since %esp is used and %ebx not */ + /* Do not clobber %ebx */ +#endif cache_as_ram: post_code(0x20) @@ -138,6 +143,10 @@ clear_mtrrs: movl %ebp, %eax movl %esp, %ebp pushl %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + /* should I push %ebx in the stack? */ +#endif post_code(0x23) diff --git a/src/cpu/via/car/cache_as_ram.inc b/src/cpu/via/car/cache_as_ram.inc index 17b4b83..eea0b93 100644 --- a/src/cpu/via/car/cache_as_ram.inc +++ b/src/cpu/via/car/cache_as_ram.inc @@ -35,6 +35,10 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif CacheAsRam: @@ -204,6 +208,10 @@ testok: /* Restore the BIST result. */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif /* We need to set EBP? No need. */ movl %esp, %ebp diff --git a/src/cpu/x86/16bit/entry16.inc b/src/cpu/x86/16bit/entry16.inc index e4613bf..b7f90c2 100644 --- a/src/cpu/x86/16bit/entry16.inc +++ b/src/cpu/x86/16bit/entry16.inc @@ -36,6 +36,10 @@ _start: cli /* Save the BIST result */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif post_code(POST_RESET_VECTOR_CORRECT) @@ -114,6 +118,10 @@ _start: /* Restore BIST to %eax */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif /* Now that we are in protected mode jump to a 32 bit code segment. */ data32 ljmp $ROM_CODE_SEG, $__protected_start diff --git a/src/cpu/x86/32bit/entry32.inc b/src/cpu/x86/32bit/entry32.inc index f74e1b8..9299316 100644 --- a/src/cpu/x86/32bit/entry32.inc +++ b/src/cpu/x86/32bit/entry32.inc @@ -51,7 +51,10 @@ protected_start: __protected_start: /* Save the BIST value */ movl %eax, %ebp - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif post_code(POST_ENTER_PROTECTED_MODE) movw $ROM_DATA_SEG, %ax @@ -63,4 +66,7 @@ __protected_start: /* Restore the BIST value to %eax */ movl %ebp, %eax - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif diff --git a/src/cpu/x86/fpu_enable.inc b/src/cpu/x86/fpu_enable.inc index c08e8a0..2d43b34 100644 --- a/src/cpu/x86/fpu_enable.inc +++ b/src/cpu/x86/fpu_enable.inc @@ -20,7 +20,10 @@ __fpu_start: /* Preserve BIST. */ movl %eax, %ebp - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif /* * Clear the CR0[2] bit (the "Emulation" flag, EM). * @@ -37,3 +40,7 @@ __fpu_start: /* Restore BIST. */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif diff --git a/src/cpu/x86/sse_enable.inc b/src/cpu/x86/sse_enable.inc index 09dea02..1e1ed49 100644 --- a/src/cpu/x86/sse_enable.inc +++ b/src/cpu/x86/sse_enable.inc @@ -19,6 +19,10 @@ /* Preserve BIST. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + movl %ebx, %esp +#endif /* Enable SSE instructions. */ movl %cr4, %eax @@ -27,4 +31,7 @@ /* Restore BIST. */ movl %ebp, %eax - +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + movl %esp, %ebx +#endif diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c index 0652f27..df8215a 100644 --- a/src/drivers/pc80/mc146818rtc_early.c +++ b/src/drivers/pc80/mc146818rtc_early.c @@ -49,6 +49,17 @@ static inline int last_boot_normal(void) return (byte & (1 << 1)); } +#if CONFIG_X86_BOOTBLOCK_FAILBOOT +static inline void set_boot_fallback(void) +{ + unsigned char byte; + byte = cmos_read(RTC_BOOT_BYTE); + /* set it back to Fallback */ + byte &= ~(1<<0); + cmos_write(byte, RTC_BOOT_BYTE); +} +#endif + static inline int do_normal_boot(void) { unsigned char byte; diff --git a/src/mainboard/emulation/qemu-i440fx/cache_as_ram.inc b/src/mainboard/emulation/qemu-i440fx/cache_as_ram.inc index 11ac91d..deb7b65 100644 --- a/src/mainboard/emulation/qemu-i440fx/cache_as_ram.inc +++ b/src/mainboard/emulation/qemu-i440fx/cache_as_ram.inc @@ -31,6 +31,11 @@ /* Save the BIST result. */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #warning "CONFIG_X86_BOOTBLOCK_FAILBOOT is used, the build may fail" + movl %ebx, %esp +#endif cache_as_ram: post_code(0x20) @@ -49,6 +54,11 @@ cache_as_ram: /* Restore the BIST result. */ movl %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + #warning "CONFIG_X86_BOOTBLOCK_FAILBOOT is used, the build may fail" + movl %esp, %ebx +#endif movl %esp, %ebp pushl %eax diff --git a/src/northbridge/intel/i5000/halt_second_bsp.S b/src/northbridge/intel/i5000/halt_second_bsp.S index 041807e..f21e23d 100644 --- a/src/northbridge/intel/i5000/halt_second_bsp.S +++ b/src/northbridge/intel/i5000/halt_second_bsp.S @@ -1,6 +1,11 @@ /* Save BIST result */ movl %eax, %ebp +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Preserve the nvram's boot_option parameter */ + /* Nothing to do, since %ebx is not used */ + /* Do not clobber %ebx */ +#endif /* check if SPAD0 is cleared. If yes, it means this was a hard reset */ movl $0x800080d0, %eax @@ -56,3 +61,7 @@ loop: hlt /* Restore BIST */ mov %ebp, %eax +#if CONFIG_X86_BOOTBLOCK_FAILBOOT + /* Restore nvram's saved boot_option parameter */ + /* Nothing to do, since %ebx is not used */ +#endif
participants (1)
-
Denis Carikli