Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30778
Change subject: [TESTME]soc/intel/braswell: Implement and use open source CAR ......................................................................
[TESTME]soc/intel/braswell: Implement and use open source CAR
Copied from baytrail.
Change-Id: I29eabb8960b5e98a9b50f7c7082b9e148a42fde2 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/drivers/intel/fsp1_1/car.c M src/drivers/intel/fsp1_1/include/fsp/car.h M src/soc/intel/braswell/Kconfig M src/soc/intel/braswell/Makefile.inc M src/soc/intel/braswell/romstage/Makefile.inc A src/soc/intel/braswell/romstage/cache_as_ram.inc 6 files changed, 242 insertions(+), 17 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/78/30778/1
diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 6409ad5..10e3c60 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -21,36 +21,38 @@ #include <program_loading.h> #include <timestamp.h>
-asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params) +asmlinkage void cache_as_ram_main(unsigned long bist, uint64_t tsc) { + /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram + * is still enabled. We can directly access work buffer here. */ + FSP_INFO_HEADER *fih; + struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); + /* Initialize timestamp book keeping only once. */ - timestamp_init(car_params->tsc); + timestamp_init(tsc);
/* Call into pre-console init code then initialize console. */ car_soc_pre_console_init(); car_mainboard_pre_console_init(); console_init();
- printk(BIOS_DEBUG, "FSP TempRamInit successful\n"); + printk(BIOS_SPEW, "bist: 0x%08lx\n", bist); + printk(BIOS_SPEW, "tsc: 0x%016llx\n", tsc);
- printk(BIOS_SPEW, "bist: 0x%08x\n", car_params->bist); - printk(BIOS_SPEW, "tsc: 0x%016llx\n", car_params->tsc); - - if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE || - car_params->bootloader_car_end != - (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)) { - printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n", - CONFIG_DCACHE_RAM_BASE, - CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE, - (long)car_params->bootloader_car_start, - (long)car_params->bootloader_car_end); + if (prog_locate(&fsp)) { + fih = NULL; + printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp)); + } else { + /* This leaks a mapping which this code assumes is benign as + * the flash is memory mapped CPU's address space. */ + fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); }
car_soc_post_console_init(); car_mainboard_post_console_init();
/* Return new stack value in RAM back to assembly stub. */ - cache_as_ram_stage_main(car_params->fih); + cache_as_ram_stage_main(fih); }
/* Entry point taken when romstage is called after a separate verstage. */ diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h index df5e0da..96c9cf9 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/car.h +++ b/src/drivers/intel/fsp1_1/include/fsp/car.h @@ -30,7 +30,7 @@ };
/* Entry points from the cache-as-ram assembly code. */ -asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params); +asmlinkage void cache_as_ram_main(unsigned long bist, uint64_t tsc); asmlinkage void after_cache_as_ram(void *chipset_context); asmlinkage void romstage_c_entry(void); /* Per stage calls from the above two functions. The void * return from diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig index d0a250a..b780038 100644 --- a/src/soc/intel/braswell/Kconfig +++ b/src/soc/intel/braswell/Kconfig @@ -39,7 +39,8 @@ select TSC_MONOTONIC_TIMER select TSC_SYNC_MFENCE select UDELAY_TSC - select USE_GENERIC_FSP_CAR_INC +# select USE_GENERIC_FSP_CAR_INC + select SKIP_FSP_CAR select INTEL_DESCRIPTOR_MODE_CAPABLE select HAVE_SPI_CONSOLE_SUPPORT select HAVE_FSP_GOP diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index 3296331..1a5addb 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -18,6 +18,7 @@
postcar-y += memmap.c postcar-y += iosf.c +postcar-y += ../../../cpu/intel/car/non-evict/exit_car.S
ramstage-y += acpi.c ramstage-y += chip.c diff --git a/src/soc/intel/braswell/romstage/Makefile.inc b/src/soc/intel/braswell/romstage/Makefile.inc index c3ed415..1ab1b45 100644 --- a/src/soc/intel/braswell/romstage/Makefile.inc +++ b/src/soc/intel/braswell/romstage/Makefile.inc @@ -1,3 +1,5 @@ romstage-y += early_spi.c romstage-y += pmc.c romstage-y += romstage.c + +cpu_incs-y += $(src)/soc/intel/braswell/romstage/cache_as_ram.inc diff --git a/src/soc/intel/braswell/romstage/cache_as_ram.inc b/src/soc/intel/braswell/romstage/cache_as_ram.inc new file mode 100644 index 0000000..9db7f85 --- /dev/null +++ b/src/soc/intel/braswell/romstage/cache_as_ram.inc @@ -0,0 +1,219 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2000,2007 Ronald G. Minnich rminnich@gmail.com + * Copyright (C) 2007-2008 coresystems GmbH + * + * 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 + * the Free Software Foundation; version 2 of the License. + * + * This program 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. + */ + +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/post_code.h> +#include <cpu/x86/msr.h> + +#include "fmap_config.h" + +/* The full cache-as-ram size includes the cache-as-ram portion from coreboot + * and the space used by the reference code. These 2 values combined should + * be a power of 2 because the MTRR setup assumes that. */ +#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE +#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE + +/* Cache all of CBFS just below 4GiB as Write-Protect type. */ +#define CODE_CACHE_SIZE _ALIGN_UP_POW2(___FMAP__COREBOOT_SIZE) +#define CODE_CACHE_BASE (-CODE_CACHE_SIZE) +#define CODE_CACHE_MASK (~(CODE_CACHE_SIZE - 1)) + +#define NoEvictMod_MSR 0x2e0 +#define BBL_CR_CTL3_MSR 0x11e + + /* Save the BIST result. */ + movl %eax, %ebp + +cache_as_ram: + post_code(0x20) + + /* Send INIT IPI to all excluding ourself. */ + movl $0x000C4500, %eax + movl $0xFEE00300, %esi + movl %eax, (%esi) + + /* All CPUs need to be in Wait for SIPI state */ +wait_for_sipi: + movl (%esi), %eax + bt $12, %eax + jc wait_for_sipi + + post_code(0x21) + /* Configure the default memory type to uncacheable as well as disable + * fixed and variable range mtrrs. */ + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + andl $(~0x00000cff), %eax + wrmsr + + post_code(0x22) + /* Zero the variable MTRRs. */ + movl $IA32_MCG_CAP, %ecx + rdmsr + movzx %al, %ebx + /* First variable MTRR. */ + movl $MTRR_PHYS_BASE(0), %ecx + xorl %eax, %eax + xorl %edx, %edx +1: + wrmsr + inc %ecx + dec %ebx + jnz 1b + + /* Clear/disable fixed MTRRs */ + mov $fixed_mtrr_list_size, %ebx + xor %eax, %eax + xor %edx, %edx + +clear_fixed_mtrr: + add $-2, %ebx + movzwl fixed_mtrr_list(%ebx), %ecx + wrmsr + jnz clear_fixed_mtrr + + /* Determine CPU_ADDR_BITS and load PHYSMASK high word to %edx. */ + movl $0x80000008, %eax + cpuid + movb %al, %cl + sub $32, %cl + movl $1, %edx + shl %cl, %edx + subl $1, %edx + + /* Preload high word of address mask (in %edx) for Variable + * MTRRs 0 and 1. + */ +addrsize_set_high: + xorl %eax, %eax + movl $MTRR_PHYS_MASK(0), %ecx + wrmsr + movl $MTRR_PHYS_MASK(1), %ecx + wrmsr + + + post_code(0x23) + /* Set Cache-as-RAM base address. */ + movl $(MTRR_PHYS_BASE(0)), %ecx + movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax + xorl %edx, %edx + wrmsr + + post_code(0x24) + /* Set Cache-as-RAM mask. */ + movl $(MTRR_PHYS_MASK(0)), %ecx + rdmsr + movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax + wrmsr + + post_code(0x25) + /* Set code caching up for romstage. */ + movl $(MTRR_PHYS_BASE(1)), %ecx + movl $(CODE_CACHE_BASE | MTRR_TYPE_WRPROT), %eax + xorl %edx, %edx + wrmsr + + movl $MTRR_PHYS_MASK(1), %ecx + rdmsr + movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax + wrmsr + + /* Enable MTRR. */ + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + orl $MTRR_DEF_TYPE_EN, %eax + wrmsr + + post_code(0x26) + + /* Enable the L2 cache. */ + movl $BBL_CR_CTL3_MSR, %ecx + rdmsr + orl $0x100, %eax + wrmsr + + post_code(0x27) + + /* Enable cache (CR0.CD = 0, CR0.NW = 0). */ + movl %cr0, %eax + andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax + invd + movl %eax, %cr0 + + /* enable the 'no eviction' mode */ + movl $NoEvictMod_MSR, %ecx + rdmsr + orl $1, %eax + wrmsr + + post_code(0x28) + + /* Clear the cache memory region. This will also fill up the cache */ + movl $CACHE_AS_RAM_BASE, %esi + movl %esi, %edi + movl $(CACHE_AS_RAM_SIZE >> 2), %ecx + xorl %eax, %eax + rep stosl + + /* enable no evict mode */ + movl $NoEvictMod_MSR, %ecx + rdmsr + orl $2, %eax + wrmsr + + post_code(0x29) + + /* Setup the stack. */ + movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax + movl %eax, %esp + + /* Push the initial TSC value from boot block. The low 32 bits are + * in mm0, and the high 32 bits are in mm1. */ + movd %mm1, %eax + pushl %eax + movd %mm0, %eax + pushl %eax + /* Restore the BIST result. */ + movl %ebp, %eax + movl %esp, %ebp + pushl %eax + +before_romstage: + post_code(0x2a) + /* Call car.c main function. */ + call cache_as_ram_main + + /* Should never see this postcode */ + post_code(POST_DEAD_CODE) + +.Lhlt: + hlt + jmp .Lhlt + +fixed_mtrr_list: + .word MTRR_FIX_64K_00000 + .word MTRR_FIX_16K_80000 + .word MTRR_FIX_16K_A0000 + .word MTRR_FIX_4K_C0000 + .word MTRR_FIX_4K_C8000 + .word MTRR_FIX_4K_D0000 + .word MTRR_FIX_4K_D8000 + .word MTRR_FIX_4K_E0000 + .word MTRR_FIX_4K_E8000 + .word MTRR_FIX_4K_F0000 + .word MTRR_FIX_4K_F8000 +fixed_mtrr_list_size = . - fixed_mtrr_list