blob: 5aeeb3f8d42973e385a0c0081cd45f67e7523401 [file] [log] [blame]
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +02005 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02006 * Copyright (C) 2007-2008 coresystems GmbH
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +02007 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02008 *
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.
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020017 */
18
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020019#include <cpu/x86/mtrr.h>
Patrick Georgi05e740f2012-03-31 12:52:21 +020020#include <cpu/x86/cache.h>
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020021#include <cpu/x86/post_code.h>
22
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020023#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
24#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
25
26 /* Save the BIST result. */
27 movl %eax, %ebp
28
29cache_as_ram:
30 post_code(0x20)
31
Kyösti Mälkki5bc46d82018-06-14 06:21:53 +030032 /* Clear/disable fixed MTRRs */
33 mov $fixed_mtrr_list_size, %ebx
34 xor %eax, %eax
35 xor %edx, %edx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020036
Kyösti Mälkki5bc46d82018-06-14 06:21:53 +030037clear_fixed_mtrr:
38 add $-2, %ebx
39 movzwl fixed_mtrr_list(%ebx), %ecx
40 wrmsr
41 jnz clear_fixed_mtrr
42
43 /* Figure put how many MTRRs we have, and clear them out */
44 mov $MTRR_CAP_MSR, %ecx
45 rdmsr
46 movzb %al, %ebx /* Number of variable MTRRs */
47 mov $MTRR_PHYS_BASE(0), %ecx
48 xor %eax, %eax
49 xor %edx, %edx
50
51clear_var_mtrr:
52 wrmsr
53 inc %ecx
54 wrmsr
55 inc %ecx
56 dec %ebx
57 jnz clear_var_mtrr
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020058 post_code(0x21)
59
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020060 /* Configure the default memory type to uncacheable. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070061 movl $MTRR_DEF_TYPE_MSR, %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020062 rdmsr
63 andl $(~0x00000cff), %eax
64 wrmsr
65
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020066 post_code(0x22)
67
Kyösti Mälkki54d6a282018-05-25 06:03:14 +030068 /* Determine CPU_ADDR_BITS and load PHYSMASK high word to %edx. */
Kyösti Mälkkia860c682012-02-28 02:06:45 +020069 movl $1, %eax
70 cpuid
Elyes HAOUAS168ef392017-06-27 22:54:42 +020071 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
Kyösti Mälkkia860c682012-02-28 02:06:45 +020072 jz addrsize_set_high
73 movl $0x0f, %edx
74
75 /* Preload high word of address mask (in %edx) for Variable
Kyösti Mälkki54d6a282018-05-25 06:03:14 +030076 MTRRs 0 and 1. */
Kyösti Mälkkia860c682012-02-28 02:06:45 +020077addrsize_set_high:
78 xorl %eax, %eax
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070079 movl $MTRR_PHYS_MASK(0), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +020080 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070081 movl $MTRR_PHYS_MASK(1), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +020082 wrmsr
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020083
84 post_code(0x2a)
85
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020086 /* Set Cache-as-RAM base address. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070087 movl $(MTRR_PHYS_BASE(0)), %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020088 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
89 xorl %edx, %edx
90 wrmsr
91
92 /* Set Cache-as-RAM mask. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070093 movl $(MTRR_PHYS_MASK(0)), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +020094 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070095 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020096 wrmsr
97
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +030098 post_code(0x2b)
99
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200100 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700101 movl $MTRR_DEF_TYPE_MSR, %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200102 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700103 orl $MTRR_DEF_TYPE_EN, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200104 wrmsr
105
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200106 post_code(0x2c)
107
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200108 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200109 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200110 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200111 invd
112 movl %eax, %cr0
113
Kyösti Mälkki54d6a282018-05-25 06:03:14 +0300114 /* Read then clear the CAR region. This will also fill up the cache.
115 * IMPORTANT: The read is mandatory.
116 */
117 movl $CACHE_AS_RAM_BASE, %esi
118 movl %esi, %edi
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200119 cld
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200120 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
Kyösti Mälkki54d6a282018-05-25 06:03:14 +0300121 rep lodsl
122 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
123 xorl %eax, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200124 rep stosl
125
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300126 post_code(0x2d)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200127 /* Enable Cache-as-RAM mode by disabling cache. */
128 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200129 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200130 movl %eax, %cr0
131
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200132 /* 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
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200134 xorl %edx, %edx
135 /*
136 * IMPORTANT: The following calculation _must_ be done at runtime. See
Paul Menzela8843de2017-06-05 12:33:23 +0200137 * https://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200138 */
139 movl $copy_and_run, %eax
140 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
Kyösti Mälkkidc4820b2016-07-21 19:51:01 +0300141 orl $MTRR_TYPE_WRPROT, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200142 wrmsr
143
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700144 movl $MTRR_PHYS_MASK(1), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200145 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700146 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200147 wrmsr
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200148
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300149 post_code(0x2e)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200150 /* Enable cache. */
151 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200152 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200153 movl %eax, %cr0
154
Kyösti Mälkki39915bc2016-11-08 12:13:15 +0200155 /* Setup the stack. */
156 movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
157 movl %eax, %esp
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200158
159 /* Restore the BIST result. */
160 movl %ebp, %eax
161 movl %esp, %ebp
162 pushl %eax
163
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300164before_romstage:
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200165 post_code(0x2f)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200166 /* Call romstage.c main function. */
Kyösti Mälkki408d3922016-06-17 10:43:48 +0300167 call romstage_main
Kyösti Mälkki408d3922016-06-17 10:43:48 +0300168 /* Save return value from romstage_main. It contains the stack to use
Kyösti Mälkki823020d2016-07-22 22:53:19 +0300169 * after cache-as-ram is torn down. It also contains the information
170 * for setting up MTRRs. */
Kyösti Mälkki39915bc2016-11-08 12:13:15 +0200171 movl %eax, %esp
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200172
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200173 post_code(0x30)
174
175 /* Disable cache. */
176 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200177 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200178 movl %eax, %cr0
179
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300180 post_code(0x31)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200181
182 /* Disable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700183 movl $MTRR_DEF_TYPE_MSR, %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200184 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700185 andl $(~MTRR_DEF_TYPE_EN), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200186 wrmsr
187
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300188 post_code(0x32)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200189
190 invd
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200191
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300192 post_code(0x33)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200193
194 /* Enable cache. */
195 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200196 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200197 movl %eax, %cr0
198
Kyösti Mälkki8a2f1672016-07-20 13:29:59 +0300199 post_code(0x36)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200200
201 /* Disable cache. */
202 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200203 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200204 movl %eax, %cr0
205
206 post_code(0x38)
207
Kyösti Mälkki823020d2016-07-22 22:53:19 +0300208 /* Clear all of the variable MTRRs. */
209 popl %ebx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700210 movl $MTRR_PHYS_BASE(0), %ecx
Kyösti Mälkki823020d2016-07-22 22:53:19 +0300211 clr %eax
212 clr %edx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200213
Kyösti Mälkki823020d2016-07-22 22:53:19 +03002141:
215 testl %ebx, %ebx
216 jz 1f
217 wrmsr /* Write MTRR base. */
218 inc %ecx
219 wrmsr /* Write MTRR mask. */
220 inc %ecx
221 dec %ebx
222 jmp 1b
223
2241:
225 /* Get number of MTRRs. */
226 popl %ebx
227 movl $MTRR_PHYS_BASE(0), %ecx
2282:
229 testl %ebx, %ebx
230 jz 2f
231
232 /* Low 32 bits of MTRR base. */
233 popl %eax
234 /* Upper 32 bits of MTRR base. */
235 popl %edx
236 /* Write MTRR base. */
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200237 wrmsr
Kyösti Mälkki823020d2016-07-22 22:53:19 +0300238 inc %ecx
239 /* Low 32 bits of MTRR mask. */
240 popl %eax
241 /* Upper 32 bits of MTRR mask. */
242 popl %edx
243 /* Write MTRR mask. */
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200244 wrmsr
Kyösti Mälkki823020d2016-07-22 22:53:19 +0300245 inc %ecx
246
247 dec %ebx
248 jmp 2b
2492:
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200250
251 post_code(0x39)
252
253 /* And enable cache again after setting MTRRs. */
254 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200255 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200256 movl %eax, %cr0
257
258 post_code(0x3a)
259
260 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700261 movl $MTRR_DEF_TYPE_MSR, %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200262 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700263 orl $MTRR_DEF_TYPE_EN, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200264 wrmsr
265
266 post_code(0x3b)
267
268 /* Invalidate the cache again. */
269 invd
270
271 post_code(0x3c)
272
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200273__main:
274 post_code(POST_PREPARE_RAMSTAGE)
275 cld /* Clear direction flag. */
Kyösti Mälkki39915bc2016-11-08 12:13:15 +0200276 call romstage_after_car
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200277
278.Lhlt:
279 post_code(POST_DEAD_CODE)
280 hlt
281 jmp .Lhlt
282
Kyösti Mälkki5bc46d82018-06-14 06:21:53 +0300283fixed_mtrr_list:
284 .word MTRR_FIX_64K_00000
285 .word MTRR_FIX_16K_80000
286 .word MTRR_FIX_16K_A0000
287 .word MTRR_FIX_4K_C0000
288 .word MTRR_FIX_4K_C8000
289 .word MTRR_FIX_4K_D0000
290 .word MTRR_FIX_4K_D8000
291 .word MTRR_FIX_4K_E0000
292 .word MTRR_FIX_4K_E8000
293 .word MTRR_FIX_4K_F0000
294 .word MTRR_FIX_4K_F8000
295fixed_mtrr_list_size = . - fixed_mtrr_list