diff options
Diffstat (limited to 'src/drivers/intel/fsp1_1/cache_as_ram.inc')
-rw-r--r-- | src/drivers/intel/fsp1_1/cache_as_ram.inc | 268 |
1 files changed, 212 insertions, 56 deletions
diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc index 941da3bdf9..4a0827d2df 100644 --- a/src/drivers/intel/fsp1_1/cache_as_ram.inc +++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc @@ -4,6 +4,7 @@ * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com> * Copyright (C) 2007-2008 coresystems GmbH * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. + * Copyright (C) 2015 Intel Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +20,17 @@ * Foundation, Inc. */ +/* + * Replacement for cache_as_ram.inc when using the FSP binary. This code + * locates the FSP binary, initializes the cache as RAM and performs the + * first stage of initialization. Next this code switches the stack from + * the cache to RAM and then disables the cache as RAM. Finally this code + * performs the final stage of initialization. + */ + #include <cpu/x86/mtrr.h> #include <cpu/x86/cache.h> #include <cpu/x86/post_code.h> -#include <microcode_size.h> #include <cbmem.h> #ifndef CONFIG_FSP_LOC @@ -33,7 +41,7 @@ # error "CONFIG_POST_IO must be set." #endif -#if CONFIG_POST_IO +#if IS_ENABLED(CONFIG_POST_IO) # ifndef CONFIG_POST_IO_PORT # error "CONFIG_POST_IO_PORT must be set." # endif @@ -45,79 +53,216 @@ #define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */ - cmp $0, %eax - jne bisthalt + /* + * eax: BIST value + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + */ + + mov %eax, %edi cache_as_ram: post_code(0x20) /* + * edi: BIST value + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + */ + + /* * Find the FSP binary in cbfs. * Make a fake stack that has the return value back to this code. */ - lea fake_fsp_stack, %esp - jmp find_fsp + lea fake_fsp_stack, %esp + jmp find_fsp find_fsp_ret: /* Save the FSP location */ - mov %eax, %ebp - cmp $CONFIG_FSP_LOC, %eax - jb halt1 + mov %eax, %ebp + + /* + * Only when a valid FSP binary is found at CONFIG_FSP_LOC is + * the returned FSP_INFO_HEADER structure address above the base + * address of FSP binary specified by the CONFIG_FSP_LOC value. + * All of the error values are in the 0x8xxxxxxx range which are + * below the CONFIG_FSP_LOC value. + */ + cmp $CONFIG_FSP_LOC, %eax + jbe halt1 post_code(0x22) /* Calculate entry into FSP */ - mov 0x30(%ebp), %eax /* Load TempRamInitEntry */ - add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */ + mov 0x30(%ebp), %eax /* Load TempRamInitEntry */ + add 0x1c(%ebp), %eax /* add in the offset for FSP */ /* * Pass early init variables on a fake stack (no memory yet) * as well as the return location */ - lea CAR_init_stack, %esp + lea CAR_init_stack, %esp + + /* + * BIST value is zero + * eax: TempRamInitApi address + * ebp: FSP_INFO_HEADER address + * edi: BIST value + * esi: Not used + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + */ /* call FSP binary to setup temporary stack */ - jmp *%eax + jmp *%eax CAR_init_done: - addl $4, %esp - cmp $0, %eax - jne halt2 + addl $4, %esp + + /* + * ebp: FSP_INFO_HEADER address + * ecx: Temp RAM base + * edx: Temp RAM top + * edi: BIST value + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + */ + + cmp $0, %eax + jne halt2 + + /* Setup bootloader stack */ + movl %edx, %esp + + /* Save BIST value */ + movd %edi, %mm2 + + /* + * ebp: FSP_INFO_HEADER address + * ecx: Temp RAM base + * edx: Temp RAM top + * esp: Top of stack in temp RAM + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + * mm2: BIST value + */ + + /* Coreboot assumes stack/heap region will be zero */ + cld + movl %ecx, %edi + neg %ecx + add %edx, %ecx + shrl $2, %ecx + xorl %eax, %eax + rep stosl /* Save FSP_INFO_HEADER location in ebx */ - mov %ebp, %ebx + mov %ebp, %ebx /* - * set up bootloader stack - * ecx: stack base - * edx: stack top + * ebx: FSP_INFO_HEADER address + * esi: Temp RAM base + * esp: Top of stack in temp RAM + * mm0: low 32-bits of TSC value + * mm1: high 32-bits of TSC value + * mm2: BIST value */ - mov %edx, %esp - movl %esp, %ebp - /* Clear the cbmem CAR memory region. */ - movl %ecx, %edi - movl %edx, %ecx - sub %edi, %ecx - shr $2, %ecx - xorl %eax, %eax - rep stosl + /* Frame for romstage_main(bist, tsc_low, tsc_hi, fih) */ + pushl %ebx + movd %mm1, %eax + pushl %eax + movd %mm0, %eax + pushl %eax + movd %mm2, %eax + pushl %eax before_romstage: post_code(0x23) /* Call romstage.c main function. */ - pushl %ebx /* main takes FSP_INFO_HEADER as its argument */ - call main /* does not return */ - movb $0xB8, %ah - jmp .Lhlt + call romstage_main + + /* + * eax: New stack address + * ebx: FSP_INFO_HEADER address + */ + + /* Switch to the stack in RAM */ + movl %eax, %esp + + /* Calculate TempRamExit entry into FSP */ + movl %ebx, %ebp + mov 0x40(%ebp), %eax + add 0x1c(%ebp), %eax + + /* Build the call frame */ + pushl $0 + + /* Call TempRamExit */ + call *%eax + add $4, %esp + cmp $0, %eax + jne halt3 + + /* Get number of MTRRs. */ + popl %ebx + movl $MTRRphysBase_MSR(0), %ecx +1: + testl %ebx, %ebx + jz 1f + + /* Low 32 bits of MTRR base. */ + popl %eax + /* Upper 32 bits of MTRR base. */ + popl %edx + /* Write MTRR base. */ + wrmsr + inc %ecx + /* Low 32 bits of MTRR mask. */ + popl %eax + /* Upper 32 bits of MTRR mask. */ + popl %edx + /* Write MTRR mask. */ + wrmsr + inc %ecx + + dec %ebx + jmp 1b +1: + post_code(0x39) + + /* And enable cache again after setting MTRRs. */ + movl %cr0, %eax + andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax + movl %eax, %cr0 + + post_code(0x3a) + + /* Enable MTRR. */ + movl $MTRRdefType_MSR, %ecx + rdmsr + orl $MTRRdefTypeEn, %eax + wrmsr + + post_code(0x3b) -bisthalt: - movb $0xB9, %ah - jmp .Lhlt + /* Invalidate the cache again. */ + invd + + post_code(0x3c) + +__main: + post_code(POST_PREPARE_RAMSTAGE) + cld /* Clear direction flag. */ + call romstage_after_car + + + movb $0x69, %ah + jmp .Lhlt halt1: /* - * Failures for postcode 0xBA - failed in find_fsp() + * Failures for postcode 0xBA - failed in fsp_fih_early_find() * * Values are: * 0x01 - FV signature, "_FVH" not present @@ -128,8 +273,8 @@ halt1: * 0x05 - FSP INFO Header signature "FSPH" not found * 0x06 - FSP Image ID is not the expected ID. */ - movb $0xBA, %ah - jmp .Lhlt + movb $0xBA, %ah + jmp .Lhlt halt2: /* @@ -137,25 +282,37 @@ halt2: * * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully. * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid. - * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region. * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met. * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed + * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region. * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked */ - movb $0xBB, %ah + movb $0xBB, %ah + jmp .Lhlt + +halt3: + /* + * Failures for post code BC - failed in TempRamExit + * + * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully. + * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid. + * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met. + * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed. + */ + movb $0xBC, %ah .Lhlt: - xchg %al, %ah -#if CONFIG_POST_IO - outb %al, $CONFIG_POST_IO_PORT + xchg %al, %ah +#if IS_ENABLED(CONFIG_POST_IO) + outb %al, $CONFIG_POST_IO_PORT #else post_code(POST_DEAD_CODE) #endif - movl $LHLT_DELAY, %ecx + movl $LHLT_DELAY, %ecx .Lhlt_Delay: - outb %al, $0xED - loop .Lhlt_Delay - jmp .Lhlt + outb %al, $0xED + loop .Lhlt_Delay + jmp .Lhlt /* * esp is set to this location so that the call into and return from the FSP @@ -163,15 +320,14 @@ halt2: */ .align 4 fake_fsp_stack: - .long find_fsp_ret + .long find_fsp_ret CAR_init_params: - .long CONFIG_CPU_MICROCODE_CBFS_LOC - .long MICROCODE_REGION_LENGTH - .long 0xFFFFFFFF - CACHE_ROM_SIZE + 1 /* Firmware Location */ - .long CACHE_ROM_SIZE /* Total Firmware Length */ + .long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */ + .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */ + .long 0xFFFFFFFF - CONFIG_CBFS_SIZE + 1 /* Firmware Location */ + .long CONFIG_CBFS_SIZE /* Total Firmware Length */ CAR_init_stack: - .long CAR_init_done - .long CAR_init_params - + .long CAR_init_done + .long CAR_init_params |