1 /* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
2 * Copyright (C) 2012 ChromeOS Authors
4 * 2006.3 yhlu add copy data from CAR to ram
7 #include <arch/stages.h>
8 #include <arch/early_variables.h>
9 #include <cpu/x86/mtrr.h>
10 #include <cpu/amd/mtrr.h>
11 #include <cpu/amd/car.h>
12 #include <arch/acpi.h>
13 #include <romstage_handoff.h>
15 #include "cpu/amd/car/disable_cache_as_ram.c"
17 #if CONFIG_RAMTOP <= 0x100000
18 #error "You need to set CONFIG_RAMTOP greater than 1M"
21 #if IS_ENABLED(CONFIG_DEBUG_CAR)
22 #define print_car_debug(format, arg...) printk(BIOS_DEBUG, "%s: " format, __func__, ##arg)
24 #define print_car_debug(format, arg...)
27 static size_t backup_size(void)
29 size_t car_size
= car_data_size();
30 return ALIGN(car_size
+ 1024, 1024);
33 static void memcpy_(void *d
, const void *s
, size_t len
)
35 print_car_debug(" Copy [%08x-%08x] to [%08x - %08x] ...",
36 (uint32_t) s
, (uint32_t) (s
+ len
- 1), (uint32_t) d
, (uint32_t) (d
+ len
- 1));
40 static void memset_(void *d
, int val
, size_t len
)
42 print_car_debug(" Fill [%08x-%08x] ...", (uint32_t) d
, (uint32_t) (d
+ len
- 1));
46 static int memcmp_(void *d
, const void *s
, size_t len
)
48 print_car_debug(" Compare [%08x-%08x] with [%08x - %08x] ...",
49 (uint32_t) s
, (uint32_t) (s
+ len
- 1), (uint32_t) d
, (uint32_t) (d
+ len
- 1));
50 return memcmp(d
, s
, len
);
53 static void prepare_romstage_ramstack(void *resume_backup_memory
)
55 size_t backup_top
= backup_size();
56 print_car_debug("Prepare CAR migration and stack regions...");
58 if (resume_backup_memory
) {
59 memcpy_(resume_backup_memory
+ HIGH_MEMORY_SAVE
- backup_top
,
60 (void *)(CONFIG_RAMTOP
- backup_top
), backup_top
);
62 memset_((void *)(CONFIG_RAMTOP
- backup_top
), 0, backup_top
);
64 print_car_debug(" Done\n");
67 static void prepare_ramstage_region(void *resume_backup_memory
)
69 size_t backup_top
= backup_size();
70 print_car_debug("Prepare ramstage memory region...");
72 if (resume_backup_memory
) {
73 memcpy_(resume_backup_memory
, (void *) CONFIG_RAMBASE
, HIGH_MEMORY_SAVE
- backup_top
);
74 memset_((void*) CONFIG_RAMBASE
, 0, HIGH_MEMORY_SAVE
- backup_top
);
76 memset_((void*)0, 0, CONFIG_RAMTOP
- backup_top
);
79 #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
80 initialize_romstage_console_lock();
82 #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
83 initialize_romstage_nvram_cbfs_lock();
86 print_car_debug(" Done\n");
89 /* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33
90 * and RevGuide for Fam12h, Pub#44739 Rev 3.10
93 static void vErrata343(void)
96 unsigned int uiMask
= 0xFFFFFFF7;
98 msr
= rdmsr(BU_CFG2_MSR
);
99 msr
.hi
&= uiMask
; // IcDisSpecTlbWr (bit 35) = 0
100 wrmsr(BU_CFG2_MSR
, msr
);
103 void post_cache_as_ram(void)
105 void *resume_backup_memory
= NULL
;
106 uint32_t family
= amd_fam1x_cpu_family();
108 /* Verify that the BSP didn't overrun the lower stack
109 * boundary during romstage execution
111 volatile uint32_t *lower_stack_boundary
;
112 lower_stack_boundary
= (void *)((CONFIG_DCACHE_RAM_BASE
+ CONFIG_DCACHE_RAM_SIZE
) - CONFIG_DCACHE_BSP_STACK_SIZE
);
113 if ((*lower_stack_boundary
) != 0xdeadbeef)
114 printk(BIOS_WARNING
, "BSP overran lower stack boundary. Undefined behaviour may result!\n");
116 struct romstage_handoff
*handoff
;
117 handoff
= romstage_handoff_find_or_add();
119 handoff
->s3_resume
= acpi_is_wakeup_s3();
121 printk(BIOS_DEBUG
, "Romstage handoff structure not added!\n");
123 int s3resume
= acpi_is_wakeup_s3();
125 cbmem_recovery(s3resume
);
126 resume_backup_memory
= cbmem_find(CBMEM_ID_RESUME
);
128 prepare_romstage_ramstack(resume_backup_memory
);
130 /* from here don't store more data in CAR */
131 if (family
>= 0x1f && family
<= 0x3f) {
132 /* Family 10h and 12h, 11h until shown otherwise */
136 size_t car_size
= car_data_size();
137 void *migrated_car
= (void *)(CONFIG_RAMTOP
- car_size
);
139 print_car_debug("Copying data from cache to RAM...");
140 memcpy_(migrated_car
, &_car_data_start
[0], car_size
);
141 print_car_debug(" Done\n");
143 print_car_debug("Verifying data integrity in RAM...");
144 if (memcmp_(migrated_car
, &_car_data_start
[0], car_size
) == 0)
145 print_car_debug(" Done\n");
147 print_car_debug(" FAILED\n");
149 /* New stack grows right below migrated_car. */
150 print_car_debug("Switching to use RAM as stack...");
151 cache_as_ram_switch_stack(migrated_car
);
153 /* We do not come back. */
156 void cache_as_ram_new_stack (void)
158 void *resume_backup_memory
= NULL
;
160 print_car_debug("Top about %08x ... Done\n", (uint32_t) &resume_backup_memory
);
161 print_car_debug("Disabling cache as ram now\n");
162 disable_cache_as_ram_bsp();
165 /* Enable cached access to RAM in the range 1M to CONFIG_RAMTOP */
166 set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP
, MTRR_TYPE_WRBACK
);
169 if (acpi_is_wakeup_s3()) {
170 resume_backup_memory
= cbmem_find(CBMEM_ID_RESUME
);
171 print_car_debug("Resume backup memory location: %p\n", resume_backup_memory
);
173 prepare_ramstage_region(resume_backup_memory
);
175 set_sysinfo_in_ram(1); // So other core0 could start to train mem
177 /*copy and execute ramstage */
179 /* We will not return */
181 print_car_debug("should not be here -\n");