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 |
Timothy Pearson | a97e007 | 2015-06-02 13:53:25 -0500 | [diff] [blame] | 6 | * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU General Public License for more details. |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 16 | */ |
| 17 | |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 18 | #include <cpu/x86/mtrr.h> |
Patrick Georgi | 05e740f | 2012-03-31 12:52:21 +0200 | [diff] [blame] | 19 | #include <cpu/x86/cache.h> |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 20 | #include <cpu/amd/mtrr.h> |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 21 | |
| 22 | #define CacheSize CONFIG_DCACHE_RAM_SIZE |
Timothy Pearson | 1f78099 | 2015-06-01 23:58:59 -0500 | [diff] [blame] | 23 | #define CacheBase CONFIG_DCACHE_RAM_BASE |
Timothy Pearson | b5e4655 | 2015-06-02 13:47:36 -0500 | [diff] [blame] | 24 | #define CacheSizeBSPStack CONFIG_DCACHE_BSP_STACK_SIZE |
Timothy Pearson | fb39f82 | 2015-06-02 20:25:03 -0500 | [diff] [blame] | 25 | #define CacheSizeBSPSlush CONFIG_DCACHE_BSP_STACK_SLUSH |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 26 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 27 | /* For CAR with Fam10h. */ |
Timothy Pearson | b5e4655 | 2015-06-02 13:47:36 -0500 | [diff] [blame] | 28 | #define CacheSizeAPStack CONFIG_DCACHE_AP_STACK_SIZE |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 29 | |
| 30 | #define MSR_MCFG_BASE 0xC0010058 |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 31 | #define MSR_BU_CFG2 0xC001102A |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 32 | |
Timothy Pearson | e67d240 | 2015-10-29 01:09:55 -0500 | [diff] [blame] | 33 | #define jmp_if_not_k8(x) comisd %xmm2, %xmm1; jae x |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 34 | #define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 35 | #define jmp_if_not_fam15h(x) comisd %xmm3, %xmm1; jb x |
| 36 | #define jmp_if_fam15h(x) comisd %xmm3, %xmm1; jae x |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 37 | |
| 38 | #define CPUID_MASK 0x0ff00f00 |
| 39 | #define CPUID_VAL_FAM10_ROTATED 0x0f000010 |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 40 | #define CPUID_VAL_FAM15_ROTATED 0x0f000060 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 41 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 42 | /* |
Stefan Reinauer | 6f57b51 | 2010-07-08 16:41:05 +0000 | [diff] [blame] | 43 | * XMM map: |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 44 | * xmm1: CPU family |
| 45 | * xmm2: Fam10h comparison value |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 46 | * xmm3: Fam15h comparison value |
| 47 | * xmm4: Backup EBX |
| 48 | * xmm5: Coreboot init detect |
Stefan Reinauer | 6f57b51 | 2010-07-08 16:41:05 +0000 | [diff] [blame] | 49 | */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 50 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 51 | /* Save the BIST result. */ |
| 52 | movl %eax, %ebp |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 53 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 54 | /* |
| 55 | * For normal part %ebx already contain cpu_init_detected |
| 56 | * from fallback call. |
| 57 | */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 58 | |
Stefan Reinauer | 806e146 | 2005-12-01 10:54:44 +0000 | [diff] [blame] | 59 | cache_as_ram_setup: |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 60 | post_code(0xa0) |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 61 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 62 | /* Enable SSE. */ |
| 63 | movl %cr4, %eax |
| 64 | orl $(3 << 9), %eax |
| 65 | movl %eax, %cr4 |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 66 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 67 | /* Figure out the CPU family. */ |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 68 | cvtsi2sd %ebx, %xmm4 |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 69 | movl $0x01, %eax |
| 70 | cpuid |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 71 | /* Base family is bits 8..11, extended family is bits 20..27. */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 72 | andl $CPUID_MASK, %eax |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 73 | /* Reorder bits for easier comparison by value. */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 74 | roll $0x10, %eax |
| 75 | cvtsi2sd %eax, %xmm1 |
| 76 | movl $CPUID_VAL_FAM10_ROTATED, %eax |
| 77 | cvtsi2sd %eax, %xmm2 |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 78 | movl $CPUID_VAL_FAM15_ROTATED, %eax |
| 79 | cvtsi2sd %eax, %xmm3 |
| 80 | cvtsd2si %xmm4, %ebx |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 81 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 82 | /* Check if cpu_init_detected. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 83 | movl $MTRR_DEF_TYPE_MSR, %ecx |
Ronald G. Minnich | fb0a64b | 2005-11-23 21:01:08 +0000 | [diff] [blame] | 84 | rdmsr |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 85 | andl $MTRR_DEF_TYPE_EN, %eax |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 86 | movl %eax, %ebx /* We store the status. */ |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 87 | cvtsi2sd %ebx, %xmm5 |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 88 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 89 | jmp_if_k8(CAR_FAM10_out_post_errata) |
| 90 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 91 | /* |
| 92 | * For GH, CAR need to set DRAM Base/Limit registers to direct that |
| 93 | * to node0. |
| 94 | * Only BSP needed, for other nodes set during HT/memory init. |
| 95 | * So we need to check if it is BSP. |
| 96 | */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 97 | movl $0x1b, %ecx |
| 98 | rdmsr |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 99 | bt $8, %eax /* BSP */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 100 | jnc CAR_FAM10_out |
| 101 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 102 | /* Enable RT tables on BSP. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 103 | movl $0x8000c06c, %eax |
| 104 | movw $0xcf8, %dx |
| 105 | outl %eax, %dx |
| 106 | addw $4, %dx |
| 107 | inl %dx, %eax |
| 108 | btr $0, %eax |
| 109 | outl %eax, %dx |
| 110 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 111 | /* Setup temporary DRAM map: [0,16M) bit 0-23. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 112 | movl $0x8000c144, %eax |
| 113 | movw $0xcf8, %dx |
| 114 | outl %eax, %dx |
| 115 | addw $4, %dx |
| 116 | movl $0, %eax |
| 117 | outl %eax, %dx |
| 118 | |
| 119 | movl $0x8000c140, %eax |
| 120 | movw $0xcf8, %dx |
| 121 | outl %eax, %dx |
| 122 | addw $4, %dx |
| 123 | movl $3, %eax |
| 124 | outl %eax, %dx |
| 125 | |
| 126 | CAR_FAM10_out: |
| 127 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 128 | jmp_if_fam15h(CAR_FAM10_errata_applied) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 129 | /* |
| 130 | * Errata 193: Disable clean copybacks to L3 cache to allow cached ROM. |
| 131 | * 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] | 132 | */ |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 133 | movl $MSR_BU_CFG2, %ecx |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 134 | rdmsr |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 135 | bts $15, %eax /* Set bit 15 in EDX:EAX (bit 15 in EAX). */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 136 | wrmsr |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 137 | |
Marco Schmidt | c263b44 | 2009-06-06 11:21:52 +0000 | [diff] [blame] | 138 | /* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */ |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 139 | movl $MSR_BU_CFG2, %ecx |
Marco Schmidt | c263b44 | 2009-06-06 11:21:52 +0000 | [diff] [blame] | 140 | rdmsr |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 141 | 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] | 142 | wrmsr |
| 143 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 144 | CAR_FAM10_errata_applied: |
| 145 | |
Myles Watson | 2b28614 | 2010-09-13 17:46:13 +0000 | [diff] [blame] | 146 | #if CONFIG_MMCONF_SUPPORT |
Scott Duplichan | bda153b | 2010-10-19 21:08:11 +0000 | [diff] [blame] | 147 | #if (CONFIG_MMCONF_BASE_ADDRESS > 0xFFFFFFFF) |
| 148 | #error "MMCONF_BASE_ADDRESS too big" |
| 149 | #elif (CONFIG_MMCONF_BASE_ADDRESS & 0xFFFFF) |
| 150 | #error "MMCONF_BASE_ADDRESS not 1MB aligned" |
| 151 | #endif |
| 152 | movl $0, %edx |
| 153 | movl $((CONFIG_MMCONF_BASE_ADDRESS) | (1 << 0)), %eax |
| 154 | #if (CONFIG_MMCONF_BUS_NUMBER == 1) |
| 155 | #elif (CONFIG_MMCONF_BUS_NUMBER == 2) |
| 156 | orl $(1 << 2), %eax |
| 157 | #elif (CONFIG_MMCONF_BUS_NUMBER == 4) |
Patrick Georgi | 472efa6 | 2012-02-16 20:44:20 +0100 | [diff] [blame] | 158 | orl $(2 << 2), %eax |
Scott Duplichan | bda153b | 2010-10-19 21:08:11 +0000 | [diff] [blame] | 159 | #elif (CONFIG_MMCONF_BUS_NUMBER == 8) |
| 160 | orl $(3 << 2), %eax |
| 161 | #elif (CONFIG_MMCONF_BUS_NUMBER == 16) |
| 162 | orl $(4 << 2), %eax |
| 163 | #elif (CONFIG_MMCONF_BUS_NUMBER == 32) |
| 164 | orl $(5 << 2), %eax |
| 165 | #elif (CONFIG_MMCONF_BUS_NUMBER == 64) |
| 166 | orl $(6 << 2), %eax |
| 167 | #elif (CONFIG_MMCONF_BUS_NUMBER == 128) |
| 168 | orl $(7 << 2), %eax |
| 169 | #elif (CONFIG_MMCONF_BUS_NUMBER == 256) |
| 170 | orl $(8 << 2), %eax |
| 171 | #else |
| 172 | #error "bad MMCONF_BUS_NUMBER value" |
| 173 | #endif |
Patrick Georgi | e5760af | 2014-03-30 18:53:12 +0200 | [diff] [blame] | 174 | movl $MSR_MCFG_BASE, %ecx |
Arne Georg Gleditsch | e7a5b76 | 2010-09-13 15:11:35 +0000 | [diff] [blame] | 175 | wrmsr |
| 176 | #endif |
| 177 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 178 | CAR_FAM10_out_post_errata: |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 179 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 180 | /* Fam15h APIC IDs do not depend on NB config bit 54 */ |
| 181 | jmp_if_not_fam15h(skip_nb54_set) |
| 182 | movl $0xc001001f, %ecx /* NB_CFG_MSR */ |
| 183 | rdmsr |
| 184 | bts $(54 - 32), %edx /* Set NB config bit 54 */ |
| 185 | wrmsr |
| 186 | |
| 187 | skip_nb54_set: |
| 188 | /* On Fam15h CPUs each compute unit's MTRRs are shared between two cores */ |
| 189 | jmp_if_not_fam15h(skip_cu_check) |
| 190 | |
| 191 | /* Get the initial APIC ID. */ |
| 192 | movl $1, %eax |
| 193 | cpuid |
| 194 | movl %ebx, %eax |
| 195 | |
| 196 | /* Restore init detect */ |
| 197 | cvtsd2si %xmm5, %ebx |
| 198 | |
| 199 | /* Determine if this is the second core to start in a compute unit; if so, wait for first core start, clear init detect and skip MTRR init */ |
| 200 | bt $24, %eax |
| 201 | jnc skip_cu_check /* First core in the compute unit jumps to skip_cu_check */ |
| 202 | |
| 203 | /* Determine if this is the second core to start in a compute unit; if so, clear init detect and skip MTRR init */ |
| 204 | /* Busywait until the first core sets up the MTRRs */ |
| 205 | check_init_detect_1: |
| 206 | /* Check if cpu_init_detected. */ |
| 207 | movl $MTRR_DEF_TYPE_MSR, %ecx |
| 208 | rdmsr |
| 209 | andl $MTRR_DEF_TYPE_EN, %eax |
| 210 | cmp $0x00000000, %eax |
| 211 | je check_init_detect_1 /* First core has not yet started */ |
| 212 | |
| 213 | check_init_detect_2: |
| 214 | movl $SYSCFG_MSR, %ecx |
| 215 | rdmsr |
| 216 | andl $(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn), %eax |
| 217 | cmp $0x00000000, %eax |
| 218 | je check_init_detect_2 /* First core has not yet started */ |
| 219 | |
| 220 | /* First core has now started */ |
| 221 | movl $0x00000000, %ebx /* Clear init detect flag */ |
| 222 | cvtsi2sd %ebx, %xmm5 |
| 223 | jmp fam10_mtrr_setup_complete |
| 224 | |
| 225 | skip_cu_check: |
| 226 | |
| 227 | jmp_if_not_fam15h(CAR_FAM15_errata_applied) |
| 228 | |
| 229 | /* Erratum 714, RevGuide for Fam15h, Pub#48063 Rev. 3.24 */ |
| 230 | movl $MSR_BU_CFG2, %ecx |
| 231 | rdmsr |
| 232 | bts $8, %eax /* Set bit 8 in EDX:EAX (bit 8 in EAX). */ |
| 233 | wrmsr |
| 234 | |
| 235 | CAR_FAM15_errata_applied: |
| 236 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 237 | /* Set MtrrFixDramModEn for clear fixed MTRR. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 238 | enable_fixed_mtrr_dram_modify: |
| 239 | movl $SYSCFG_MSR, %ecx |
| 240 | rdmsr |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 241 | andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 242 | orl $SYSCFG_MSR_MtrrFixDramModEn, %eax |
| 243 | wrmsr |
| 244 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 245 | /* Clear all MTRRs. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 246 | xorl %edx, %edx |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 247 | movl $all_mtrr_msrs, %esi |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 248 | |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 249 | clear_fixed_var_mtrr: |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 250 | lodsl (%esi), %eax |
| 251 | testl %eax, %eax |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 252 | jz clear_fixed_var_mtrr_out |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 253 | |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 254 | movl %eax, %ecx |
| 255 | xorl %eax, %eax |
| 256 | wrmsr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 257 | |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 258 | jmp clear_fixed_var_mtrr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 259 | clear_fixed_var_mtrr_out: |
| 260 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 261 | /* |
| 262 | * 0x06 is the WB IO type for a given 4k segment. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 263 | * 0x1e is the MEM IO type for a given 4k segment (K10 and above). |
| 264 | * 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] | 265 | * register we want to use for CAR. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 266 | * reg is the register where the IO type should be stored. |
| 267 | */ |
| 268 | .macro extractmask segs, reg |
| 269 | .if \segs <= 0 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 270 | /* |
| 271 | * 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] | 272 | * of this macro, %eax and %edx are cleared. Later invocations of this |
| 273 | * macro will have a monotonically increasing segs parameter. |
| 274 | */ |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 275 | xorl \reg, \reg |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 276 | .else |
| 277 | jmp_if_k8(1f) |
| 278 | |
| 279 | .if \segs == 1 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 280 | movl $0x1e000000, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 281 | .elseif \segs == 2 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 282 | movl $0x1e1e0000, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 283 | .elseif \segs == 3 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 284 | movl $0x1e1e1e00, \reg /* WB MEM type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 285 | .elseif \segs >= 4 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 286 | movl $0x1e1e1e1e, \reg /* WB MEM type */ |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 287 | .endif |
| 288 | jmp 2f |
| 289 | 1: |
| 290 | .if \segs == 1 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 291 | movl $0x06000000, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 292 | .elseif \segs == 2 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 293 | movl $0x06060000, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 294 | .elseif \segs == 3 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 295 | movl $0x06060600, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 296 | .elseif \segs >= 4 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 297 | movl $0x06060606, \reg /* WB IO type */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 298 | .endif |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 299 | 2: |
| 300 | .endif /* if \segs <= 0 */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 301 | .endm |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 302 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 303 | /* |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 304 | * 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] | 305 | * windowoffset is the 32k-aligned window into CAR size. |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 306 | */ |
| 307 | .macro simplemask carsize, windowoffset |
Stefan Reinauer | 4a45ec4 | 2015-07-07 00:54:05 +0200 | [diff] [blame] | 308 | .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12) - 4) |
Carl-Daniel Hailfinger | ed8dc58 | 2008-01-10 17:59:25 +0000 | [diff] [blame] | 309 | extractmask gas_bug_workaround, %eax |
Stefan Reinauer | 4a45ec4 | 2015-07-07 00:54:05 +0200 | [diff] [blame] | 310 | .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12)) |
Carl-Daniel Hailfinger | ed8dc58 | 2008-01-10 17:59:25 +0000 | [diff] [blame] | 311 | extractmask gas_bug_workaround, %edx |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 312 | /* |
| 313 | * Without the gas bug workaround, the entire macro would consist |
| 314 | * only of the two lines below: |
Stefan Reinauer | 4a45ec4 | 2015-07-07 00:54:05 +0200 | [diff] [blame] | 315 | * extractmask (((\carsize - \windowoffset) >> 12) - 4), %eax |
| 316 | * extractmask (((\carsize - \windowoffset) >> 12)), %edx |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 317 | */ |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 318 | .endm |
| 319 | |
Timothy Pearson | a97e007 | 2015-06-02 13:53:25 -0500 | [diff] [blame] | 320 | #if IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX) |
| 321 | #if CacheSize > 0x80000 |
| 322 | #error Invalid CAR size, must be at most 128k (processor limit is 512k). |
| 323 | #endif |
| 324 | #else |
| 325 | #if CacheSize > 0x10000 |
| 326 | #error Invalid CAR size, must be at most 64k. |
| 327 | #endif |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 328 | #endif |
| 329 | #if CacheSize < 0x1000 |
| 330 | #error Invalid CAR size, must be at least 4k. This is a processor limitation. |
| 331 | #endif |
| 332 | #if (CacheSize & (0x1000 - 1)) |
| 333 | #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] | 334 | #endif |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 335 | |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 336 | #if CacheSize > 0x8000 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 337 | /* Enable caching for 32K-64K using fixed MTRR. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 338 | movl $MTRR_FIX_4K_C0000, %ecx |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 339 | simplemask CacheSize, 0x8000 |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 340 | wrmsr |
Yinghai Lu | d4b278c | 2006-10-04 20:46:15 +0000 | [diff] [blame] | 341 | #endif |
| 342 | |
Timothy Pearson | a97e007 | 2015-06-02 13:53:25 -0500 | [diff] [blame] | 343 | #if CacheSize > 0x10000 |
| 344 | /* Enable caching for 64K-96K using fixed MTRR. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 345 | movl $MTRR_FIX_4K_D0000, %ecx |
Timothy Pearson | a97e007 | 2015-06-02 13:53:25 -0500 | [diff] [blame] | 346 | simplemask CacheSize, 0x10000 |
| 347 | wrmsr |
| 348 | #endif |
| 349 | |
| 350 | #if CacheSize > 0x18000 |
| 351 | /* Enable caching for 96K-128K using fixed MTRR. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 352 | movl $MTRR_FIX_4K_D8000, %ecx |
Timothy Pearson | a97e007 | 2015-06-02 13:53:25 -0500 | [diff] [blame] | 353 | simplemask CacheSize, 0x18000 |
| 354 | wrmsr |
| 355 | #endif |
| 356 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 357 | /* Enable caching for 0-32K using fixed MTRR. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 358 | movl $MTRR_FIX_4K_C8000, %ecx |
Carl-Daniel Hailfinger | 1923fc4 | 2008-01-10 17:48:25 +0000 | [diff] [blame] | 359 | simplemask CacheSize, 0 |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 360 | wrmsr |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 361 | |
Timothy Pearson | 38508a0 | 2015-06-25 15:07:34 -0500 | [diff] [blame] | 362 | jmp_if_fam15h(fam15_skip_dram_mtrr_setup) |
| 363 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 364 | /* Enable memory access for first MBs using top_mem. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 365 | movl $TOP_MEM, %ecx |
| 366 | xorl %edx, %edx |
Myles Watson | 0f61a4f | 2009-10-16 16:32:57 +0000 | [diff] [blame] | 367 | movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 368 | wrmsr |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 369 | |
Timothy Pearson | 38508a0 | 2015-06-25 15:07:34 -0500 | [diff] [blame] | 370 | fam15_skip_dram_mtrr_setup: |
| 371 | |
Patrick Georgi | 784544b | 2011-10-31 17:07:52 +0100 | [diff] [blame] | 372 | #if CONFIG_XIP_ROM_SIZE |
Rudolf Marek | 95c50c6 | 2010-01-05 17:35:44 +0000 | [diff] [blame] | 373 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 374 | /* Enable write base caching so we can do execute in place (XIP) |
| 375 | * on the flash ROM. |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 376 | */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 377 | movl $MTRR_PHYS_BASE(1), %ecx |
Uwe Hermann | 1d36d6d | 2010-09-30 21:22:40 +0000 | [diff] [blame] | 378 | xorl %edx, %edx |
Uwe Hermann | 36455aa | 2010-10-02 20:51:29 +0000 | [diff] [blame] | 379 | /* |
Patrick Georgi | 1da1046 | 2011-10-28 20:28:03 +0200 | [diff] [blame] | 380 | * IMPORTANT: The following calculation _must_ be done at runtime. See |
Uwe Hermann | 36455aa | 2010-10-02 20:51:29 +0000 | [diff] [blame] | 381 | * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html |
| 382 | */ |
Rudolf Marek | 9438da3 | 2011-10-30 18:06:58 +0100 | [diff] [blame] | 383 | movl $copy_and_run, %eax |
Patrick Georgi | 1da1046 | 2011-10-28 20:28:03 +0200 | [diff] [blame] | 384 | andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax |
| 385 | orl $MTRR_TYPE_WRBACK, %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 386 | wrmsr |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 387 | |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 388 | movl $MTRR_PHYS_MASK(1), %ecx |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 389 | 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] | 390 | jmp_if_k8(wbcache_post_fam10_setup) |
Stefan Reinauer | 0867062 | 2009-06-30 15:17:49 +0000 | [diff] [blame] | 391 | 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] | 392 | wbcache_post_fam10_setup: |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 393 | movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 394 | wrmsr |
Patrick Georgi | 784544b | 2011-10-31 17:07:52 +0100 | [diff] [blame] | 395 | #endif /* CONFIG_XIP_ROM_SIZE */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 396 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 397 | /* Set the default memory type and enable fixed and variable MTRRs. */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 398 | movl $MTRR_DEF_TYPE_MSR, %ecx |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 399 | xorl %edx, %edx |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 400 | movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 401 | wrmsr |
| 402 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 403 | /* Enable the MTRRs and IORRs in SYSCFG. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 404 | movl $SYSCFG_MSR, %ecx |
| 405 | rdmsr |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 406 | orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 407 | wrmsr |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 408 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 409 | fam10_mtrr_setup_complete: |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 410 | post_code(0xa1) |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 411 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 412 | /* Disable conversion of INVD to WBINVD (INVDWBINVD = 0) */ |
| 413 | mov $0xc0010015, %ecx |
| 414 | rdmsr |
| 415 | btr $4, %eax |
| 416 | wrmsr |
| 417 | |
| 418 | jmp_if_not_fam15h(fam15_car_msr_setup_complete) |
| 419 | /* Disable streaming store (DisSS = 1) */ |
| 420 | mov $0xc0011020, %ecx |
| 421 | rdmsr |
| 422 | bts $28, %eax |
| 423 | wrmsr |
| 424 | |
| 425 | /* Disable speculative ITLB reloads (DisSpecTlbRld = 1) */ |
| 426 | mov $0xc0011021, %ecx |
| 427 | rdmsr |
| 428 | bts $9, %eax |
| 429 | wrmsr |
| 430 | |
| 431 | /* Disable speculative DTLB reloads (DisSpecTlbRld = 1) and set DisHwPf = 1 */ |
| 432 | mov $0xc0011022, %ecx |
| 433 | rdmsr |
| 434 | bts $4, %eax |
| 435 | bts $13, %eax |
| 436 | wrmsr |
| 437 | |
| 438 | /* Disable CR0 combining (CombineCr0Cd = 0) */ |
| 439 | mov $0xc001102b, %ecx |
| 440 | rdmsr |
| 441 | btr $49-32, %edx |
| 442 | wrmsr |
| 443 | fam15_car_msr_setup_complete: |
| 444 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 445 | /* Enable cache. */ |
| 446 | movl %cr0, %eax |
Patrick Georgi | 05e740f | 2012-03-31 12:52:21 +0200 | [diff] [blame] | 447 | andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 448 | movl %eax, %cr0 |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 449 | |
Timothy Pearson | e67d240 | 2015-10-29 01:09:55 -0500 | [diff] [blame] | 450 | jmp_if_not_k8(CAR_skip_k8_errata_part1) |
| 451 | |
| 452 | /* Set DisFillP on BSP. */ |
| 453 | movl $0x8000c068, %eax |
| 454 | movw $0xcf8, %dx |
| 455 | outl %eax, %dx |
| 456 | addw $4, %dx |
| 457 | inl %dx, %eax |
| 458 | bts $10, %eax |
| 459 | outl %eax, %dx |
| 460 | |
| 461 | CAR_skip_k8_errata_part1: |
| 462 | |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 463 | jmp_if_k8(fam10_end_part1) |
| 464 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 465 | /* So we need to check if it is BSP. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 466 | movl $0x1b, %ecx |
| 467 | rdmsr |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 468 | bt $8, %eax /* BSP */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 469 | jnc CAR_FAM10_ap |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 470 | fam10_end_part1: |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 471 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 472 | post_code(0xa2) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 473 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 474 | /* Read the range with lodsl. */ |
Yinghai Lu | 6f63c02 | 2005-12-14 20:08:23 +0000 | [diff] [blame] | 475 | cld |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 476 | movl $CacheBase, %esi |
| 477 | movl $(CacheSize >> 2), %ecx |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 478 | rep lodsl |
| 479 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 480 | /* Clear the range. */ |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 481 | movl $CacheBase, %edi |
| 482 | movl $(CacheSize >> 2), %ecx |
| 483 | xorl %eax, %eax |
Myles Watson | 707fad0 | 2009-10-23 18:22:27 +0000 | [diff] [blame] | 484 | rep stosl |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 485 | |
Timothy Pearson | e67d240 | 2015-10-29 01:09:55 -0500 | [diff] [blame] | 486 | jmp_if_not_k8(CAR_skip_k8_errata_part2) |
| 487 | |
| 488 | /* Clear DisFillP on BSP. */ |
| 489 | movl $0x8000c068, %eax |
| 490 | movw $0xcf8, %dx |
| 491 | outl %eax, %dx |
| 492 | addw $4, %dx |
| 493 | inl %dx, %eax |
| 494 | btr $10, %eax |
| 495 | outl %eax, %dx |
| 496 | |
| 497 | CAR_skip_k8_errata_part2: |
| 498 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 499 | /* Set up the stack pointer. */ |
Patrick Georgi | bbc880e | 2012-11-20 18:20:56 +0100 | [diff] [blame] | 500 | movl $(CacheBase + CacheSize), %eax |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 501 | movl %eax, %esp |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 502 | |
Timothy Pearson | 1f78099 | 2015-06-01 23:58:59 -0500 | [diff] [blame] | 503 | /* Poison the lower stack boundary */ |
| 504 | movl $((CacheBase + CacheSize) - CacheSizeBSPStack), %eax |
| 505 | movl $0xdeadbeef, (%eax) |
| 506 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 507 | post_code(0xa3) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 508 | |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 509 | jmp CAR_FAM10_ap_out |
| 510 | CAR_FAM10_ap: |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 511 | /* |
| 512 | * Need to set stack pointer for AP. |
| 513 | * It will be from: |
Timothy Pearson | fb39f82 | 2015-06-02 20:25:03 -0500 | [diff] [blame] | 514 | * CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush)) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 515 | * - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack |
Timothy Pearson | fb39f82 | 2015-06-02 20:25:03 -0500 | [diff] [blame] | 516 | * The spacing between the BSP stack and the top of the AP |
| 517 | * stacks is purposefully set larger (an extra CacheSizeBSPSlush |
| 518 | * worth of unused space) than necessary to aid debugging when |
| 519 | * additional stack variables are added by future developers. |
| 520 | * The extra space will allow BSP overruns to be caught by |
| 521 | * the warning logic and easily fixed instead of crashing the |
| 522 | * system with no obvious clues of what went wrong. |
| 523 | * |
| 524 | * So, need to get the NodeID and CoreID at first. |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 525 | * If NB_CFG bit 54 is set just use initial APIC ID, otherwise need |
| 526 | * to reverse it. |
| 527 | */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 528 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 529 | /* Get the coreid bits at first. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 530 | movl $0x80000008, %eax |
| 531 | cpuid |
| 532 | shrl $12, %ecx |
| 533 | andl $0x0f, %ecx |
| 534 | movl %ecx, %edi |
| 535 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 536 | /* Get the initial APIC ID. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 537 | movl $1, %eax |
| 538 | cpuid |
| 539 | shrl $24, %ebx |
| 540 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 541 | /* Get the nb cfg bit 54. */ |
| 542 | movl $0xc001001f, %ecx /* NB_CFG_MSR */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 543 | rdmsr |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 544 | movl %edi, %ecx /* CoreID bits */ |
Uwe Hermann | 66d1687 | 2010-10-01 07:27:51 +0000 | [diff] [blame] | 545 | bt $(54 - 32), %edx |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 546 | jc roll_cfg |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 547 | |
| 548 | /* Fam10h NB config bit 54 was not set */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 549 | rolb %cl, %bl |
| 550 | roll_cfg: |
Timothy Pearson | 0122afb | 2015-07-30 14:07:15 -0500 | [diff] [blame] | 551 | jmp_if_not_fam15h(ap_apicid_ready) |
| 552 | cmp $0x5, %ecx |
| 553 | jne ap_apicid_ready |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 554 | |
Timothy Pearson | 0122afb | 2015-07-30 14:07:15 -0500 | [diff] [blame] | 555 | /* This is a multi-node CPU |
| 556 | * Adjust the maximum APIC ID to a more reasonable value |
| 557 | * given that no 32-core Family 15h processors exist |
| 558 | */ |
| 559 | movl %ebx, %ecx |
| 560 | and $0x0f, %ecx /* Get lower 4 bits of CPU number */ |
| 561 | and $0x60, %ebx /* Get node ID */ |
| 562 | shrl $0x1, %ebx /* Shift node ID part of APIC ID down by 1 */ |
| 563 | or %ecx, %ebx /* Recombine node ID and CPU number */ |
| 564 | |
| 565 | ap_apicid_ready: |
| 566 | |
| 567 | /* Calculate stack pointer using adjusted APIC ID stored in ebx */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 568 | movl $CacheSizeAPStack, %eax |
| 569 | mull %ebx |
Timothy Pearson | fb39f82 | 2015-06-02 20:25:03 -0500 | [diff] [blame] | 570 | movl $(CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))), %esp |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 571 | subl %eax, %esp |
| 572 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 573 | /* Restore init detect */ |
| 574 | cvtsd2si %xmm5, %ebx |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 575 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 576 | post_code(0xa4) |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 577 | |
| 578 | CAR_FAM10_ap_out: |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 579 | |
Stefan Reinauer | aed9920 | 2010-06-07 08:29:36 +0000 | [diff] [blame] | 580 | post_code(0xa5) |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 581 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 582 | /* Disable SSE. */ |
| 583 | movl %cr4, %eax |
| 584 | andl $~(3 << 9), %eax |
| 585 | movl %eax, %cr4 |
Patrick Georgi | 08afc6d | 2009-02-17 12:56:58 +0000 | [diff] [blame] | 586 | |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 587 | post_code(0xa6) |
| 588 | |
Stefan Reinauer | 7b0500c | 2011-01-19 06:54:42 +0000 | [diff] [blame] | 589 | /* Restore the BIST result. */ |
| 590 | movl %ebp, %eax |
Carl-Daniel Hailfinger | f2ecb74 | 2008-01-08 17:28:35 +0000 | [diff] [blame] | 591 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 592 | /* We need to set EBP? No need. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 593 | movl %esp, %ebp |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 594 | pushl %ebx /* Init detected. */ |
| 595 | pushl %eax /* BIST */ |
Timothy Pearson | 730a043 | 2015-10-16 13:51:51 -0500 | [diff] [blame] | 596 | |
| 597 | post_code(0xa7) |
| 598 | |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 599 | call cache_as_ram_main |
Vladimir Serbinenko | a6c29fe | 2013-11-26 17:49:29 +0100 | [diff] [blame] | 600 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 601 | /* We will not go back. */ |
arch import user (historical) | 6ca7636 | 2005-07-06 17:17:25 +0000 | [diff] [blame] | 602 | |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 603 | post_code(0xaf) /* Should never see this POST code. */ |
Marc Jones | 8ae8c88 | 2007-12-19 01:32:08 +0000 | [diff] [blame] | 604 | |
Vladimir Serbinenko | a6c29fe | 2013-11-26 17:49:29 +0100 | [diff] [blame] | 605 | .globl cache_as_ram_switch_stack |
| 606 | |
| 607 | cache_as_ram_switch_stack: |
| 608 | /* Return address. */ |
| 609 | popl %eax |
Kyösti Mälkki | abc083e | 2013-12-29 12:07:54 +0200 | [diff] [blame] | 610 | /* New stack. */ |
Vladimir Serbinenko | a6c29fe | 2013-11-26 17:49:29 +0100 | [diff] [blame] | 611 | popl %eax |
Kyösti Mälkki | abc083e | 2013-12-29 12:07:54 +0200 | [diff] [blame] | 612 | movl %eax, %esp |
Vladimir Serbinenko | a6c29fe | 2013-11-26 17:49:29 +0100 | [diff] [blame] | 613 | call cache_as_ram_new_stack |
| 614 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 615 | all_mtrr_msrs: |
| 616 | /* fixed MTRR MSRs */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 617 | .long MTRR_FIX_64K_00000 |
| 618 | .long MTRR_FIX_16K_80000 |
| 619 | .long MTRR_FIX_16K_A0000 |
| 620 | .long MTRR_FIX_4K_C0000 |
| 621 | .long MTRR_FIX_4K_C8000 |
| 622 | .long MTRR_FIX_4K_D0000 |
| 623 | .long MTRR_FIX_4K_D8000 |
| 624 | .long MTRR_FIX_4K_E0000 |
| 625 | .long MTRR_FIX_4K_E8000 |
| 626 | .long MTRR_FIX_4K_F0000 |
| 627 | .long MTRR_FIX_4K_F8000 |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 628 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 629 | /* var MTRR MSRs */ |
Alexandru Gagniuc | 86091f9 | 2015-09-30 20:23:09 -0700 | [diff] [blame] | 630 | .long MTRR_PHYS_BASE(0) |
| 631 | .long MTRR_PHYS_MASK(0) |
| 632 | .long MTRR_PHYS_BASE(1) |
| 633 | .long MTRR_PHYS_MASK(1) |
| 634 | .long MTRR_PHYS_BASE(2) |
| 635 | .long MTRR_PHYS_MASK(2) |
| 636 | .long MTRR_PHYS_BASE(3) |
| 637 | .long MTRR_PHYS_MASK(3) |
| 638 | .long MTRR_PHYS_BASE(4) |
| 639 | .long MTRR_PHYS_MASK(4) |
| 640 | .long MTRR_PHYS_BASE(5) |
| 641 | .long MTRR_PHYS_MASK(5) |
| 642 | .long MTRR_PHYS_BASE(6) |
| 643 | .long MTRR_PHYS_MASK(6) |
| 644 | .long MTRR_PHYS_BASE(7) |
| 645 | .long MTRR_PHYS_MASK(7) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 646 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 647 | /* Variable IORR MTRR MSRs */ |
| 648 | .long IORRBase_MSR(0) |
| 649 | .long IORRMask_MSR(0) |
| 650 | .long IORRBase_MSR(1) |
| 651 | .long IORRMask_MSR(1) |
Uwe Hermann | 4292684 | 2010-09-30 23:15:36 +0000 | [diff] [blame] | 652 | |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 653 | /* Top of memory MTRR MSRs */ |
Kyösti Mälkki | 0127c6c | 2015-03-05 14:35:04 +0200 | [diff] [blame] | 654 | .long TOP_MEM |
| 655 | .long TOP_MEM2 |
Warren Turkal | 4ffde94 | 2010-10-12 06:13:40 +0000 | [diff] [blame] | 656 | |
Marc Jones | 2006b38 | 2007-12-19 00:47:09 +0000 | [diff] [blame] | 657 | .long 0x000 /* NULL, end of table */ |
| 658 | |
Stefan Reinauer | 806e146 | 2005-12-01 10:54:44 +0000 | [diff] [blame] | 659 | cache_as_ram_setup_out: |