blob: 2cd0c5e92212af1e6a6dfe51a068fc8be55c1539 [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
180 /* delay 10 ms */
181 movl $10000, %ecx
1821: inb $0x80, %al
183 dec %ecx
184 jnz 1b
185
186 post_code(0x25)
187
188 /* Send Start IPI to all excluding ourself. */
189 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200190 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
191 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001921: movl %eax, (%edi)
193 movl $0x30, %ecx
1942: pause
195 dec %ecx
196 jnz 2b
197 movl (%edi), %ecx
198 andl $LAPIC_ICR_BUSY, %ecx
199 jnz 1b
200
201 /* delay 250 us */
202 movl $250, %ecx
2031: inb $0x80, %al
204 dec %ecx
205 jnz 1b
206
207 post_code(0x26)
208
209 /* Wait for sibling CPU to start. */
2101: movl $(MTRR_PHYS_BASE(0)), %ecx
211 rdmsr
212 andl %eax, %eax
213 jnz sipi_complete
214
215 movl $0x30, %ecx
2162: pause
217 dec %ecx
218 jnz 2b
219 jmp 1b
220
221
222ap_init:
223 post_code(0x27)
224
225 /* Do not disable cache (so BSP can enable it). */
226 movl %cr0, %eax
227 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
228 movl %eax, %cr0
229
230 post_code(0x28)
231
232 /* MTRR registers are shared between HT siblings. */
233 movl $(MTRR_PHYS_BASE(0)), %ecx
234 movl $(1 << 12), %eax
235 xorl %edx, %edx
236 wrmsr
237
238 post_code(0x29)
239
240ap_halt:
241 cli
2421: hlt
243 jmp 1b
244
245
246
247sipi_complete:
248
249 post_code(0x2a)
250
251 /* Set Cache-as-RAM base address. */
252 movl $(MTRR_PHYS_BASE(0)), %ecx
253 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
254 xorl %edx, %edx
255 wrmsr
256
257 /* Set Cache-as-RAM mask. */
258 movl $(MTRR_PHYS_MASK(0)), %ecx
259 rdmsr
260 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
261 wrmsr
262
263 post_code(0x2b)
264
265 /* Enable MTRR. */
266 movl $MTRR_DEF_TYPE_MSR, %ecx
267 rdmsr
268 orl $MTRR_DEF_TYPE_EN, %eax
269 wrmsr
270
271 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
272 *
273 * MSR is set when DisplayFamily_DisplayModel is one of:
274 * 06_0x, 06_17, 06_1C
275 *
276 * Description says this bit enables use of WBINVD and FLUSH#.
277 * Should this be set only after the system bus and/or memory
278 * controller can successfully handle write cycles?
279 */
280
281#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
282#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
283
284 movl $1, %eax
285 cpuid
286 movl %eax, %ebx
287 andl $EAX_FAMILY(0x0f), %eax
288 cmpl $EAX_FAMILY(0x06), %eax
289 jne no_msr_11e
290 movl %ebx, %eax
291 andl $EAX_MODEL(0xff), %eax
292 cmpl $EAX_MODEL(0x17), %eax
293 je has_msr_11e
294 cmpl $EAX_MODEL(0x1c), %eax
295 je has_msr_11e
296 andl $EAX_MODEL(0xf0), %eax
297 cmpl $EAX_MODEL(0x00), %eax
298 jne no_msr_11e
299has_msr_11e:
300 movl $0x11e, %ecx
301 rdmsr
302 orl $(1 << 8), %eax
303 wrmsr
304no_msr_11e:
305
306 post_code(0x2c)
307
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100308 /* Cache the whole rom to fetch microcode updates */
309 movl $MTRR_PHYS_BASE(1), %ecx
310 xorl %edx, %edx
Arthur Heymanseeedf832019-02-08 16:27:35 +0100311 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100312 wrmsr
313
314 movl $MTRR_PHYS_MASK(1), %ecx
315 rdmsr
316 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
317 wrmsr
318
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300319 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
320 movl %cr0, %eax
321 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
322 invd
323 movl %eax, %cr0
324
Julius Wernercd49cce2019-03-05 16:53:33 -0800325#if CONFIG(MICROCODE_UPDATE_PRE_RAM)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100326 update_microcode:
327 /* put the return address in %esp */
328 movl $end_microcode_update, %esp
329 jmp update_bsp_microcode
330 end_microcode_update:
331#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300332 post_code(0x2d)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100333 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300334 movl %cr0, %eax
335 orl $CR0_CacheDisable, %eax
336 movl %eax, %cr0
337
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200338 /*
339 * An unidentified combination of speculative reads and branch
340 * predictions inside WRPROT-cacheable memory can cause invalidation
341 * of cachelines and loss of stack on models based on NetBurst
342 * microarchitecture. Therefore disable WRPROT region entirely for
343 * all family F models.
344 */
345 movl $1, %eax
346 cpuid
347 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100348 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200349
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100350disable_cache_rom:
351 movl $MTRR_PHYS_MASK(1), %ecx
352 rdmsr
353 andl $(~MTRR_PHYS_MASK_VALID), %eax
354 wrmsr
355 jmp fill_cache
356
357cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300358 /* Enable cache for our code in Flash because we do XIP here */
359 movl $MTRR_PHYS_BASE(1), %ecx
360 xorl %edx, %edx
361 /*
362 * IMPORTANT: The following calculation _must_ be done at runtime. See
Stefan Taunerde028782018-08-19 20:02:05 +0200363 * https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300364 */
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300365 movl $_program, %eax
Arthur Heymans942ad6a2019-10-12 18:06:46 +0200366 andl $(~(XIP_ROM_SIZE - 1)), %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300367 orl $MTRR_TYPE_WRPROT, %eax
368 wrmsr
369
370 movl $MTRR_PHYS_MASK(1), %ecx
371 rdmsr
Arthur Heymans942ad6a2019-10-12 18:06:46 +0200372 movl $(~(XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300373 wrmsr
374
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100375fill_cache:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300376 post_code(0x2e)
377 /* Enable cache. */
378 movl %cr0, %eax
379 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100380 invd
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300381 movl %eax, %cr0
382
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100383 /* Clear the cache memory region. This will also fill up the cache. */
384 cld
385 xorl %eax, %eax
386 movl $CACHE_AS_RAM_BASE, %edi
387 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
388 rep stosl
389
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300390 /* Setup the stack. */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200391 mov $_car_stack_end, %esp
392
393 /* Need to align stack to 16 bytes at call instruction. Account for
394 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200395 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200396 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300397
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200398 /* push TSC and BIST to stack */
399 movd %mm0, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100400 pushl %eax /* BIST */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200401 movd %mm2, %eax
402 pushl %eax /* tsc[63:32] */
403 movd %mm1, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100404 pushl %eax /* tsc[31:0] */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300405
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200406before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300407 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200408 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300409
410 /* Should never see this postcode */
411 post_code(POST_DEAD_CODE)
412
413.Lhlt:
414 hlt
415 jmp .Lhlt
416
417fixed_mtrr_list:
418 .word MTRR_FIX_64K_00000
419 .word MTRR_FIX_16K_80000
420 .word MTRR_FIX_16K_A0000
421 .word MTRR_FIX_4K_C0000
422 .word MTRR_FIX_4K_C8000
423 .word MTRR_FIX_4K_D0000
424 .word MTRR_FIX_4K_D8000
425 .word MTRR_FIX_4K_E0000
426 .word MTRR_FIX_4K_E8000
427 .word MTRR_FIX_4K_F0000
428 .word MTRR_FIX_4K_F8000
429fixed_mtrr_list_size = . - fixed_mtrr_list
430
431_cache_as_ram_setup_end: