blob: 01abdf884fce231665fb1c909fbae4bb30daea74 [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
Martin Rothc87ab012022-11-20 19:32:51 -07003#include <cpu/intel/post_codes.h>
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03004#include <cpu/x86/mtrr.h>
5#include <cpu/x86/cache.h>
6#include <cpu/x86/post_code.h>
7#include <cpu/x86/lapic_def.h>
8
9/* Macro to access Local APIC registers at default base. */
10#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030011
Kyösti Mälkki7522a8f2020-11-20 16:47:38 +020012.section .init
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020013.global bootblock_pre_c_entry
14
Arthur Heymansbc7b63f2021-07-02 10:03:17 +020015#include <cpu/intel/car/cache_as_ram_symbols.inc>
16
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030017.code32
18_cache_as_ram_setup:
19
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020020bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030021
22cache_as_ram:
Martin Rothc87ab012022-11-20 19:32:51 -070023 post_code(POST_BOOTBLOCK_CAR)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030024
25 movl $LAPIC_BASE_MSR, %ecx
26 rdmsr
27 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
28 jz ap_init
29
30 /* Clear/disable fixed MTRRs */
31 mov $fixed_mtrr_list_size, %ebx
32 xor %eax, %eax
33 xor %edx, %edx
34
35clear_fixed_mtrr:
36 add $-2, %ebx
37 movzwl fixed_mtrr_list(%ebx), %ecx
38 wrmsr
39 jnz clear_fixed_mtrr
40
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020041 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030042 mov $MTRR_CAP_MSR, %ecx
43 rdmsr
44 movzb %al, %ebx /* Number of variable MTRRs */
45 mov $MTRR_PHYS_BASE(0), %ecx
46 xor %eax, %eax
47 xor %edx, %edx
48
49clear_var_mtrr:
50 wrmsr
51 inc %ecx
52 wrmsr
53 inc %ecx
54 dec %ebx
55 jnz clear_var_mtrr
Martin Rothc87ab012022-11-20 19:32:51 -070056 post_code(POST_SOC_SET_DEF_MTRR_TYPE)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030057
58 /* Configure the default memory type to uncacheable. */
59 movl $MTRR_DEF_TYPE_MSR, %ecx
60 rdmsr
61 andl $(~0x00000cff), %eax
62 wrmsr
63
Martin Rothc87ab012022-11-20 19:32:51 -070064 post_code(POST_SOC_DETERMINE_CPU_ADDR_BITS)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030065
66 /* Determine CPU_ADDR_BITS and load PHYSMASK high
67 * word to %edx.
68 */
69 movl $0x80000000, %eax
70 cpuid
71 cmpl $0x80000008, %eax
72 jc addrsize_no_MSR
73 movl $0x80000008, %eax
74 cpuid
75 movb %al, %cl
76 sub $32, %cl
77 movl $1, %edx
78 shl %cl, %edx
79 subl $1, %edx
80 jmp addrsize_set_high
81addrsize_no_MSR:
82 movl $1, %eax
83 cpuid
84 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
85 jz addrsize_set_high
86 movl $0x0f, %edx
87
88 /* Preload high word of address mask (in %edx) for Variable
89 * MTRRs 0 and 1 and enable local APIC at default base.
90 */
91addrsize_set_high:
92 xorl %eax, %eax
93 movl $MTRR_PHYS_MASK(0), %ecx
94 wrmsr
95 movl $MTRR_PHYS_MASK(1), %ecx
96 wrmsr
97 movl $LAPIC_BASE_MSR, %ecx
98 not %edx
99 movl %edx, %ebx
100 rdmsr
101 andl %ebx, %edx
102 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
103 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
104 wrmsr
105
106bsp_init:
107
Martin Rothc87ab012022-11-20 19:32:51 -0700108 post_code(POST_SOC_BSP_INIT)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300109
110 /* Send INIT IPI to all excluding ourself. */
111 movl LAPIC(ICR), %edi
112 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1131: movl %eax, (%edi)
114 movl $0x30, %ecx
1152: pause
116 dec %ecx
117 jnz 2b
118 movl (%edi), %ecx
119 andl $LAPIC_ICR_BUSY, %ecx
120 jnz 1b
121
Martin Rothc87ab012022-11-20 19:32:51 -0700122 post_code(POST_SOC_COUNT_CORES)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300123
124 movl $1, %eax
125 cpuid
126 btl $28, %edx
127 jnc sipi_complete
128 bswapl %ebx
129 movzx %bh, %edi
130 cmpb $1, %bh
131 jbe sipi_complete /* only one LAPIC ID in package */
132
133 movl $0, %eax
134 cpuid
135 movb $1, %bl
136 cmpl $4, %eax
137 jb cores_counted
138 movl $4, %eax
139 movl $0, %ecx
140 cpuid
141 shr $26, %eax
142 movb %al, %bl
143 inc %bl
144
145cores_counted:
146 movl %edi, %eax
147 divb %bl
148 cmpb $1, %al
149 jbe sipi_complete /* only LAPIC ID of a core */
150
151 /* For a hyper-threading processor, cache must not be disabled
152 * on an AP on the same physical package with the BSP.
153 */
154
155hyper_threading_cpu:
156
Martin Rothc87ab012022-11-20 19:32:51 -0700157 post_code(POST_SOC_CPU_HYPER_THREADING)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300158
159 /* Send Start IPI to all excluding ourself. */
160 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200161 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
162 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001631: movl %eax, (%edi)
164 movl $0x30, %ecx
1652: pause
166 dec %ecx
167 jnz 2b
168 movl (%edi), %ecx
169 andl $LAPIC_ICR_BUSY, %ecx
170 jnz 1b
171
Martin Rothc87ab012022-11-20 19:32:51 -0700172 post_code(POST_SOC_CPU_SIBLING_DELAY)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300173
174 /* Wait for sibling CPU to start. */
1751: movl $(MTRR_PHYS_BASE(0)), %ecx
176 rdmsr
177 andl %eax, %eax
178 jnz sipi_complete
179
180 movl $0x30, %ecx
1812: pause
182 dec %ecx
183 jnz 2b
184 jmp 1b
185
186
187ap_init:
Martin Rothc87ab012022-11-20 19:32:51 -0700188 post_code(POST_SOC_CPU_AP_INIT)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300189
190 /* Do not disable cache (so BSP can enable it). */
191 movl %cr0, %eax
192 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
193 movl %eax, %cr0
194
Martin Rothc87ab012022-11-20 19:32:51 -0700195 post_code(POST_SOC_SET_MTRR_BASE)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300196
197 /* MTRR registers are shared between HT siblings. */
198 movl $(MTRR_PHYS_BASE(0)), %ecx
199 movl $(1 << 12), %eax
200 xorl %edx, %edx
201 wrmsr
202
Martin Rothc87ab012022-11-20 19:32:51 -0700203 post_code(POST_SOC_AP_HALT)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300204
205ap_halt:
206 cli
2071: hlt
208 jmp 1b
209
210
211
212sipi_complete:
213
Martin Rothc87ab012022-11-20 19:32:51 -0700214 post_code(POST_SOC_SET_CAR_BASE)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300215
216 /* Set Cache-as-RAM base address. */
217 movl $(MTRR_PHYS_BASE(0)), %ecx
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200218 movl car_mtrr_start, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200219 orl $MTRR_TYPE_WRBACK, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300220 xorl %edx, %edx
221 wrmsr
222
223 /* Set Cache-as-RAM mask. */
224 movl $(MTRR_PHYS_MASK(0)), %ecx
225 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200226 movl car_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200227 orl $MTRR_PHYS_MASK_VALID, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300228 wrmsr
229
Martin Rothc87ab012022-11-20 19:32:51 -0700230 post_code(POST_SOC_ENABLE_MTRRS)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300231
232 /* Enable MTRR. */
233 movl $MTRR_DEF_TYPE_MSR, %ecx
234 rdmsr
235 orl $MTRR_DEF_TYPE_EN, %eax
236 wrmsr
237
238 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
239 *
240 * MSR is set when DisplayFamily_DisplayModel is one of:
241 * 06_0x, 06_17, 06_1C
242 *
243 * Description says this bit enables use of WBINVD and FLUSH#.
244 * Should this be set only after the system bus and/or memory
245 * controller can successfully handle write cycles?
246 */
247
248#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
249#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
250
251 movl $1, %eax
252 cpuid
253 movl %eax, %ebx
254 andl $EAX_FAMILY(0x0f), %eax
255 cmpl $EAX_FAMILY(0x06), %eax
256 jne no_msr_11e
257 movl %ebx, %eax
258 andl $EAX_MODEL(0xff), %eax
259 cmpl $EAX_MODEL(0x17), %eax
260 je has_msr_11e
261 cmpl $EAX_MODEL(0x1c), %eax
262 je has_msr_11e
263 andl $EAX_MODEL(0xf0), %eax
264 cmpl $EAX_MODEL(0x00), %eax
265 jne no_msr_11e
266has_msr_11e:
267 movl $0x11e, %ecx
268 rdmsr
269 orl $(1 << 8), %eax
270 wrmsr
271no_msr_11e:
272
Martin Rothc87ab012022-11-20 19:32:51 -0700273 post_code(POST_SOC_ENABLE_CACHE)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300274
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100275 /* Cache the whole rom to fetch microcode updates */
276 movl $MTRR_PHYS_BASE(1), %ecx
277 xorl %edx, %edx
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200278 movl rom_mtrr_base, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200279 orl $MTRR_TYPE_WRPROT, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100280 wrmsr
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100281 movl $MTRR_PHYS_MASK(1), %ecx
282 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200283 movl rom_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200284 orl $MTRR_PHYS_MASK_VALID, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100285 wrmsr
286
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300287 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
288 movl %cr0, %eax
289 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
290 invd
291 movl %eax, %cr0
292
Julius Wernercd49cce2019-03-05 16:53:33 -0800293#if CONFIG(MICROCODE_UPDATE_PRE_RAM)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100294 update_microcode:
295 /* put the return address in %esp */
296 movl $end_microcode_update, %esp
297 jmp update_bsp_microcode
298 end_microcode_update:
299#endif
Martin Rothc87ab012022-11-20 19:32:51 -0700300 post_code(POST_SOC_DISABLE_CACHE)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100301 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300302 movl %cr0, %eax
303 orl $CR0_CacheDisable, %eax
304 movl %eax, %cr0
305
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200306 /*
307 * An unidentified combination of speculative reads and branch
308 * predictions inside WRPROT-cacheable memory can cause invalidation
309 * of cachelines and loss of stack on models based on NetBurst
310 * microarchitecture. Therefore disable WRPROT region entirely for
311 * all family F models.
312 */
313 movl $1, %eax
314 cpuid
315 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100316 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200317
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100318disable_cache_rom:
319 movl $MTRR_PHYS_MASK(1), %ecx
320 rdmsr
321 andl $(~MTRR_PHYS_MASK_VALID), %eax
322 wrmsr
323 jmp fill_cache
324
325cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300326 /* Enable cache for our code in Flash because we do XIP here */
327 movl $MTRR_PHYS_BASE(1), %ecx
328 xorl %edx, %edx
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300329 movl $_program, %eax
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200330 andl xip_mtrr_mask, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300331 orl $MTRR_TYPE_WRPROT, %eax
332 wrmsr
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300333 movl $MTRR_PHYS_MASK(1), %ecx
334 rdmsr
Arthur Heymansbc7b63f2021-07-02 10:03:17 +0200335 movl xip_mtrr_mask, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200336 orl $MTRR_PHYS_MASK_VALID, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300337 wrmsr
338
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100339fill_cache:
Martin Rothc87ab012022-11-20 19:32:51 -0700340 post_code(POST_SOC_FILL_CACHE)
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300341 /* Enable cache. */
342 movl %cr0, %eax
343 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100344 invd
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300345 movl %eax, %cr0
346
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100347 /* Clear the cache memory region. This will also fill up the cache. */
348 cld
349 xorl %eax, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200350 movl $_car_mtrr_start, %edi
351 movl $_car_mtrr_size, %ecx
352 shr $2, %ecx
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100353 rep stosl
354
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300355 /* Setup the stack. */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100356 mov $_ecar_stack, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200357
358 /* Need to align stack to 16 bytes at call instruction. Account for
359 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200360 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200361 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300362
Arthur Heymans8a6053b2021-07-02 10:07:34 +0200363#if ENV_X86_64
364 #include <cpu/x86/64bit/entry64.inc>
365
366 movd %mm2, %rdi
367 shlq $32, %rdi /* BIST */
368 movd %mm1, %rsi
369 or %rsi, %rdi /* tsc[63:32] */
370 movd %mm0, %rsi /* tsc[31:0] */
371
372#else
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200373 /* push TSC and BIST to stack */
374 movd %mm0, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100375 pushl %eax /* BIST */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200376 movd %mm2, %eax
377 pushl %eax /* tsc[63:32] */
378 movd %mm1, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100379 pushl %eax /* tsc[31:0] */
Arthur Heymans8a6053b2021-07-02 10:07:34 +0200380#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300381
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200382before_c_entry:
Martin Rothc87ab012022-11-20 19:32:51 -0700383 post_code(POST_BOOTBLOCK_BEFORE_C_ENTRY)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200384 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300385
386 /* Should never see this postcode */
387 post_code(POST_DEAD_CODE)
388
389.Lhlt:
390 hlt
391 jmp .Lhlt
392
393fixed_mtrr_list:
394 .word MTRR_FIX_64K_00000
395 .word MTRR_FIX_16K_80000
396 .word MTRR_FIX_16K_A0000
397 .word MTRR_FIX_4K_C0000
398 .word MTRR_FIX_4K_C8000
399 .word MTRR_FIX_4K_D0000
400 .word MTRR_FIX_4K_D8000
401 .word MTRR_FIX_4K_E0000
402 .word MTRR_FIX_4K_E8000
403 .word MTRR_FIX_4K_F0000
404 .word MTRR_FIX_4K_F8000
405fixed_mtrr_list_size = . - fixed_mtrr_list
406
407_cache_as_ram_setup_end: