1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cpu/x86/mtrr.h>
4 #include <cpu/x86/cache.h>
5 #include <cpu/x86/post_code.h>
8 * Replacement for cache_as_ram.inc when using the FSP binary. This code
9 * locates the FSP binary, initializes the cache as RAM and performs the
10 * first stage of initialization. Next this code switches the stack from
11 * the cache to RAM and then disables the cache as RAM. Finally this code
12 * performs the final stage of initialization.
15 #define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
17 .section .init, "ax", @progbits
19 .global bootblock_pre_c_entry
20 bootblock_pre_c_entry:
22 * Per FSP1.1 specs, following registers are preserved:
23 * EBX, EDI, ESI, EBP, MM0, MM1
25 * Shift values to release MM2.
26 * mm0 -> ebx: BIST value
27 * mm1 -> mm0: low 32-bits of TSC value
28 * mm2 -> mm1: high 32-bits of TSC value
37 post_code(POSTCODE_BOOTBLOCK_CAR)
39 /* Cache the rom and update the microcode */
43 orl $CR0_CacheDisable, %eax
46 movl $MTRR_PHYS_BASE(1), %ecx
48 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
51 movl $MTRR_PHYS_MASK(1), %ecx
53 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
58 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
63 movl $MTRR_DEF_TYPE_MSR, %ecx
65 orl $MTRR_DEF_TYPE_EN, %eax
68 /* The Google FSP release for Braswell has broken microcode update
69 code and FSP needs the installed microcode revision to be non zero.
70 It is better to have coreboot do it instead of relying on a fragile
73 /* put the return address in %esp */
74 movl $end_microcode_update, %esp
75 jmp update_bsp_microcode
79 * Find the FSP binary in cbfs.
80 * Make a fake stack that has the return value back to this code.
82 lea fake_fsp_stack, %esp
85 /* Save the FSP location */
89 * Only when a valid FSP binary is found at CONFIG_FSP_LOC is
90 * the returned FSP_INFO_HEADER structure address above the base
91 * address of FSP binary specified by the CONFIG_FSP_LOC value.
92 * All of the error values are in the 0x8xxxxxxx range which are
93 * below the CONFIG_FSP_LOC value.
95 cmp $CONFIG_FSP_LOC, %eax
98 post_code(POSTCODE_FSP_TEMP_RAM_INIT)
100 /* Calculate entry into FSP */
101 mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
102 add 0x1c(%ebp), %eax /* add in the offset for FSP */
105 * Pass early init variables on a fake stack (no memory yet)
106 * as well as the return location
108 lea CAR_init_stack, %esp
112 * eax: TempRamInitApi address
114 * ebp: FSP_INFO_HEADER address
116 * mm0: low 32-bits of TSC value
117 * mm1: high 32-bits of TSC value
120 /* call FSP binary to setup temporary stack */
126 * ebp: FSP_INFO_HEADER address
130 * mm0: low 32-bits of TSC value
131 * mm1: high 32-bits of TSC value
137 /* Setup bootblock stack */
138 movl $_ecar_stack, %esp
141 * ebp: FSP_INFO_HEADER address
145 * esp: Top of stack in temp RAM
146 * mm0: low 32-bits of TSC value
147 * mm1: high 32-bits of TSC value
151 * temp_memory_start/end reside in the .bss section, which gets cleared
152 * below. Save the FSP return value to the stack before writing those
158 /* clear .bss section */
168 movl %edx, temp_memory_end
170 movl %ecx, temp_memory_start
172 /* Need to align stack to 16 bytes at call instruction. Account for
174 andl $0xfffffff0, %esp
177 /* Push initial timestamp on the stack */
179 pushl %eax /* tsc[63:32] */
181 pushl %eax /* tsc[31:0] */
183 /* Copy .data section content to Cache-As-Ram */
184 #include <cpu/x86/copy_data_section.inc>
187 /* Call bootblock_c_entry(uint64_t base_timestamp) */
188 call bootblock_c_entry
194 * Failures for postcode 0xBA - failed in fsp_fih_early_find()
197 * 0x01 - FV signature, "_FVH" not present
198 * 0x02 - FFS GUID not present
199 * 0x03 - FSP INFO Header not found
200 * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased
201 * to a different location, or does it need to be?
202 * 0x05 - FSP INFO Header signature "FSPH" not found
203 * 0x06 - FSP Image ID is not the expected ID.
210 * Failures for postcode 0xBB - failed in the FSP:
212 * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
213 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
214 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
215 * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
216 * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode
218 * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
226 outb %al, $CONFIG_POST_IO_PORT
228 post_code(POSTCODE_DEAD_CODE)
230 movl $LHLT_DELAY, %ecx
237 * esp is set to this location so that the call into and return from the FSP
238 * in find_fsp will work.
243 .long CONFIG_FSP_LOC /* FSP base address */
246 .long fake_microcode /* Microcode Location */
247 .long fake_microcode_end - fake_microcode /* Microcode Length */
248 .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */
249 .long CONFIG_ROM_SIZE /* Firmware Length */
253 .long CAR_init_params
255 /* coreboot updates microcode itself. FSP still needs a pointer
256 to something that looks like microcode, so provide it with fake
259 fake_microcode_header_start:
260 .long 1 /* Header Version */
261 .long 1 /* Microcode revision */
262 .long 0x10232019 /* Date: Time of writing 23-10-2019 */
263 .long 0x00010ff0 /* Sig: (non existing) Family: 0xf, Model: 0x1f, stepping: 0 */
264 .long 0 /* Checksum: not checked by FSP, so won't care */
265 .long 1 /* Loader Revision */
266 .long 1 /* Processor Flags */
267 .long fake_microcode_end - fake_microcode_header_end /* Data Size */
268 .long fake_microcode_end - fake_microcode /* Total Size */
269 .space 12 /* Reserved */
270 fake_microcode_header_end:
271 .space 0x10 /* 16 bytes of empty data */