Whitespace fixes
[coreboot.git] / src / cpu / intel / car / cache_as_ram_ht.inc
1 /*
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  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 #include <cpu/x86/stack.h>
24 #include <cpu/x86/mtrr.h>
25 #include <cpu/x86/post_code.h>
26 #include <cpu/x86/lapic_def.h>
27
28 /* Macro to access Local APIC registers at default base. */
29 #define LAPIC(x)                $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
30 #define START_IPI_VECTOR        ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff)
31
32 /* Base address to cache all of Flash ROM, just below 4GB. */
33 #define CACHE_ROM_BASE  ((1<<22 - CONFIG_CACHE_ROM_SIZE>>10)<<10)
34
35 #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
36 #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
37
38         /* Save the BIST result. */
39         movl    %eax, %ebp
40
41 cache_as_ram:
42         post_code(0x20)
43
44         movl    $LAPIC_BASE_MSR, %ecx
45         rdmsr
46         andl    $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
47         jz      ap_init
48
49         /* Zero out all fixed range and variable range MTRRs.
50          * For hyper-threaded CPUs these are shared.
51          */
52         movl    $mtrr_table, %esi
53         movl    $((mtrr_table_end - mtrr_table) / 2), %edi
54         xorl    %eax, %eax
55         xorl    %edx, %edx
56 clear_mtrrs:
57         movw    (%esi), %bx
58         movzx   %bx, %ecx
59         wrmsr
60         add     $2, %esi
61         dec     %edi
62         jnz     clear_mtrrs
63
64         post_code(0x21)
65
66         /* Configure the default memory type to uncacheable. */
67         movl    $MTRRdefType_MSR, %ecx
68         rdmsr
69         andl    $(~0x00000cff), %eax
70         wrmsr
71
72         post_code(0x22)
73
74         /* Determine CPU_ADDR_BITS and load PHYSMASK high
75          * word to %edx.
76          */
77         movl    $0x80000000, %eax
78         cpuid
79         cmpl    $0x80000008, %eax
80         jc      addrsize_no_MSR
81         movl    $0x80000008, %eax
82         cpuid
83         movb    %al, %cl
84         sub     $32, %cl
85         movl    $1, %edx
86         shl     %cl, %edx
87         subl    $1, %edx
88         jmp     addrsize_set_high
89 addrsize_no_MSR:
90         movl    $1, %eax
91         cpuid
92         andl    $(1<<6 | 1<<17), %edx   /* PAE or PSE36 */
93         jz      addrsize_set_high
94         movl    $0x0f, %edx
95
96         /* Preload high word of address mask (in %edx) for Variable
97          * MTRRs 0 and 1 and enable local apic at default base.
98          */
99 addrsize_set_high:
100         xorl    %eax, %eax
101         movl    $MTRRphysMask_MSR(0), %ecx
102         wrmsr
103         movl    $MTRRphysMask_MSR(1), %ecx
104         wrmsr
105         movl    $LAPIC_BASE_MSR, %ecx
106         not     %edx
107         movl    %edx, %ebx
108         rdmsr
109         andl    %ebx, %edx
110         andl    $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
111         orl     $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
112         wrmsr
113
114 bsp_init:
115
116         post_code(0x23)
117
118         /* Send INIT IPI to all excluding ourself. */
119         movl    LAPIC(ICR), %edi
120         movl    $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
121 1:      movl    %eax, (%edi)
122         movl    $0x30, %ecx
123 2:      pause
124         dec     %ecx
125         jnz     2b
126         movl    (%edi), %ecx
127         andl    $LAPIC_ICR_BUSY, %ecx
128         jnz     1b
129
130         post_code(0x24)
131
132         /* For a hyper-threading processor, cache must not be disabled
133          * on an AP on the same physical package with the BSP.
134          */
135         movl    $01, %eax
136         cpuid
137         btl     $28, %edx
138         jnc     sipi_complete
139         bswapl  %ebx
140         cmpb    $01, %bh
141         jbe     sipi_complete
142
143 hyper_threading_cpu:
144
145         /* delay 10 ms */
146         movl    $10000, %ecx
147 1:      inb     $0x80, %al
148         dec     %ecx
149         jnz     1b
150
151         post_code(0x25)
152
153         /* Send Start IPI to all excluding ourself. */
154         movl    LAPIC(ICR), %edi
155         movl    $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax
156 1:      movl    %eax, (%edi)
157         movl    $0x30, %ecx
158 2:      pause
159         dec     %ecx
160         jnz     2b
161         movl    (%edi), %ecx
162         andl    $LAPIC_ICR_BUSY, %ecx
163         jnz     1b
164
165         /* delay 250 us */
166         movl    $250, %ecx
167 1:      inb     $0x80, %al
168         dec     %ecx
169         jnz     1b
170
171         post_code(0x26)
172
173         /* Wait for sibling CPU to start. */
174 1:      movl    $(MTRRphysBase_MSR(0)), %ecx
175         rdmsr
176         andl    %eax, %eax
177         jnz     sipi_complete
178
179         movl    $0x30, %ecx
180 2:      pause
181         dec     %ecx
182         jnz     2b
183         jmp     1b
184
185
186 ap_init:
187         post_code(0x27)
188
189         /* Do not disable cache (so BSP can enable it). */
190         movl    %cr0, %eax
191         andl    $(~((1 << 30) | (1 << 29))), %eax
192         movl    %eax, %cr0
193
194         post_code(0x28)
195
196         /* MTRR registers are shared between HT siblings. */
197         movl    $(MTRRphysBase_MSR(0)), %ecx
198         movl    $(1<<12), %eax
199         xorl    %edx, %edx
200         wrmsr
201
202         post_code(0x29)
203
204 ap_halt:
205         cli
206 1:      hlt
207         jnz     1b
208
209
210
211 sipi_complete:
212
213         post_code(0x2a)
214
215         /* Set Cache-as-RAM base address. */
216         movl    $(MTRRphysBase_MSR(0)), %ecx
217         movl    $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
218         xorl    %edx, %edx
219         wrmsr
220
221         /* Set Cache-as-RAM mask. */
222         movl    $(MTRRphysMask_MSR(0)), %ecx
223         rdmsr
224         movl    $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
225         wrmsr
226
227         /* Enable MTRR. */
228         movl    $MTRRdefType_MSR, %ecx
229         rdmsr
230         orl     $MTRRdefTypeEn, %eax
231         wrmsr
232
233         post_code(0x2b)
234
235         /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
236          *
237          * MSR is set when DisplayFamily_DisplayModel is one of:
238          * 06_0x, 06_17, 06_1C
239          *
240          * Description says this bit enables use of WBINVD and FLUSH#.
241          * Should this be set only after the system bus and/or memory
242          * controller can successfully handle write cycles?
243          */
244
245 #define EAX_FAMILY(a)   (a << 8)        /* for family <= 0fH */
246 #define EAX_MODEL(a)    (((a & 0xf0) << 12) | ((a & 0xf) << 4))
247
248         movl    $1, %eax
249         cpuid
250         movl    %eax, %ebx
251         andl    $EAX_FAMILY(0x0f), %eax
252         cmpl    $EAX_FAMILY(0x06), %eax
253         jne     no_msr_11e
254         movl    %ebx, %eax
255         andl    $EAX_MODEL(0xff), %eax
256         cmpl    $EAX_MODEL(0x17), %eax
257         je      has_msr_11e
258         cmpl    $EAX_MODEL(0x1c), %eax
259         je      has_msr_11e
260         andl    $EAX_MODEL(0xf0), %eax
261         cmpl    $EAX_MODEL(0x00), %eax
262         jne     no_msr_11e
263 has_msr_11e:
264         movl    $0x11e, %ecx
265         rdmsr
266         orl     $(1 << 8), %eax
267         wrmsr
268 no_msr_11e:
269
270         post_code(0x2c)
271
272         /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
273         movl    %cr0, %eax
274         andl    $(~((1 << 30) | (1 << 29))), %eax
275         invd
276         movl    %eax, %cr0
277
278         /* Clear the cache memory reagion. */
279         cld
280         xorl    %eax, %eax
281         movl    $CACHE_AS_RAM_BASE, %edi
282         movl    $(CACHE_AS_RAM_SIZE / 4), %ecx
283         rep     stosl
284
285         /* Enable Cache-as-RAM mode by disabling cache. */
286         movl    %cr0, %eax
287         orl     $(1 << 30), %eax
288         movl    %eax, %cr0
289
290         post_code(0x2d)
291
292 #if CONFIG_XIP_ROM_SIZE
293         /* Enable cache for our code in Flash because we do XIP here */
294         movl    $MTRRphysBase_MSR(1), %ecx
295         xorl    %edx, %edx
296         /*
297          * IMPORTANT: The following calculation _must_ be done at runtime. See
298          * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
299          */
300         movl    $copy_and_run, %eax
301         andl    $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
302         orl     $MTRR_TYPE_WRBACK, %eax
303         wrmsr
304
305         movl    $MTRRphysMask_MSR(1), %ecx
306         rdmsr
307         movl    $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
308         wrmsr
309 #endif /* CONFIG_XIP_ROM_SIZE */
310
311         /* Enable cache. */
312         movl    %cr0, %eax
313         andl    $(~((1 << 30) | (1 << 29))), %eax
314         movl    %eax, %cr0
315
316         post_code(0x2e)
317
318         /* Set up the stack pointer. */
319 #if CONFIG_USBDEBUG
320         /* Leave some space for the struct ehci_debug_info. */
321         movl    $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4 - 128), %esp
322 #else
323         movl    $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %esp
324 #endif
325
326         /* Restore the BIST result. */
327         movl    %ebp, %eax
328         movl    %esp, %ebp
329         pushl   %eax
330
331         post_code(0x2f)
332
333         /* Call romstage.c main function. */
334         call    main
335         addl    $4, %esp
336
337         post_code(0x30)
338
339         /* Disable cache. */
340         movl    %cr0, %eax
341         orl     $(1 << 30), %eax
342         movl    %eax, %cr0
343
344         post_code(0x34)
345
346         /* Disable MTRR. */
347         movl    $MTRRdefType_MSR, %ecx
348         rdmsr
349         andl    $(~MTRRdefTypeEn), %eax
350         wrmsr
351
352         post_code(0x35)
353
354         invd
355
356         post_code(0x36)
357
358         /* Enable cache. */
359         movl    %cr0, %eax
360         andl    $~((1 << 30) | (1 << 29)), %eax
361         movl    %eax, %cr0
362
363         post_code(0x37)
364
365         /* Disable cache. */
366         movl    %cr0, %eax
367         orl     $(1 << 30), %eax
368         movl    %eax, %cr0
369
370         post_code(0x38)
371
372         /* Enable Write Back and Speculative Reads for low RAM. */
373         movl    $MTRRphysBase_MSR(0), %ecx
374         movl    $(0x00000000 | MTRR_TYPE_WRBACK), %eax
375         xorl    %edx, %edx
376         wrmsr
377         movl    $MTRRphysMask_MSR(0), %ecx
378         rdmsr
379         movl    $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
380         wrmsr
381
382         /* Enable caching and Speculative Reads for Flash ROM device. */
383         movl    $MTRRphysBase_MSR(1), %ecx
384         movl    $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
385         xorl    %edx, %edx
386         wrmsr
387         movl    $MTRRphysMask_MSR(1), %ecx
388         rdmsr
389         movl    $(~(CONFIG_CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
390         wrmsr
391
392         post_code(0x39)
393
394         /* And enable cache again after setting MTRRs. */
395         movl    %cr0, %eax
396         andl    $~((1 << 30) | (1 << 29)), %eax
397         movl    %eax, %cr0
398
399         post_code(0x3a)
400
401         /* Enable MTRR. */
402         movl    $MTRRdefType_MSR, %ecx
403         rdmsr
404         orl     $MTRRdefTypeEn, %eax
405         wrmsr
406
407         post_code(0x3b)
408
409         /* Invalidate the cache again. */
410         invd
411
412         post_code(0x3c)
413
414         /* Clear boot_complete flag. */
415         xorl    %ebp, %ebp
416 __main:
417         post_code(POST_PREPARE_RAMSTAGE)
418         cld                     /* Clear direction flag. */
419
420         movl    %ebp, %esi
421
422         movl    $ROMSTAGE_STACK, %esp
423         movl    %esp, %ebp
424         pushl   %esi
425         call    copy_and_run
426
427 .Lhlt:
428         post_code(POST_DEAD_CODE)
429         hlt
430         jmp     .Lhlt
431
432 mtrr_table:
433         /* Fixed MTRRs */
434         .word 0x250, 0x258, 0x259
435         .word 0x268, 0x269, 0x26A
436         .word 0x26B, 0x26C, 0x26D
437         .word 0x26E, 0x26F
438         /* Variable MTRRs */
439         .word 0x200, 0x201, 0x202, 0x203
440         .word 0x204, 0x205, 0x206, 0x207
441         .word 0x208, 0x209, 0x20A, 0x20B
442         .word 0x20C, 0x20D, 0x20E, 0x20F
443 mtrr_table_end:
444