blob: ddbffbbc6096f12cd0d20d6654fab6a582899cc3 [file] [log] [blame]
Aaron Durbin76c37002012-10-30 09:03:43 -05001/*
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.
Aaron Durbin76c37002012-10-30 09:03:43 -050015 */
16
Aaron Durbin76c37002012-10-30 09:03:43 -050017#include <cpu/x86/mtrr.h>
18#include <cpu/x86/cache.h>
19#include <cpu/x86/post_code.h>
20#include <cbmem.h>
21
Aaron Durbin3d0071b2013-01-18 14:32:50 -060022/* The full cache-as-ram size includes the cache-as-ram portion from coreboot
23 * and the space used by the reference code. These 2 values combined should
24 * be a power of 2 because the MTRR setup assumes that. */
25#define CACHE_AS_RAM_SIZE \
26 (CONFIG_DCACHE_RAM_SIZE + CONFIG_DCACHE_RAM_MRC_VAR_SIZE)
Aaron Durbin76c37002012-10-30 09:03:43 -050027#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
28
29/* Cache 4GB - MRC_SIZE_KB for MRC */
30#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
31#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
32#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
33
34#define CPU_MAXPHYSADDR CONFIG_CPU_ADDR_BITS
35#define CPU_PHYSMASK_HI (1 << (CPU_MAXPHYSADDR - 32) - 1)
36
37#define NoEvictMod_MSR 0x2e0
38
39 /* Save the BIST result. */
40 movl %eax, %ebp
41
42cache_as_ram:
43 post_code(0x20)
44
45 /* Send INIT IPI to all excluding ourself. */
46 movl $0x000C4500, %eax
47 movl $0xFEE00300, %esi
48 movl %eax, (%esi)
49
50 /* All CPUs need to be in Wait for SIPI state */
51wait_for_sipi:
52 movl (%esi), %eax
53 bt $12, %eax
54 jc wait_for_sipi
55
56 post_code(0x21)
57 /* Zero out all fixed range and variable range MTRRs. */
58 movl $mtrr_table, %esi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +020059 movl $((mtrr_table_end - mtrr_table) >> 1), %edi
Aaron Durbin76c37002012-10-30 09:03:43 -050060 xorl %eax, %eax
61 xorl %edx, %edx
62clear_mtrrs:
63 movw (%esi), %bx
64 movzx %bx, %ecx
65 wrmsr
66 add $2, %esi
67 dec %edi
68 jnz clear_mtrrs
69
70 post_code(0x22)
71 /* Configure the default memory type to uncacheable. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070072 movl $MTRR_DEF_TYPE_MSR, %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -050073 rdmsr
74 andl $(~0x00000cff), %eax
75 wrmsr
76
77 post_code(0x23)
78 /* Set Cache-as-RAM base address. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070079 movl $(MTRR_PHYS_BASE(0)), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -050080 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
81 xorl %edx, %edx
82 wrmsr
83
84 post_code(0x24)
85 /* Set Cache-as-RAM mask. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070086 movl $(MTRR_PHYS_MASK(0)), %ecx
87 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Aaron Durbin76c37002012-10-30 09:03:43 -050088 movl $CPU_PHYSMASK_HI, %edx
89 wrmsr
90
91 post_code(0x25)
92
93 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070094 movl $MTRR_DEF_TYPE_MSR, %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -050095 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070096 orl $MTRR_DEF_TYPE_EN, %eax
Aaron Durbin76c37002012-10-30 09:03:43 -050097 wrmsr
98
99 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
100 movl %cr0, %eax
101 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
102 invd
103 movl %eax, %cr0
104
105 /* enable the 'no eviction' mode */
106 movl $NoEvictMod_MSR, %ecx
107 rdmsr
108 orl $1, %eax
109 andl $~2, %eax
110 wrmsr
111
112 /* Clear the cache memory region. This will also fill up the cache */
113 movl $CACHE_AS_RAM_BASE, %esi
114 movl %esi, %edi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200115 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500116 // movl $0x23322332, %eax
117 xorl %eax, %eax
118 rep stosl
119
120 /* enable the 'no eviction run' state */
121 movl $NoEvictMod_MSR, %ecx
122 rdmsr
123 orl $3, %eax
124 wrmsr
125
126 post_code(0x26)
127 /* Enable Cache-as-RAM mode by disabling cache. */
128 movl %cr0, %eax
129 orl $CR0_CacheDisable, %eax
130 movl %eax, %cr0
131
132 /* Enable cache for our code in Flash because we do XIP here */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700133 movl $MTRR_PHYS_BASE(1), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500134 xorl %edx, %edx
135 /*
136 * IMPORTANT: The following calculation _must_ be done at runtime. See
137 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
138 */
139 movl $copy_and_run, %eax
140 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
141 orl $MTRR_TYPE_WRPROT, %eax
142 wrmsr
143
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700144 movl $MTRR_PHYS_MASK(1), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500145 movl $CPU_PHYSMASK_HI, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700146 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Aaron Durbin76c37002012-10-30 09:03:43 -0500147 wrmsr
148
149 post_code(0x27)
Aaron Durbin76c37002012-10-30 09:03:43 -0500150 /* Enable caching for ram init code to run faster */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700151 movl $MTRR_PHYS_BASE(2), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500152 movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
153 xorl %edx, %edx
154 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700155 movl $MTRR_PHYS_MASK(2), %ecx
156 movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
Aaron Durbin76c37002012-10-30 09:03:43 -0500157 movl $CPU_PHYSMASK_HI, %edx
158 wrmsr
Aaron Durbin76c37002012-10-30 09:03:43 -0500159
160 post_code(0x28)
161 /* Enable cache. */
162 movl %cr0, %eax
163 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
164 movl %eax, %cr0
165
Aaron Durbin3d0071b2013-01-18 14:32:50 -0600166 /* Setup the stack. */
167 movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
Aaron Durbin76c37002012-10-30 09:03:43 -0500168 movl %eax, %esp
169
170 /* Restore the BIST result. */
171 movl %ebp, %eax
172 movl %esp, %ebp
173 pushl %eax
174
175before_romstage:
176 post_code(0x29)
177 /* Call romstage.c main function. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600178 call romstage_main
179 /* Save return value from romstage_main. It contains the stack to use
180 * after cache-as-ram is torn down. It also contains the information
Paul Menzel4fe98132014-01-25 15:55:28 +0100181 * for setting up MTRRs. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600182 movl %eax, %ebx
Aaron Durbin76c37002012-10-30 09:03:43 -0500183
184 post_code(0x2f)
185
Aaron Durbin76c37002012-10-30 09:03:43 -0500186 post_code(0x30)
187
188 /* Disable cache. */
189 movl %cr0, %eax
190 orl $CR0_CacheDisable, %eax
191 movl %eax, %cr0
192
193 post_code(0x31)
194
195 /* Disable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700196 movl $MTRR_DEF_TYPE_MSR, %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500197 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700198 andl $(~MTRR_DEF_TYPE_EN), %eax
Aaron Durbin76c37002012-10-30 09:03:43 -0500199 wrmsr
200
201 post_code(0x31)
202
203 /* Disable the no eviction run state */
204 movl $NoEvictMod_MSR, %ecx
205 rdmsr
206 andl $~2, %eax
207 wrmsr
208
209 invd
210
211 /* Disable the no eviction mode */
212 rdmsr
213 andl $~1, %eax
214 wrmsr
215
Aaron Durbin76c37002012-10-30 09:03:43 -0500216 /* Clear MTRR that was used to cache MRC */
217 xorl %eax, %eax
218 xorl %edx, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700219 movl $MTRR_PHYS_BASE(2), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500220 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700221 movl $MTRR_PHYS_MASK(2), %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500222 wrmsr
Aaron Durbin76c37002012-10-30 09:03:43 -0500223
224 post_code(0x33)
225
226 /* Enable cache. */
227 movl %cr0, %eax
228 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
229 movl %eax, %cr0
230
231 post_code(0x36)
232
233 /* Disable cache. */
234 movl %cr0, %eax
235 orl $CR0_CacheDisable, %eax
236 movl %eax, %cr0
237
238 post_code(0x38)
239
Aaron Durbin38d94232013-02-07 00:03:33 -0600240 /* Setup stack as indicated by return value from ramstage_main(). */
241 movl %ebx, %esp
242
Paul Menzel4fe98132014-01-25 15:55:28 +0100243 /* Get number of MTRRs. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600244 popl %ebx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700245 movl $MTRR_PHYS_BASE(0), %ecx
Aaron Durbin38d94232013-02-07 00:03:33 -06002461:
247 testl %ebx, %ebx
248 jz 1f
Aaron Durbin76c37002012-10-30 09:03:43 -0500249
Paul Menzel4fe98132014-01-25 15:55:28 +0100250 /* Low 32 bits of MTRR base. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600251 popl %eax
Paul Menzel4fe98132014-01-25 15:55:28 +0100252 /* Upper 32 bits of MTRR base. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600253 popl %edx
254 /* Write MTRR base. */
Aaron Durbin76c37002012-10-30 09:03:43 -0500255 wrmsr
Aaron Durbin38d94232013-02-07 00:03:33 -0600256 inc %ecx
Paul Menzel4fe98132014-01-25 15:55:28 +0100257 /* Low 32 bits of MTRR mask. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600258 popl %eax
Paul Menzel4fe98132014-01-25 15:55:28 +0100259 /* Upper 32 bits of MTRR mask. */
Aaron Durbin38d94232013-02-07 00:03:33 -0600260 popl %edx
261 /* Write MTRR mask. */
Aaron Durbin76c37002012-10-30 09:03:43 -0500262 wrmsr
Aaron Durbin38d94232013-02-07 00:03:33 -0600263 inc %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500264
Aaron Durbin38d94232013-02-07 00:03:33 -0600265 dec %ebx
266 jmp 1b
2671:
Aaron Durbin76c37002012-10-30 09:03:43 -0500268 post_code(0x39)
269
270 /* And enable cache again after setting MTRRs. */
271 movl %cr0, %eax
272 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
273 movl %eax, %cr0
274
275 post_code(0x3a)
276
277 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700278 movl $MTRR_DEF_TYPE_MSR, %ecx
Aaron Durbin76c37002012-10-30 09:03:43 -0500279 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700280 orl $MTRR_DEF_TYPE_EN, %eax
Aaron Durbin76c37002012-10-30 09:03:43 -0500281 wrmsr
282
283 post_code(0x3b)
284
285 /* Invalidate the cache again. */
286 invd
287
288 post_code(0x3c)
289
Aaron Durbin76c37002012-10-30 09:03:43 -0500290__main:
291 post_code(POST_PREPARE_RAMSTAGE)
292 cld /* Clear direction flag. */
Aaron Durbin7492ec12013-02-08 22:18:04 -0600293 call romstage_after_car
Aaron Durbin76c37002012-10-30 09:03:43 -0500294
295.Lhlt:
296 post_code(POST_DEAD_CODE)
297 hlt
298 jmp .Lhlt
299
300mtrr_table:
301 /* Fixed MTRRs */
302 .word 0x250, 0x258, 0x259
303 .word 0x268, 0x269, 0x26A
304 .word 0x26B, 0x26C, 0x26D
305 .word 0x26E, 0x26F
306 /* Variable MTRRs */
307 .word 0x200, 0x201, 0x202, 0x203
308 .word 0x204, 0x205, 0x206, 0x207
309 .word 0x208, 0x209, 0x20A, 0x20B
310 .word 0x20C, 0x20D, 0x20E, 0x20F
311 .word 0x210, 0x211, 0x212, 0x213
312mtrr_table_end: