blob: eef12b7e8d2492026b1d23bac3532d5f522a0ecb [file] [log] [blame]
Stefan Reinauer5c554632012-04-04 00:09:50 +02001/*
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 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauer5c554632012-04-04 00:09:50 +020015 */
16
Stefan Reinauer5c554632012-04-04 00:09:50 +020017#include <cpu/x86/mtrr.h>
Patrick Georgi05e740f2012-03-31 12:52:21 +020018#include <cpu/x86/cache.h>
Stefan Reinauer5c554632012-04-04 00:09:50 +020019#include <cpu/x86/post_code.h>
20#include <cbmem.h>
21
22#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
23#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
24
25/* Cache 4GB - MRC_SIZE_KB for MRC */
26#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
27#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
28#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
29
Kyösti Mälkkic7fb2ae2012-06-28 21:26:41 +030030#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
Stefan Reinauer5c554632012-04-04 00:09:50 +020031
32#define NoEvictMod_MSR 0x2e0
33
34 /* Save the BIST result. */
35 movl %eax, %ebp
36
37cache_as_ram:
38 post_code(0x20)
39
40 /* Send INIT IPI to all excluding ourself. */
41 movl $0x000C4500, %eax
42 movl $0xFEE00300, %esi
43 movl %eax, (%esi)
44
45 /* All CPUs need to be in Wait for SIPI state */
46wait_for_sipi:
47 movl (%esi), %eax
48 bt $12, %eax
49 jc wait_for_sipi
50
51 post_code(0x21)
52 /* Zero out all fixed range and variable range MTRRs. */
53 movl $mtrr_table, %esi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +020054 movl $((mtrr_table_end - mtrr_table) >> 1), %edi
Stefan Reinauer5c554632012-04-04 00:09:50 +020055 xorl %eax, %eax
56 xorl %edx, %edx
57clear_mtrrs:
58 movw (%esi), %bx
59 movzx %bx, %ecx
60 wrmsr
61 add $2, %esi
62 dec %edi
63 jnz clear_mtrrs
64
65 post_code(0x22)
66 /* Configure the default memory type to uncacheable. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070067 movl $MTRR_DEF_TYPE_MSR, %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +020068 rdmsr
69 andl $(~0x00000cff), %eax
70 wrmsr
71
72 post_code(0x23)
73 /* Set Cache-as-RAM base address. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070074 movl $(MTRR_PHYS_BASE(0)), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +020075 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
76 xorl %edx, %edx
77 wrmsr
78
79 post_code(0x24)
80 /* Set Cache-as-RAM mask. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070081 movl $(MTRR_PHYS_MASK(0)), %ecx
82 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +020083 movl $CPU_PHYSMASK_HI, %edx
84 wrmsr
85
86 post_code(0x25)
87
88 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070089 movl $MTRR_DEF_TYPE_MSR, %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +020090 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070091 orl $MTRR_DEF_TYPE_EN, %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +020092 wrmsr
93
94 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
95 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +020096 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +020097 invd
98 movl %eax, %cr0
99
100 /* enable the 'no eviction' mode */
101 movl $NoEvictMod_MSR, %ecx
102 rdmsr
103 orl $1, %eax
104 andl $~2, %eax
105 wrmsr
106
107 /* Clear the cache memory region. This will also fill up the cache */
108 movl $CACHE_AS_RAM_BASE, %esi
109 movl %esi, %edi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200110 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200111 // movl $0x23322332, %eax
112 xorl %eax, %eax
113 rep stosl
114
115 /* enable the 'no eviction run' state */
116 movl $NoEvictMod_MSR, %ecx
117 rdmsr
118 orl $3, %eax
119 wrmsr
120
121 post_code(0x26)
122 /* Enable Cache-as-RAM mode by disabling cache. */
123 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200124 orl $CR0_CacheDisable, %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200125 movl %eax, %cr0
126
127 /* Enable cache for our code in Flash because we do XIP here */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700128 movl $MTRR_PHYS_BASE(1), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200129 xorl %edx, %edx
130 /*
131 * IMPORTANT: The following calculation _must_ be done at runtime. See
132 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
133 */
134 movl $copy_and_run, %eax
135 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
136 orl $MTRR_TYPE_WRPROT, %eax
137 wrmsr
138
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700139 movl $MTRR_PHYS_MASK(1), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200140 movl $CPU_PHYSMASK_HI, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700141 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200142 wrmsr
143
144 post_code(0x27)
Stefan Reinauer5c554632012-04-04 00:09:50 +0200145 /* Enable caching for ram init code to run faster */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700146 movl $MTRR_PHYS_BASE(2), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200147 movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
148 xorl %edx, %edx
149 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700150 movl $MTRR_PHYS_MASK(2), %ecx
151 movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200152 movl $CPU_PHYSMASK_HI, %edx
153 wrmsr
Stefan Reinauer5c554632012-04-04 00:09:50 +0200154
155 post_code(0x28)
156 /* Enable cache. */
157 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200158 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200159 movl %eax, %cr0
160
161 /* Set up the stack pointer below MRC variable space. */
162 movl $(CACHE_AS_RAM_SIZE + CACHE_AS_RAM_BASE - \
163 CONFIG_DCACHE_RAM_MRC_VAR_SIZE - 4), %eax
164 movl %eax, %esp
165
166 /* Restore the BIST result. */
167 movl %ebp, %eax
168 movl %esp, %ebp
169 pushl %eax
170
171before_romstage:
172 post_code(0x29)
173 /* Call romstage.c main function. */
174 call main
175
176 post_code(0x2f)
177
Stefan Reinauer5c554632012-04-04 00:09:50 +0200178 post_code(0x30)
179
180 /* Disable cache. */
181 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200182 orl $CR0_CacheDisable, %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200183 movl %eax, %cr0
184
185 post_code(0x31)
186
187 /* Disable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700188 movl $MTRR_DEF_TYPE_MSR, %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200189 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700190 andl $(~MTRR_DEF_TYPE_EN), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200191 wrmsr
192
193 post_code(0x31)
194
195 /* Disable the no eviction run state */
196 movl $NoEvictMod_MSR, %ecx
197 rdmsr
198 andl $~2, %eax
199 wrmsr
200
201 invd
202
203 /* Disable the no eviction mode */
204 rdmsr
205 andl $~1, %eax
206 wrmsr
207
Stefan Reinauer5c554632012-04-04 00:09:50 +0200208 /* Clear MTRR that was used to cache MRC */
209 xorl %eax, %eax
210 xorl %edx, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700211 movl $MTRR_PHYS_BASE(2), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200212 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700213 movl $MTRR_PHYS_MASK(2), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200214 wrmsr
Stefan Reinauer5c554632012-04-04 00:09:50 +0200215
216 post_code(0x33)
217
218 /* Enable cache. */
219 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200220 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200221 movl %eax, %cr0
222
223 post_code(0x36)
224
225 /* Disable cache. */
226 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200227 orl $CR0_CacheDisable, %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200228 movl %eax, %cr0
229
230 post_code(0x38)
231
232 /* Enable Write Back and Speculative Reads for the first MB
Furquan Shaikh20f25dd2014-04-22 10:41:05 -0700233 * and ramstage.
Stefan Reinauer5c554632012-04-04 00:09:50 +0200234 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700235 movl $MTRR_PHYS_BASE(0), %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200236 movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
237 xorl %edx, %edx
238 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700239 movl $MTRR_PHYS_MASK(0), %ecx
240 movl $(~(CONFIG_RAMTOP - 1) | MTRR_PHYS_MASK_VALID), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200241 movl $CPU_PHYSMASK_HI, %edx // 36bit address space
242 wrmsr
243
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200244#if CACHE_ROM_SIZE
Stefan Reinauer5c554632012-04-04 00:09:50 +0200245 /* Enable Caching and speculative Reads for the
246 * complete ROM now that we actually have RAM.
247 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700248 movl $MTRR_PHYS_BASE(1), %ecx
Kyösti Mälkki5458b9d2012-06-30 11:41:08 +0300249 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200250 xorl %edx, %edx
251 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700252 movl $MTRR_PHYS_MASK(1), %ecx
253 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200254 movl $CPU_PHYSMASK_HI, %edx
255 wrmsr
Kyösti Mälkki5458b9d2012-06-30 11:41:08 +0300256#endif
Stefan Reinauer5c554632012-04-04 00:09:50 +0200257
258 post_code(0x39)
259
260 /* And enable cache again after setting MTRRs. */
261 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200262 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200263 movl %eax, %cr0
264
265 post_code(0x3a)
266
267 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700268 movl $MTRR_DEF_TYPE_MSR, %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200269 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700270 orl $MTRR_DEF_TYPE_EN, %eax
Stefan Reinauer5c554632012-04-04 00:09:50 +0200271 wrmsr
272
273 post_code(0x3b)
274
275 /* Invalidate the cache again. */
276 invd
277
278 post_code(0x3c)
279
280#if CONFIG_HAVE_ACPI_RESUME
281 movl CBMEM_BOOT_MODE, %eax
282 cmpl $0x2, %eax // Resume?
283 jne __acpi_resume_backup_done
284
285 /* copy 1MB - 64K to high tables ram_base to prevent memory corruption
286 * through stage 2. We could keep stuff like stack and heap in high
287 * tables memory completely, but that's a wonderful clean up task for
288 * another day.
289 */
290 cld
291 movl $CONFIG_RAMBASE, %esi
292 movl CBMEM_RESUME_BACKUP, %edi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200293 movl $HIGH_MEMORY_SAVE >> 2, %ecx
Stefan Reinauer5c554632012-04-04 00:09:50 +0200294 rep movsl
295
296__acpi_resume_backup_done:
297#endif
298
299 post_code(0x3d)
300
Stefan Reinauer5c554632012-04-04 00:09:50 +0200301__main:
302 post_code(POST_PREPARE_RAMSTAGE)
303 cld /* Clear direction flag. */
304
Kyösti Mälkki1729cd82014-10-16 12:47:25 +0300305 movl $CONFIG_RAMTOP, %esp
Stefan Reinauer5c554632012-04-04 00:09:50 +0200306 movl %esp, %ebp
Stefan Reinauer5c554632012-04-04 00:09:50 +0200307 call copy_and_run
308
309.Lhlt:
310 post_code(POST_DEAD_CODE)
311 hlt
312 jmp .Lhlt
313
314mtrr_table:
315 /* Fixed MTRRs */
316 .word 0x250, 0x258, 0x259
317 .word 0x268, 0x269, 0x26A
318 .word 0x26B, 0x26C, 0x26D
319 .word 0x26E, 0x26F
320 /* Variable MTRRs */
321 .word 0x200, 0x201, 0x202, 0x203
322 .word 0x204, 0x205, 0x206, 0x207
323 .word 0x208, 0x209, 0x20A, 0x20B
324 .word 0x20C, 0x20D, 0x20E, 0x20F
325 .word 0x210, 0x211, 0x212, 0x213
326mtrr_table_end: