fc4eb8ae7401ff1d74b6a043218be20497fbf68c
[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 #include <cpu/x86/post_code.h>
28
29 #define CacheSize               CONFIG_DCACHE_RAM_SIZE
30 #define CacheBase               (0xd0000 - CacheSize)
31
32         /* Save the BIST result. */
33         movl    %eax, %ebp
34
35 CacheAsRam:
36         /* Check whether the processor has HT capability. */
37         movl    $01, %eax
38         cpuid
39         btl     $28, %edx
40         jnc     NotHtProcessor
41         bswapl  %ebx
42         cmpb    $01, %bh
43         jbe     NotHtProcessor
44
45         /*
46          * It is a HT processor. Send SIPI to the other logical processor
47          * within this processor so that the CAR related common system
48          * registers are programmed accordingly.
49          */
50
51         /*
52          * Use some register that is common to both logical processors
53          * as semaphore. Refer Appendix B, Vol.3.
54          */
55         xorl    %eax, %eax
56         xorl    %edx, %edx
57         movl    $MTRRfix64K_00000_MSR, %ecx
58         wrmsr
59
60         /*
61          * Figure out the logical AP's APIC ID; the following logic will
62          * work only for processors with 2 threads.
63          * Refer to Vol 3. Table 7-1 for details about this logic.
64          */
65         movl    $0xFEE00020, %esi
66         movl    (%esi), %ebx
67         andl    $0xFF000000, %ebx
68         bswapl  %ebx
69         btl     $0, %ebx
70         jnc     LogicalAP0
71         andb    $0xFE, %bl
72         jmp     Send_SIPI
73 LogicalAP0:
74         orb     $0x01, %bl
75 Send_SIPI:
76         bswapl  %ebx    /* EBX - logical AP's APIC ID. */
77
78         /*
79          * Fill up the IPI command registers in the Local APIC mapped to
80          * default address and issue SIPI to the other logical processor
81          * within this processor die.
82          */
83 Retry_SIPI:
84         movl    %ebx, %eax
85         movl    $0xFEE00310, %esi
86         movl    %eax, (%esi)
87
88         /* SIPI vector - F900:0000 */
89         movl    $0x000006F9, %eax
90         movl    $0xFEE00300, %esi
91         movl    %eax, (%esi)
92
93         movl    $0x30, %ecx
94 SIPI_Delay:
95         pause
96         decl    %ecx
97         jnz     SIPI_Delay
98
99         movl    (%esi), %eax
100         andl    $0x00001000, %eax
101         jnz     Retry_SIPI
102
103         /* Wait for the Logical AP to complete initialization. */
104 LogicalAP_SIPINotdone:
105         movl    $MTRRfix64K_00000_MSR, %ecx
106         rdmsr
107         orl     %eax, %eax
108         jz      LogicalAP_SIPINotdone
109
110 NotHtProcessor:
111         /* Set the default memory type and enable fixed and variable MTRRs. */
112         movl    $MTRRdefType_MSR, %ecx
113         xorl    %edx, %edx
114         movl    $(MTRRdefTypeEn | MTRRdefTypeFixEn), %eax
115         wrmsr
116
117         /* Clear all MTRRs. */
118         xorl    %edx, %edx
119         movl    $all_mtrr_msrs, %esi
120
121 clear_fixed_var_mtrr:
122         lodsl   (%esi), %eax
123         testl   %eax, %eax
124         jz      clear_fixed_var_mtrr_out
125
126         movl    %eax, %ecx
127         xorl    %eax, %eax
128         wrmsr
129
130         jmp     clear_fixed_var_mtrr
131
132 all_mtrr_msrs:
133         /* fixed MTRR MSRs */
134         .long   MTRRfix64K_00000_MSR
135         .long   MTRRfix16K_80000_MSR
136         .long   MTRRfix16K_A0000_MSR
137         .long   MTRRfix4K_C0000_MSR
138         .long   MTRRfix4K_C8000_MSR
139         .long   MTRRfix4K_D0000_MSR
140         .long   MTRRfix4K_D8000_MSR
141         .long   MTRRfix4K_E0000_MSR
142         .long   MTRRfix4K_E8000_MSR
143         .long   MTRRfix4K_F0000_MSR
144         .long   MTRRfix4K_F8000_MSR
145
146         /* var MTRR MSRs */
147         .long   MTRRphysBase_MSR(0)
148         .long   MTRRphysMask_MSR(0)
149         .long   MTRRphysBase_MSR(1)
150         .long   MTRRphysMask_MSR(1)
151         .long   MTRRphysBase_MSR(2)
152         .long   MTRRphysMask_MSR(2)
153         .long   MTRRphysBase_MSR(3)
154         .long   MTRRphysMask_MSR(3)
155         .long   MTRRphysBase_MSR(4)
156         .long   MTRRphysMask_MSR(4)
157         .long   MTRRphysBase_MSR(5)
158         .long   MTRRphysMask_MSR(5)
159         .long   MTRRphysBase_MSR(6)
160         .long   MTRRphysMask_MSR(6)
161         .long   MTRRphysBase_MSR(7)
162         .long   MTRRphysMask_MSR(7)
163
164         .long   0x000 /* NULL, end of table */
165
166 clear_fixed_var_mtrr_out:
167
168 /*
169  * 0x06 is the WB IO type for a given 4k segment.
170  * segs is the number of 4k segments in the area of the particular
171  *      register we want to use for CAR.
172  * reg  is the register where the IO type should be stored.
173  */
174 .macro extractmask segs, reg
175 .if \segs <= 0
176         /*
177          * The xorl here is superfluous because at the point of first execution
178          * of this macro, %eax and %edx are cleared. Later invocations of this
179          * macro will have a monotonically increasing segs parameter.
180          */
181         xorl \reg, \reg
182 .elseif \segs == 1
183         movl    $0x06000000, \reg /* WB IO type */
184 .elseif \segs == 2
185         movl    $0x06060000, \reg /* WB IO type */
186 .elseif \segs == 3
187         movl    $0x06060600, \reg /* WB IO type */
188 .elseif \segs >= 4
189         movl    $0x06060606, \reg /* WB IO type */
190 .endif
191 .endm
192
193 /*
194  * carsize is the cache size in bytes we want to use for CAR.
195  * windowoffset is the 32k-aligned window into CAR size.
196  */
197 .macro simplemask carsize, windowoffset
198         .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
199         extractmask gas_bug_workaround, %eax
200         .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
201         extractmask gas_bug_workaround, %edx
202         /*
203          * Without the gas bug workaround, the entire macro would consist
204          * only of the two lines below:
205          *   extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
206          *   extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
207          */
208 .endm
209
210 #if CacheSize > 0x10000
211 #error Invalid CAR size, must be at most 64k.
212 #endif
213 #if CacheSize < 0x1000
214 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
215 #endif
216 #if (CacheSize & (0x1000 - 1))
217 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
218 #endif
219
220 #if CacheSize > 0x8000
221         /* Enable caching for 32K-64K using fixed MTRR. */
222         movl    $MTRRfix4K_C0000_MSR, %ecx
223         simplemask CacheSize, 0x8000
224         wrmsr
225 #endif
226
227         /* Enable caching for 0-32K using fixed MTRR. */
228         movl    $MTRRfix4K_C8000_MSR, %ecx
229         simplemask CacheSize, 0
230         wrmsr
231
232 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
233
234 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
235 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
236 #else
237 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
238 #endif
239
240         /*
241          * Enable write base caching so we can do execute in place (XIP)
242          * on the flash ROM.
243          */
244         movl    $MTRRphysBase_MSR(1), %ecx
245         xorl    %edx, %edx
246         /*
247          * IMPORTANT: The two lines below can _not_ be written like this:
248          *   movl $(REAL_XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
249          * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
250          */
251         movl    $REAL_XIP_ROM_BASE, %eax
252         orl     $MTRR_TYPE_WRBACK, %eax
253         wrmsr
254
255         movl    $MTRRphysMask_MSR(1), %ecx
256         movl    $0x0000000f, %edx
257         movl    $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
258         wrmsr
259 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
260
261         /* Enable cache. */
262         movl    %cr0, %eax
263         andl    $(~((1 << 30) | (1 << 29))), %eax
264         movl    %eax, %cr0
265
266         /* Read the range with lodsl. */
267         movl    $CacheBase, %esi
268         cld
269         movl    $(CacheSize >> 2), %ecx
270         rep     lodsl
271
272         /* Clear the range. */
273         movl    $CacheBase, %edi
274         movl    $(CacheSize >> 2), %ecx
275         xorl    %eax, %eax
276         rep     stosl
277
278 #if 0
279         /* Check the cache as ram. */
280         movl    $CacheBase, %esi
281         movl    $(CacheSize >> 2), %ecx
282 .xin1:
283         movl    %esi, %eax
284         movl    %eax, (%esi)
285         decl    %ecx
286         je      .xout1
287         add     $4, %esi
288         jmp     .xin1
289 .xout1:
290
291         movl    $CacheBase, %esi
292         // movl $(CacheSize >> 2), %ecx
293         movl    $4, %ecx
294 .xin1x:
295         movl    %esi, %eax
296
297         movl    $0x4000, %edx
298         movb    %ah, %al
299 .testx1:
300         outb    %al, $0x80
301         decl    %edx
302         jnz     .testx1
303
304         movl    (%esi), %eax
305         cmpb    0xff, %al
306         je      .xin2   /* Don't show. */
307
308         movl    $0x4000, %edx
309 .testx2:
310         outb    %al, $0x80
311         decl    %edx
312         jnz     .testx2
313
314 .xin2:
315         decl    %ecx
316         je      .xout1x
317         add     $4, %esi
318         jmp     .xin1x
319 .xout1x:
320 #endif
321
322         movl    $(CacheBase + CacheSize - 4), %eax
323         movl    %eax, %esp
324 lout:
325         /* Restore the BIST result. */
326         movl    %ebp, %eax
327
328         /* We need to set EBP? No need. */
329         movl    %esp, %ebp
330         pushl   %eax  /* BIST */
331         call    main
332
333         /* We don't need CAR from now on. */
334
335         /* Disable cache. */
336         movl    %cr0, %eax
337         orl     $(1 << 30), %eax
338         movl    %eax, %cr0
339
340         /* Clear sth. */
341         movl    $MTRRfix4K_C8000_MSR, %ecx
342         xorl    %edx, %edx
343         xorl    %eax, %eax
344         wrmsr
345
346 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
347         movl    $MTRRfix4K_C0000_MSR, %ecx
348         wrmsr
349 #endif
350
351         /*
352          * Set the default memory type and disable fixed
353          * and enable variable MTRRs.
354          */
355         movl    $MTRRdefType_MSR, %ecx
356         xorl    %edx, %edx
357         movl    $MTRRdefTypeEn, %eax /* Enable variable and disable fixed MTRRs. */
358         wrmsr
359
360         /* Enable cache. */
361         movl    %cr0, %eax
362         andl    $(~((1 << 30) | (1 << 29))), %eax
363         movl    %eax, %cr0
364
365         /* Clear boot_complete flag. */
366         xorl    %ebp, %ebp
367 __main:
368         post_code(POST_PREPARE_RAMSTAGE)
369         cld                     /* Clear direction flag. */
370
371         movl    %ebp, %esi
372
373         movl    $ROMSTAGE_STACK, %esp
374         movl    %esp, %ebp
375         pushl   %esi
376         call    copy_and_run
377
378 .Lhlt:
379         post_code(POST_DEAD_CODE)
380         hlt
381         jmp     .Lhlt
382