Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 1 | /* |
Stefan Reinauer | 7e61e45 | 2008-01-18 10:35:56 +0000 | [diff] [blame] | 2 | * This file is part of the coreboot project. |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 3 | * |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 4 | * Copyright (C) 2005-2007 Advanced Micro Devices, Inc. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 5 | * Copyright (C) 2008 Carl-Daniel Hailfinger |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 6 | * |
| 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. |
| 10 | * |
| 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. |
| 15 | * |
| 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 |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 21 | #include <cpu/x86/mtrr.h> |
| 22 | #include <cpu/amd/mtrr.h> |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 23 | |
| 24 | #define CacheSize CONFIG_DCACHE_RAM_SIZE |
| 25 | #define CacheBase (0xd0000 - CacheSize) |
| 26 | |
| 27 | /* Leave some space for global variable to pass to RAM stage. */ |
| 28 | #define GlobalVarSize CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE |
| 29 | |
| 30 | /* For CAR with Fam10h. */ |
| 31 | #define CacheSizeAPStack 0x400 /* 1K */ |
| 32 | |
| 33 | #define MSR_MCFG_BASE 0xC0010058 |
| 34 | #define MSR_FAM10 0xC001102A |
| 35 | |
| 36 | #define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x |
| 37 | |
| 38 | #define CPUID_MASK 0x0ff00f00 |
| 39 | #define CPUID_VAL_FAM10_ROTATED 0x0f000010 |
| 40 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 41 | /* |
Stefan Reinauer | 6f57b51 | 2010-07-08 16:41:05 +0000 | [diff] [blame] | 42 | * XMM map: |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 43 | * xmm1: CPU family |
| 44 | * xmm2: Fam10h comparison value |
| 45 | * xmm3: Backup EBX |
Stefan Reinauer | 6f57b51 | 2010-07-08 16:41:05 +0000 | [diff] [blame] | 46 | */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 47 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 48 | /* Save the BIST result. */ |
| 49 | movl %eax, %ebp |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 50 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 51 | /* |
| 52 | * For normal part %ebx already contain cpu_init_detected |
| 53 | * from fallback call. |
| 54 | */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 55 | |
Stefan Reinauer | 806e146 | 2005-12-01 10:54:44 +0000 | [diff] [blame] | 56 | cache_as_ram_setup: |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 57 | post_code(0xa0) |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 58 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 59 | /* Enable SSE. */ |
| 60 | movl %cr4, %eax |
| 61 | orl $(3 << 9), %eax |
| 62 | movl %eax, %cr4 |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 63 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 64 | /* Figure out the CPU family. */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 65 | cvtsi2sd %ebx, %xmm3 |
| 66 | movl $0x01, %eax |
| 67 | cpuid |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 68 | /* Base family is bits 8..11, extended family is bits 20..27. */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 69 | andl $CPUID_MASK, %eax |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 70 | /* Reorder bits for easier comparison by value. */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 71 | roll $0x10, %eax |
| 72 | cvtsi2sd %eax, %xmm1 |
| 73 | movl $CPUID_VAL_FAM10_ROTATED, %eax |
| 74 | cvtsi2sd %eax, %xmm2 |
| 75 | cvtsd2si %xmm3, %ebx |
| 76 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 77 | /* Check if cpu_init_detected. */ |
Ronald G. Minnich | fb0a64b | 2005-11-23 21:01:08 +0000 | [diff] [blame] | 78 | movl $MTRRdefType_MSR, %ecx |
| 79 | rdmsr |
Stefan Reinauer | 139e6f9 | 2011-04-14 20:06:30 +0000 | [diff] [blame] | 80 | andl $MTRRdefTypeEn, %eax |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 81 | movl %eax, %ebx /* We store the status. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 82 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 83 | jmp_if_k8(CAR_FAM10_out_post_errata) |
| 84 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 85 | /* |
| 86 | * For GH, CAR need to set DRAM Base/Limit registers to direct that |
| 87 | * to node0. |
| 88 | * Only BSP needed, for other nodes set during HT/memory init. |
| 89 | * So we need to check if it is BSP. |
| 90 | */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 91 | movl $0x1b, %ecx |
| 92 | rdmsr |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 93 | bt $8, %eax /* BSP */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 94 | jnc CAR_FAM10_out |
| 95 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 96 | /* Enable RT tables on BSP. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 97 | movl $0x8000c06c, %eax |
| 98 | movw $0xcf8, %dx |
| 99 | outl %eax, %dx |
| 100 | addw $4, %dx |
| 101 | inl %dx, %eax |
| 102 | btr $0, %eax |
| 103 | outl %eax, %dx |
| 104 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 105 | /* Setup temporary DRAM map: [0,16M) bit 0-23. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 106 | movl $0x8000c144, %eax |
| 107 | movw $0xcf8, %dx |
| 108 | outl %eax, %dx |
| 109 | addw $4, %dx |
| 110 | movl $0, %eax |
| 111 | outl %eax, %dx |
| 112 | |
| 113 | movl $0x8000c140, %eax |
| 114 | movw $0xcf8, %dx |
| 115 | outl %eax, %dx |
| 116 | addw $4, %dx |
| 117 | movl $3, %eax |
| 118 | outl %eax, %dx |
| 119 | |
| 120 | CAR_FAM10_out: |
| 121 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 122 | /* |
| 123 | * Errata 193: Disable clean copybacks to L3 cache to allow cached ROM. |
| 124 | * Re-enable it in after RAM is initialized and before CAR is disabled. |
Stefan Reinauer | 6f57b51 | 2010-07-08 16:41:05 +0000 | [diff] [blame] | 125 | */ |
Arne Georg Gleditsch | e7a5b76 | 2010-09-13 15:11:35 +0000 | [diff] [blame] | 126 | movl $MSR_FAM10, %ecx |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 127 | rdmsr |
| 128 | bts $15, %eax |
| 129 | wrmsr |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 130 | |
Marco Schmidt | c263b44 | 2009-06-06 11:21:52 +0000 | [diff] [blame] | 131 | /* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */ |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 132 | movl $MSR_FAM10, %ecx |
Marco Schmidt | c263b44 | 2009-06-06 11:21:52 +0000 | [diff] [blame] | 133 | rdmsr |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 134 | bts $35-32, %edx /* Set bit 35 in EDX:EAX (bit 3 in EDX). */ |
Marco Schmidt | c263b44 | 2009-06-06 11:21:52 +0000 | [diff] [blame] | 135 | wrmsr |
| 136 | |
Myles Watson | 2b28614 | 2010-09-13 17:46:13 +0000 | [diff] [blame] | 137 | #if CONFIG_MMCONF_SUPPORT |
Scott Duplichan | bda153b | 2010-10-19 21:08:11 +0000 | [diff] [blame] | 138 | #if (CONFIG_MMCONF_BASE_ADDRESS > 0xFFFFFFFF) |
| 139 | #error "MMCONF_BASE_ADDRESS too big" |
| 140 | #elif (CONFIG_MMCONF_BASE_ADDRESS & 0xFFFFF) |
| 141 | #error "MMCONF_BASE_ADDRESS not 1MB aligned" |
| 142 | #endif |
| 143 | movl $0, %edx |
| 144 | movl $((CONFIG_MMCONF_BASE_ADDRESS) | (1 << 0)), %eax |
| 145 | #if (CONFIG_MMCONF_BUS_NUMBER == 1) |
| 146 | #elif (CONFIG_MMCONF_BUS_NUMBER == 2) |
| 147 | orl $(1 << 2), %eax |
| 148 | #elif (CONFIG_MMCONF_BUS_NUMBER == 4) |
| 149 | orl $(2 << 2), %eax |
| 150 | #elif (CONFIG_MMCONF_BUS_NUMBER == 8) |
| 151 | orl $(3 << 2), %eax |
| 152 | #elif (CONFIG_MMCONF_BUS_NUMBER == 16) |
| 153 | orl $(4 << 2), %eax |
| 154 | #elif (CONFIG_MMCONF_BUS_NUMBER == 32) |
| 155 | orl $(5 << 2), %eax |
| 156 | #elif (CONFIG_MMCONF_BUS_NUMBER == 64) |
| 157 | orl $(6 << 2), %eax |
| 158 | #elif (CONFIG_MMCONF_BUS_NUMBER == 128) |
| 159 | orl $(7 << 2), %eax |
| 160 | #elif (CONFIG_MMCONF_BUS_NUMBER == 256) |
| 161 | orl $(8 << 2), %eax |
| 162 | #else |
| 163 | #error "bad MMCONF_BUS_NUMBER value" |
| 164 | #endif |
| 165 | movl $(0xc0010058), %ecx |
Arne Georg Gleditsch | e7a5b76 | 2010-09-13 15:11:35 +0000 | [diff] [blame] | 166 | wrmsr |
| 167 | #endif |
| 168 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 169 | CAR_FAM10_out_post_errata: |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 170 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 171 | /* Set MtrrFixDramModEn for clear fixed MTRR. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 172 | enable_fixed_mtrr_dram_modify: |
| 173 | movl $SYSCFG_MSR, %ecx |
| 174 | rdmsr |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 175 | andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 176 | orl $SYSCFG_MSR_MtrrFixDramModEn, %eax |
| 177 | wrmsr |
| 178 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 179 | /* Clear all MTRRs. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 180 | xorl %edx, %edx |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 181 | movl $all_mtrr_msrs, %esi |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 182 | |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 183 | clear_fixed_var_mtrr: |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 184 | lodsl (%esi), %eax |
| 185 | testl %eax, %eax |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 186 | jz clear_fixed_var_mtrr_out |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 187 | |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 188 | movl %eax, %ecx |
| 189 | xorl %eax, %eax |
| 190 | wrmsr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 191 | |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 192 | jmp clear_fixed_var_mtrr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 193 | clear_fixed_var_mtrr_out: |
| 194 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 195 | /* |
| 196 | * 0x06 is the WB IO type for a given 4k segment. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 197 | * 0x1e is the MEM IO type for a given 4k segment (K10 and above). |
| 198 | * segs is the number of 4k segments in the area of the particular |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 199 | * register we want to use for CAR. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 200 | * reg is the register where the IO type should be stored. |
| 201 | */ |
| 202 | .macro extractmask segs, reg |
| 203 | .if \segs <= 0 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 204 | /* |
| 205 | * The xorl here is superfluous because at the point of first execution |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 206 | * of this macro, %eax and %edx are cleared. Later invocations of this |
| 207 | * macro will have a monotonically increasing segs parameter. |
| 208 | */ |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 209 | xorl \reg, \reg |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 210 | .else |
| 211 | jmp_if_k8(1f) |
| 212 | |
| 213 | .if \segs == 1 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 214 | movl $0x1e000000, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 215 | .elseif \segs == 2 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 216 | movl $0x1e1e0000, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 217 | .elseif \segs == 3 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 218 | movl $0x1e1e1e00, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 219 | .elseif \segs >= 4 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 220 | movl $0x1e1e1e1e, \reg /* WB MEM type */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 221 | .endif |
| 222 | jmp 2f |
| 223 | 1: |
| 224 | .if \segs == 1 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 225 | movl $0x06000000, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 226 | .elseif \segs == 2 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 227 | movl $0x06060000, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 228 | .elseif \segs == 3 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 229 | movl $0x06060600, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 230 | .elseif \segs >= 4 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 231 | movl $0x06060606, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 232 | .endif |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 233 | 2: |
| 234 | .endif /* if \segs <= 0 */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 235 | .endm |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 236 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 237 | /* |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 238 | * carsize is the cache size in bytes we want to use for CAR. |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 239 | * windowoffset is the 32k-aligned window into CAR size. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 240 | */ |
| 241 | .macro simplemask carsize, windowoffset |
Carl-Daniel Hailfinger | ed8dc58 | 2008-01-10 17:59:25 +0000 | [diff] [blame] | 242 | .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4) |
| 243 | extractmask gas_bug_workaround, %eax |
| 244 | .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000)) |
| 245 | extractmask gas_bug_workaround, %edx |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 246 | /* |
| 247 | * Without the gas bug workaround, the entire macro would consist |
| 248 | * only of the two lines below: |
| 249 | * extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax |
| 250 | * extractmask (((\carsize - \windowoffset) / 0x1000)), %edx |
| 251 | */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 252 | .endm |
| 253 | |
| 254 | #if CacheSize > 0x10000 |
| 255 | #error Invalid CAR size, must be at most 64k. |
| 256 | #endif |
| 257 | #if CacheSize < 0x1000 |
| 258 | #error Invalid CAR size, must be at least 4k. This is a processor limitation. |
| 259 | #endif |
| 260 | #if (CacheSize & (0x1000 - 1)) |
| 261 | #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation. |
Yinghai Lu | d4b278c | 2006-10-04 20:46:15 +0000 | [diff] [blame] | 262 | #endif |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 263 | |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 264 | #if CacheSize > 0x8000 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 265 | /* Enable caching for 32K-64K using fixed MTRR. */ |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 266 | movl $MTRRfix4K_C0000_MSR, %ecx |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 267 | simplemask CacheSize, 0x8000 |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 268 | wrmsr |
Yinghai Lu | d4b278c | 2006-10-04 20:46:15 +0000 | [diff] [blame] | 269 | #endif |
| 270 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 271 | /* Enable caching for 0-32K using fixed MTRR. */ |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 272 | movl $MTRRfix4K_C8000_MSR, %ecx |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 273 | simplemask CacheSize, 0 |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 274 | wrmsr |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 275 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 276 | /* Enable memory access for first MBs using top_mem. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 277 | movl $TOP_MEM, %ecx |
| 278 | xorl %edx, %edx |
Myles Watson | 0f61a4f | 2009-10-16 16:32:57 +0000 | [diff] [blame] | 279 | movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 280 | wrmsr |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 281 | |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 282 | #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE) |
Rudolf Marek | 95c50c6 | 2010-01-05 17:35:44 +0000 | [diff] [blame] | 283 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 284 | /* Enable write base caching so we can do execute in place (XIP) |
| 285 | * on the flash ROM. |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 286 | */ |
| 287 | movl $MTRRphysBase_MSR(1), %ecx |
| 288 | xorl %edx, %edx |
Uwe Hermann | 36455aa | 2010-10-02 20:51:29 +0000 | [diff] [blame] | 289 | /* |
Patrick Georgi | 1da1046 | 2011-10-28 20:28:03 +0200 | [diff] [blame] | 290 | * IMPORTANT: The following calculation _must_ be done at runtime. See |
Uwe Hermann | 36455aa | 2010-10-02 20:51:29 +0000 | [diff] [blame] | 291 | * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html |
| 292 | */ |
Patrick Georgi | 1da1046 | 2011-10-28 20:28:03 +0200 | [diff] [blame] | 293 | movl copy_and_run, %eax |
| 294 | andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax |
| 295 | orl $MTRR_TYPE_WRBACK, %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 296 | wrmsr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 297 | |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 298 | movl $MTRRphysMask_MSR(1), %ecx |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 299 | movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 300 | jmp_if_k8(wbcache_post_fam10_setup) |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 301 | movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 302 | wbcache_post_fam10_setup: |
Stefan Reinauer | 139e6f9 | 2011-04-14 20:06:30 +0000 | [diff] [blame] | 303 | movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 304 | wrmsr |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 305 | #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 306 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 307 | /* Set the default memory type and enable fixed and variable MTRRs. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 308 | movl $MTRRdefType_MSR, %ecx |
| 309 | xorl %edx, %edx |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 310 | movl $(MTRRdefTypeEn | MTRRdefTypeFixEn), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 311 | wrmsr |
| 312 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 313 | /* Enable the MTRRs and IORRs in SYSCFG. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 314 | movl $SYSCFG_MSR, %ecx |
| 315 | rdmsr |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 316 | orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 317 | wrmsr |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 318 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 319 | post_code(0xa1) |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 320 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 321 | /* Enable cache. */ |
| 322 | movl %cr0, %eax |
| 323 | andl $(~((1 << 30) | (1 << 29))), %eax |
| 324 | movl %eax, %cr0 |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 325 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 326 | jmp_if_k8(fam10_end_part1) |
| 327 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 328 | /* So we need to check if it is BSP. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 329 | movl $0x1b, %ecx |
| 330 | rdmsr |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 331 | bt $8, %eax /* BSP */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 332 | jnc CAR_FAM10_ap |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 333 | fam10_end_part1: |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 334 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 335 | post_code(0xa2) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 336 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 337 | /* Read the range with lodsl. */ |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 338 | cld |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 339 | movl $CacheBase, %esi |
| 340 | movl $(CacheSize >> 2), %ecx |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 341 | rep lodsl |
| 342 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 343 | /* Clear the range. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 344 | movl $CacheBase, %edi |
| 345 | movl $(CacheSize >> 2), %ecx |
| 346 | xorl %eax, %eax |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 347 | rep stosl |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 348 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 349 | /* Set up the stack pointer. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 350 | movl $(CacheBase + CacheSize - GlobalVarSize), %eax |
| 351 | movl %eax, %esp |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 352 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 353 | post_code(0xa3) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 354 | |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 355 | jmp CAR_FAM10_ap_out |
| 356 | CAR_FAM10_ap: |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 357 | /* |
| 358 | * Need to set stack pointer for AP. |
| 359 | * It will be from: |
| 360 | * CacheBase + (CacheSize - GlobalVarSize) / 2 |
| 361 | * - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack |
| 362 | * So need to get the NodeID and CoreID at first. |
| 363 | * If NB_CFG bit 54 is set just use initial APIC ID, otherwise need |
| 364 | * to reverse it. |
| 365 | */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 366 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 367 | /* Store our init detected. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 368 | movl %ebx, %esi |
| 369 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 370 | /* Get the coreid bits at first. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 371 | movl $0x80000008, %eax |
| 372 | cpuid |
| 373 | shrl $12, %ecx |
| 374 | andl $0x0f, %ecx |
| 375 | movl %ecx, %edi |
| 376 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 377 | /* Get the initial APIC ID. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 378 | movl $1, %eax |
| 379 | cpuid |
| 380 | shrl $24, %ebx |
| 381 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 382 | /* Get the nb cfg bit 54. */ |
| 383 | movl $0xc001001f, %ecx /* NB_CFG_MSR */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 384 | rdmsr |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 385 | movl %edi, %ecx /* CoreID bits */ |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 386 | bt $(54 - 32), %edx |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 387 | jc roll_cfg |
| 388 | rolb %cl, %bl |
| 389 | roll_cfg: |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 390 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 391 | /* Calculate stack pointer. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 392 | movl $CacheSizeAPStack, %eax |
| 393 | mull %ebx |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 394 | movl $(CacheBase + (CacheSize - GlobalVarSize) / 2), %esp |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 395 | subl %eax, %esp |
| 396 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 397 | /* Retrive init detected. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 398 | movl %esi, %ebx |
| 399 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 400 | post_code(0xa4) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 401 | |
| 402 | CAR_FAM10_ap_out: |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 403 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 404 | post_code(0xa5) |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 405 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 406 | /* Disable SSE. */ |
| 407 | movl %cr4, %eax |
| 408 | andl $~(3 << 9), %eax |
| 409 | movl %eax, %cr4 |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 410 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 411 | /* Restore the BIST result. */ |
| 412 | movl %ebp, %eax |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 413 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 414 | /* We need to set EBP? No need. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 415 | movl %esp, %ebp |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 416 | pushl %ebx /* Init detected. */ |
| 417 | pushl %eax /* BIST */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 418 | call cache_as_ram_main |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 419 | /* We will not go back. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 420 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 421 | post_code(0xaf) /* Should never see this POST code. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 422 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 423 | all_mtrr_msrs: |
| 424 | /* fixed MTRR MSRs */ |
| 425 | .long MTRRfix64K_00000_MSR |
| 426 | .long MTRRfix16K_80000_MSR |
| 427 | .long MTRRfix16K_A0000_MSR |
| 428 | .long MTRRfix4K_C0000_MSR |
| 429 | .long MTRRfix4K_C8000_MSR |
| 430 | .long MTRRfix4K_D0000_MSR |
| 431 | .long MTRRfix4K_D8000_MSR |
| 432 | .long MTRRfix4K_E0000_MSR |
| 433 | .long MTRRfix4K_E8000_MSR |
| 434 | .long MTRRfix4K_F0000_MSR |
| 435 | .long MTRRfix4K_F8000_MSR |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 436 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 437 | /* var MTRR MSRs */ |
| 438 | .long MTRRphysBase_MSR(0) |
| 439 | .long MTRRphysMask_MSR(0) |
| 440 | .long MTRRphysBase_MSR(1) |
| 441 | .long MTRRphysMask_MSR(1) |
| 442 | .long MTRRphysBase_MSR(2) |
| 443 | .long MTRRphysMask_MSR(2) |
| 444 | .long MTRRphysBase_MSR(3) |
| 445 | .long MTRRphysMask_MSR(3) |
| 446 | .long MTRRphysBase_MSR(4) |
| 447 | .long MTRRphysMask_MSR(4) |
| 448 | .long MTRRphysBase_MSR(5) |
| 449 | .long MTRRphysMask_MSR(5) |
| 450 | .long MTRRphysBase_MSR(6) |
| 451 | .long MTRRphysMask_MSR(6) |
| 452 | .long MTRRphysBase_MSR(7) |
| 453 | .long MTRRphysMask_MSR(7) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 454 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 455 | /* Variable IORR MTRR MSRs */ |
| 456 | .long IORRBase_MSR(0) |
| 457 | .long IORRMask_MSR(0) |
| 458 | .long IORRBase_MSR(1) |
| 459 | .long IORRMask_MSR(1) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 460 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 461 | /* Top of memory MTRR MSRs */ |
| 462 | .long TOP_MEM_MSR |
| 463 | .long TOP_MEM2_MSR |
| 464 | |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 465 | .long 0x000 /* NULL, end of table */ |
| 466 | |
Stefan Reinauer | 806e146 | 2005-12-01 10:54:44 +0000 | [diff] [blame] | 467 | cache_as_ram_setup_out: |