blob: fda572d659d1e133c3e94e12b7624f57a6234fbe [file] [log] [blame]
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
5 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
6 * Copyright (C) 2007-2008 coresystems GmbH
7 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
8 *
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.
17 */
18
19#include <cpu/x86/mtrr.h>
20#include <cpu/x86/cache.h>
21#include <cpu/x86/post_code.h>
22#include <cpu/x86/lapic_def.h>
23
24/* Macro to access Local APIC registers at default base. */
25#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
Kyösti Mälkki34856572019-01-09 20:30:52 +020026#if !IS_ENABLED(CONFIG_C_ENVIRONMENT_BOOTBLOCK)
27/* Fixed location, ASSERTED in failover.ld if it changes. */
28.set ap_sipi_vector_in_rom, 0xff
29#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030030
31#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
32#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
33
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020034.global bootblock_pre_c_entry
35
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030036.code32
37_cache_as_ram_setup:
38
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020039bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030040
41cache_as_ram:
42 post_code(0x20)
43
44 movl $LAPIC_BASE_MSR, %ecx
45 rdmsr
46 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
47 jz ap_init
48
49 /* Clear/disable fixed MTRRs */
50 mov $fixed_mtrr_list_size, %ebx
51 xor %eax, %eax
52 xor %edx, %edx
53
54clear_fixed_mtrr:
55 add $-2, %ebx
56 movzwl fixed_mtrr_list(%ebx), %ecx
57 wrmsr
58 jnz clear_fixed_mtrr
59
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020060 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030061 mov $MTRR_CAP_MSR, %ecx
62 rdmsr
63 movzb %al, %ebx /* Number of variable MTRRs */
64 mov $MTRR_PHYS_BASE(0), %ecx
65 xor %eax, %eax
66 xor %edx, %edx
67
68clear_var_mtrr:
69 wrmsr
70 inc %ecx
71 wrmsr
72 inc %ecx
73 dec %ebx
74 jnz clear_var_mtrr
75 post_code(0x21)
76
77 /* Configure the default memory type to uncacheable. */
78 movl $MTRR_DEF_TYPE_MSR, %ecx
79 rdmsr
80 andl $(~0x00000cff), %eax
81 wrmsr
82
83 post_code(0x22)
84
85 /* Determine CPU_ADDR_BITS and load PHYSMASK high
86 * word to %edx.
87 */
88 movl $0x80000000, %eax
89 cpuid
90 cmpl $0x80000008, %eax
91 jc addrsize_no_MSR
92 movl $0x80000008, %eax
93 cpuid
94 movb %al, %cl
95 sub $32, %cl
96 movl $1, %edx
97 shl %cl, %edx
98 subl $1, %edx
99 jmp addrsize_set_high
100addrsize_no_MSR:
101 movl $1, %eax
102 cpuid
103 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
104 jz addrsize_set_high
105 movl $0x0f, %edx
106
107 /* Preload high word of address mask (in %edx) for Variable
108 * MTRRs 0 and 1 and enable local APIC at default base.
109 */
110addrsize_set_high:
111 xorl %eax, %eax
112 movl $MTRR_PHYS_MASK(0), %ecx
113 wrmsr
114 movl $MTRR_PHYS_MASK(1), %ecx
115 wrmsr
116 movl $LAPIC_BASE_MSR, %ecx
117 not %edx
118 movl %edx, %ebx
119 rdmsr
120 andl %ebx, %edx
121 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
122 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
123 wrmsr
124
125bsp_init:
126
127 post_code(0x23)
128
129 /* Send INIT IPI to all excluding ourself. */
130 movl LAPIC(ICR), %edi
131 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1321: movl %eax, (%edi)
133 movl $0x30, %ecx
1342: pause
135 dec %ecx
136 jnz 2b
137 movl (%edi), %ecx
138 andl $LAPIC_ICR_BUSY, %ecx
139 jnz 1b
140
141 post_code(0x24)
142
143 movl $1, %eax
144 cpuid
145 btl $28, %edx
146 jnc sipi_complete
147 bswapl %ebx
148 movzx %bh, %edi
149 cmpb $1, %bh
150 jbe sipi_complete /* only one LAPIC ID in package */
151
152 movl $0, %eax
153 cpuid
154 movb $1, %bl
155 cmpl $4, %eax
156 jb cores_counted
157 movl $4, %eax
158 movl $0, %ecx
159 cpuid
160 shr $26, %eax
161 movb %al, %bl
162 inc %bl
163
164cores_counted:
165 movl %edi, %eax
166 divb %bl
167 cmpb $1, %al
168 jbe sipi_complete /* only LAPIC ID of a core */
169
170 /* For a hyper-threading processor, cache must not be disabled
171 * on an AP on the same physical package with the BSP.
172 */
173
174hyper_threading_cpu:
175
176 /* delay 10 ms */
177 movl $10000, %ecx
1781: inb $0x80, %al
179 dec %ecx
180 jnz 1b
181
182 post_code(0x25)
183
184 /* Send Start IPI to all excluding ourself. */
185 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200186 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
187 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001881: movl %eax, (%edi)
189 movl $0x30, %ecx
1902: pause
191 dec %ecx
192 jnz 2b
193 movl (%edi), %ecx
194 andl $LAPIC_ICR_BUSY, %ecx
195 jnz 1b
196
197 /* delay 250 us */
198 movl $250, %ecx
1991: inb $0x80, %al
200 dec %ecx
201 jnz 1b
202
203 post_code(0x26)
204
205 /* Wait for sibling CPU to start. */
2061: movl $(MTRR_PHYS_BASE(0)), %ecx
207 rdmsr
208 andl %eax, %eax
209 jnz sipi_complete
210
211 movl $0x30, %ecx
2122: pause
213 dec %ecx
214 jnz 2b
215 jmp 1b
216
217
218ap_init:
219 post_code(0x27)
220
221 /* Do not disable cache (so BSP can enable it). */
222 movl %cr0, %eax
223 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
224 movl %eax, %cr0
225
226 post_code(0x28)
227
228 /* MTRR registers are shared between HT siblings. */
229 movl $(MTRR_PHYS_BASE(0)), %ecx
230 movl $(1 << 12), %eax
231 xorl %edx, %edx
232 wrmsr
233
234 post_code(0x29)
235
236ap_halt:
237 cli
2381: hlt
239 jmp 1b
240
241
242
243sipi_complete:
244
245 post_code(0x2a)
246
247 /* Set Cache-as-RAM base address. */
248 movl $(MTRR_PHYS_BASE(0)), %ecx
249 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
250 xorl %edx, %edx
251 wrmsr
252
253 /* Set Cache-as-RAM mask. */
254 movl $(MTRR_PHYS_MASK(0)), %ecx
255 rdmsr
256 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
257 wrmsr
258
259 post_code(0x2b)
260
261 /* Enable MTRR. */
262 movl $MTRR_DEF_TYPE_MSR, %ecx
263 rdmsr
264 orl $MTRR_DEF_TYPE_EN, %eax
265 wrmsr
266
267 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
268 *
269 * MSR is set when DisplayFamily_DisplayModel is one of:
270 * 06_0x, 06_17, 06_1C
271 *
272 * Description says this bit enables use of WBINVD and FLUSH#.
273 * Should this be set only after the system bus and/or memory
274 * controller can successfully handle write cycles?
275 */
276
277#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
278#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
279
280 movl $1, %eax
281 cpuid
282 movl %eax, %ebx
283 andl $EAX_FAMILY(0x0f), %eax
284 cmpl $EAX_FAMILY(0x06), %eax
285 jne no_msr_11e
286 movl %ebx, %eax
287 andl $EAX_MODEL(0xff), %eax
288 cmpl $EAX_MODEL(0x17), %eax
289 je has_msr_11e
290 cmpl $EAX_MODEL(0x1c), %eax
291 je has_msr_11e
292 andl $EAX_MODEL(0xf0), %eax
293 cmpl $EAX_MODEL(0x00), %eax
294 jne no_msr_11e
295has_msr_11e:
296 movl $0x11e, %ecx
297 rdmsr
298 orl $(1 << 8), %eax
299 wrmsr
300no_msr_11e:
301
302 post_code(0x2c)
303
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100304 /* Cache the whole rom to fetch microcode updates */
305 movl $MTRR_PHYS_BASE(1), %ecx
306 xorl %edx, %edx
307 movl $CACHE_ROM_BASE | MTRR_TYPE_WRPROT, %eax
308 wrmsr
309
310 movl $MTRR_PHYS_MASK(1), %ecx
311 rdmsr
312 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
313 wrmsr
314
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300315 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
316 movl %cr0, %eax
317 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
318 invd
319 movl %eax, %cr0
320
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100321#if IS_ENABLED(CONFIG_MICROCODE_UPDATE_PRE_RAM)
322 update_microcode:
323 /* put the return address in %esp */
324 movl $end_microcode_update, %esp
325 jmp update_bsp_microcode
326 end_microcode_update:
327#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300328 post_code(0x2d)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100329 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300330 movl %cr0, %eax
331 orl $CR0_CacheDisable, %eax
332 movl %eax, %cr0
333
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200334 /*
335 * An unidentified combination of speculative reads and branch
336 * predictions inside WRPROT-cacheable memory can cause invalidation
337 * of cachelines and loss of stack on models based on NetBurst
338 * microarchitecture. Therefore disable WRPROT region entirely for
339 * all family F models.
340 */
341 movl $1, %eax
342 cpuid
343 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100344 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200345
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100346disable_cache_rom:
347 movl $MTRR_PHYS_MASK(1), %ecx
348 rdmsr
349 andl $(~MTRR_PHYS_MASK_VALID), %eax
350 wrmsr
351 jmp fill_cache
352
353cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300354 /* Enable cache for our code in Flash because we do XIP here */
355 movl $MTRR_PHYS_BASE(1), %ecx
356 xorl %edx, %edx
357 /*
358 * IMPORTANT: The following calculation _must_ be done at runtime. See
Stefan Taunerde028782018-08-19 20:02:05 +0200359 * https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300360 */
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300361 movl $_program, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300362 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
363 orl $MTRR_TYPE_WRPROT, %eax
364 wrmsr
365
366 movl $MTRR_PHYS_MASK(1), %ecx
367 rdmsr
368 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
369 wrmsr
370
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100371fill_cache:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300372 post_code(0x2e)
373 /* Enable cache. */
374 movl %cr0, %eax
375 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100376 invd
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300377 movl %eax, %cr0
378
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100379 /* Clear the cache memory region. This will also fill up the cache. */
380 cld
381 xorl %eax, %eax
382 movl $CACHE_AS_RAM_BASE, %edi
383 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
384 rep stosl
385
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300386 /* Setup the stack. */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200387 mov $_car_stack_end, %esp
388
389 /* Need to align stack to 16 bytes at call instruction. Account for
390 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200391 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200392 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300393
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200394 /* push TSC and BIST to stack */
395 movd %mm0, %eax
396 pushl %eax /* BIST */
397 movd %mm2, %eax
398 pushl %eax /* tsc[63:32] */
399 movd %mm1, %eax
400 pushl %eax /* tsc[31:0] */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300401
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200402before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300403 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200404 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300405
406 /* Should never see this postcode */
407 post_code(POST_DEAD_CODE)
408
409.Lhlt:
410 hlt
411 jmp .Lhlt
412
413fixed_mtrr_list:
414 .word MTRR_FIX_64K_00000
415 .word MTRR_FIX_16K_80000
416 .word MTRR_FIX_16K_A0000
417 .word MTRR_FIX_4K_C0000
418 .word MTRR_FIX_4K_C8000
419 .word MTRR_FIX_4K_D0000
420 .word MTRR_FIX_4K_D8000
421 .word MTRR_FIX_4K_E0000
422 .word MTRR_FIX_4K_E8000
423 .word MTRR_FIX_4K_F0000
424 .word MTRR_FIX_4K_F8000
425fixed_mtrr_list_size = . - fixed_mtrr_list
426
427_cache_as_ram_setup_end: