blob: 3be9eb92dffaac40ac0512592cb78ff54f6db08b [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy3dad4892015-05-05 11:14:02 -07002
Arthur Heymans8256ca02019-10-21 18:47:46 +02003#include <cpu/x86/mtrr.h>
4#include <cpu/x86/cache.h>
Frans Hendriks4e0ec592019-06-06 10:07:17 +02005#include <cpu/x86/post_code.h>
6
Lee Leahyb5ad8272015-04-20 15:29:16 -07007/*
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.
13 */
14
Frans Hendriks4e0ec592019-06-06 10:07:17 +020015#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
16
17.global bootblock_pre_c_entry
18bootblock_pre_c_entry:
Lee Leahyb5ad8272015-04-20 15:29:16 -070019 /*
Kyösti Mälkkiee2e9362018-12-28 16:06:45 +020020 * Per FSP1.1 specs, following registers are preserved:
21 * EBX, EDI, ESI, EBP, MM0, MM1
22 *
23 * Shift values to release MM2.
Arthur Heymans59b65422019-05-23 15:24:30 +020024 * mm0 -> ebx: BIST value
Kyösti Mälkkiee2e9362018-12-28 16:06:45 +020025 * mm1 -> mm0: low 32-bits of TSC value
26 * mm2 -> mm1: high 32-bits of TSC value
Lee Leahyb5ad8272015-04-20 15:29:16 -070027 */
Arthur Heymans59b65422019-05-23 15:24:30 +020028 movd %mm0, %ebx
Kyösti Mälkkiee2e9362018-12-28 16:06:45 +020029 movd %mm1, %eax
30 movd %eax, %mm0
31 movd %mm2, %eax
32 movd %eax, %mm1
33
Lee Leahy3dad4892015-05-05 11:14:02 -070034cache_as_ram:
35 post_code(0x20)
36
Arthur Heymans8256ca02019-10-21 18:47:46 +020037 /* Cache the rom and update the microcode */
38cache_rom:
39 /* Disable cache */
40 movl %cr0, %eax
41 orl $CR0_CacheDisable, %eax
42 movl %eax, %cr0
43
44 movl $MTRR_PHYS_BASE(1), %ecx
45 xorl %edx, %edx
46 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
47 wrmsr
48
49 movl $MTRR_PHYS_MASK(1), %ecx
50 rdmsr
51 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
52 wrmsr
53
54 /* Enable cache */
55 movl %cr0, %eax
56 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
57 invd
58 movl %eax, %cr0
59
60 /* Enable MTRR. */
61 movl $MTRR_DEF_TYPE_MSR, %ecx
62 rdmsr
63 orl $MTRR_DEF_TYPE_EN, %eax
64 wrmsr
65
66 /* The Google FSP release for Braswell has broken microcode update
67 code and FSP needs the installed microcode revision to be non zero.
68 It is better to have coreboot do it instead of relying on a fragile
69 blob. */
70update_microcode:
71 /* put the return address in %esp */
72 movl $end_microcode_update, %esp
73 jmp update_bsp_microcode
74end_microcode_update:
75
Lee Leahyb5ad8272015-04-20 15:29:16 -070076 /*
Lee Leahy3dad4892015-05-05 11:14:02 -070077 * Find the FSP binary in cbfs.
78 * Make a fake stack that has the return value back to this code.
79 */
Lee Leahyb5ad8272015-04-20 15:29:16 -070080 lea fake_fsp_stack, %esp
81 jmp find_fsp
Lee Leahy3dad4892015-05-05 11:14:02 -070082find_fsp_ret:
83 /* Save the FSP location */
Lee Leahyb5ad8272015-04-20 15:29:16 -070084 mov %eax, %ebp
85
86 /*
87 * Only when a valid FSP binary is found at CONFIG_FSP_LOC is
88 * the returned FSP_INFO_HEADER structure address above the base
89 * address of FSP binary specified by the CONFIG_FSP_LOC value.
90 * All of the error values are in the 0x8xxxxxxx range which are
91 * below the CONFIG_FSP_LOC value.
92 */
93 cmp $CONFIG_FSP_LOC, %eax
94 jbe halt1
Lee Leahy3dad4892015-05-05 11:14:02 -070095
Duncan Lauriefb509832015-11-22 14:53:57 -080096 post_code(POST_FSP_TEMP_RAM_INIT)
Lee Leahy3dad4892015-05-05 11:14:02 -070097
98 /* Calculate entry into FSP */
Lee Leahyb5ad8272015-04-20 15:29:16 -070099 mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
100 add 0x1c(%ebp), %eax /* add in the offset for FSP */
Lee Leahy3dad4892015-05-05 11:14:02 -0700101
102 /*
103 * Pass early init variables on a fake stack (no memory yet)
104 * as well as the return location
105 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700106 lea CAR_init_stack, %esp
Lee Leahy3dad4892015-05-05 11:14:02 -0700107
108 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -0700109 * BIST value is zero
110 * eax: TempRamInitApi address
Arthur Heymans59b65422019-05-23 15:24:30 +0200111 * ebx: BIST value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700112 * ebp: FSP_INFO_HEADER address
Lee Leahyb5ad8272015-04-20 15:29:16 -0700113 * esi: Not used
114 * mm0: low 32-bits of TSC value
115 * mm1: high 32-bits of TSC value
Lee Leahy3dad4892015-05-05 11:14:02 -0700116 */
Lee Leahy3dad4892015-05-05 11:14:02 -0700117
Lee Leahyb5ad8272015-04-20 15:29:16 -0700118 /* call FSP binary to setup temporary stack */
119 jmp *%eax
120
121CAR_init_done:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700122
123 /*
124 * ebp: FSP_INFO_HEADER address
Arthur Heymans59b65422019-05-23 15:24:30 +0200125 * ebx: BIST value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700126 * ecx: Temp RAM base
127 * edx: Temp RAM top
Lee Leahyb5ad8272015-04-20 15:29:16 -0700128 * mm0: low 32-bits of TSC value
129 * mm1: high 32-bits of TSC value
130 */
131
132 cmp $0, %eax
133 jne halt2
134
135 /* Setup bootloader stack */
Frans Hendriks7ba970a2020-11-19 08:10:47 +0100136 movl $_ecar_stack, %esp
Lee Leahyb5ad8272015-04-20 15:29:16 -0700137
Lee Leahyb5ad8272015-04-20 15:29:16 -0700138 /*
139 * ebp: FSP_INFO_HEADER address
Arthur Heymans59b65422019-05-23 15:24:30 +0200140 * ebx: BIST value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700141 * ecx: Temp RAM base
142 * edx: Temp RAM top
143 * esp: Top of stack in temp RAM
144 * mm0: low 32-bits of TSC value
145 * mm1: high 32-bits of TSC value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700146 */
147
Martin Rothe18e6422017-06-03 20:03:18 -0600148 /* coreboot assumes stack/heap region will be zero */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700149 cld
150 movl %ecx, %edi
151 neg %ecx
Arthur Heymans59b65422019-05-23 15:24:30 +0200152 /* Clear up to Temp Ram top. */
153 add %edx, %ecx
Lee Leahyb5ad8272015-04-20 15:29:16 -0700154 shrl $2, %ecx
155 xorl %eax, %eax
156 rep stosl
157
Arthur Heymans59b65422019-05-23 15:24:30 +0200158 /* Need to align stack to 16 bytes at call instruction. Account for
159 the pushes below. */
160 andl $0xfffffff0, %esp
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200161 subl $8, %esp
Arthur Heymans59b65422019-05-23 15:24:30 +0200162
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200163 /* Push initial timestamp on the stack */
Arthur Heymans59b65422019-05-23 15:24:30 +0200164 movd %mm1, %eax
165 pushl %eax /* tsc[63:32] */
166 movd %mm0, %eax
167 pushl %eax /* tsc[31:0] */
168
Lee Leahy3dad4892015-05-05 11:14:02 -0700169before_romstage:
Subrata Banikfbdc7192016-01-19 19:19:15 +0530170 post_code(0x2A)
Lee Leahy3dad4892015-05-05 11:14:02 -0700171
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200172 /* Call bootblock_c_entry(uint64_t base_timestamp) */
173 call bootblock_c_entry
Lee Leahy3dad4892015-05-05 11:14:02 -0700174
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200175 /* Never reached */
Lee Leahy3dad4892015-05-05 11:14:02 -0700176
177halt1:
178 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -0700179 * Failures for postcode 0xBA - failed in fsp_fih_early_find()
Lee Leahy3dad4892015-05-05 11:14:02 -0700180 *
181 * Values are:
182 * 0x01 - FV signature, "_FVH" not present
183 * 0x02 - FFS GUID not present
184 * 0x03 - FSP INFO Header not found
Frans Hendriks683e77e2019-04-29 13:29:36 +0200185 * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased
186 * to a different location, or does it need to be?
Lee Leahy3dad4892015-05-05 11:14:02 -0700187 * 0x05 - FSP INFO Header signature "FSPH" not found
188 * 0x06 - FSP Image ID is not the expected ID.
189 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700190 movb $0xBA, %ah
191 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700192
193halt2:
194 /*
195 * Failures for postcode 0xBB - failed in the FSP:
196 *
197 * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
198 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
Lee Leahy3dad4892015-05-05 11:14:02 -0700199 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
200 * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
Frans Hendriks683e77e2019-04-29 13:29:36 +0200201 * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode
202 * region.
Lee Leahy3dad4892015-05-05 11:14:02 -0700203 * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
204 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700205 movb $0xBB, %ah
206 jmp .Lhlt
207
Lee Leahy3dad4892015-05-05 11:14:02 -0700208.Lhlt:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700209 xchg %al, %ah
Julius Wernercd49cce2019-03-05 16:53:33 -0800210#if CONFIG(POST_IO)
Lee Leahyb5ad8272015-04-20 15:29:16 -0700211 outb %al, $CONFIG_POST_IO_PORT
Lee Leahy3dad4892015-05-05 11:14:02 -0700212#else
213 post_code(POST_DEAD_CODE)
214#endif
Lee Leahyb5ad8272015-04-20 15:29:16 -0700215 movl $LHLT_DELAY, %ecx
Lee Leahy3dad4892015-05-05 11:14:02 -0700216.Lhlt_Delay:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700217 outb %al, $0xED
218 loop .Lhlt_Delay
219 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700220
221/*
222 * esp is set to this location so that the call into and return from the FSP
223 * in find_fsp will work.
224 */
225 .align 4
226fake_fsp_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700227 .long find_fsp_ret
Lee Leahya8874922015-08-26 14:58:29 -0700228 .long CONFIG_FSP_LOC /* FSP base address */
Lee Leahy3dad4892015-05-05 11:14:02 -0700229
230CAR_init_params:
Arthur Heymans12440ce2019-10-23 11:30:22 +0200231 .long fake_microcode /* Microcode Location */
232 .long fake_microcode_end - fake_microcode /* Microcode Length */
Aaron Durbin2524be42015-10-29 10:43:21 -0500233 .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */
Frans Hendriks683e77e2019-04-29 13:29:36 +0200234 .long CONFIG_ROM_SIZE /* Firmware Length */
Lee Leahy3dad4892015-05-05 11:14:02 -0700235
236CAR_init_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700237 .long CAR_init_done
238 .long CAR_init_params
Arthur Heymans12440ce2019-10-23 11:30:22 +0200239
240 /* coreboot updates microcode itself. FSP still needs a pointer
241 to something that looks like microcode, so provide it with fake
242 microcode. */
243fake_microcode:
244fake_microcode_header_start:
245 .long 1 /* Header Version */
246 .long 1 /* Microcode revision */
247 .long 0x10232019 /* Date: Time of writing 23-10-2019 */
248 .long 0x00010ff0 /* Sig: (non existing) Family: 0xf, Model: 0x1f, stepping: 0 */
249 .long 0 /* Checksum: not checked by FSP, so won't care */
250 .long 1 /* Loader Revision */
251 .long 1 /* Processor Flags */
252 .long fake_microcode_end - fake_microcode_header_end /* Data Size */
253 .long fake_microcode_end - fake_microcode /* Total Size */
254 .space 12 /* Reserved */
255fake_microcode_header_end:
256 .space 0x10 /* 16 bytes of empty data */
257fake_microcode_end: