blob: 8587ea522f31cc7534adc7665cdf230b99a8ad3e [file] [log] [blame]
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +03001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
5 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
6 * Copyright (C) 2007-2008 coresystems GmbH
7 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <cpu/x86/mtrr.h>
20#include <cpu/x86/cache.h>
21#include <cpu/x86/post_code.h>
22#include <cpu/x86/lapic_def.h>
23
24/* Macro to access Local APIC registers at default base. */
25#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
26#define START_IPI_VECTOR ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff)
27
28#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
29#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
30
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020031.global bootblock_pre_c_entry
32
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030033.code32
34_cache_as_ram_setup:
35
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +020036bootblock_pre_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030037
38cache_as_ram:
39 post_code(0x20)
40
41 movl $LAPIC_BASE_MSR, %ecx
42 rdmsr
43 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
44 jz ap_init
45
46 /* Clear/disable fixed MTRRs */
47 mov $fixed_mtrr_list_size, %ebx
48 xor %eax, %eax
49 xor %edx, %edx
50
51clear_fixed_mtrr:
52 add $-2, %ebx
53 movzwl fixed_mtrr_list(%ebx), %ecx
54 wrmsr
55 jnz clear_fixed_mtrr
56
Elyes HAOUAS02820ca2018-09-30 07:44:39 +020057 /* Figure out how many MTRRs we have, and clear them out */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +030058 mov $MTRR_CAP_MSR, %ecx
59 rdmsr
60 movzb %al, %ebx /* Number of variable MTRRs */
61 mov $MTRR_PHYS_BASE(0), %ecx
62 xor %eax, %eax
63 xor %edx, %edx
64
65clear_var_mtrr:
66 wrmsr
67 inc %ecx
68 wrmsr
69 inc %ecx
70 dec %ebx
71 jnz clear_var_mtrr
72 post_code(0x21)
73
74 /* Configure the default memory type to uncacheable. */
75 movl $MTRR_DEF_TYPE_MSR, %ecx
76 rdmsr
77 andl $(~0x00000cff), %eax
78 wrmsr
79
80 post_code(0x22)
81
82 /* Determine CPU_ADDR_BITS and load PHYSMASK high
83 * word to %edx.
84 */
85 movl $0x80000000, %eax
86 cpuid
87 cmpl $0x80000008, %eax
88 jc addrsize_no_MSR
89 movl $0x80000008, %eax
90 cpuid
91 movb %al, %cl
92 sub $32, %cl
93 movl $1, %edx
94 shl %cl, %edx
95 subl $1, %edx
96 jmp addrsize_set_high
97addrsize_no_MSR:
98 movl $1, %eax
99 cpuid
100 andl $(1 << 6 | 1 << 17), %edx /* PAE or PSE36 */
101 jz addrsize_set_high
102 movl $0x0f, %edx
103
104 /* Preload high word of address mask (in %edx) for Variable
105 * MTRRs 0 and 1 and enable local APIC at default base.
106 */
107addrsize_set_high:
108 xorl %eax, %eax
109 movl $MTRR_PHYS_MASK(0), %ecx
110 wrmsr
111 movl $MTRR_PHYS_MASK(1), %ecx
112 wrmsr
113 movl $LAPIC_BASE_MSR, %ecx
114 not %edx
115 movl %edx, %ebx
116 rdmsr
117 andl %ebx, %edx
118 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
119 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
120 wrmsr
121
122bsp_init:
123
124 post_code(0x23)
125
126 /* Send INIT IPI to all excluding ourself. */
127 movl LAPIC(ICR), %edi
128 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1291: movl %eax, (%edi)
130 movl $0x30, %ecx
1312: pause
132 dec %ecx
133 jnz 2b
134 movl (%edi), %ecx
135 andl $LAPIC_ICR_BUSY, %ecx
136 jnz 1b
137
138 post_code(0x24)
139
140 movl $1, %eax
141 cpuid
142 btl $28, %edx
143 jnc sipi_complete
144 bswapl %ebx
145 movzx %bh, %edi
146 cmpb $1, %bh
147 jbe sipi_complete /* only one LAPIC ID in package */
148
149 movl $0, %eax
150 cpuid
151 movb $1, %bl
152 cmpl $4, %eax
153 jb cores_counted
154 movl $4, %eax
155 movl $0, %ecx
156 cpuid
157 shr $26, %eax
158 movb %al, %bl
159 inc %bl
160
161cores_counted:
162 movl %edi, %eax
163 divb %bl
164 cmpb $1, %al
165 jbe sipi_complete /* only LAPIC ID of a core */
166
167 /* For a hyper-threading processor, cache must not be disabled
168 * on an AP on the same physical package with the BSP.
169 */
170
171hyper_threading_cpu:
172
173 /* delay 10 ms */
174 movl $10000, %ecx
1751: inb $0x80, %al
176 dec %ecx
177 jnz 1b
178
179 post_code(0x25)
180
181 /* Send Start IPI to all excluding ourself. */
182 movl LAPIC(ICR), %edi
183 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax
1841: movl %eax, (%edi)
185 movl $0x30, %ecx
1862: pause
187 dec %ecx
188 jnz 2b
189 movl (%edi), %ecx
190 andl $LAPIC_ICR_BUSY, %ecx
191 jnz 1b
192
193 /* delay 250 us */
194 movl $250, %ecx
1951: inb $0x80, %al
196 dec %ecx
197 jnz 1b
198
199 post_code(0x26)
200
201 /* Wait for sibling CPU to start. */
2021: movl $(MTRR_PHYS_BASE(0)), %ecx
203 rdmsr
204 andl %eax, %eax
205 jnz sipi_complete
206
207 movl $0x30, %ecx
2082: pause
209 dec %ecx
210 jnz 2b
211 jmp 1b
212
213
214ap_init:
215 post_code(0x27)
216
217 /* Do not disable cache (so BSP can enable it). */
218 movl %cr0, %eax
219 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
220 movl %eax, %cr0
221
222 post_code(0x28)
223
224 /* MTRR registers are shared between HT siblings. */
225 movl $(MTRR_PHYS_BASE(0)), %ecx
226 movl $(1 << 12), %eax
227 xorl %edx, %edx
228 wrmsr
229
230 post_code(0x29)
231
232ap_halt:
233 cli
2341: hlt
235 jmp 1b
236
237
238
239sipi_complete:
240
241 post_code(0x2a)
242
243 /* Set Cache-as-RAM base address. */
244 movl $(MTRR_PHYS_BASE(0)), %ecx
245 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
246 xorl %edx, %edx
247 wrmsr
248
249 /* Set Cache-as-RAM mask. */
250 movl $(MTRR_PHYS_MASK(0)), %ecx
251 rdmsr
252 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
253 wrmsr
254
255 post_code(0x2b)
256
257 /* Enable MTRR. */
258 movl $MTRR_DEF_TYPE_MSR, %ecx
259 rdmsr
260 orl $MTRR_DEF_TYPE_EN, %eax
261 wrmsr
262
263 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
264 *
265 * MSR is set when DisplayFamily_DisplayModel is one of:
266 * 06_0x, 06_17, 06_1C
267 *
268 * Description says this bit enables use of WBINVD and FLUSH#.
269 * Should this be set only after the system bus and/or memory
270 * controller can successfully handle write cycles?
271 */
272
273#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
274#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
275
276 movl $1, %eax
277 cpuid
278 movl %eax, %ebx
279 andl $EAX_FAMILY(0x0f), %eax
280 cmpl $EAX_FAMILY(0x06), %eax
281 jne no_msr_11e
282 movl %ebx, %eax
283 andl $EAX_MODEL(0xff), %eax
284 cmpl $EAX_MODEL(0x17), %eax
285 je has_msr_11e
286 cmpl $EAX_MODEL(0x1c), %eax
287 je has_msr_11e
288 andl $EAX_MODEL(0xf0), %eax
289 cmpl $EAX_MODEL(0x00), %eax
290 jne no_msr_11e
291has_msr_11e:
292 movl $0x11e, %ecx
293 rdmsr
294 orl $(1 << 8), %eax
295 wrmsr
296no_msr_11e:
297
298 post_code(0x2c)
299
300 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
301 movl %cr0, %eax
302 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
303 invd
304 movl %eax, %cr0
305
306 /* Clear the cache memory region. This will also fill up the cache. */
307 cld
308 xorl %eax, %eax
309 movl $CACHE_AS_RAM_BASE, %edi
310 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
311 rep stosl
312
313 post_code(0x2d)
314 /* Enable Cache-as-RAM mode by disabling cache. */
315 movl %cr0, %eax
316 orl $CR0_CacheDisable, %eax
317 movl %eax, %cr0
318
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200319 /*
320 * An unidentified combination of speculative reads and branch
321 * predictions inside WRPROT-cacheable memory can cause invalidation
322 * of cachelines and loss of stack on models based on NetBurst
323 * microarchitecture. Therefore disable WRPROT region entirely for
324 * all family F models.
325 */
326 movl $1, %eax
327 cpuid
328 cmp $0xf, %ah
329 je skip_cache_rom
330
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300331 /* Enable cache for our code in Flash because we do XIP here */
332 movl $MTRR_PHYS_BASE(1), %ecx
333 xorl %edx, %edx
334 /*
335 * IMPORTANT: The following calculation _must_ be done at runtime. See
Stefan Taunerde028782018-08-19 20:02:05 +0200336 * https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300337 */
Kyösti Mälkkice9f4222018-06-25 18:53:36 +0300338 movl $_program, %eax
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300339 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
340 orl $MTRR_TYPE_WRPROT, %eax
341 wrmsr
342
343 movl $MTRR_PHYS_MASK(1), %ecx
344 rdmsr
345 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
346 wrmsr
347
Arthur Heymans7875dbd2018-06-16 20:01:47 +0200348skip_cache_rom:
349
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300350 post_code(0x2e)
351 /* Enable cache. */
352 movl %cr0, %eax
353 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
354 movl %eax, %cr0
355
356 /* Setup the stack. */
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200357 mov $_car_stack_end, %esp
358
359 /* Need to align stack to 16 bytes at call instruction. Account for
360 the pushes below. */
Arthur Heymans348b79f2018-06-03 17:14:19 +0200361 andl $0xfffffff0, %esp
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200362 subl $4, %esp
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300363
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200364 /* push TSC and BIST to stack */
365 movd %mm0, %eax
366 pushl %eax /* BIST */
367 movd %mm2, %eax
368 pushl %eax /* tsc[63:32] */
369 movd %mm1, %eax
370 pushl %eax /* tsc[31:0] */
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300371
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200372before_c_entry:
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300373 post_code(0x2f)
Kyösti Mälkkic641f7e2018-12-28 16:54:54 +0200374 call bootblock_c_entry_bist
Kyösti Mälkki6a8ce0d2018-05-17 17:22:51 +0300375
376 /* Should never see this postcode */
377 post_code(POST_DEAD_CODE)
378
379.Lhlt:
380 hlt
381 jmp .Lhlt
382
383fixed_mtrr_list:
384 .word MTRR_FIX_64K_00000
385 .word MTRR_FIX_16K_80000
386 .word MTRR_FIX_16K_A0000
387 .word MTRR_FIX_4K_C0000
388 .word MTRR_FIX_4K_C8000
389 .word MTRR_FIX_4K_D0000
390 .word MTRR_FIX_4K_D8000
391 .word MTRR_FIX_4K_E0000
392 .word MTRR_FIX_4K_E8000
393 .word MTRR_FIX_4K_F0000
394 .word MTRR_FIX_4K_F8000
395fixed_mtrr_list_size = . - fixed_mtrr_list
396
397_cache_as_ram_setup_end: