Arthur Heymans has uploaded this change for review.

View Change

[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

To view, visit change 30778. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I29eabb8960b5e98a9b50f7c7082b9e148a42fde2
Gerrit-Change-Number: 30778
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur@aheymans.xyz>
Gerrit-MessageType: newchange