blob: 23499853264d7803e5f1ecce93e6e4e42fd9efed [file] [log] [blame]
Lee Leahy3dad4892015-05-05 11:14:02 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
5 * Copyright (C) 2007-2008 coresystems GmbH
6 * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
Lee Leahyb5ad8272015-04-20 15:29:16 -07007 * Copyright (C) 2015 Intel Corp.
Lee Leahy3dad4892015-05-05 11:14:02 -07008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010020 * Foundation, Inc.
Lee Leahy3dad4892015-05-05 11:14:02 -070021 */
22
Lee Leahyb5ad8272015-04-20 15:29:16 -070023/*
24 * Replacement for cache_as_ram.inc when using the FSP binary. This code
25 * locates the FSP binary, initializes the cache as RAM and performs the
26 * first stage of initialization. Next this code switches the stack from
27 * the cache to RAM and then disables the cache as RAM. Finally this code
28 * performs the final stage of initialization.
29 */
30
Lee Leahy3dad4892015-05-05 11:14:02 -070031#include <cpu/x86/mtrr.h>
32#include <cpu/x86/cache.h>
33#include <cpu/x86/post_code.h>
Lee Leahy3dad4892015-05-05 11:14:02 -070034#include <cbmem.h>
35
Lee Leahy3dad4892015-05-05 11:14:02 -070036#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
37
Lee Leahyb5ad8272015-04-20 15:29:16 -070038 /*
39 * eax: BIST value
40 * mm0: low 32-bits of TSC value
41 * mm1: high 32-bits of TSC value
42 */
43
44 mov %eax, %edi
Lee Leahy3dad4892015-05-05 11:14:02 -070045
46cache_as_ram:
47 post_code(0x20)
48
49 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -070050 * edi: BIST value
51 * mm0: low 32-bits of TSC value
52 * mm1: high 32-bits of TSC value
53 */
54
55 /*
Lee Leahy3dad4892015-05-05 11:14:02 -070056 * Find the FSP binary in cbfs.
57 * Make a fake stack that has the return value back to this code.
58 */
Lee Leahyb5ad8272015-04-20 15:29:16 -070059 lea fake_fsp_stack, %esp
60 jmp find_fsp
Lee Leahy3dad4892015-05-05 11:14:02 -070061find_fsp_ret:
62 /* Save the FSP location */
Lee Leahyb5ad8272015-04-20 15:29:16 -070063 mov %eax, %ebp
64
65 /*
66 * Only when a valid FSP binary is found at CONFIG_FSP_LOC is
67 * the returned FSP_INFO_HEADER structure address above the base
68 * address of FSP binary specified by the CONFIG_FSP_LOC value.
69 * All of the error values are in the 0x8xxxxxxx range which are
70 * below the CONFIG_FSP_LOC value.
71 */
72 cmp $CONFIG_FSP_LOC, %eax
73 jbe halt1
Lee Leahy3dad4892015-05-05 11:14:02 -070074
75 post_code(0x22)
76
77 /* Calculate entry into FSP */
Lee Leahyb5ad8272015-04-20 15:29:16 -070078 mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
79 add 0x1c(%ebp), %eax /* add in the offset for FSP */
Lee Leahy3dad4892015-05-05 11:14:02 -070080
81 /*
82 * Pass early init variables on a fake stack (no memory yet)
83 * as well as the return location
84 */
Lee Leahyb5ad8272015-04-20 15:29:16 -070085 lea CAR_init_stack, %esp
Lee Leahy3dad4892015-05-05 11:14:02 -070086
87 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -070088 * BIST value is zero
89 * eax: TempRamInitApi address
90 * ebp: FSP_INFO_HEADER address
91 * edi: BIST value
92 * esi: Not used
93 * mm0: low 32-bits of TSC value
94 * mm1: high 32-bits of TSC value
Lee Leahy3dad4892015-05-05 11:14:02 -070095 */
Lee Leahy3dad4892015-05-05 11:14:02 -070096
Lee Leahyb5ad8272015-04-20 15:29:16 -070097 /* call FSP binary to setup temporary stack */
98 jmp *%eax
99
100CAR_init_done:
101 addl $4, %esp
102
103 /*
104 * ebp: FSP_INFO_HEADER address
105 * ecx: Temp RAM base
106 * edx: Temp RAM top
107 * edi: BIST value
108 * mm0: low 32-bits of TSC value
109 * mm1: high 32-bits of TSC value
110 */
111
112 cmp $0, %eax
113 jne halt2
114
115 /* Setup bootloader stack */
116 movl %edx, %esp
117
Lee Leahyb5ad8272015-04-20 15:29:16 -0700118 /*
119 * ebp: FSP_INFO_HEADER address
120 * ecx: Temp RAM base
121 * edx: Temp RAM top
Aaron Durbine1ecfc92015-09-16 15:18:04 -0500122 * edi: BIST value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700123 * esp: Top of stack in temp RAM
124 * mm0: low 32-bits of TSC value
125 * mm1: high 32-bits of TSC value
Lee Leahyb5ad8272015-04-20 15:29:16 -0700126 */
127
Aaron Durbine1ecfc92015-09-16 15:18:04 -0500128 /* Create fsp_car_context on stack. */
129 pushl %edx /* bootloader CAR end */
130 pushl %ecx /* bootloader CAR begin */
131 pushl %ebp /* FSP_INFO_HEADER */
132 /* Create cache_as_ram_params on stack */
133 pushl %esp /* chipset_context -> fsp_car_context */
134 pushl %edi /* bist */
135 movd %mm1, %eax
136 pushl %eax /* tsc[63:32] */
137 movd %mm0, %eax
138 pushl %eax /* tsc[31:0] */
139 pushl %esp /* pointer to cache_as_ram_params */
140
141 /* Save FSP_INFO_HEADER location in ebx */
142 mov %ebp, %ebx
143
Lee Leahyb5ad8272015-04-20 15:29:16 -0700144 /* Coreboot assumes stack/heap region will be zero */
145 cld
146 movl %ecx, %edi
147 neg %ecx
Aaron Durbine1ecfc92015-09-16 15:18:04 -0500148 /* Only clear up to current stack value. */
149 add %esp, %ecx
Lee Leahyb5ad8272015-04-20 15:29:16 -0700150 shrl $2, %ecx
151 xorl %eax, %eax
152 rep stosl
153
Lee Leahy3dad4892015-05-05 11:14:02 -0700154before_romstage:
155 post_code(0x23)
156
Aaron Durbine1ecfc92015-09-16 15:18:04 -0500157 /* Call romstage_main(struct cache_as_ram_params *) */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700158 call romstage_main
Lee Leahy3dad4892015-05-05 11:14:02 -0700159
Lee Leahyb5ad8272015-04-20 15:29:16 -0700160 /*
161 * eax: New stack address
162 * ebx: FSP_INFO_HEADER address
163 */
164
165 /* Switch to the stack in RAM */
166 movl %eax, %esp
167
168 /* Calculate TempRamExit entry into FSP */
169 movl %ebx, %ebp
170 mov 0x40(%ebp), %eax
171 add 0x1c(%ebp), %eax
172
173 /* Build the call frame */
174 pushl $0
175
176 /* Call TempRamExit */
177 call *%eax
178 add $4, %esp
179 cmp $0, %eax
180 jne halt3
181
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700182 /* Display the MTRRs */
183 call soc_display_mtrrs
184
185 /*
186 * The stack contents are initialized in src/soc/intel/common/stack.c
187 * to be the following:
188 *
189 * *
190 * *
191 * *
192 * +36: MTRR mask 1 63:32
193 * +32: MTRR mask 1 31:0
194 * +28: MTRR base 1 63:32
195 * +24: MTRR base 1 31:0
196 * +20: MTRR mask 0 63:32
197 * +16: MTRR mask 0 31:0
198 * +12: MTRR base 0 63:32
199 * +8: MTRR base 0 31:0
200 * +4: Number of MTRRs to setup (described above)
201 * +0: Number of variable MTRRs to clear
202 */
203
204 /* Clear all of the variable MTRRs. */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700205 popl %ebx
206 movl $MTRRphysBase_MSR(0), %ecx
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700207 clr %eax
208 clr %edx
209
Lee Leahyb5ad8272015-04-20 15:29:16 -07002101:
211 testl %ebx, %ebx
212 jz 1f
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700213 wrmsr /* Write MTRR base. */
214 inc %ecx
215 wrmsr /* Write MTRR mask. */
216 inc %ecx
217 dec %ebx
218 jmp 1b
219
2201:
221 /* Get number of MTRRs. */
222 popl %ebx
223 movl $MTRRphysBase_MSR(0), %ecx
2242:
225 testl %ebx, %ebx
226 jz 2f
Lee Leahyb5ad8272015-04-20 15:29:16 -0700227
228 /* Low 32 bits of MTRR base. */
229 popl %eax
230 /* Upper 32 bits of MTRR base. */
231 popl %edx
232 /* Write MTRR base. */
233 wrmsr
234 inc %ecx
235 /* Low 32 bits of MTRR mask. */
236 popl %eax
237 /* Upper 32 bits of MTRR mask. */
238 popl %edx
239 /* Write MTRR mask. */
240 wrmsr
241 inc %ecx
242
243 dec %ebx
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700244 jmp 2b
2452:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700246 post_code(0x39)
247
248 /* And enable cache again after setting MTRRs. */
249 movl %cr0, %eax
250 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
251 movl %eax, %cr0
252
253 post_code(0x3a)
254
255 /* Enable MTRR. */
256 movl $MTRRdefType_MSR, %ecx
257 rdmsr
258 orl $MTRRdefTypeEn, %eax
259 wrmsr
260
261 post_code(0x3b)
262
263 /* Invalidate the cache again. */
264 invd
265
266 post_code(0x3c)
267
268__main:
269 post_code(POST_PREPARE_RAMSTAGE)
270 cld /* Clear direction flag. */
271 call romstage_after_car
272
273
274 movb $0x69, %ah
275 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700276
277halt1:
278 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -0700279 * Failures for postcode 0xBA - failed in fsp_fih_early_find()
Lee Leahy3dad4892015-05-05 11:14:02 -0700280 *
281 * Values are:
282 * 0x01 - FV signature, "_FVH" not present
283 * 0x02 - FFS GUID not present
284 * 0x03 - FSP INFO Header not found
285 * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
286 * a different location, or does it need to be?
287 * 0x05 - FSP INFO Header signature "FSPH" not found
288 * 0x06 - FSP Image ID is not the expected ID.
289 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700290 movb $0xBA, %ah
291 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700292
293halt2:
294 /*
295 * Failures for postcode 0xBB - failed in the FSP:
296 *
297 * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
298 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
Lee Leahy3dad4892015-05-05 11:14:02 -0700299 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
300 * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
Lee Leahyb5ad8272015-04-20 15:29:16 -0700301 * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
Lee Leahy3dad4892015-05-05 11:14:02 -0700302 * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
303 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700304 movb $0xBB, %ah
305 jmp .Lhlt
306
307halt3:
308 /*
309 * Failures for post code BC - failed in TempRamExit
310 *
311 * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully.
312 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
313 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
314 * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed.
315 */
316 movb $0xBC, %ah
Lee Leahy3dad4892015-05-05 11:14:02 -0700317
318.Lhlt:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700319 xchg %al, %ah
320#if IS_ENABLED(CONFIG_POST_IO)
321 outb %al, $CONFIG_POST_IO_PORT
Lee Leahy3dad4892015-05-05 11:14:02 -0700322#else
323 post_code(POST_DEAD_CODE)
324#endif
Lee Leahyb5ad8272015-04-20 15:29:16 -0700325 movl $LHLT_DELAY, %ecx
Lee Leahy3dad4892015-05-05 11:14:02 -0700326.Lhlt_Delay:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700327 outb %al, $0xED
328 loop .Lhlt_Delay
329 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700330
331/*
332 * esp is set to this location so that the call into and return from the FSP
333 * in find_fsp will work.
334 */
335 .align 4
336fake_fsp_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700337 .long find_fsp_ret
Lee Leahya8874922015-08-26 14:58:29 -0700338 .long CONFIG_FSP_LOC /* FSP base address */
Lee Leahy3dad4892015-05-05 11:14:02 -0700339
340CAR_init_params:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700341 .long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */
342 .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
343 .long 0xFFFFFFFF - CONFIG_CBFS_SIZE + 1 /* Firmware Location */
344 .long CONFIG_CBFS_SIZE /* Total Firmware Length */
Lee Leahy3dad4892015-05-05 11:14:02 -0700345
346CAR_init_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700347 .long CAR_init_done
348 .long CAR_init_params