2 * This file is part of the LinuxBIOS project.
4 * Copyright (C) 2005-2007 Advanced Micro Devices, Inc.
5 * Copyright (C) 2008 Carl-Daniel Hailfinger
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #define CacheSize DCACHE_RAM_SIZE
22 #define CacheBase (0xd0000 - CacheSize)
24 /* leave some space for global variable to pass to RAM stage */
25 #define GlobalVarSize DCACHE_RAM_GLOBAL_VAR_SIZE
28 #define CacheSizeAPStack 0x400 /* 1K */
31 #include <cpu/x86/mtrr.h>
32 #include <cpu/amd/mtrr.h>
34 /* Save the BIST result */
37 /*for normal part %ebx already contain cpu_init_detected from fallback call */
44 /* hope we can skip the double set for normal part */
45 #if ((HAVE_FAILOVER_BOOT == 1) && (USE_FAILOVER_IMAGE == 1)) || ((HAVE_FAILOVER_BOOT == 0) && (USE_FALLBACK_IMAGE == 1))
47 /* check if cpu_init_detected */
48 movl $MTRRdefType_MSR, %ecx
51 movl %eax, %ebx /* We store the status */
54 /* for GH, CAR need to set DRAM Base/Limit Registers to direct that to node0 */
56 /* Only BSP needed, for other nodes set during HT/memory init. */
57 /* So we need to check if it is BSP */
63 /* Enable RT tables on BSP */
64 movl $0x8000c06c, %eax
72 /* Setup temporary DRAM map: [0,16M) bit 0-23 */
73 movl $0x8000c144, %eax
80 movl $0x8000c140, %eax
92 /* Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
93 Re-enable it in after RAM is initialized and before CAR is disabled */
94 movl $0xc001102a, %ecx
100 /* Set MtrrFixDramModEn for clear fixed mtrr */
101 enable_fixed_mtrr_dram_modify:
102 movl $SYSCFG_MSR, %ecx
104 andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax
105 orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
108 /* Clear all MTRRs */
110 movl $fixed_mtrr_msr, %esi
112 clear_fixed_var_mtrr:
115 jz clear_fixed_var_mtrr_out
121 jmp clear_fixed_var_mtrr
122 clear_fixed_var_mtrr_out:
124 /* 0x06 is the WB IO type for a given 4k segment.
125 * 0x1e is the MEM IO type for a given 4k segment (K10 and above).
126 * segs is the number of 4k segments in the area of the particular
127 * register we want to use for CAR.
128 * reg is the register where the IO type should be stored.
130 .macro extractmask segs, reg
132 /* The xorl here is superfluous because at the point of first execution
133 * of this macro, %eax and %edx are cleared. Later invocations of this
134 * macro will have a monotonically increasing segs parameter.
139 movl $0x1e000000, \reg /* WB MEM type */
141 movl $0x1e1e0000, \reg /* WB MEM type */
143 movl $0x1e1e1e00, \reg /* WB MEM type */
145 movl $0x1e1e1e1e, \reg /* WB MEM type */
148 movl $0x06000000, \reg /* WB IO type */
150 movl $0x06060000, \reg /* WB IO type */
152 movl $0x06060600, \reg /* WB IO type */
154 movl $0x06060606, \reg /* WB IO type */
159 /* size is the cache size in bytes we want to use for CAR.
160 * windowoffset is the 32k-aligned window into CAR size
162 .macro simplemask carsize, windowoffset
163 extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
164 extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
167 #if CacheSize > 0x10000
168 #error Invalid CAR size, must be at most 64k.
170 #if CacheSize < 0x1000
171 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
173 #if (CacheSize & (0x1000 - 1))
174 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
177 #if CacheSize > 0x8000
178 /* enable caching for 32K-64K using fixed mtrr */
179 movl $0x268, %ecx /* fix4k_c0000*/
180 simplemask CacheSize, 0x8000
184 /* enable caching for 0-32K using fixed mtrr */
185 movl $0x269, %ecx /* fix4k_c8000*/
186 simplemask CacheSize, 0
189 /* enable memory access for first MBs using top_mem */
192 movl $(((CONFIG_LB_MEM_TOPK << 10) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
194 #endif /* USE_FAILOVER_IMAGE == 1*/
197 #if ((HAVE_FAILOVER_BOOT == 1) && (USE_FAILOVER_IMAGE == 0)) || ((HAVE_FAILOVER_BOOT == 0) && (USE_FALLBACK_IMAGE == 0))
205 #if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
206 /* enable write base caching so we can do execute in place
211 movl $(XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
215 movl $((1 << (CPU_ADDR_BITS - 32)) - 1), %edx /* AMD 40 bit for K8, 48 bit for GH */
216 movl $(~(XIP_ROM_SIZE - 1) | 0x800), %eax
218 #endif /* XIP_ROM_SIZE && XIP_ROM_BASE */
220 #if ((HAVE_FAILOVER_BOOT == 1) && (USE_FAILOVER_IMAGE == 1)) || ((HAVE_FAILOVER_BOOT == 0) && (USE_FALLBACK_IMAGE == 1))
221 /* Set the default memory type and enable fixed and variable MTRRs */
222 movl $MTRRdefType_MSR, %ecx
224 /* Enable Variable and Fixed MTRRs */
225 movl $0x00000c00, %eax
228 /* Enable the MTRRs and IORRs in SYSCFG */
229 movl $SYSCFG_MSR, %ecx
231 orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
240 andl $0x9fffffff, %eax
245 /* So we need to check if it is BSP */
255 #if ((HAVE_FAILOVER_BOOT == 1) && (USE_FAILOVER_IMAGE == 1)) || ((HAVE_FAILOVER_BOOT == 0) && (USE_FALLBACK_IMAGE == 1))
256 /* Read the range with lodsl*/
258 movl $CacheBase, %esi
259 movl $(CacheSize >> 2), %ecx
261 /* Clear the range */
262 movl $CacheBase, %edi
263 movl $(CacheSize >> 2), %ecx
267 #endif /*USE_FAILOVER_IMAGE == 1*/
269 /* set up the stack pointer */
270 movl $(CacheBase + CacheSize - GlobalVarSize), %eax
280 /* need to set stack pointer for AP */
281 /* it will be from CacheBase + (CacheSize - GlobalVarSize)/2 - (NodeID<<CoreIDbits + CoreID) * CacheSizeAPStack*/
282 /* So need to get the NodeID and CoreID at first */
283 /* If NB_CFG bit 54 is set just use initial apicid, otherwise need to reverse it */
285 /* store our init detected */
288 /* get the coreid bits at first */
289 movl $0x80000008, %eax
295 /* get the initial apic id */
300 /* get the nb cfg bit 54 */
301 movl $0xc001001f, %ecx /* NB_CFG_MSR */
303 movl %edi, %ecx /* CoreID bits */
309 /* calculate stack pointer */
310 movl $CacheSizeAPStack, %eax
312 movl $(CacheBase + (CacheSize - GlobalVarSize)/2), %esp
315 /* retrive init detected */
327 /* Restore the BIST result */
330 /* We need to set ebp ? No need */
332 pushl %ebx /* init detected */
333 pushl %eax /* bist */
334 call cache_as_ram_main
335 /* We will not go back */
337 movb $0xAF, %al /* Should never see this postcode */
341 .long 0x250, 0x258, 0x259
342 .long 0x268, 0x269, 0x26A
343 .long 0x26B, 0x26C, 0x26D
346 .long 0x200, 0x201, 0x202, 0x203
347 .long 0x204, 0x205, 0x206, 0x207
348 .long 0x208, 0x209, 0x20A, 0x20B
349 .long 0x20C, 0x20D, 0x20E, 0x20F
351 .long 0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019
353 .long 0xC001001A, 0xC001001D
354 .long 0x000 /* NULL, end of table */
356 cache_as_ram_setup_out: