blob: 4a0827d2df06a99b2f2c358e710ba0f439cb4c9a [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
36#ifndef CONFIG_FSP_LOC
37# error "CONFIG_FSP_LOC must be set."
38#endif
39
40#ifndef CONFIG_POST_IO
41# error "CONFIG_POST_IO must be set."
42#endif
43
Lee Leahyb5ad8272015-04-20 15:29:16 -070044#if IS_ENABLED(CONFIG_POST_IO)
Lee Leahy3dad4892015-05-05 11:14:02 -070045# ifndef CONFIG_POST_IO_PORT
46# error "CONFIG_POST_IO_PORT must be set."
47# endif
48#endif
49
50#ifndef CONFIG_CPU_MICROCODE_CBFS_LOC
51# error "CONFIG_CPU_MICROCODE_CBFS_LOC must be set."
52#endif
53
54#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
55
Lee Leahyb5ad8272015-04-20 15:29:16 -070056 /*
57 * eax: BIST value
58 * mm0: low 32-bits of TSC value
59 * mm1: high 32-bits of TSC value
60 */
61
62 mov %eax, %edi
Lee Leahy3dad4892015-05-05 11:14:02 -070063
64cache_as_ram:
65 post_code(0x20)
66
67 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -070068 * edi: BIST value
69 * mm0: low 32-bits of TSC value
70 * mm1: high 32-bits of TSC value
71 */
72
73 /*
Lee Leahy3dad4892015-05-05 11:14:02 -070074 * Find the FSP binary in cbfs.
75 * Make a fake stack that has the return value back to this code.
76 */
Lee Leahyb5ad8272015-04-20 15:29:16 -070077 lea fake_fsp_stack, %esp
78 jmp find_fsp
Lee Leahy3dad4892015-05-05 11:14:02 -070079find_fsp_ret:
80 /* Save the FSP location */
Lee Leahyb5ad8272015-04-20 15:29:16 -070081 mov %eax, %ebp
82
83 /*
84 * Only when a valid FSP binary is found at CONFIG_FSP_LOC is
85 * the returned FSP_INFO_HEADER structure address above the base
86 * address of FSP binary specified by the CONFIG_FSP_LOC value.
87 * All of the error values are in the 0x8xxxxxxx range which are
88 * below the CONFIG_FSP_LOC value.
89 */
90 cmp $CONFIG_FSP_LOC, %eax
91 jbe halt1
Lee Leahy3dad4892015-05-05 11:14:02 -070092
93 post_code(0x22)
94
95 /* Calculate entry into FSP */
Lee Leahyb5ad8272015-04-20 15:29:16 -070096 mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
97 add 0x1c(%ebp), %eax /* add in the offset for FSP */
Lee Leahy3dad4892015-05-05 11:14:02 -070098
99 /*
100 * Pass early init variables on a fake stack (no memory yet)
101 * as well as the return location
102 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700103 lea CAR_init_stack, %esp
Lee Leahy3dad4892015-05-05 11:14:02 -0700104
105 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -0700106 * BIST value is zero
107 * eax: TempRamInitApi address
108 * ebp: FSP_INFO_HEADER address
109 * edi: BIST value
110 * esi: Not used
111 * mm0: low 32-bits of TSC value
112 * mm1: high 32-bits of TSC value
Lee Leahy3dad4892015-05-05 11:14:02 -0700113 */
Lee Leahy3dad4892015-05-05 11:14:02 -0700114
Lee Leahyb5ad8272015-04-20 15:29:16 -0700115 /* call FSP binary to setup temporary stack */
116 jmp *%eax
117
118CAR_init_done:
119 addl $4, %esp
120
121 /*
122 * ebp: FSP_INFO_HEADER address
123 * ecx: Temp RAM base
124 * edx: Temp RAM top
125 * edi: BIST value
126 * mm0: low 32-bits of TSC value
127 * mm1: high 32-bits of TSC value
128 */
129
130 cmp $0, %eax
131 jne halt2
132
133 /* Setup bootloader stack */
134 movl %edx, %esp
135
136 /* Save BIST value */
137 movd %edi, %mm2
138
139 /*
140 * ebp: FSP_INFO_HEADER address
141 * 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
146 * mm2: BIST value
147 */
148
149 /* Coreboot assumes stack/heap region will be zero */
150 cld
151 movl %ecx, %edi
152 neg %ecx
153 add %edx, %ecx
154 shrl $2, %ecx
155 xorl %eax, %eax
156 rep stosl
157
158 /* Save FSP_INFO_HEADER location in ebx */
159 mov %ebp, %ebx
160
161 /*
162 * ebx: FSP_INFO_HEADER address
163 * esi: Temp RAM base
164 * esp: Top of stack in temp RAM
165 * mm0: low 32-bits of TSC value
166 * mm1: high 32-bits of TSC value
167 * mm2: BIST value
168 */
169
170 /* Frame for romstage_main(bist, tsc_low, tsc_hi, fih) */
171 pushl %ebx
172 movd %mm1, %eax
173 pushl %eax
174 movd %mm0, %eax
175 pushl %eax
176 movd %mm2, %eax
177 pushl %eax
Lee Leahy3dad4892015-05-05 11:14:02 -0700178
179before_romstage:
180 post_code(0x23)
181
182 /* Call romstage.c main function. */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700183 call romstage_main
Lee Leahy3dad4892015-05-05 11:14:02 -0700184
Lee Leahyb5ad8272015-04-20 15:29:16 -0700185 /*
186 * eax: New stack address
187 * ebx: FSP_INFO_HEADER address
188 */
189
190 /* Switch to the stack in RAM */
191 movl %eax, %esp
192
193 /* Calculate TempRamExit entry into FSP */
194 movl %ebx, %ebp
195 mov 0x40(%ebp), %eax
196 add 0x1c(%ebp), %eax
197
198 /* Build the call frame */
199 pushl $0
200
201 /* Call TempRamExit */
202 call *%eax
203 add $4, %esp
204 cmp $0, %eax
205 jne halt3
206
207 /* Get number of MTRRs. */
208 popl %ebx
209 movl $MTRRphysBase_MSR(0), %ecx
2101:
211 testl %ebx, %ebx
212 jz 1f
213
214 /* Low 32 bits of MTRR base. */
215 popl %eax
216 /* Upper 32 bits of MTRR base. */
217 popl %edx
218 /* Write MTRR base. */
219 wrmsr
220 inc %ecx
221 /* Low 32 bits of MTRR mask. */
222 popl %eax
223 /* Upper 32 bits of MTRR mask. */
224 popl %edx
225 /* Write MTRR mask. */
226 wrmsr
227 inc %ecx
228
229 dec %ebx
230 jmp 1b
2311:
232 post_code(0x39)
233
234 /* And enable cache again after setting MTRRs. */
235 movl %cr0, %eax
236 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
237 movl %eax, %cr0
238
239 post_code(0x3a)
240
241 /* Enable MTRR. */
242 movl $MTRRdefType_MSR, %ecx
243 rdmsr
244 orl $MTRRdefTypeEn, %eax
245 wrmsr
246
247 post_code(0x3b)
248
249 /* Invalidate the cache again. */
250 invd
251
252 post_code(0x3c)
253
254__main:
255 post_code(POST_PREPARE_RAMSTAGE)
256 cld /* Clear direction flag. */
257 call romstage_after_car
258
259
260 movb $0x69, %ah
261 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700262
263halt1:
264 /*
Lee Leahyb5ad8272015-04-20 15:29:16 -0700265 * Failures for postcode 0xBA - failed in fsp_fih_early_find()
Lee Leahy3dad4892015-05-05 11:14:02 -0700266 *
267 * Values are:
268 * 0x01 - FV signature, "_FVH" not present
269 * 0x02 - FFS GUID not present
270 * 0x03 - FSP INFO Header not found
271 * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
272 * a different location, or does it need to be?
273 * 0x05 - FSP INFO Header signature "FSPH" not found
274 * 0x06 - FSP Image ID is not the expected ID.
275 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700276 movb $0xBA, %ah
277 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700278
279halt2:
280 /*
281 * Failures for postcode 0xBB - failed in the FSP:
282 *
283 * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
284 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
Lee Leahy3dad4892015-05-05 11:14:02 -0700285 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
286 * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
Lee Leahyb5ad8272015-04-20 15:29:16 -0700287 * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
Lee Leahy3dad4892015-05-05 11:14:02 -0700288 * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
289 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700290 movb $0xBB, %ah
291 jmp .Lhlt
292
293halt3:
294 /*
295 * Failures for post code BC - failed in TempRamExit
296 *
297 * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully.
298 * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
299 * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
300 * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed.
301 */
302 movb $0xBC, %ah
Lee Leahy3dad4892015-05-05 11:14:02 -0700303
304.Lhlt:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700305 xchg %al, %ah
306#if IS_ENABLED(CONFIG_POST_IO)
307 outb %al, $CONFIG_POST_IO_PORT
Lee Leahy3dad4892015-05-05 11:14:02 -0700308#else
309 post_code(POST_DEAD_CODE)
310#endif
Lee Leahyb5ad8272015-04-20 15:29:16 -0700311 movl $LHLT_DELAY, %ecx
Lee Leahy3dad4892015-05-05 11:14:02 -0700312.Lhlt_Delay:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700313 outb %al, $0xED
314 loop .Lhlt_Delay
315 jmp .Lhlt
Lee Leahy3dad4892015-05-05 11:14:02 -0700316
317/*
318 * esp is set to this location so that the call into and return from the FSP
319 * in find_fsp will work.
320 */
321 .align 4
322fake_fsp_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700323 .long find_fsp_ret
Lee Leahy3dad4892015-05-05 11:14:02 -0700324
325CAR_init_params:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700326 .long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */
327 .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
328 .long 0xFFFFFFFF - CONFIG_CBFS_SIZE + 1 /* Firmware Location */
329 .long CONFIG_CBFS_SIZE /* Total Firmware Length */
Lee Leahy3dad4892015-05-05 11:14:02 -0700330
331CAR_init_stack:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700332 .long CAR_init_done
333 .long CAR_init_params