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