98d227db2f8b8d477c1ed327b6beb45894372304
[coreboot.git] / src / cpu / intel / car / cache_as_ram.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 Eswar Nallusamy, LANL
6  * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
7  * Copyright (C) 2007-2010 coresystems GmbH
8  * Copyright (C) 2007 Carl-Daniel Hailfinger
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; version 2 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
22  */
23
24 #include <cpu/x86/stack.h>
25 #include <cpu/x86/mtrr.h>
26 #include <cpu/x86/lapic_def.h>
27
28 #define CacheSize               CONFIG_DCACHE_RAM_SIZE
29 #define CacheBase               (0xd0000 - CacheSize)
30
31         /* Save the BIST result. */
32         movl    %eax, %ebp
33
34 CacheAsRam:
35         /* Check whether the processor has HT capability. */
36         movl    $01, %eax
37         cpuid
38         btl     $28, %edx
39         jnc     NotHtProcessor
40         bswapl  %ebx
41         cmpb    $01, %bh
42         jbe     NotHtProcessor
43
44         /*
45          * It is a HT processor. Send SIPI to the other logical processor
46          * within this processor so that the CAR related common system
47          * registers are programmed accordingly.
48          */
49
50         /*
51          * Use some register that is common to both logical processors
52          * as semaphore. Refer Appendix B, Vol.3.
53          */
54         xorl    %eax, %eax
55         xorl    %edx, %edx
56         movl    $MTRRfix64K_00000_MSR, %ecx
57         wrmsr
58
59         /*
60          * Figure out the logical AP's APIC ID; the following logic will
61          * work only for processors with 2 threads.
62          * Refer to Vol 3. Table 7-1 for details about this logic.
63          */
64         movl    $0xFEE00020, %esi
65         movl    (%esi), %ebx
66         andl    $0xFF000000, %ebx
67         bswapl  %ebx
68         btl     $0, %ebx
69         jnc     LogicalAP0
70         andb    $0xFE, %bl
71         jmp     Send_SIPI
72 LogicalAP0:
73         orb     $0x01, %bl
74 Send_SIPI:
75         bswapl  %ebx    /* EBX - logical AP's APIC ID. */
76
77         /*
78          * Fill up the IPI command registers in the Local APIC mapped to
79          * default address and issue SIPI to the other logical processor
80          * within this processor die.
81          */
82 Retry_SIPI:
83         movl    %ebx, %eax
84         movl    $0xFEE00310, %esi
85         movl    %eax, (%esi)
86
87         /* SIPI vector - F900:0000 */
88         movl    $0x000006F9, %eax
89         movl    $0xFEE00300, %esi
90         movl    %eax, (%esi)
91
92         movl    $0x30, %ecx
93 SIPI_Delay:
94         pause
95         decl    %ecx
96         jnz     SIPI_Delay
97
98         movl    (%esi), %eax
99         andl    $0x00001000, %eax
100         jnz     Retry_SIPI
101
102         /* Wait for the Logical AP to complete initialization. */
103 LogicalAP_SIPINotdone:
104         movl    $MTRRfix64K_00000_MSR, %ecx
105         rdmsr
106         orl     %eax, %eax
107         jz      LogicalAP_SIPINotdone
108
109 NotHtProcessor:
110         /* Set the default memory type and enable fixed and variable MTRRs. */
111         movl    $MTRRdefType_MSR, %ecx
112         xorl    %edx, %edx
113         movl    $(MTRRdefTypeEn | MTRRdefTypeFixEn), %eax
114         wrmsr
115
116         /* Clear all MTRRs. */
117         xorl    %edx, %edx
118         movl    $fixed_mtrr_msr, %esi
119
120 clear_fixed_var_mtrr:
121         lodsl   (%esi), %eax
122         testl   %eax, %eax
123         jz      clear_fixed_var_mtrr_out
124
125         movl    %eax, %ecx
126         xorl    %eax, %eax
127         wrmsr
128
129         jmp     clear_fixed_var_mtrr
130
131 fixed_mtrr_msr:
132         .long   0x250, 0x258, 0x259
133         .long   0x268, 0x269, 0x26A
134         .long   0x26B, 0x26C, 0x26D
135         .long   0x26E, 0x26F
136
137 var_mtrr_msr:
138         .long   0x200, 0x201, 0x202, 0x203
139         .long   0x204, 0x205, 0x206, 0x207
140         .long   0x208, 0x209, 0x20A, 0x20B
141         .long   0x20C, 0x20D, 0x20E, 0x20F
142         .long   0x000 /* NULL, end of table */
143
144 clear_fixed_var_mtrr_out:
145
146 /*
147  * 0x06 is the WB IO type for a given 4k segment.
148  * segs is the number of 4k segments in the area of the particular
149  *      register we want to use for CAR.
150  * reg  is the register where the IO type should be stored.
151  */
152 .macro extractmask segs, reg
153 .if \segs <= 0
154         /*
155          * The xorl here is superfluous because at the point of first execution
156          * of this macro, %eax and %edx are cleared. Later invocations of this
157          * macro will have a monotonically increasing segs parameter.
158          */
159         xorl \reg, \reg
160 .elseif \segs == 1
161         movl    $0x06000000, \reg /* WB IO type */
162 .elseif \segs == 2
163         movl    $0x06060000, \reg /* WB IO type */
164 .elseif \segs == 3
165         movl    $0x06060600, \reg /* WB IO type */
166 .elseif \segs >= 4
167         movl    $0x06060606, \reg /* WB IO type */
168 .endif
169 .endm
170
171 /*
172  * carsize is the cache size in bytes we want to use for CAR.
173  * windowoffset is the 32k-aligned window into CAR size.
174  */
175 .macro simplemask carsize, windowoffset
176         .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
177         extractmask gas_bug_workaround, %eax
178         .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
179         extractmask gas_bug_workaround, %edx
180         /*
181          * Without the gas bug workaround, the entire macro would consist
182          * only of the two lines below:
183          *   extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
184          *   extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
185          */
186 .endm
187
188 #if CacheSize > 0x10000
189 #error Invalid CAR size, must be at most 64k.
190 #endif
191 #if CacheSize < 0x1000
192 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
193 #endif
194 #if (CacheSize & (0x1000 - 1))
195 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
196 #endif
197
198 #if CacheSize > 0x8000
199         /* Enable caching for 32K-64K using fixed MTRR. */
200         movl    $MTRRfix4K_C0000_MSR, %ecx
201         simplemask CacheSize, 0x8000
202         wrmsr
203 #endif
204
205         /* Enable caching for 0-32K using fixed MTRR. */
206         movl    $MTRRfix4K_C8000_MSR, %ecx
207         simplemask CacheSize, 0
208         wrmsr
209
210 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
211
212 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
213 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
214 #else
215 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
216 #endif
217
218         /*
219          * Enable write base caching so we can do execute in place (XIP)
220          * on the flash ROM.
221          */
222         movl    $MTRRphysBase_MSR(1), %ecx
223         xorl    %edx, %edx
224         movl    $(REAL_XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
225         wrmsr
226
227         movl    $MTRRphysMask_MSR(1), %ecx
228         movl    $0x0000000f, %edx
229         movl    $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
230         wrmsr
231 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
232
233         /* Enable cache. */
234         movl    %cr0, %eax
235         andl    $(~((1 << 30) | (1 << 29))), %eax
236         movl    %eax, %cr0
237
238         /* Read the range with lodsl. */
239         movl    $CacheBase, %esi
240         cld
241         movl    $(CacheSize >> 2), %ecx
242         rep     lodsl
243
244         /* Clear the range. */
245         movl    $CacheBase, %edi
246         movl    $(CacheSize >> 2), %ecx
247         xorl    %eax, %eax
248         rep     stosl
249
250 #if 0
251         /* Check the cache as ram. */
252         movl    $CacheBase, %esi
253         movl    $(CacheSize >> 2), %ecx
254 .xin1:
255         movl    %esi, %eax
256         movl    %eax, (%esi)
257         decl    %ecx
258         je      .xout1
259         add     $4, %esi
260         jmp     .xin1
261 .xout1:
262
263         movl    $CacheBase, %esi
264         // movl $(CacheSize >> 2), %ecx
265         movl    $4, %ecx
266 .xin1x:
267         movl    %esi, %eax
268
269         movl    $0x4000, %edx
270         movb    %ah, %al
271 .testx1:
272         outb    %al, $0x80
273         decl    %edx
274         jnz     .testx1
275
276         movl    (%esi), %eax
277         cmpb    0xff, %al
278         je      .xin2   /* Don't show. */
279
280         movl    $0x4000, %edx
281 .testx2:
282         outb    %al, $0x80
283         decl    %edx
284         jnz     .testx2
285
286 .xin2:
287         decl    %ecx
288         je      .xout1x
289         add     $4, %esi
290         jmp     .xin1x
291 .xout1x:
292 #endif
293
294         movl    $(CacheBase + CacheSize - 4), %eax
295         movl    %eax, %esp
296 lout:
297         /* Restore the BIST result. */
298         movl    %ebp, %eax
299
300         /* We need to set EBP? No need. */
301         movl    %esp, %ebp
302         pushl   %eax  /* BIST */
303         call    main
304
305         /* We don't need CAR from now on. */
306
307         /* Disable cache. */
308         movl    %cr0, %eax
309         orl     $(1 << 30), %eax
310         movl    %eax, %cr0
311
312         /* Clear sth. */
313         movl    $MTRRfix4K_C8000_MSR, %ecx
314         xorl    %edx, %edx
315         xorl    %eax, %eax
316         wrmsr
317
318 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
319         movl    $MTRRfix4K_C0000_MSR, %ecx
320         wrmsr
321 #endif
322
323         /*
324          * Set the default memory type and disable fixed
325          * and enable variable MTRRs.
326          */
327         movl    $MTRRdefType_MSR, %ecx
328         xorl    %edx, %edx
329         movl    $0x00000800, %eax /* Enable variable and disable fixed MTRRs. */
330         wrmsr
331
332         /* Enable cache. */
333         movl    %cr0, %eax
334         andl    $(~((1 << 30) | (1 << 29))), %eax
335         movl    %eax, %cr0
336
337         /* Clear boot_complete flag. */
338         xorl    %ebp, %ebp
339 __main:
340         post_code(0x11)
341         cld                     /* Clear direction flag. */
342
343         movl    %ebp, %esi
344
345         movl    $ROMSTAGE_STACK, %esp
346         movl    %esp, %ebp
347         pushl   %esi
348         call    copy_and_run
349
350 .Lhlt:
351         post_code(0xee)
352         hlt
353         jmp     .Lhlt
354