blob: 7815eb3235c001ef54eb5ecdd82919bfc4202778 [file] [log] [blame]
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001/*
2 * This file is part of the coreboot project.
3 *
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <cpu/x86/mtrr.h>
15#include <cpu/x86/cache.h>
16#include <cpu/x86/post_code.h>
17#include <cpu/x86/lapic_def.h>
18
19/* Macro to access Local APIC registers at default base. */
20#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
Julius Wernercd49cce2019-03-05 16:53:33 -080021#if !CONFIG(C_ENVIRONMENT_BOOTBLOCK)
Kyösti Mälkki34856572019-01-09 20:30:52 +020022/* Fixed location, ASSERTED in failover.ld if it changes. */
23.set ap_sipi_vector_in_rom, 0xff
24#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030025
26#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
27#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
28
Arthur Heymans942ad6a2019-10-12 18:06:46 +020029#if CONFIG(C_ENVIRONMENT_BOOTBLOCK)
30#if ((CONFIG_C_ENV_BOOTBLOCK_SIZE & (CONFIG_C_ENV_BOOTBLOCK_SIZE - 1)) != 0)
31#error "CONFIG_C_ENV_BOOTBLOCK_SIZE must be a power of 2!"
32#endif
33#define XIP_ROM_SIZE CONFIG_C_ENV_BOOTBLOCK_SIZE
34#else
35#define XIP_ROM_SIZE CONFIG_XIP_ROM_SIZE
36#endif
37
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020038.global bootblock_pre_c_entry
39
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030040.code32
41_cache_as_ram_setup:
42
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020043bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030044
45cache_as_ram:
46 post_code(0x20)
47
48 movl $LAPIC_BASE_MSR, %ecx
49 rdmsr
50 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
51 jz ap_init
52
53 /* Clear/disable fixed MTRRs */
54 mov $fixed_mtrr_list_size, %ebx
55 xor %eax, %eax
56 xor %edx, %edx
57
58clear_fixed_mtrr:
59 add $-2, %ebx
60 movzwl fixed_mtrr_list(%ebx), %ecx
61 wrmsr
62 jnz clear_fixed_mtrr
63
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020064 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030065 mov $MTRR_CAP_MSR, %ecx
66 rdmsr
67 movzb %al, %ebx /* Number of variable MTRRs */
68 mov $MTRR_PHYS_BASE(0), %ecx
69 xor %eax, %eax
70 xor %edx, %edx
71
72clear_var_mtrr:
73 wrmsr
74 inc %ecx
75 wrmsr
76 inc %ecx
77 dec %ebx
78 jnz clear_var_mtrr
79 post_code(0x21)
80
81 /* Configure the default memory type to uncacheable. */
82 movl $MTRR_DEF_TYPE_MSR, %ecx
83 rdmsr
84 andl $(~0x00000cff), %eax
85 wrmsr
86
87 post_code(0x22)
88
89 /* Determine CPU_ADDR_BITS and load PHYSMASK high
90 * word to %edx.
91 */
92 movl $0x80000000, %eax
93 cpuid
94 cmpl $0x80000008, %eax
95 jc addrsize_no_MSR
96 movl $0x80000008, %eax
97 cpuid
98 movb %al, %cl
99 sub $32, %cl
100 movl $1, %edx
101 shl %cl, %edx
102 subl $1, %edx
103 jmp addrsize_set_high
104addrsize_no_MSR:
105 movl $1, %eax
106 cpuid
107 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
108 jz addrsize_set_high
109 movl $0x0f, %edx
110
111 /* Preload high word of address mask (in %edx) for Variable
112 * MTRRs 0 and 1 and enable local APIC at default base.
113 */
114addrsize_set_high:
115 xorl %eax, %eax
116 movl $MTRR_PHYS_MASK(0), %ecx
117 wrmsr
118 movl $MTRR_PHYS_MASK(1), %ecx
119 wrmsr
120 movl $LAPIC_BASE_MSR, %ecx
121 not %edx
122 movl %edx, %ebx
123 rdmsr
124 andl %ebx, %edx
125 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
126 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
127 wrmsr
128
129bsp_init:
130
131 post_code(0x23)
132
133 /* Send INIT IPI to all excluding ourself. */
134 movl LAPIC(ICR), %edi
135 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1361: movl %eax, (%edi)
137 movl $0x30, %ecx
1382: pause
139 dec %ecx
140 jnz 2b
141 movl (%edi), %ecx
142 andl $LAPIC_ICR_BUSY, %ecx
143 jnz 1b
144
145 post_code(0x24)
146
147 movl $1, %eax
148 cpuid
149 btl $28, %edx
150 jnc sipi_complete
151 bswapl %ebx
152 movzx %bh, %edi
153 cmpb $1, %bh
154 jbe sipi_complete /* only one LAPIC ID in package */
155
156 movl $0, %eax
157 cpuid
158 movb $1, %bl
159 cmpl $4, %eax
160 jb cores_counted
161 movl $4, %eax
162 movl $0, %ecx
163 cpuid
164 shr $26, %eax
165 movb %al, %bl
166 inc %bl
167
168cores_counted:
169 movl %edi, %eax
170 divb %bl
171 cmpb $1, %al
172 jbe sipi_complete /* only LAPIC ID of a core */
173
174 /* For a hyper-threading processor, cache must not be disabled
175 * on an AP on the same physical package with the BSP.
176 */
177
178hyper_threading_cpu:
179
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300180 post_code(0x25)
181
182 /* Send Start IPI to all excluding ourself. */
183 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200184 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
185 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001861: movl %eax, (%edi)
187 movl $0x30, %ecx
1882: pause
189 dec %ecx
190 jnz 2b
191 movl (%edi), %ecx
192 andl $LAPIC_ICR_BUSY, %ecx
193 jnz 1b
194
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300195 post_code(0x26)
196
197 /* Wait for sibling CPU to start. */
1981: movl $(MTRR_PHYS_BASE(0)), %ecx
199 rdmsr
200 andl %eax, %eax
201 jnz sipi_complete
202
203 movl $0x30, %ecx
2042: pause
205 dec %ecx
206 jnz 2b
207 jmp 1b
208
209
210ap_init:
211 post_code(0x27)
212
213 /* Do not disable cache (so BSP can enable it). */
214 movl %cr0, %eax
215 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
216 movl %eax, %cr0
217
218 post_code(0x28)
219
220 /* MTRR registers are shared between HT siblings. */
221 movl $(MTRR_PHYS_BASE(0)), %ecx
222 movl $(1 << 12), %eax
223 xorl %edx, %edx
224 wrmsr
225
226 post_code(0x29)
227
228ap_halt:
229 cli
2301: hlt
231 jmp 1b
232
233
234
235sipi_complete:
236
237 post_code(0x2a)
238
239 /* Set Cache-as-RAM base address. */
240 movl $(MTRR_PHYS_BASE(0)), %ecx
241 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
242 xorl %edx, %edx
243 wrmsr
244
245 /* Set Cache-as-RAM mask. */
246 movl $(MTRR_PHYS_MASK(0)), %ecx
247 rdmsr
248 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
249 wrmsr
250
251 post_code(0x2b)
252
253 /* Enable MTRR. */
254 movl $MTRR_DEF_TYPE_MSR, %ecx
255 rdmsr
256 orl $MTRR_DEF_TYPE_EN, %eax
257 wrmsr
258
259 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
260 *
261 * MSR is set when DisplayFamily_DisplayModel is one of:
262 * 06_0x, 06_17, 06_1C
263 *
264 * Description says this bit enables use of WBINVD and FLUSH#.
265 * Should this be set only after the system bus and/or memory
266 * controller can successfully handle write cycles?
267 */
268
269#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
270#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
271
272 movl $1, %eax
273 cpuid
274 movl %eax, %ebx
275 andl $EAX_FAMILY(0x0f), %eax
276 cmpl $EAX_FAMILY(0x06), %eax
277 jne no_msr_11e
278 movl %ebx, %eax
279 andl $EAX_MODEL(0xff), %eax
280 cmpl $EAX_MODEL(0x17), %eax
281 je has_msr_11e
282 cmpl $EAX_MODEL(0x1c), %eax
283 je has_msr_11e
284 andl $EAX_MODEL(0xf0), %eax
285 cmpl $EAX_MODEL(0x00), %eax
286 jne no_msr_11e
287has_msr_11e:
288 movl $0x11e, %ecx
289 rdmsr
290 orl $(1 << 8), %eax
291 wrmsr
292no_msr_11e:
293
294 post_code(0x2c)
295
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100296 /* Cache the whole rom to fetch microcode updates */
297 movl $MTRR_PHYS_BASE(1), %ecx
298 xorl %edx, %edx
Arthur Heymanseeedf832019-02-08 16:27:35 +0100299 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100300 wrmsr
301
302 movl $MTRR_PHYS_MASK(1), %ecx
303 rdmsr
304 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
305 wrmsr
306
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300307 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
308 movl %cr0, %eax
309 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
310 invd
311 movl %eax, %cr0
312
Julius Wernercd49cce2019-03-05 16:53:33 -0800313#if CONFIG(MICROCODE_UPDATE_PRE_RAM)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100314 update_microcode:
315 /* put the return address in %esp */
316 movl $end_microcode_update, %esp
317 jmp update_bsp_microcode
318 end_microcode_update:
319#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300320 post_code(0x2d)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100321 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300322 movl %cr0, %eax
323 orl $CR0_CacheDisable, %eax
324 movl %eax, %cr0
325
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200326 /*
327 * An unidentified combination of speculative reads and branch
328 * predictions inside WRPROT-cacheable memory can cause invalidation
329 * of cachelines and loss of stack on models based on NetBurst
330 * microarchitecture. Therefore disable WRPROT region entirely for
331 * all family F models.
332 */
333 movl $1, %eax
334 cpuid
335 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100336 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200337
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100338disable_cache_rom:
339 movl $MTRR_PHYS_MASK(1), %ecx
340 rdmsr
341 andl $(~MTRR_PHYS_MASK_VALID), %eax
342 wrmsr
343 jmp fill_cache
344
345cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300346 /* Enable cache for our code in Flash because we do XIP here */
347 movl $MTRR_PHYS_BASE(1), %ecx
348 xorl %edx, %edx
349 /*
350 * IMPORTANT: The following calculation _must_ be done at runtime. See
Stefan Taunerde028782018-08-19 20:02:05 +0200351 * https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300352 */
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300353 movl $_program, %eax
Arthur Heymans942ad6a2019-10-12 18:06:46 +0200354 andl $(~(XIP_ROM_SIZE - 1)), %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300355 orl $MTRR_TYPE_WRPROT, %eax
356 wrmsr
357
358 movl $MTRR_PHYS_MASK(1), %ecx
359 rdmsr
Arthur Heymans942ad6a2019-10-12 18:06:46 +0200360 movl $(~(XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300361 wrmsr
362
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100363fill_cache:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300364 post_code(0x2e)
365 /* Enable cache. */
366 movl %cr0, %eax
367 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100368 invd
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300369 movl %eax, %cr0
370
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100371 /* Clear the cache memory region. This will also fill up the cache. */
372 cld
373 xorl %eax, %eax
374 movl $CACHE_AS_RAM_BASE, %edi
375 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
376 rep stosl
377
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300378 /* Setup the stack. */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100379 mov $_ecar_stack, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200380
381 /* Need to align stack to 16 bytes at call instruction. Account for
382 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200383 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200384 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300385
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200386 /* push TSC and BIST to stack */
387 movd %mm0, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100388 pushl %eax /* BIST */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200389 movd %mm2, %eax
390 pushl %eax /* tsc[63:32] */
391 movd %mm1, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100392 pushl %eax /* tsc[31:0] */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300393
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200394before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300395 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200396 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300397
398 /* Should never see this postcode */
399 post_code(POST_DEAD_CODE)
400
401.Lhlt:
402 hlt
403 jmp .Lhlt
404
405fixed_mtrr_list:
406 .word MTRR_FIX_64K_00000
407 .word MTRR_FIX_16K_80000
408 .word MTRR_FIX_16K_A0000
409 .word MTRR_FIX_4K_C0000
410 .word MTRR_FIX_4K_C8000
411 .word MTRR_FIX_4K_D0000
412 .word MTRR_FIX_4K_D8000
413 .word MTRR_FIX_4K_E0000
414 .word MTRR_FIX_4K_E8000
415 .word MTRR_FIX_4K_F0000
416 .word MTRR_FIX_4K_F8000
417fixed_mtrr_list_size = . - fixed_mtrr_list
418
419_cache_as_ram_setup_end: