blob: 3f1b12af18e96bfa83b2ac6e620c668de07ecc84 [file] [log] [blame]
Duncan Lauriec88c54c2014-04-30 16:36:13 -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) 2014 Google Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010019 * Foundation, Inc.
Duncan Lauriec88c54c2014-04-30 16:36:13 -070020 */
21
Duncan Lauriec88c54c2014-04-30 16:36:13 -070022#include <cpu/x86/mtrr.h>
23#include <cpu/x86/cache.h>
24#include <cpu/x86/post_code.h>
25#include <cbmem.h>
26
27/* The full cache-as-ram size includes the cache-as-ram portion from coreboot
28 * and the space used by the reference code. These 2 values combined should
29 * be a power of 2 because the MTRR setup assumes that. */
30#define CACHE_AS_RAM_SIZE \
31 (CONFIG_DCACHE_RAM_SIZE + CONFIG_DCACHE_RAM_MRC_VAR_SIZE)
32#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
33#define CACHE_AS_RAM_LIMIT (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
34#define USBDEBUG_VAR_SIZE 36 /* sizeof(struct ehci_debug_info) */
35
36/* Cache 4GB - MRC_SIZE_KB for MRC */
37#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
38#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
39#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
40
41#define CPU_MAXPHYSADDR CONFIG_CPU_ADDR_BITS
42#define CPU_PHYSMASK_HI (1 << (CPU_MAXPHYSADDR - 32) - 1)
43
44#define NoEvictMod_MSR 0x2e0
45
46 /* Save the BIST result. */
47 movl %eax, %ebp
48
49cache_as_ram:
50 post_code(0x20)
51
52 /* Send INIT IPI to all excluding ourself. */
53 movl $0x000C4500, %eax
54 movl $0xFEE00300, %esi
55 movl %eax, (%esi)
56
57 /* All CPUs need to be in Wait for SIPI state */
58wait_for_sipi:
59 movl (%esi), %eax
60 bt $12, %eax
61 jc wait_for_sipi
62
63 post_code(0x21)
64 /* Zero out all fixed range and variable range MTRRs. */
65 movl $mtrr_table, %esi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +020066 movl $((mtrr_table_end - mtrr_table) >> 1), %edi
Duncan Lauriec88c54c2014-04-30 16:36:13 -070067 xorl %eax, %eax
68 xorl %edx, %edx
69clear_mtrrs:
70 movw (%esi), %bx
71 movzx %bx, %ecx
72 wrmsr
73 add $2, %esi
74 dec %edi
75 jnz clear_mtrrs
76
77 post_code(0x22)
78 /* Configure the default memory type to uncacheable. */
79 movl $MTRRdefType_MSR, %ecx
80 rdmsr
81 andl $(~0x00000cff), %eax
82 wrmsr
83
84 post_code(0x23)
85 /* Set Cache-as-RAM base address. */
86 movl $(MTRRphysBase_MSR(0)), %ecx
87 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
88 xorl %edx, %edx
89 wrmsr
90
91 post_code(0x24)
92 /* Set Cache-as-RAM mask. */
93 movl $(MTRRphysMask_MSR(0)), %ecx
94 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
95 movl $CPU_PHYSMASK_HI, %edx
96 wrmsr
97
98 post_code(0x25)
99
100 /* Enable MTRR. */
101 movl $MTRRdefType_MSR, %ecx
102 rdmsr
103 orl $MTRRdefTypeEn, %eax
104 wrmsr
105
106 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
107 movl %cr0, %eax
108 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
109 invd
110 movl %eax, %cr0
111
112 /* enable the 'no eviction' mode */
113 movl $NoEvictMod_MSR, %ecx
114 rdmsr
115 orl $1, %eax
116 andl $~2, %eax
117 wrmsr
118
119 /* Clear the cache memory region. This will also fill up the cache */
120 movl $CACHE_AS_RAM_BASE, %esi
121 movl %esi, %edi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200122 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700123 xorl %eax, %eax
124 rep stosl
125
126 /* enable the 'no eviction run' state */
127 movl $NoEvictMod_MSR, %ecx
128 rdmsr
129 orl $3, %eax
130 wrmsr
131
132 post_code(0x26)
133 /* Enable Cache-as-RAM mode by disabling cache. */
134 movl %cr0, %eax
135 orl $CR0_CacheDisable, %eax
136 movl %eax, %cr0
137
138 /* Enable cache for our code in Flash because we do XIP here */
139 movl $MTRRphysBase_MSR(1), %ecx
140 xorl %edx, %edx
141 /*
142 * IMPORTANT: The following calculation _must_ be done at runtime. See
143 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
144 */
145 movl $copy_and_run, %eax
146 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
147 orl $MTRR_TYPE_WRPROT, %eax
148 wrmsr
149
150 movl $MTRRphysMask_MSR(1), %ecx
151 movl $CPU_PHYSMASK_HI, %edx
152 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
153 wrmsr
154
155 post_code(0x27)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700156 /* Enable caching for ram init code to run faster */
157 movl $MTRRphysBase_MSR(2), %ecx
158 movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
159 xorl %edx, %edx
160 wrmsr
161 movl $MTRRphysMask_MSR(2), %ecx
162 movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
163 movl $CPU_PHYSMASK_HI, %edx
164 wrmsr
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700165
166 post_code(0x28)
167 /* Enable cache. */
168 movl %cr0, %eax
169 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
170 movl %eax, %cr0
171
172 /* Setup the stack. */
173 movl $(CACHE_AS_RAM_LIMIT), %eax
174#if CONFIG_USBDEBUG
175 sub $(USBDEBUG_VAR_SIZE), %eax
176#endif
177 movl %eax, %esp
178
179 /* Restore the BIST result. */
180 movl %ebp, %eax
Lee Leahy4a69c342014-11-20 16:56:44 -0800181
182 /* Build the call frame. */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700183 movl %esp, %ebp
Lee Leahy4a69c342014-11-20 16:56:44 -0800184 movd %mm1, %ebx
185 pushl %ebx
186 movd %mm0, %ebx
187 pushl %ebx
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700188 pushl %eax
189
190before_romstage:
191 post_code(0x29)
192 /* Call romstage.c main function. */
193 call romstage_main
194 /* Save return value from romstage_main. It contains the stack to use
195 * after cache-as-ram is torn down. It also contains the information
196 * for setting up MTRRs. */
197 movl %eax, %ebx
198
199 post_code(0x2f)
200
201 /* Copy global variable space (for USBDEBUG) to memory */
202#if CONFIG_USBDEBUG
203 cld
204 movl $(CACHE_AS_RAM_LIMIT - USBDEBUG_VAR_SIZE), %esi
205 movl $(CONFIG_RAMTOP - USBDEBUG_VAR_SIZE), %edi
206 movl $USBDEBUG_VAR_SIZE, %ecx
207 rep movsb
208#endif
209
210 post_code(0x30)
211
212 /* Disable cache. */
213 movl %cr0, %eax
214 orl $CR0_CacheDisable, %eax
215 movl %eax, %cr0
216
217 post_code(0x31)
218
219 /* Disable MTRR. */
220 movl $MTRRdefType_MSR, %ecx
221 rdmsr
222 andl $(~MTRRdefTypeEn), %eax
223 wrmsr
224
225 post_code(0x31)
226
227 /* Disable the no eviction run state */
228 movl $NoEvictMod_MSR, %ecx
229 rdmsr
230 andl $~2, %eax
231 wrmsr
232
233 invd
234
235 /* Disable the no eviction mode */
236 rdmsr
237 andl $~1, %eax
238 wrmsr
239
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700240 /* Clear MTRR that was used to cache MRC */
241 xorl %eax, %eax
242 xorl %edx, %edx
243 movl $MTRRphysBase_MSR(2), %ecx
244 wrmsr
245 movl $MTRRphysMask_MSR(2), %ecx
246 wrmsr
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700247
248 post_code(0x33)
249
250 /* Enable cache. */
251 movl %cr0, %eax
252 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
253 movl %eax, %cr0
254
255 post_code(0x36)
256
257 /* Disable cache. */
258 movl %cr0, %eax
259 orl $CR0_CacheDisable, %eax
260 movl %eax, %cr0
261
262 post_code(0x38)
263
264 /* Setup stack as indicated by return value from ramstage_main(). */
265 movl %ebx, %esp
266
267 /* Get number of MTRRs. */
268 popl %ebx
269 movl $MTRRphysBase_MSR(0), %ecx
2701:
271 testl %ebx, %ebx
272 jz 1f
273
274 /* Low 32 bits of MTRR base. */
275 popl %eax
276 /* Upper 32 bits of MTRR base. */
277 popl %edx
278 /* Write MTRR base. */
279 wrmsr
280 inc %ecx
281 /* Low 32 bits of MTRR mask. */
282 popl %eax
283 /* Upper 32 bits of MTRR mask. */
284 popl %edx
285 /* Write MTRR mask. */
286 wrmsr
287 inc %ecx
288
289 dec %ebx
290 jmp 1b
2911:
292 post_code(0x39)
293
294 /* And enable cache again after setting MTRRs. */
295 movl %cr0, %eax
296 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
297 movl %eax, %cr0
298
299 post_code(0x3a)
300
301 /* Enable MTRR. */
302 movl $MTRRdefType_MSR, %ecx
303 rdmsr
304 orl $MTRRdefTypeEn, %eax
305 wrmsr
306
307 post_code(0x3b)
308
309 /* Invalidate the cache again. */
310 invd
311
312 post_code(0x3c)
313
314__main:
315 post_code(POST_PREPARE_RAMSTAGE)
316 cld /* Clear direction flag. */
317 call romstage_after_car
318
319.Lhlt:
320 post_code(POST_DEAD_CODE)
321 hlt
322 jmp .Lhlt
323
324mtrr_table:
325 /* Fixed MTRRs */
326 .word 0x250, 0x258, 0x259
327 .word 0x268, 0x269, 0x26A
328 .word 0x26B, 0x26C, 0x26D
329 .word 0x26E, 0x26F
330 /* Variable MTRRs */
331 .word 0x200, 0x201, 0x202, 0x203
332 .word 0x204, 0x205, 0x206, 0x207
333 .word 0x208, 0x209, 0x20A, 0x20B
334 .word 0x20C, 0x20D, 0x20E, 0x20F
335 .word 0x210, 0x211, 0x212, 0x213
336mtrr_table_end: