blob: 9ac9e22c3e5a77c90084bdd0ac085e65ac779ee4 [file] [log] [blame]
Angel Ponsf23ae0b2020-04-02 23:48:12 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03002
3#include <cpu/x86/mtrr.h>
4#include <cpu/x86/cache.h>
5#include <cpu/x86/post_code.h>
6#include <cpu/x86/lapic_def.h>
7
8/* Macro to access Local APIC registers at default base. */
9#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030010
Kyösti Mälkki7522a8f2020-11-20 16:47:38 +020011.section .init
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020012.global bootblock_pre_c_entry
13
Arthur Heymansbc7b63f2021-07-02 10:03:17 +020014#include <cpu/intel/car/cache_as_ram_symbols.inc>
15
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030016.code32
17_cache_as_ram_setup:
18
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020019bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030020
21cache_as_ram:
22 post_code(0x20)
23
24 movl $LAPIC_BASE_MSR, %ecx
25 rdmsr
26 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
27 jz ap_init
28
29 /* Clear/disable fixed MTRRs */
30 mov $fixed_mtrr_list_size, %ebx
31 xor %eax, %eax
32 xor %edx, %edx
33
34clear_fixed_mtrr:
35 add $-2, %ebx
36 movzwl fixed_mtrr_list(%ebx), %ecx
37 wrmsr
38 jnz clear_fixed_mtrr
39
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020040 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030041 mov $MTRR_CAP_MSR, %ecx
42 rdmsr
43 movzb %al, %ebx /* Number of variable MTRRs */
44 mov $MTRR_PHYS_BASE(0), %ecx
45 xor %eax, %eax
46 xor %edx, %edx
47
48clear_var_mtrr:
49 wrmsr
50 inc %ecx
51 wrmsr
52 inc %ecx
53 dec %ebx
54 jnz clear_var_mtrr
55 post_code(0x21)
56
57 /* Configure the default memory type to uncacheable. */
58 movl $MTRR_DEF_TYPE_MSR, %ecx
59 rdmsr
60 andl $(~0x00000cff), %eax
61 wrmsr
62
63 post_code(0x22)
64
65 /* Determine CPU_ADDR_BITS and load PHYSMASK high
66 * word to %edx.
67 */
68 movl $0x80000000, %eax
69 cpuid
70 cmpl $0x80000008, %eax
71 jc addrsize_no_MSR
72 movl $0x80000008, %eax
73 cpuid
74 movb %al, %cl
75 sub $32, %cl
76 movl $1, %edx
77 shl %cl, %edx
78 subl $1, %edx
79 jmp addrsize_set_high
80addrsize_no_MSR:
81 movl $1, %eax
82 cpuid
83 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
84 jz addrsize_set_high
85 movl $0x0f, %edx
86
87 /* Preload high word of address mask (in %edx) for Variable
88 * MTRRs 0 and 1 and enable local APIC at default base.
89 */
90addrsize_set_high:
91 xorl %eax, %eax
92 movl $MTRR_PHYS_MASK(0), %ecx
93 wrmsr
94 movl $MTRR_PHYS_MASK(1), %ecx
95 wrmsr
96 movl $LAPIC_BASE_MSR, %ecx
97 not %edx
98 movl %edx, %ebx
99 rdmsr
100 andl %ebx, %edx
101 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
102 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
103 wrmsr
104
105bsp_init:
106
107 post_code(0x23)
108
109 /* Send INIT IPI to all excluding ourself. */
110 movl LAPIC(ICR), %edi
111 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1121: movl %eax, (%edi)
113 movl $0x30, %ecx
1142: pause
115 dec %ecx
116 jnz 2b
117 movl (%edi), %ecx
118 andl $LAPIC_ICR_BUSY, %ecx
119 jnz 1b
120
121 post_code(0x24)
122
123 movl $1, %eax
124 cpuid
125 btl $28, %edx
126 jnc sipi_complete
127 bswapl %ebx
128 movzx %bh, %edi
129 cmpb $1, %bh
130 jbe sipi_complete /* only one LAPIC ID in package */
131
132 movl $0, %eax
133 cpuid
134 movb $1, %bl
135 cmpl $4, %eax
136 jb cores_counted
137 movl $4, %eax
138 movl $0, %ecx
139 cpuid
140 shr $26, %eax
141 movb %al, %bl
142 inc %bl
143
144cores_counted:
145 movl %edi, %eax
146 divb %bl
147 cmpb $1, %al
148 jbe sipi_complete /* only LAPIC ID of a core */
149
150 /* For a hyper-threading processor, cache must not be disabled
151 * on an AP on the same physical package with the BSP.
152 */
153
154hyper_threading_cpu:
155
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300156 post_code(0x25)
157
158 /* Send Start IPI to all excluding ourself. */
159 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200160 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
161 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001621: movl %eax, (%edi)
163 movl $0x30, %ecx
1642: pause
165 dec %ecx
166 jnz 2b
167 movl (%edi), %ecx
168 andl $LAPIC_ICR_BUSY, %ecx
169 jnz 1b
170
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300171 post_code(0x26)
172
173 /* Wait for sibling CPU to start. */
1741: movl $(MTRR_PHYS_BASE(0)), %ecx
175 rdmsr
176 andl %eax, %eax
177 jnz sipi_complete
178
179 movl $0x30, %ecx
1802: pause
181 dec %ecx
182 jnz 2b
183 jmp 1b
184
185
186ap_init:
187 post_code(0x27)
188
189 /* Do not disable cache (so BSP can enable it). */
190 movl %cr0, %eax
191 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
192 movl %eax, %cr0
193
194 post_code(0x28)
195
196 /* MTRR registers are shared between HT siblings. */
197 movl $(MTRR_PHYS_BASE(0)), %ecx
198 movl $(1 << 12), %eax
199 xorl %edx, %edx
200 wrmsr
201
202 post_code(0x29)
203
204ap_halt:
205 cli
2061: hlt
207 jmp 1b
208
209
210
211sipi_complete:
212
213 post_code(0x2a)
214
215 /* Set Cache-as-RAM base address. */
216 movl $(MTRR_PHYS_BASE(0)), %ecx
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200217 movl car_mtrr_start, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200218 orl $MTRR_TYPE_WRBACK, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300219 xorl %edx, %edx
220 wrmsr
221
222 /* Set Cache-as-RAM mask. */
223 movl $(MTRR_PHYS_MASK(0)), %ecx
224 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200225 movl car_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200226 orl $MTRR_PHYS_MASK_VALID, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300227 wrmsr
228
229 post_code(0x2b)
230
231 /* Enable MTRR. */
232 movl $MTRR_DEF_TYPE_MSR, %ecx
233 rdmsr
234 orl $MTRR_DEF_TYPE_EN, %eax
235 wrmsr
236
237 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
238 *
239 * MSR is set when DisplayFamily_DisplayModel is one of:
240 * 06_0x, 06_17, 06_1C
241 *
242 * Description says this bit enables use of WBINVD and FLUSH#.
243 * Should this be set only after the system bus and/or memory
244 * controller can successfully handle write cycles?
245 */
246
247#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
248#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
249
250 movl $1, %eax
251 cpuid
252 movl %eax, %ebx
253 andl $EAX_FAMILY(0x0f), %eax
254 cmpl $EAX_FAMILY(0x06), %eax
255 jne no_msr_11e
256 movl %ebx, %eax
257 andl $EAX_MODEL(0xff), %eax
258 cmpl $EAX_MODEL(0x17), %eax
259 je has_msr_11e
260 cmpl $EAX_MODEL(0x1c), %eax
261 je has_msr_11e
262 andl $EAX_MODEL(0xf0), %eax
263 cmpl $EAX_MODEL(0x00), %eax
264 jne no_msr_11e
265has_msr_11e:
266 movl $0x11e, %ecx
267 rdmsr
268 orl $(1 << 8), %eax
269 wrmsr
270no_msr_11e:
271
272 post_code(0x2c)
273
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100274 /* Cache the whole rom to fetch microcode updates */
275 movl $MTRR_PHYS_BASE(1), %ecx
276 xorl %edx, %edx
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200277 movl rom_mtrr_base, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200278 orl $MTRR_TYPE_WRPROT, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100279 wrmsr
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100280 movl $MTRR_PHYS_MASK(1), %ecx
281 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200282 movl rom_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200283 orl $MTRR_PHYS_MASK_VALID, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100284 wrmsr
285
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300286 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
287 movl %cr0, %eax
288 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
289 invd
290 movl %eax, %cr0
291
Julius Wernercd49cce2019-03-05 16:53:33 -0800292#if CONFIG(MICROCODE_UPDATE_PRE_RAM)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100293 update_microcode:
294 /* put the return address in %esp */
295 movl $end_microcode_update, %esp
296 jmp update_bsp_microcode
297 end_microcode_update:
298#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300299 post_code(0x2d)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100300 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300301 movl %cr0, %eax
302 orl $CR0_CacheDisable, %eax
303 movl %eax, %cr0
304
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200305 /*
306 * An unidentified combination of speculative reads and branch
307 * predictions inside WRPROT-cacheable memory can cause invalidation
308 * of cachelines and loss of stack on models based on NetBurst
309 * microarchitecture. Therefore disable WRPROT region entirely for
310 * all family F models.
311 */
312 movl $1, %eax
313 cpuid
314 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100315 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200316
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100317disable_cache_rom:
318 movl $MTRR_PHYS_MASK(1), %ecx
319 rdmsr
320 andl $(~MTRR_PHYS_MASK_VALID), %eax
321 wrmsr
322 jmp fill_cache
323
324cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300325 /* Enable cache for our code in Flash because we do XIP here */
326 movl $MTRR_PHYS_BASE(1), %ecx
327 xorl %edx, %edx
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300328 movl $_program, %eax
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200329 andl xip_mtrr_mask, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300330 orl $MTRR_TYPE_WRPROT, %eax
331 wrmsr
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300332 movl $MTRR_PHYS_MASK(1), %ecx
333 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200334 movl xip_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200335 orl $MTRR_PHYS_MASK_VALID, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300336 wrmsr
337
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100338fill_cache:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300339 post_code(0x2e)
340 /* Enable cache. */
341 movl %cr0, %eax
342 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100343 invd
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300344 movl %eax, %cr0
345
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100346 /* Clear the cache memory region. This will also fill up the cache. */
347 cld
348 xorl %eax, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200349 movl $_car_mtrr_start, %edi
350 movl $_car_mtrr_size, %ecx
351 shr $2, %ecx
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100352 rep stosl
353
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300354 /* Setup the stack. */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100355 mov $_ecar_stack, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200356
357 /* Need to align stack to 16 bytes at call instruction. Account for
358 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200359 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200360 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300361
Arthur Heymans8a6053b2021-07-02 10:07:34 +0200362#if ENV_X86_64
363 #include <cpu/x86/64bit/entry64.inc>
364
365 movd %mm2, %rdi
366 shlq $32, %rdi /* BIST */
367 movd %mm1, %rsi
368 or %rsi, %rdi /* tsc[63:32] */
369 movd %mm0, %rsi /* tsc[31:0] */
370
371#else
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200372 /* push TSC and BIST to stack */
373 movd %mm0, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100374 pushl %eax /* BIST */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200375 movd %mm2, %eax
376 pushl %eax /* tsc[63:32] */
377 movd %mm1, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100378 pushl %eax /* tsc[31:0] */
Arthur Heymans8a6053b2021-07-02 10:07:34 +0200379#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300380
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200381before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300382 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200383 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300384
385 /* Should never see this postcode */
386 post_code(POST_DEAD_CODE)
387
388.Lhlt:
389 hlt
390 jmp .Lhlt
391
392fixed_mtrr_list:
393 .word MTRR_FIX_64K_00000
394 .word MTRR_FIX_16K_80000
395 .word MTRR_FIX_16K_A0000
396 .word MTRR_FIX_4K_C0000
397 .word MTRR_FIX_4K_C8000
398 .word MTRR_FIX_4K_D0000
399 .word MTRR_FIX_4K_D8000
400 .word MTRR_FIX_4K_E0000
401 .word MTRR_FIX_4K_E8000
402 .word MTRR_FIX_4K_F0000
403 .word MTRR_FIX_4K_F8000
404fixed_mtrr_list_size = . - fixed_mtrr_list
405
406_cache_as_ram_setup_end: