blob: 6fa3eb82b5c003e5f98001574e68ce8c9eaaa161 [file] [log] [blame]
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +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.
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020015 */
16
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020017#include <cpu/x86/mtrr.h>
18#include <cpu/x86/cache.h>
19#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
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020025#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
26
27#define NoEvictMod_MSR 0x2e0
28
29 /* Save the BIST result. */
30 movl %eax, %ebp
31
32cache_as_ram:
33 post_code(0x20)
34
35 /* Send INIT IPI to all excluding ourself. */
36 movl $0x000C4500, %eax
37 movl $0xFEE00300, %esi
38 movl %eax, (%esi)
39
40 /* All CPUs need to be in Wait for SIPI state */
41wait_for_sipi:
42 movl (%esi), %eax
43 bt $12, %eax
44 jc wait_for_sipi
45
46 post_code(0x21)
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070047 /* Clean-up MTRR_DEF_TYPE_MSR. */
48 movl $MTRR_DEF_TYPE_MSR, %ecx
Vladimir Serbinenko75b90a12013-11-14 18:49:26 +010049 xorl %eax, %eax
50 xorl %edx, %edx
51 wrmsr
52
53 post_code(0x22)
54 /* Zero out all fixed range MTRRs. */
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020055 movl $mtrr_table, %esi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +020056 movl $((mtrr_table_end - mtrr_table) >> 1), %edi
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020057 xorl %eax, %eax
58 xorl %edx, %edx
59clear_mtrrs:
60 movw (%esi), %bx
61 movzx %bx, %ecx
62 wrmsr
63 add $2, %esi
64 dec %edi
65 jnz clear_mtrrs
66
Vladimir Serbinenko75b90a12013-11-14 18:49:26 +010067 /* Zero out all variable range MTRRs. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070068 movl $MTRR_CAP_MSR, %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020069 rdmsr
Vladimir Serbinenko75b90a12013-11-14 18:49:26 +010070 andl $0xff, %eax
71 shl $1, %eax
72 movl %eax, %edi
73 movl $0x200, %ecx
74 xorl %eax, %eax
75 xorl %edx, %edx
76clear_var_mtrrs:
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020077 wrmsr
Vladimir Serbinenko75b90a12013-11-14 18:49:26 +010078 add $1, %ecx
79 dec %edi
80 jnz clear_var_mtrrs
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020081
82 post_code(0x23)
83 /* Set Cache-as-RAM base address. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070084 movl $(MTRR_PHYS_BASE(0)), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020085 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
86 xorl %edx, %edx
87 wrmsr
88
89 post_code(0x24)
90 /* Set Cache-as-RAM mask. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070091 movl $(MTRR_PHYS_MASK(0)), %ecx
92 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +020093 movl $CPU_PHYSMASK_HI, %edx
94 wrmsr
95
96 post_code(0x25)
97
98 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070099 movl $MTRR_DEF_TYPE_MSR, %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200100 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700101 orl $MTRR_DEF_TYPE_EN, %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200102 wrmsr
103
104 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
105 movl %cr0, %eax
106 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
107 invd
108 movl %eax, %cr0
109
110 /* enable the 'no eviction' mode */
111 movl $NoEvictMod_MSR, %ecx
112 rdmsr
113 orl $1, %eax
114 andl $~2, %eax
115 wrmsr
116
117 /* Clear the cache memory region. This will also fill up the cache */
118 movl $CACHE_AS_RAM_BASE, %esi
119 movl %esi, %edi
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200120 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200121 // movl $0x23322332, %eax
122 xorl %eax, %eax
123 rep stosl
124
125 /* enable the 'no eviction run' state */
126 movl $NoEvictMod_MSR, %ecx
127 rdmsr
128 orl $3, %eax
129 wrmsr
130
131 post_code(0x26)
132 /* Enable Cache-as-RAM mode by disabling cache. */
133 movl %cr0, %eax
134 orl $CR0_CacheDisable, %eax
135 movl %eax, %cr0
136
137 /* Enable cache for our code in Flash because we do XIP here */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700138 movl $MTRR_PHYS_BASE(1), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200139 xorl %edx, %edx
140 /*
141 * IMPORTANT: The following calculation _must_ be done at runtime. See
142 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
143 */
144 movl $copy_and_run, %eax
145 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
146 orl $MTRR_TYPE_WRPROT, %eax
147 wrmsr
148
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700149 movl $MTRR_PHYS_MASK(1), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200150 movl $CPU_PHYSMASK_HI, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700151 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200152 wrmsr
153
154 post_code(0x27)
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200155
156 post_code(0x28)
157 /* Enable cache. */
158 movl %cr0, %eax
159 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
160 movl %eax, %cr0
161
Vladimir Serbinenko75b90a12013-11-14 18:49:26 +0100162 /* Set up the stack pointer below the end of CAR. */
163 movl $(CACHE_AS_RAM_SIZE + CACHE_AS_RAM_BASE - 4), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200164 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
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200178 post_code(0x30)
179
180 /* Disable cache. */
181 movl %cr0, %eax
182 orl $CR0_CacheDisable, %eax
183 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
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200189 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700190 andl $(~MTRR_DEF_TYPE_EN), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +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
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200208 post_code(0x33)
209
210 /* Enable cache. */
211 movl %cr0, %eax
212 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
213 movl %eax, %cr0
214
215 post_code(0x36)
216
217 /* Disable cache. */
218 movl %cr0, %eax
219 orl $CR0_CacheDisable, %eax
220 movl %eax, %cr0
221
222 post_code(0x38)
223
224 /* Enable Write Back and Speculative Reads for the first MB
Furquan Shaikh20f25dd2014-04-22 10:41:05 -0700225 * and ramstage.
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200226 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700227 movl $MTRR_PHYS_BASE(0), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200228 movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
229 xorl %edx, %edx
230 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700231 movl $MTRR_PHYS_MASK(0), %ecx
232 movl $(~(CONFIG_RAMTOP - 1) | MTRR_PHYS_MASK_VALID), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200233 movl $CPU_PHYSMASK_HI, %edx // 36bit address space
234 wrmsr
235
Kyösti Mälkki107f72e2014-01-06 11:06:26 +0200236#if CACHE_ROM_SIZE
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200237 /* Enable Caching and speculative Reads for the
238 * complete ROM now that we actually have RAM.
239 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700240 movl $MTRR_PHYS_BASE(1), %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200241 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
242 xorl %edx, %edx
243 wrmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700244 movl $MTRR_PHYS_MASK(1), %ecx
245 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200246 movl $CPU_PHYSMASK_HI, %edx
247 wrmsr
248#endif
249
250 post_code(0x39)
251
252 /* And enable cache again after setting MTRRs. */
253 movl %cr0, %eax
254 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
255 movl %eax, %cr0
256
257 post_code(0x3a)
258
259 /* Enable MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700260 movl $MTRR_DEF_TYPE_MSR, %ecx
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200261 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700262 orl $MTRR_DEF_TYPE_EN, %eax
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200263 wrmsr
264
265 post_code(0x3b)
266
267 /* Invalidate the cache again. */
268 invd
269
270 post_code(0x3c)
271
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200272__main:
273 post_code(POST_PREPARE_RAMSTAGE)
274 cld /* Clear direction flag. */
275
Kyösti Mälkki1729cd82014-10-16 12:47:25 +0300276 movl $CONFIG_RAMTOP, %esp
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200277 movl %esp, %ebp
278 call copy_and_run
279
280.Lhlt:
281 post_code(POST_DEAD_CODE)
282 hlt
283 jmp .Lhlt
284
285mtrr_table:
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200286 /* Fixed MTRRs */
287 .word 0x250, 0x258, 0x259
288 .word 0x268, 0x269, 0x26A
289 .word 0x26B, 0x26C, 0x26D
290 .word 0x26E, 0x26F
Vladimir Serbinenko22dcdd92013-06-06 22:10:45 +0200291mtrr_table_end: