Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30064
Change subject: [WIP]amd/fam10: Implement POSTCAR stage ......................................................................
[WIP]amd/fam10: Implement POSTCAR stage
This patch does the following: - Set up a postcar frame for the ramstage to use - Implements an assembly version of the CAR tear down for the postcar stage to use - Gets rid of the HIGH_MEMORY for S3 resume support
TODO clean things up
Change-Id: I23dd48700777d3afeca27c8e78a48f81f7d6c589 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/amd/car/cache_as_ram.inc A src/cpu/amd/car/exit_car.S M src/cpu/amd/car/post_cache_as_ram.c A src/cpu/amd/car/postcar.c M src/cpu/amd/family_10h-family_15h/Kconfig M src/cpu/amd/family_10h-family_15h/Makefile.inc M src/cpu/amd/family_10h-family_15h/ram_calc.c M src/include/cpu/amd/car.h M src/northbridge/amd/amdfam10/Makefile.inc M src/northbridge/amd/amdfam10/amdfam10.h 10 files changed, 195 insertions(+), 117 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/64/30064/1
diff --git a/src/cpu/amd/car/cache_as_ram.inc b/src/cpu/amd/car/cache_as_ram.inc index e4c2704..2a427af 100644 --- a/src/cpu/amd/car/cache_as_ram.inc +++ b/src/cpu/amd/car/cache_as_ram.inc @@ -597,9 +597,6 @@ call cache_as_ram_main
call post_cache_as_ram - movl %eax, %esp - - call cache_as_ram_new_stack
/* We will not go back. */
diff --git a/src/cpu/amd/car/exit_car.S b/src/cpu/amd/car/exit_car.S new file mode 100644 index 0000000..12597e9 --- /dev/null +++ b/src/cpu/amd/car/exit_car.S @@ -0,0 +1,125 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Arthur Heymans arthur@aheymans.xyz + * + * 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/amd/mtrr.h> +#include <cpu/amd/msr.h> + +.code32 +.global chipset_teardown_car + +chipset_teardown_car: + pop %esp + + post_code(0x30) + + /* Disable cache. */ + movl %cr0, %eax + orl $CR0_CacheDisable, %eax + movl %eax, %cr0 + + post_code(0x31) + + xor %eax, %eax + xor %edx, %edx + movl $MTRR_FIX_4K_C8000, %ecx + wrmsr +#if (CONFIG_DCACHE_RAM_SIZE > 0x8000) + movl $MTRR_FIX_4K_C0000, %ecx + wrmsr +#endif + +#if (CONFIG_DCACHE_RAM_SIZE > 0x10000) + movl $MTRR_FIX_4K_D0000, %ecx + wrmsr +#endif + +#if (CONFIG_DCACHE_RAM_SIZE > 0x18000) + movl $MTRR_FIX_4K_D8000, %ecx + wrmsr +#endif + + /* disable fixed mtrr from now on, + * it will be enabled by ramstage again + */ + movl $SYSCFG_MSR, %ecx + rdmsr + andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn)) , %eax + wrmsr + + /* Disable MTRR. */ + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + andl $(~MTRR_DEF_TYPE_EN), %eax + wrmsr + + /* Enable Cache */ + mov %cr0, %eax + and $(~(CR0_CD | CR0_NW)), %eax + mov %eax, %cr0 + + /* INVDWBINVD = 1 */ + movl $HWCR_MSR, %ecx + orl $(1 << 4), %eax + wrmsr + + /* Fetch family */ + movl $0x80000001, %eax + cpuid + movl %eax, %ebx + andl $(0xf00000), %eax + shrl $16, %eax + andl $(0xf00), %ebx + shrl $8, %ebx + orl %ebx, %eax + + cmpl $0x6f, %eax + jl ret + /* Family 15h or later */ + + /* DisSS = 0 */ + movl $LS_CFG_MSR, %ecx + rdmsr + andl $(~(1 << 28)), %eax + wrmsr + + /* DisSpecTlbRld = 0 */ + movl $IC_CFG_MSR, %ecx + rdmsr + andl $(~(1 << 9)), %eax + wrmsr + + /* Erratum 714: SpecNbReqDis = 0 */ + movl $BU_CFG2_MSR, %ecx + rdmsr + andl $(~(1 << 8)), %eax + wrmsr + + /* DisSpecTlbRld = 0 */ + /* DisHwPf = 0 */ + movl $DC_CFG_MSR, %ecx + rdmsr + andl $(~(1 << 4)), %eax + andl $(~(1 << 13)), %eax + wrmsr + + + post_code(0x32) + + /* Return to caller. */ +ret: + jmp *%esp diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c index e55ef40..90d9617 100644 --- a/src/cpu/amd/car/post_cache_as_ram.c +++ b/src/cpu/amd/car/post_cache_as_ram.c @@ -26,6 +26,7 @@ #include <cpu/amd/msr.h> #include <arch/acpi.h> #include <romstage_handoff.h> +#include <cbmem.h>
#include "cpu/amd/car/disable_cache_as_ram.c"
@@ -36,76 +37,6 @@ #error "You need to set CONFIG_RAMTOP greater than 1M" #endif
-#if IS_ENABLED(CONFIG_DEBUG_CAR) -#define print_car_debug(format, arg...) printk(BIOS_DEBUG, "%s: " format, __func__, ##arg) -#else -#define print_car_debug(format, arg...) -#endif - -static size_t backup_size(void) -{ - size_t car_size = car_data_size(); - return ALIGN(car_size + 1024, 1024); -} - -static void memcpy_(void *d, const void *s, size_t len) -{ - print_car_debug(" Copy [%08x-%08x] to [%08x - %08x] ...", - (uint32_t) s, (uint32_t) (s + len - 1), - (uint32_t) d, (uint32_t) (d + len - 1)); - memcpy(d, s, len); -} - -static void memset_(void *d, int val, size_t len) -{ - print_car_debug(" Fill [%08x-%08x] ...", - (uint32_t) d, (uint32_t) (d + len - 1)); - memset(d, val, len); -} - -static int memcmp_(void *d, const void *s, size_t len) -{ - print_car_debug(" Compare [%08x-%08x] with [%08x - %08x] ...", - (uint32_t) s, (uint32_t) (s + len - 1), - (uint32_t) d, (uint32_t) (d + len - 1)); - return memcmp(d, s, len); -} - -static void prepare_romstage_ramstack(int s3resume) -{ - size_t backup_top = backup_size(); - print_car_debug("Prepare CAR migration and stack regions..."); - - if (s3resume) { - void *resume_backup_memory = - acpi_backup_container(CONFIG_RAMBASE, HIGH_MEMORY_SAVE); - if (resume_backup_memory) - memcpy_(resume_backup_memory - + HIGH_MEMORY_SAVE - backup_top, - (void *)(CONFIG_RAMTOP - backup_top), - backup_top); - } - memset_((void *)(CONFIG_RAMTOP - backup_top), 0, backup_top); - - print_car_debug(" Done\n"); -} - -static void prepare_ramstage_region(int s3resume) -{ - size_t backup_top = backup_size(); - print_car_debug("Prepare ramstage memory region..."); - - if (s3resume) { - void *resume_backup_memory = - acpi_backup_container(CONFIG_RAMBASE, HIGH_MEMORY_SAVE); - if (resume_backup_memory) - memcpy_(resume_backup_memory, (void *) CONFIG_RAMBASE, - HIGH_MEMORY_SAVE - backup_top); - } - - print_car_debug(" Done\n"); -} - /* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33 * and RevGuide for Fam12h, Pub#44739 Rev 3.10 */ @@ -120,7 +51,37 @@ wrmsr(BU_CFG2_MSR, msr); }
-asmlinkage void *post_cache_as_ram(void) +#define ROMSTAGE_RAM_STACK_SIZE 0x5000 + +/* platform_enter_postcar() determines the stack to use after + * cache-as-ram is torn down as well as the MTRR settings to use, + * and continues execution in postcar stage. */ +static void platform_enter_postcar(void) +{ + struct postcar_frame pcf; + uintptr_t top_of_ram; + + if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE)) + die("Unable to initialize postcar frame.\n"); + + /* Cache the ROM as WP just below 4GiB. */ + postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT); + + /* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */ + postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK); + + /* Cache 8 MiB region below the top of ram. */ + top_of_ram = (uintptr_t)cbmem_top(); + postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 8*MiB, + MTRR_TYPE_WRBACK); + + run_postcar_phase(&pcf); + + /* We do not return here. */ +} + + +asmlinkage void post_cache_as_ram(void) { uint32_t family = amd_fam1x_cpu_family(); int s3resume = 0; @@ -137,8 +98,6 @@
s3resume = acpi_is_wakeup_s3();
- prepare_romstage_ramstack(s3resume); - romstage_handoff_init(s3resume);
/* from here don't store more data in CAR */ @@ -147,41 +106,7 @@ vErrata343(); }
- size_t car_size = car_data_size(); - void *migrated_car = (void *)(CONFIG_RAMTOP - car_size); + platform_enter_postcar();
- print_car_debug("Copying data from cache to RAM..."); - memcpy_(migrated_car, _car_relocatable_data_start, car_size); - print_car_debug(" Done\n"); - - print_car_debug("Verifying data integrity in RAM..."); - if (memcmp_(migrated_car, _car_relocatable_data_start, car_size) == 0) - print_car_debug(" Done\n"); - else - print_car_debug(" FAILED\n"); - - /* New stack grows right below migrated_car. */ - print_car_debug("Switching to use RAM as stack..."); - return migrated_car; -} - -asmlinkage void cache_as_ram_new_stack(void) -{ - print_car_debug("Disabling cache as RAM now\n"); - disable_cache_as_ram_real(0); // inline - - disable_cache(); - /* Enable cached access to RAM in the range 0M to CACHE_TMP_RAMTOP */ - set_var_mtrr(0, 0x00000000, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK); - enable_cache(); - - prepare_ramstage_region(acpi_is_wakeup_s3()); - - set_sysinfo_in_ram(1); // So other core0 could start to train mem - - /*copy and execute ramstage */ - copy_and_run(); - /* We will not return */ - - print_car_debug("should not be here -\n"); + /* We don't return here */ } diff --git a/src/cpu/amd/car/postcar.c b/src/cpu/amd/car/postcar.c new file mode 100644 index 0000000..86c6c32 --- /dev/null +++ b/src/cpu/amd/car/postcar.c @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Timothy Pearson tpearson@raptorengineeringinc.com, + * Raptor Engineering + * Copyright (C) 2012 Google LLC + * 2005.6 by yhlu + * 2006.3 yhlu add copy data from CAR to ram + * + * 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 <arch/cpu.h> +#include <northbridge/amd/amdfam10/amdfam10.h> + +void late_car_teardown(void) +{ + set_sysinfo_in_ram(1); +} diff --git a/src/cpu/amd/family_10h-family_15h/Kconfig b/src/cpu/amd/family_10h-family_15h/Kconfig index 8e90247..8d50a46 100644 --- a/src/cpu/amd/family_10h-family_15h/Kconfig +++ b/src/cpu/amd/family_10h-family_15h/Kconfig @@ -11,7 +11,8 @@ select HAVE_MONOTONIC_TIMER select SUPPORT_CPU_UCODE_IN_CBFS select CPU_MICROCODE_MULTIPLE_FILES if !CPU_MICROCODE_CBFS_NONE - select ACPI_HUGE_LOWMEM_BACKUP + select POSTCAR_STAGE + select POSTCAR_CONSOLE
if CPU_AMD_MODEL_10XXX
diff --git a/src/cpu/amd/family_10h-family_15h/Makefile.inc b/src/cpu/amd/family_10h-family_15h/Makefile.inc index 2ed76e1..c5d1fa5 100644 --- a/src/cpu/amd/family_10h-family_15h/Makefile.inc +++ b/src/cpu/amd/family_10h-family_15h/Makefile.inc @@ -1,6 +1,9 @@ romstage-y += ../../x86/mtrr/earlymtrr.c romstage-y += ../car/post_cache_as_ram.c
+postcar-y += ../car/exit_car.S +postcar-y += ../car/postcar.c + romstage-y += init_cpus.c
ramstage-y += model_10xxx_init.c @@ -11,6 +14,7 @@ ramstage-y += tsc_freq.c romstage-y += ram_calc.c ramstage-y += ram_calc.c +postcar-y += ram_calc.c ramstage-y += monotonic_timer.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c
diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.c b/src/cpu/amd/family_10h-family_15h/ram_calc.c index ab2cafd..db7fc40 100644 --- a/src/cpu/amd/family_10h-family_15h/ram_calc.c +++ b/src/cpu/amd/family_10h-family_15h/ram_calc.c @@ -68,7 +68,7 @@ if (is_fam15h()) { enable_cc6 = 0;
-#ifdef __PRE_RAM__ +#ifdef __SIMPLE_DEVICE__ if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18)) enable_cc6 = 1; #else diff --git a/src/include/cpu/amd/car.h b/src/include/cpu/amd/car.h index 359fa6b..b71dda0 100644 --- a/src/include/cpu/amd/car.h +++ b/src/include/cpu/amd/car.h @@ -4,8 +4,7 @@ #include <arch/cpu.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx); -asmlinkage void *post_cache_as_ram(void); -asmlinkage void cache_as_ram_new_stack(void); +asmlinkage void post_cache_as_ram(void);
void disable_cache_as_ram(void);
diff --git a/src/northbridge/amd/amdfam10/Makefile.inc b/src/northbridge/amd/amdfam10/Makefile.inc index 787f444..c3705a8 100644 --- a/src/northbridge/amd/amdfam10/Makefile.inc +++ b/src/northbridge/amd/amdfam10/Makefile.inc @@ -8,6 +8,7 @@ # Generic ROMSTAGE stuff romstage-y += reset_test.c debug.c setup_resource_map.c raminit_sysinfo_in_ram.c romstage-y += raminit_amdmct.c pci.c early_ht.c amdfam10_util.c +postcar-y += raminit_sysinfo_in_ram.c
# RAMSTAGE ramstage-y += northbridge.c misc_control.c link_control.c nb_control.c diff --git a/src/northbridge/amd/amdfam10/amdfam10.h b/src/northbridge/amd/amdfam10/amdfam10.h index f16ef83..c28022e 100644 --- a/src/northbridge/amd/amdfam10/amdfam10.h +++ b/src/northbridge/amd/amdfam10/amdfam10.h @@ -912,7 +912,7 @@
#include "nums.h"
-#ifdef __PRE_RAM__ +#ifdef __SIMPLE_DEVICE__ #if NODE_NUMS == 64 #define NODE_PCI(x, fn) ((x < 32)?(PCI_DEV(CONFIG_CBB,(CONFIG_CDB+x),fn)):(PCI_DEV((CONFIG_CBB-1),(CONFIG_CDB+x-32),fn))) #else