AMD k8 fam10: Drop excessive spinlock initialization
[coreboot.git] / src / cpu / amd / car / post_cache_as_ram.c
blob9cf3c6e78f9f55f3cfb3bf22ec0b2b3a5d67ec0b
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>,
5 * Raptor Engineering
6 * Copyright (C) 2012 ChromeOS Authors
7 * 2005.6 by yhlu
8 * 2006.3 yhlu add copy data from CAR to ram
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 #include <string.h>
20 #include <arch/stages.h>
21 #include <arch/early_variables.h>
22 #include <cpu/x86/mtrr.h>
23 #include <cpu/amd/mtrr.h>
24 #include <cpu/amd/car.h>
25 #include <arch/acpi.h>
26 #include <romstage_handoff.h>
27 #include "cbmem.h"
28 #include "cpu/amd/car/disable_cache_as_ram.c"
30 #if CONFIG_RAMTOP <= 0x100000
31 #error "You need to set CONFIG_RAMTOP greater than 1M"
32 #endif
34 #if IS_ENABLED(CONFIG_DEBUG_CAR)
35 #define print_car_debug(format, arg...) printk(BIOS_DEBUG, "%s: " format, __func__, ##arg)
36 #else
37 #define print_car_debug(format, arg...)
38 #endif
40 static size_t backup_size(void)
42 size_t car_size = car_data_size();
43 return ALIGN(car_size + 1024, 1024);
46 static void memcpy_(void *d, const void *s, size_t len)
48 print_car_debug(" Copy [%08x-%08x] to [%08x - %08x] ...",
49 (uint32_t) s, (uint32_t) (s + len - 1), (uint32_t) d, (uint32_t) (d + len - 1));
50 memcpy(d, s, len);
53 static void memset_(void *d, int val, size_t len)
55 print_car_debug(" Fill [%08x-%08x] ...", (uint32_t) d, (uint32_t) (d + len - 1));
56 memset(d, val, len);
59 static int memcmp_(void *d, const void *s, size_t len)
61 print_car_debug(" Compare [%08x-%08x] with [%08x - %08x] ...",
62 (uint32_t) s, (uint32_t) (s + len - 1), (uint32_t) d, (uint32_t) (d + len - 1));
63 return memcmp(d, s, len);
66 static void prepare_romstage_ramstack(int s3resume)
68 size_t backup_top = backup_size();
69 print_car_debug("Prepare CAR migration and stack regions...");
71 if (s3resume) {
72 void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
73 if (resume_backup_memory)
74 memcpy_(resume_backup_memory + HIGH_MEMORY_SAVE - backup_top,
75 (void *)(CONFIG_RAMTOP - backup_top), backup_top);
77 memset_((void *)(CONFIG_RAMTOP - backup_top), 0, backup_top);
79 print_car_debug(" Done\n");
82 static void prepare_ramstage_region(int s3resume)
84 size_t backup_top = backup_size();
85 print_car_debug("Prepare ramstage memory region...");
87 if (s3resume) {
88 void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
89 if (resume_backup_memory)
90 memcpy_(resume_backup_memory, (void *) CONFIG_RAMBASE,
91 HIGH_MEMORY_SAVE - backup_top);
92 memset_((void*) CONFIG_RAMBASE, 0, HIGH_MEMORY_SAVE - backup_top);
93 } else {
94 memset_((void*)0, 0, CONFIG_RAMTOP - backup_top);
97 print_car_debug(" Done\n");
100 /* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33
101 * and RevGuide for Fam12h, Pub#44739 Rev 3.10
104 static void vErrata343(void)
106 msr_t msr;
107 unsigned int uiMask = 0xFFFFFFF7;
109 msr = rdmsr(BU_CFG2_MSR);
110 msr.hi &= uiMask; // IcDisSpecTlbWr (bit 35) = 0
111 wrmsr(BU_CFG2_MSR, msr);
114 void post_cache_as_ram(void)
116 uint32_t family = amd_fam1x_cpu_family();
118 /* Verify that the BSP didn't overrun the lower stack
119 * boundary during romstage execution
121 volatile uint32_t *lower_stack_boundary;
122 lower_stack_boundary = (void *)((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) - CONFIG_DCACHE_BSP_STACK_SIZE);
123 if ((*lower_stack_boundary) != 0xdeadbeef)
124 printk(BIOS_WARNING, "BSP overran lower stack boundary. Undefined behaviour may result!\n");
126 int s3resume = acpi_is_wakeup_s3();
128 /* Boards with EARLY_CBMEM_INIT need to do this in cache_as_ram_main().
130 if (s3resume && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT))
131 cbmem_recovery(s3resume);
133 prepare_romstage_ramstack(s3resume);
135 if (IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)) {
136 struct romstage_handoff *handoff;
137 handoff = romstage_handoff_find_or_add();
138 if (handoff != NULL)
139 handoff->s3_resume = s3resume;
140 else
141 printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
144 /* from here don't store more data in CAR */
145 if (family >= 0x1f && family <= 0x3f) {
146 /* Family 10h and 12h, 11h until shown otherwise */
147 vErrata343();
150 size_t car_size = car_data_size();
151 void *migrated_car = (void *)(CONFIG_RAMTOP - car_size);
153 print_car_debug("Copying data from cache to RAM...");
154 memcpy_(migrated_car, _car_relocatable_data_start, car_size);
155 print_car_debug(" Done\n");
157 print_car_debug("Verifying data integrity in RAM...");
158 if (memcmp_(migrated_car, _car_relocatable_data_start, car_size) == 0)
159 print_car_debug(" Done\n");
160 else
161 print_car_debug(" FAILED\n");
163 /* New stack grows right below migrated_car. */
164 print_car_debug("Switching to use RAM as stack...");
165 cache_as_ram_switch_stack(migrated_car);
167 /* We do not come back. */
170 void cache_as_ram_new_stack (void)
172 print_car_debug("Disabling cache as ram now\n");
173 disable_cache_as_ram_bsp();
175 disable_cache();
176 /* Enable cached access to RAM in the range 0M to CACHE_TMP_RAMTOP */
177 set_var_mtrr(0, 0x00000000, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
178 enable_cache();
180 prepare_ramstage_region(acpi_is_wakeup_s3());
182 set_sysinfo_in_ram(1); // So other core0 could start to train mem
184 /*copy and execute ramstage */
185 copy_and_run();
186 /* We will not return */
188 print_car_debug("should not be here -\n");