From eebe0e0db14476dde980896b8eb8a97129436af3 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 18 Mar 2016 11:19:38 -0500 Subject: [PATCH] soc/intel/apollolake: utilize postcar phase/stage The current Apollolake flow has its code executing out of cache-as-ram for the pre-DRAM stages. This is different from past platforms where they were just executing-in-place against the memory-mapped SPI flash boot media. The implication is that when cache-as-ram needs to be torn down one needs to be executing out of DRAM since the act of cache-as-ram going away means the code disappears out from under the processor. Therefore load and use the postcar infrastructure to bootstrap this process for tearing down cache-as-ram and subsequently loading ramstage. Change-Id: I856f4b992dd2609b95375767bfa4fe64a267d89e Signed-off-by: Aaron Durbin Reviewed-on: https://review.coreboot.org/14141 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Furquan Shaikh --- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/Makefile.inc | 5 ++ .../intel/apollolake/bootblock/cache_as_ram.S | 7 ++- src/soc/intel/apollolake/exit_car.S | 47 +++++++++++++++++++ src/soc/intel/apollolake/include/soc/cpu.h | 8 ++-- .../intel/apollolake/include/soc/pci_devs.h | 2 +- src/soc/intel/apollolake/romstage.c | 7 ++- 7 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 src/soc/intel/apollolake/exit_car.S diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index a11c5a28d6..efebe513c2 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -28,6 +28,7 @@ config CPU_SPECIFIC_OPTIONS select PCIEXP_COMMON_CLOCK select PCIEXP_CLK_PM select PCIEXP_L1_SUB_STATE + select POSTCAR_STAGE select REG_SCRIPT select RELOCATABLE_RAMSTAGE # Build fails if this is not selected select SOC_INTEL_COMMON diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index c425f2e2e7..41ac847ce4 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -37,6 +37,11 @@ ramstage-y += mmap_boot.c ramstage-y += uart.c ramstage-y += northbridge.c +postcar-y += exit_car.S +postcar-y += memmap.c +postcar-y += mmap_boot.c +postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.c + CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include endif diff --git a/src/soc/intel/apollolake/bootblock/cache_as_ram.S b/src/soc/intel/apollolake/bootblock/cache_as_ram.S index c81fe0a8e3..cc021dc3fe 100644 --- a/src/soc/intel/apollolake/bootblock/cache_as_ram.S +++ b/src/soc/intel/apollolake/bootblock/cache_as_ram.S @@ -16,8 +16,7 @@ #include #include #include - -#define EVICT_CTL_MSR 0x2e0 +#include .global bootblock_pre_c_entry bootblock_pre_c_entry: @@ -96,7 +95,7 @@ clear_var_mtrr: mov %eax, %cr0 /* Disable cache eviction (setup stage) */ - mov $EVICT_CTL_MSR, %ecx + mov $MSR_EVICT_CTL, %ecx rdmsr or $0x1, %eax wrmsr @@ -112,7 +111,7 @@ clear_var_mtrr: post_code(0x27) /* Disable cache eviction (run stage) */ - mov $EVICT_CTL_MSR, %ecx + mov $MSR_EVICT_CTL, %ecx rdmsr or $0x2, %eax wrmsr diff --git a/src/soc/intel/apollolake/exit_car.S b/src/soc/intel/apollolake/exit_car.S new file mode 100644 index 0000000000..339242b319 --- /dev/null +++ b/src/soc/intel/apollolake/exit_car.S @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * 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 +#include +#include + +.text +.global chipset_teardown_car +chipset_teardown_car: + /* + * Retrieve return address from stack as it will get trashed below if + * execution is utilizing the cache-as-ram stack. + */ + pop %ebx + + /* invalidate cache contents. */ + invd + /* Disable MTRRs. */ + mov $(MTRR_DEF_TYPE_MSR), %ecx + rdmsr + and $(~(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)), %eax + wrmsr + + /* Knock down bit 1 then bit 0 of NEM control not combining steps. */ + mov $(MSR_EVICT_CTL), %ecx + rdmsr + and $(~(1 << 1)), %eax + wrmsr + and $(~(1 << 0)), %eax + wrmsr + + /* Return to caller. */ + jmp *%ebx diff --git a/src/soc/intel/apollolake/include/soc/cpu.h b/src/soc/intel/apollolake/include/soc/cpu.h index 765be7037e..7c3228ef2e 100644 --- a/src/soc/intel/apollolake/include/soc/cpu.h +++ b/src/soc/intel/apollolake/include/soc/cpu.h @@ -13,19 +13,21 @@ #ifndef _SOC_APOLLOLAKE_CPU_H_ #define _SOC_APOLLOLAKE_CPU_H_ +#ifndef __ASSEMBLER__ #include #include +void apollolake_init_cpus(struct device *dev); +#endif + #define CPUID_APOLLOLAKE_A0 0x506c8 #define CPUID_APOLLOLAKE_B0 0x506c9 #define MSR_PLATFORM_INFO 0xce #define MSR_POWER_MISC 0x120 #define MSR_CORE_THREAD_COUNT 0x35 +#define MSR_EVICT_CTL 0x2e0 #define BASE_CLOCK_MHZ 100 -void apollolake_init_cpus(struct device *dev); - - #endif /* _SOC_APOLLOLAKE_CPU_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/pci_devs.h b/src/soc/intel/apollolake/include/soc/pci_devs.h index 3116389090..2a65a22cbf 100644 --- a/src/soc/intel/apollolake/include/soc/pci_devs.h +++ b/src/soc/intel/apollolake/include/soc/pci_devs.h @@ -7,7 +7,7 @@ #define _LPSS_PCI_DEVFN(slot, func) PCI_DEVFN(LPSS_DEV_SLOT_##slot, func) -#if ENV_RAMSTAGE +#if !defined(__SIMPLE_DEVICE__) #include #include #define _NB_DEV(slot) dev_find_slot(0, _NB_DEVFN(slot)) diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index 7c8924dab4..d24cdf8d3e 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -11,6 +11,7 @@ * (at your option) any later version. */ +#include #include #include #include @@ -80,6 +81,7 @@ asmlinkage void car_stage_entry(void) void *hob_list_ptr; struct range_entry fsp_mem; struct range_entry reg_car; + struct postcar_frame pcf; printk(BIOS_DEBUG, "Starting romstage...\n"); @@ -109,7 +111,10 @@ asmlinkage void car_stage_entry(void) /* Now that CBMEM is up, save the list so ramstage can use it */ fsp_save_hob_list(hob_list_ptr); - run_ramstage(); + if (postcar_frame_init(&pcf, 1*KiB)) + die("Unable to initialize postcar frame.\n"); + + run_postcar_phase(&pcf); } static void fill_console_params(struct FSPM_UPD *mupd)