blob: 806102f0b00228e2affa5bc14c74cd009ce525d8 [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älkkic641f7e2018-12-28 16:54:54 +020011.global bootblock_pre_c_entry
12
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030013.code32
14_cache_as_ram_setup:
15
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020016bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030017
18cache_as_ram:
19 post_code(0x20)
20
21 movl $LAPIC_BASE_MSR, %ecx
22 rdmsr
23 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
24 jz ap_init
25
26 /* Clear/disable fixed MTRRs */
27 mov $fixed_mtrr_list_size, %ebx
28 xor %eax, %eax
29 xor %edx, %edx
30
31clear_fixed_mtrr:
32 add $-2, %ebx
33 movzwl fixed_mtrr_list(%ebx), %ecx
34 wrmsr
35 jnz clear_fixed_mtrr
36
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020037 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030038 mov $MTRR_CAP_MSR, %ecx
39 rdmsr
40 movzb %al, %ebx /* Number of variable MTRRs */
41 mov $MTRR_PHYS_BASE(0), %ecx
42 xor %eax, %eax
43 xor %edx, %edx
44
45clear_var_mtrr:
46 wrmsr
47 inc %ecx
48 wrmsr
49 inc %ecx
50 dec %ebx
51 jnz clear_var_mtrr
52 post_code(0x21)
53
54 /* Configure the default memory type to uncacheable. */
55 movl $MTRR_DEF_TYPE_MSR, %ecx
56 rdmsr
57 andl $(~0x00000cff), %eax
58 wrmsr
59
60 post_code(0x22)
61
62 /* Determine CPU_ADDR_BITS and load PHYSMASK high
63 * word to %edx.
64 */
65 movl $0x80000000, %eax
66 cpuid
67 cmpl $0x80000008, %eax
68 jc addrsize_no_MSR
69 movl $0x80000008, %eax
70 cpuid
71 movb %al, %cl
72 sub $32, %cl
73 movl $1, %edx
74 shl %cl, %edx
75 subl $1, %edx
76 jmp addrsize_set_high
77addrsize_no_MSR:
78 movl $1, %eax
79 cpuid
80 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
81 jz addrsize_set_high
82 movl $0x0f, %edx
83
84 /* Preload high word of address mask (in %edx) for Variable
85 * MTRRs 0 and 1 and enable local APIC at default base.
86 */
87addrsize_set_high:
88 xorl %eax, %eax
89 movl $MTRR_PHYS_MASK(0), %ecx
90 wrmsr
91 movl $MTRR_PHYS_MASK(1), %ecx
92 wrmsr
93 movl $LAPIC_BASE_MSR, %ecx
94 not %edx
95 movl %edx, %ebx
96 rdmsr
97 andl %ebx, %edx
98 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
99 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
100 wrmsr
101
102bsp_init:
103
104 post_code(0x23)
105
106 /* Send INIT IPI to all excluding ourself. */
107 movl LAPIC(ICR), %edi
108 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1091: movl %eax, (%edi)
110 movl $0x30, %ecx
1112: pause
112 dec %ecx
113 jnz 2b
114 movl (%edi), %ecx
115 andl $LAPIC_ICR_BUSY, %ecx
116 jnz 1b
117
118 post_code(0x24)
119
120 movl $1, %eax
121 cpuid
122 btl $28, %edx
123 jnc sipi_complete
124 bswapl %ebx
125 movzx %bh, %edi
126 cmpb $1, %bh
127 jbe sipi_complete /* only one LAPIC ID in package */
128
129 movl $0, %eax
130 cpuid
131 movb $1, %bl
132 cmpl $4, %eax
133 jb cores_counted
134 movl $4, %eax
135 movl $0, %ecx
136 cpuid
137 shr $26, %eax
138 movb %al, %bl
139 inc %bl
140
141cores_counted:
142 movl %edi, %eax
143 divb %bl
144 cmpb $1, %al
145 jbe sipi_complete /* only LAPIC ID of a core */
146
147 /* For a hyper-threading processor, cache must not be disabled
148 * on an AP on the same physical package with the BSP.
149 */
150
151hyper_threading_cpu:
152
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300153 post_code(0x25)
154
155 /* Send Start IPI to all excluding ourself. */
156 movl LAPIC(ICR), %edi
Kyösti Mälkki34856572019-01-09 20:30:52 +0200157 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP), %eax
158 orl $ap_sipi_vector_in_rom, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001591: movl %eax, (%edi)
160 movl $0x30, %ecx
1612: pause
162 dec %ecx
163 jnz 2b
164 movl (%edi), %ecx
165 andl $LAPIC_ICR_BUSY, %ecx
166 jnz 1b
167
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300168 post_code(0x26)
169
170 /* Wait for sibling CPU to start. */
1711: movl $(MTRR_PHYS_BASE(0)), %ecx
172 rdmsr
173 andl %eax, %eax
174 jnz sipi_complete
175
176 movl $0x30, %ecx
1772: pause
178 dec %ecx
179 jnz 2b
180 jmp 1b
181
182
183ap_init:
184 post_code(0x27)
185
186 /* Do not disable cache (so BSP can enable it). */
187 movl %cr0, %eax
188 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
189 movl %eax, %cr0
190
191 post_code(0x28)
192
193 /* MTRR registers are shared between HT siblings. */
194 movl $(MTRR_PHYS_BASE(0)), %ecx
195 movl $(1 << 12), %eax
196 xorl %edx, %edx
197 wrmsr
198
199 post_code(0x29)
200
201ap_halt:
202 cli
2031: hlt
204 jmp 1b
205
206
207
208sipi_complete:
209
210 post_code(0x2a)
211
212 /* Set Cache-as-RAM base address. */
213 movl $(MTRR_PHYS_BASE(0)), %ecx
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200214 movl $_car_mtrr_start, %eax
215 orl $MTRR_TYPE_WRBACK, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300216 xorl %edx, %edx
217 wrmsr
218
219 /* Set Cache-as-RAM mask. */
220 movl $(MTRR_PHYS_MASK(0)), %ecx
221 rdmsr
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200222 movl $_car_mtrr_mask, %eax
223 orl $MTRR_PHYS_MASK_VALID, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300224 wrmsr
225
226 post_code(0x2b)
227
228 /* Enable MTRR. */
229 movl $MTRR_DEF_TYPE_MSR, %ecx
230 rdmsr
231 orl $MTRR_DEF_TYPE_EN, %eax
232 wrmsr
233
234 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
235 *
236 * MSR is set when DisplayFamily_DisplayModel is one of:
237 * 06_0x, 06_17, 06_1C
238 *
239 * Description says this bit enables use of WBINVD and FLUSH#.
240 * Should this be set only after the system bus and/or memory
241 * controller can successfully handle write cycles?
242 */
243
244#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
245#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
246
247 movl $1, %eax
248 cpuid
249 movl %eax, %ebx
250 andl $EAX_FAMILY(0x0f), %eax
251 cmpl $EAX_FAMILY(0x06), %eax
252 jne no_msr_11e
253 movl %ebx, %eax
254 andl $EAX_MODEL(0xff), %eax
255 cmpl $EAX_MODEL(0x17), %eax
256 je has_msr_11e
257 cmpl $EAX_MODEL(0x1c), %eax
258 je has_msr_11e
259 andl $EAX_MODEL(0xf0), %eax
260 cmpl $EAX_MODEL(0x00), %eax
261 jne no_msr_11e
262has_msr_11e:
263 movl $0x11e, %ecx
264 rdmsr
265 orl $(1 << 8), %eax
266 wrmsr
267no_msr_11e:
268
269 post_code(0x2c)
270
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100271 /* Cache the whole rom to fetch microcode updates */
272 movl $MTRR_PHYS_BASE(1), %ecx
273 xorl %edx, %edx
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200274 movl $_rom_mtrr_base, %eax
275 orl $MTRR_TYPE_WRPROT, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100276 wrmsr
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100277 movl $MTRR_PHYS_MASK(1), %ecx
278 rdmsr
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200279 movl $_rom_mtrr_mask, %eax
280 orl $MTRR_PHYS_MASK_VALID, %eax
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100281 wrmsr
282
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300283 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
284 movl %cr0, %eax
285 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
286 invd
287 movl %eax, %cr0
288
Julius Wernercd49cce2019-03-05 16:53:33 -0800289#if CONFIG(MICROCODE_UPDATE_PRE_RAM)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100290 update_microcode:
291 /* put the return address in %esp */
292 movl $end_microcode_update, %esp
293 jmp update_bsp_microcode
294 end_microcode_update:
295#endif
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300296 post_code(0x2d)
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100297 /* Disable caching to change MTRR's. */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300298 movl %cr0, %eax
299 orl $CR0_CacheDisable, %eax
300 movl %eax, %cr0
301
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200302 /*
303 * An unidentified combination of speculative reads and branch
304 * predictions inside WRPROT-cacheable memory can cause invalidation
305 * of cachelines and loss of stack on models based on NetBurst
306 * microarchitecture. Therefore disable WRPROT region entirely for
307 * all family F models.
308 */
309 movl $1, %eax
310 cpuid
311 cmp $0xf, %ah
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100312 jne cache_rom
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200313
Arthur Heymans95b3ba52019-01-09 12:24:58 +0100314disable_cache_rom:
315 movl $MTRR_PHYS_MASK(1), %ecx
316 rdmsr
317 andl $(~MTRR_PHYS_MASK_VALID), %eax
318 wrmsr
319 jmp fill_cache
320
321cache_rom:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300322 /* Enable cache for our code in Flash because we do XIP here */
323 movl $MTRR_PHYS_BASE(1), %ecx
324 xorl %edx, %edx
325 /*
326 * IMPORTANT: The following calculation _must_ be done at runtime. See
Stefan Taunerde028782018-08-19 20:02:05 +0200327 * https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300328 */
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300329 movl $_program, %eax
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +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
Kyösti Mälkkidc6bb6c2019-11-08 00:08:55 +0200335 movl $_xip_mtrr_mask, %eax
336 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:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300340 post_code(0x2e)
341 /* 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
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200363 /* push TSC and BIST to stack */
364 movd %mm0, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100365 pushl %eax /* BIST */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200366 movd %mm2, %eax
367 pushl %eax /* tsc[63:32] */
368 movd %mm1, %eax
Elyes HAOUAS87930b32019-01-16 12:41:57 +0100369 pushl %eax /* tsc[31:0] */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300370
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200371before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300372 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200373 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300374
375 /* Should never see this postcode */
376 post_code(POST_DEAD_CODE)
377
378.Lhlt:
379 hlt
380 jmp .Lhlt
381
382fixed_mtrr_list:
383 .word MTRR_FIX_64K_00000
384 .word MTRR_FIX_16K_80000
385 .word MTRR_FIX_16K_A0000
386 .word MTRR_FIX_4K_C0000
387 .word MTRR_FIX_4K_C8000
388 .word MTRR_FIX_4K_D0000
389 .word MTRR_FIX_4K_D8000
390 .word MTRR_FIX_4K_E0000
391 .word MTRR_FIX_4K_E8000
392 .word MTRR_FIX_4K_F0000
393 .word MTRR_FIX_4K_F8000
394fixed_mtrr_list_size = . - fixed_mtrr_list
395
396_cache_as_ram_setup_end: