blob: 6a3ebaf7f876a2a41a1246611070e71f9111780a [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/*
2 * Copyright (c) 2012, Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
13 * its contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29/******************************************************************************
30* AMD Generic Encapsulated Software Architecture
31*
32* $Workfile:: GccCar.inc $Revision:: 32932 $
33*
34* Description: GccCar.inc - AGESA cache-as-RAM setup Include File for GCC complier
35*
36******************************************************************************/
37
38.altmacro
39
40BSP_STACK_BASE_ADDR = 0x30000 /* Base address for primary cores stack */
41BSP_STACK_SIZE = 0x10000 /* 64KB for BSP core */
42CORE0_STACK_BASE_ADDR = 0x80000 /* Base address for primary cores stack */
43CORE0_STACK_SIZE = 0x4000 /* 16KB for primary cores */
44CORE1_STACK_BASE_ADDR = 0x40000 /* Base address for AP cores */
Kyösti Mälkkiacd139852017-07-13 22:48:22 +030045
46#ifdef __x86_64__
47CORE1_STACK_SIZE = 0x2000 /* 8KB for each AP cores */
48#else
zbao7d94cf92012-07-02 14:19:14 +080049CORE1_STACK_SIZE = 0x1000 /* 4KB for each AP cores */
Kyösti Mälkkiacd139852017-07-13 22:48:22 +030050#endif
zbao7d94cf92012-07-02 14:19:14 +080051
52APIC_BASE_ADDRESS = 0x0000001B
53 APIC_BSC = 8 /* Boot Strap Core */
54
55APIC_MSG_REG = 0x380 # Location of BSC message
56 APIC_MSG = 0x00DE00AD # Message data
57APIC_CMD_LO_REG = 0x300 # APIC command low
58APIC_CMD_HI_REG = 0x310 # APIC command high
59 CMD_REG_TO_READ_DATA = 0x00000338 # APIC command for remote read of APIC_MSG_REG
60 REMOTE_READ_STS = 0x00030000 # Remote read status mask
61 REMOTE_DELIVERY_PEND = 0x00010000 # Remote read is pending
62 REMOTE_DELIVERY_DONE = 0x00020000 # Remote read is complete
63 DELIVERY_STS_BIT = 12 #Delivery status valid bit
64APIC_ID_REG = 0x0020 # Local APIC ID offset
65 APIC20_APICID = 24
66APIC_REMOTE_READ_REG = 0x00C0 # Remote read offset
67
68# Flags can only run from bits 31 to 24. Bits 23:0 are in use.
69AMD_CU_NEED_TO_WAIT = 31
70AMD_CU_SEND_INVD_MSG = 30
71AMD_CU_RESTORE_ES = 29
72
73AMD_MTRR_VARIABLE_BASE0 = 0x0200
74AMD_MTRR_VARIABLE_BASE6 = 0x020C
75AMD_MTRR_VARIABLE_BASE7 = 0x020E
76 VMTRR_VALID = 11
77 MTRR_TYPE_WB = 0x06
78 MTRR_TYPE_WP = 0x05
79 MTRR_TYPE_WT = 0x04
80 MTRR_TYPE_UC = 0x00
81AMD_MTRR_VARIABLE_MASK7 = 0x020F
82AMD_MTRR_FIX64k_00000 = 0x0250
83AMD_MTRR_FIX16k_80000 = 0x0258
84AMD_MTRR_FIX16k_A0000 = 0x0259
85AMD_MTRR_FIX4k_C0000 = 0x0268
86AMD_MTRR_FIX4k_C8000 = 0x0269
87AMD_MTRR_FIX4k_D0000 = 0x026A
88AMD_MTRR_FIX4k_D8000 = 0x026B
89AMD_MTRR_FIX4k_E0000 = 0x026C
90AMD_MTRR_FIX4k_E8000 = 0x026D
91AMD_MTRR_FIX4k_F0000 = 0x026E
92AMD_MTRR_FIX4k_F8000 = 0x026F
93
94/* Reproduced from AGESA.h */
95AMD_AP_MTRR_FIX64k_00000 = 0x00000250
96AMD_AP_MTRR_FIX16k_80000 = 0x00000258
97AMD_AP_MTRR_FIX16k_A0000 = 0x00000259
98AMD_AP_MTRR_FIX4k_C0000 = 0x00000268
99AMD_AP_MTRR_FIX4k_C8000 = 0x00000269
100AMD_AP_MTRR_FIX4k_D0000 = 0x0000026A
101AMD_AP_MTRR_FIX4k_D8000 = 0x0000026B
102AMD_AP_MTRR_FIX4k_E0000 = 0x0000026C
103AMD_AP_MTRR_FIX4k_E8000 = 0x0000026D
104AMD_AP_MTRR_FIX4k_F0000 = 0x0000026E
105AMD_AP_MTRR_FIX4k_F8000 = 0x0000026F
106CPU_LIST_TERMINAL = 0xFFFFFFFF
107
108AMD_MTRR_DEFTYPE = 0x02FF
109 WB_DRAM_TYPE = 0x1E /* MemType - memory type */
110 MTRR_DEF_TYPE_EN = 11 /* MtrrDefTypeEn - variable and fixed MTRRs default enabled */
111 MTRR_DEF_TYPE_FIX_EN = 10 /* MtrrDefTypeEn - fixed MTRRs default enabled */
112
113HWCR = 0x0C0010015 /* Hardware Configuration */
114 INVD_WBINVD = 0x04 /* INVD to WBINVD conversion */
115
116IORR_BASE = 0x0C0010016 /* IO Range Regusters Base/Mask, 2 pairs */
117 /* uses 16h - 19h */
118TOP_MEM = 0x0C001001A /* Top of Memory */
119TOP_MEM2 = 0x0C001001D /* Top of Memory2 */
120
121LS_CFG = 0x0C0011020 /* Load-Store Configuration */
122 DIS_SS = 28 /* Family 10h,12h,15h:Disable Streng Store functionality */
123 DIS_STREAM_ST = 28 /* Family 14h:DisStreamSt - Disable Streaming Store functionality */
124
125IC_CFG = 0x0C0011021 /* Instruction Cache Config Register */
126 IC_DIS_SPEC_TLB_RLD = 9 /* Disable speculative TLB reloads */
127 DIS_IND = 14 /* Family 10-14h:Disable Indirect Branch Predictor */
128 DIS_I_CACHE = 14 /* Family 15h:DisICache - Disable Indirect Branch Predictor */
129
130DC_CFG = 0x0C0011022 /* Data Cache Configuration */
131 DC_DIS_SPEC_TLB_RLD = 4 /* Disable speculative TLB reloads */
132 DIS_CLR_WBTOL2_SMC_HIT = 8 /* self modifying code check buffer bit */
133 DIS_HW_PF = 13 /* Hardware prefetches bit */
134
135CU_CFG = 0x0C0011023 /* Family 15h: Combined Unit Configuration */
136 L2_WAY_LOCK_EN = 23 /* L2WayLock - L2 way lock enable */
137 L2_FIRST_LOCKED_WAY = 19 /* L2FirstLockedWay - first L2 way lockedh */
138 L2_FIRST_LOCKED_WAY_OR_MASK = 0x000780000
139
140DE_CFG = 0x0C0011029 /* Decode Configuration */
141 CL_FLUSH_SERIALIZE = 23 /* Family 12h,15h: CL Flush Serialization */
142
143BU_CFG2 = 0x0C001102A /* Family 10h: Bus Unit Configuration 2 */
144CU_CFG2 = 0x0C001102A /* Family 15h: Combined Unit Configuration 2 */
145 F10_CL_LINES_TO_NB_DIS = 15 /* ClLinesToNbDis - allows WP code to be cached in L2 */
146 IC_DIS_SPEC_TLB_WR = 35 /* IcDisSpecTlbWr - ITLB speculative writes */
147
148CU_CFG3 = 0x0C001102B /* Combined Unit Configuration 3 */
149 COMBINE_CR0_CD = 49 /* Combine CR0.CD for both cores of a compute unit */
150
151CR0_PE = 0 # Protection Enable
152CR0_NW = 29 # Not Write-through
153CR0_CD = 30 # Cache Disable
154CR0_PG = 31 # Paging Enable
155
156/* CPUID Functions */
157
158CPUID_MODEL = 1
159AMD_CPUID_FMF = 0x80000001 /* Family Model Features information */
Subrata Banik8e6d5f22020-08-30 13:51:44 +0530160AMD_CPUID_L2Cache = 0x80000006 /* L2/L3 cache info */
zbao7d94cf92012-07-02 14:19:14 +0800161AMD_CPUID_APIC = 0x80000008 /* Long Mode and APIC info., core count */
162 APIC_ID_CORE_ID_SIZE = 12 /* ApicIdCoreIdSize bit position */
163
164NB_CFG = 0x0C001001F /* Northbridge Configuration Register */
165 INIT_APIC_ID_CPU_ID_LO = 54 /* InitApicIdCpuIdLo - is core# in high or low half of APIC ID? */
166 ENABLE_CF8_EXT_CFG = 46 /* EnableCf8ExtCfg - enable CF8 extended configuration cycles */
167
168MTRR_SYS_CFG = 0x0C0010010 /* System Configuration Register */
169 CHX_TO_DIRTY_DIS = 16 /* ChxToDirtyDis Change to dirty disable */
170 SYS_UC_LOCK_EN = 17 /* SysUcLockEn System lock command enable */
171 MTRR_FIX_DRAM_EN = 18 /* MtrrFixDramEn MTRR fixed RdDram and WrDram attributes enable */
172 MTRR_FIX_DRAM_MOD_EN = 19 /* MtrrFixDramModEn MTRR fixed RdDram and WrDram modification enable */
173 MTRR_VAR_DRAM_EN = 20 /* MtrrVarDramEn MTRR variable DRAM enable */
174 MTRR_TOM2_EN = 21 /* MtrrTom2En MTRR top of memory 2 enable */
175
176PERF_CONTROL3 = 0x0C0010003 /* Performance event control three */
177 PERF_CONTROL3_RESERVE_L = 0x00200000 /* Preserve the reserved bits */
178 PERF_CONTROL3_RESERVE_H = 0x0FCF0 /* Preserve the reserved bits */
179 CONFIG_EVENT_L = 0x0F0E2 /* All cores with level detection */
180 CONFIG_EVENT_H = 4 /* Increment count by number of event */
181 /* occured in clock cycle */
182 EVENT_ENABLE = 22 /* Enable the event */
183PERF_COUNTER3 = 0x0C0010007 /* Performance event counter three */
184
185FUNC_3 = 3
186MCA_NB_CFG = 0x44 /* MCA NB Configuration */
187CPU_ERR_DIS = 6 /* CPU error response disable */
188PRODUCT_INFO_REG1 = 0x1FC /* Product Information Register 1 */
189
190# Local use flags, in upper most byte if ESI
191FLAG_UNKNOWN_FAMILY = 24 # Signals that the family# of the installed processor is not recognized
192FLAG_STACK_REENTRY = 25 # Signals that the environment has made a re-entry (2nd) call to set up the stack
193FLAG_IS_PRIMARY = 26 # Signals that this core is the primary within the comoute unit
194FLAG_CORE_NOT_IDENTIFIED = 27 # Signals that the cores/compute units of the installed processor is not recognized
195FLAG_FORCE_32K_STACK = 28 # Signals that to force 32KB stack size for BSP core
196CR0_MASK = ((1 << CR0_CD) | (1 << CR0_NW))
197MSR_MASK = ((1 << MTRR_DEF_TYPE_EN)+(1 << MTRR_DEF_TYPE_FIX_EN))
198
199/****************************************************************************
200 *
201 * CPU MACROS - PUBLIC
202 *
203 ****************************************************************************/
204.macro _WRMSR
205 .byte 0x0f, 0x30
206.endm
207
208.macro _RDMSR
209 .byte 0x0F, 0x32
210.endm
211
212.macro AMD_CPUID arg0
213 .ifb \arg0
214 mov $0x1, %eax
215 .byte 0x0F, 0x0A2 /* Execute instruction */
216 bswap %eax
217 xchg %ah, %al /* Ext model in al now */
218 rol $0x08, %eax /* Ext model in ah, model in al */
219 and $0x0FFCF, ax /* Keep 23:16, 7:6, 3:0 */
220 .else
221 mov \arg0, %eax
222 .byte 0x0F, 0x0A2
223 .endif
224.endm
225
226.macro MAKE_EXT_PCI_ADDR Seg, Bus, Dev, Func, Offset
Arthur Heymans90157852022-03-23 21:34:56 +0100227 mov $(1 << 31 | (\Seg) << 28 | (((\Offset) & (0x0F00)) >> 8) << 24 | (\Bus) << 16 | (\Dev) << 11 | (\Func) << 8) | ((\Offset) & (0xFC)), %eax
zbao7d94cf92012-07-02 14:19:14 +0800228.endm
229/****************************************************************************
230*
231* AMD_ENABLE_STACK_FAMILY_HOOK Macro - Stackless
232*
233* Set any family specific controls needed to enable the use of
234* cache as general storage before main memory is available.
235*
236* Inputs:
237* none
238* Outputs:
239* none
240 ****************************************************************************/
241.macro AMD_ENABLE_STACK_FAMILY_HOOK
242
243 AMD_ENABLE_STACK_FAMILY_HOOK_F10
244 AMD_ENABLE_STACK_FAMILY_HOOK_F12
245 AMD_ENABLE_STACK_FAMILY_HOOK_F14
246 AMD_ENABLE_STACK_FAMILY_HOOK_F15
247.endm
248
249/****************************************************************************
250*
251* AMD_DISABLE_STACK_FAMILY_HOOK Macro - Stackless
252*
253* Return any family specific controls to their 'standard'
254* settings for using cache with main memory.
255*
256* Inputs:
257* none
258* Outputs:
259* none
260 ****************************************************************************/
261.macro AMD_DISABLE_STACK_FAMILY_HOOK
262
263 AMD_DISABLE_STACK_FAMILY_HOOK_F10
264 AMD_DISABLE_STACK_FAMILY_HOOK_F12
265 AMD_DISABLE_STACK_FAMILY_HOOK_F14
266 AMD_DISABLE_STACK_FAMILY_HOOK_F15
267
268.endm
269
270/****************************************************************************
271*
272* GET_NODE_ID_CORE_ID Macro - Stackless
273*
274* Read family specific values to determine the node and core
275* numbers for the core executing this code.
276*
277* Inputs:
278* none
279* Outputs:
280* SI[7:0] = Core# (0..N, relative to node)
281* SI[15:8]= Node# (0..N)
282* SI[23:16]= reserved
283* SI[24]= flag: 1=Family Unrecognized
284* SI[25]= flag: 1=Interface re-entry call
285* SI[26]= flag: 1=Core is primary of compute unit
286* SI[31:27]= reserved, =0
287****************************************************************************/
288.macro GET_NODE_ID_CORE_ID
zbao7d94cf92012-07-02 14:19:14 +0800289
290 mov $-1, %si
291 GET_NODE_ID_CORE_ID_F10
292 GET_NODE_ID_CORE_ID_F12
293 GET_NODE_ID_CORE_ID_F14
294 GET_NODE_ID_CORE_ID_F15
295 /*
296 * Check for unrecognized Family
297 */
298 cmp $-1, %si # Has family (node/core) already been discovered?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100299 jnz node_core_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800300
301 mov $((1 << FLAG_UNKNOWN_FAMILY)+(1 << FLAG_IS_PRIMARY)), %esi # No, Set error code, Only let BSP continue
302
303 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
304 _RDMSR
305 bt $APIC_BSC, %eax # Is this the BSC?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100306 jc node_core_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800307 hlt # Kill APs
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100308node_core_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800309
310.endm
311
312/****************************************************************************
313## Family 10h MACROS
314##***************************************************************************
315#---------------------------------------------------
316#
317# AMD_ENABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
318#
319# Set any family specific controls needed to enable the use of
320# cache as general storage before main memory is available.
321#
322# Inputs:
323# ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
324# Outputs:
325# none
326#
327# Family 10h requirements (BKDG section 2.3.3):
328# * Paging disabled
329# * MSRC001_0015[INVDWBINVD]=0
330# * MSRC001_1021[DIS_IND]=1
331# * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
332# * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
333# * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1
334# * MSRC001_1022[DIS_HW_PF]=1
335# * MSRC001_102A[IcDisSpecTlbWr]=1
336# * MSRC001_102A[ClLinesToNbDis]=1
337# * No INVD or WBINVD, no exceptions, page faults or interrupts
338****************************************************************************/
339.macro AMD_ENABLE_STACK_FAMILY_HOOK_F10
zbao7d94cf92012-07-02 14:19:14 +0800340
341 AMD_CPUID $CPUID_MODEL
342 shr $20, %eax # AL = cpu extended family
343 cmp $0x01, %al # Is this family 10h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100344 jnz fam10_enable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800345
346 mov $DC_CFG, %ecx # MSR:C001_1022
347 _RDMSR
348 bts $DC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative DTLB reloads bit
349 bts $DIS_CLR_WBTOL2_SMC_HIT, %eax # Turn on Disable the self modifying code check buffer bit
350 bts $DIS_HW_PF, %eax # Turn on Disable hardware prefetches bit
351 _WRMSR
352
353 dec %cx # MSR:C001_1021
354 _RDMSR
355 bts $IC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative TLB reloads bit
356 bts $DIS_IND, %eax # Turn on Disable indirect branch predictor
357 _WRMSR
358
359 mov $BU_CFG2, %ecx # MSR C001_102A
360 _RDMSR
361 bts $F10_CL_LINES_TO_NB_DIS, %eax # Allow BIOS ROM to be cached in the IC
362 bts $(IC_DIS_SPEC_TLB_WR-32), %edx #Disable speculative writes to the ITLB
363 _WRMSR
364
365 mov $HWCR, %ecx # MSR C001_0015
366 _RDMSR
367 bt $FLAG_STACK_REENTRY, %esi # Check if stack has already been set
368 jc fam10_skipClearingBit4
369 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
370 _WRMSR
371
372fam10_skipClearingBit4:
373 mov %esi, %eax # load core#
374 or %al, %al # If (BSP)
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100375 jne fam10_enable_stack_hook_exit\@
zbao7d94cf92012-07-02 14:19:14 +0800376 mov $PERF_COUNTER3, %ecx # Select performance counter three
377 # to count number of CAR evictions
378 xor %eax, %eax # Initialize the lower part of the counter to zero
379 xor %edx, %edx # Initializa the upper part of the counter to zero
380 _WRMSR # Save it
381 mov $PERF_CONTROL3, %ecx # Select the event control three
382 _RDMSR # Get the current setting
383 and $PERF_CONTROL3_RESERVE_L, %eax # Preserve the reserved bits
384 or $CONFIG_EVENT_L, %eax # Set the lower part of event register to
385 # select CAR Corruption occurred by any cores
386 and $PERF_CONTROL3_RESERVE_H, %dx # Preserve the reserved bits
387 or $CONFIG_EVENT_H, %dx # Set the upper part of event register
388 _WRMSR # Save it
389 bts $EVENT_ENABLE, %eax # Enable it
390 _WRMSR # Save it
391
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100392fam10_enable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800393.endm
394
395/****************************************************************************
396*
397* AMD_DISABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
398*
399* Return any family specific controls to their 'standard'
400* settings for using cache with main memory.
401*
402* Inputs:
403* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
404* Outputs:
405* none
406*
407* Family 10h requirements:
408* * INVD or WBINVD
409* * MSRC001_0015[INVD_WBINVD]=1
410* * MSRC001_1021[DIS_IND]=0
411* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
412* * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
413* * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
414* * MSRC001_1022[DIS_HW_PF]=0
415* * MSRC001_102A[IcDisSpecTlbWr]=0
416* * MSRC001_102A[ClLinesToNbDis]=0
417*****************************************************************************/
418
419.macro AMD_DISABLE_STACK_FAMILY_HOOK_F10
zbao7d94cf92012-07-02 14:19:14 +0800420
Damien Zammit9e818872014-11-19 00:20:08 +1100421 AMD_CPUID $CPUID_MODEL
zbao7d94cf92012-07-02 14:19:14 +0800422 shr $20, %eax # AL = cpu extended family
423 cmp $0x01, %al # Is this family 10h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100424 jnz fam10_disable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800425
426 mov $DC_CFG, %ecx # MSR:C001_1022
427 _RDMSR
428 btr $DC_DIS_SPEC_TLB_RLD, %eax # Enable speculative TLB reloads
429 btr $DIS_CLR_WBTOL2_SMC_HIT, %eax # Allow self modifying code check buffer
430 btr $DIS_HW_PF, %eax # Allow hardware prefetches
431 _WRMSR
432
433 dec %cx # MSR:C001_1021
434 _RDMSR
435 btr $DIS_IND, %eax # Turn on indirect branch predictor
436 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
437 _WRMSR
438
439 mov $BU_CFG2, %ecx # MSR:C001_102A
440 _RDMSR
441 btr $F10_CL_LINES_TO_NB_DIS, %eax # Return L3 to normal mode
442 btr $(IC_DIS_SPEC_TLB_WR-32), %edx #Re-enable speculative writes to the ITLB
443 _WRMSR
444
445 #--------------------------------------------------------------------------
446 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
447 #--------------------------------------------------------------------------
448
449 mov $HWCR, %ecx # MSR:0000_0015
450 _RDMSR
451 mov %ax, %bx # Save INVD -> WBINVD bit
452 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion for the invd instruction.
453 _WRMSR
454 invd # Clear the cache tag RAMs
455 mov %bx, %ax # Restore INVD -> WBINVD bit
456 _WRMSR
457
458 #--------------------------------------------------------------------------
459 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
460 #--------------------------------------------------------------------------
461
462 mov $PERF_CONTROL3, %ecx # Select the event control three
463 _RDMSR # Retrieve the current value
464 btc $EVENT_ENABLE, %eax # Is event enable, complement it as well
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100465 jnc fam10_disable_stack_hook_exit\@ # No
zbao7d94cf92012-07-02 14:19:14 +0800466 cmp $CONFIG_EVENT_L, %ax # Is the lower part of event set to capture the CAR Corruption
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100467 jne fam10_disable_stack_hook_exit\@ # No
zbao7d94cf92012-07-02 14:19:14 +0800468 cmp $CONFIG_EVENT_H, %dl # Is the upper part of event set to capture the CAR Corruption
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100469 jne fam10_disable_stack_hook_exit\@ # No
zbao7d94cf92012-07-02 14:19:14 +0800470 _WRMSR # Disable the event
471
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100472fam10_disable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800473.endm
474
475/****************************************************************************
476*
477* GET_NODE_ID_CORE_ID_F10 Macro - Stackless
478*
479* Read family specific values to determine the node and core
480* numbers for the core executing this code.
481*
482* Inputs:
483* none
484* Outputs:
485* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
486*****************************************************************************/
487.macro GET_NODE_ID_CORE_ID_F10
488
zbao7d94cf92012-07-02 14:19:14 +0800489
490 cmp $-1, %si # Has node/core already been discovered?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100491 jnz node_core_f10_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800492
493 AMD_CPUID $CPUID_MODEL
494 shr $20, %eax # AL = cpu extended family
495 cmp $0x01, %al # Is this family 10h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100496 jnz node_core_f10_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800497
498 xor %esi, %esi # Assume BSC, clear flags
499 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
500 _RDMSR
501 bt $APIC_BSC, %eax # Is this the BSC?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100502 jnc node_core_f10_AP\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800503
504 # This is the BSP.
505 # Enable routing tables on BSP (just in case the HT init code has not yet enabled them)
506 mov $0x8000C06C, %eax # PCI address for D18F0x6C Link Initialization Control Register
507 mov $0x0CF8, %dx
508 out %eax, %dx
509 add $4, %dx
510 in %dx, %eax
511 btr $0, %eax # Set LinkInitializationControl[RouteTblDis] = 0
512 out %eax, %dx
513 jmp 1f #
514
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100515node_core_f10_AP\@:
zbao7d94cf92012-07-02 14:19:14 +0800516 #
517 # This is an AP. Routing tables have been enabled by the HT Init process.
518 # Also, the MailBox register was set by the BSP during early init
519 # The Mailbox register content is formatted as follows:
520 # UINT32 Node:4# // The node id of Core's node.
521 # UINT32 Socket:4# // The socket of this Core's node.
522 # UINT32 Module:2# // The internal module number for Core's node.
523 # UINT32 ModuleType:2# // Single Module = 0, Multi-module = 1.
524 # UINT32 :20# // Reserved
525 #
526 mov $0x0C0000408, %ecx # Read the family 10h mailbox
527 _RDMSR # MC4_MISC1[63:32]
528 mov %dx, %si # SI = raw mailbox contents (will extract node# from this)
529 shr $24, %ebx # BL = CPUID Fn0000_0001_EBX[LocalApicId]
530 mov %bx, %di # DI = Initial APIC ID (will extract core# from this)
531
532 AMD_CPUID $AMD_CPUID_APIC #
533 shr $4, %ch # CH = ApicIdSize, #bits in APIC ID that show core#
534 inc %cl # CL = Number of enabled cores in the socket
535 mov %cx, %bx
536
537 mov $NB_CFG, %ecx # MSR:C001_001F
538 _RDMSR # EDX has InitApicIdCpuIdLo bit
539
540 mov %bh, %cl # CL = APIC ID size
541 mov $1, %al # Convert APIC ID size to an AND mask
542 shl %cl, %al # AL = 2^APIC ID size
543 dec %al # AL = mask for relative core number
544 xor %ah, %ah # AX = mask for relative core number
545 bt $(INIT_APIC_ID_CPU_ID_LO-32), %edx # InitApicIdCpuIdLo == 1?
546 #.if (!carry?) # Br if yes
547 jc 0f
548 mov $8, %ch # Calculate core number shift count
549 sub %cl, %ch # CH = core shift count
550 mov %ch, %cl
551 shr %cl, %di # Right justify core number
552 #.endif
553 0:
554 and %ax, %di # DI = socket-relative core number
555
556 mov %si, %cx # CX = raw mailbox value
557 shr $10, %cx # CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM)
558 and $3, %cl # Isolate ModuleType
559 xor %bh, %bh # BX = Number of enabled cores in the socket
560 shr %cl, %bx # BX = Number of enabled cores per node
561 xor %dx, %dx # Clear upper word for div
562 mov %di, %ax # AX = socket-relative core number
563 div %bx # DX = node-relative core number
564 movzx %si, %eax # prepare return value, [23:16]=shared Core# (=0, not shared)
565 and $0x000F, %ax # AX = node number
566 shl $8, %ax # [15:8]=node#
567 mov %dl, %al # [7:0]=core# (relative to node)
568 mov %eax, %esi # ESI = return value
5691:
570 bts $FLAG_IS_PRIMARY, %esi # all Family 10h cores are primary
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100571node_core_f10_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800572.endm
573
574/*****************************************************************************
575** Family 12h MACROS
576*****************************************************************************/
577/*****************************************************************************
578*
579* AMD_ENABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless
580*
581* Set any family specific controls needed to enable the use of
582* cache as general storage before main memory is available.
583*
584* Inputs:
585* ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
586* Outputs:
587* none
588*
589* Family 12h requirements (BKDG section 2.3.3):
590* The following requirements must be satisfied prior to using the cache as general storage:
591* * Paging must be disabled.
592* * MSRC001_0015[INVD_WBINVD]=0
593* * MSRC001_1020[DIS_SS]=1
594* * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
595* * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
596* * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1
597* * MSRC001_1022[DIS_HW_PF]=1
598* * MSRC001_1029[ClflushSerialize]=1
599* * No INVD or WBINVD, no exceptions, page faults or interrupts
600*****************************************************************************/
601.macro AMD_ENABLE_STACK_FAMILY_HOOK_F12
zbao7d94cf92012-07-02 14:19:14 +0800602
603 AMD_CPUID $CPUID_MODEL
604 shr $20, %eax # AL = cpu extended family
605 cmp $0x03, %al # Is this family 12h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100606 jnz fam12_enable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800607
608 mov $DC_CFG, %ecx # MSR:C001_1022
609 _RDMSR
610 bts $DC_DIS_SPEC_TLB_RLD, %eax # Disable speculative DC-TLB reloads
611 bts $DIS_CLR_WBTOL2_SMC_HIT, %eax # Disable self modifying code check buffer
612 bts $DIS_HW_PF, %eax # Disable hardware prefetches
613 _WRMSR
614
615 dec %cx #IC_CFG # MSR:C001_1021
616 _RDMSR
617 bts $IC_DIS_SPEC_TLB_RLD, %eax # Disable speculative IC-TLB reloads
618 _WRMSR
619
620 dec %cx #LS_CFG # MSR:C001_1020
621 _RDMSR
622 bts $DIS_SS, %eax # Disabled Streaming store functionality
623 _WRMSR
624
625 mov $HWCR, %ecx # MSR C001_0015
626 _RDMSR
627 bt $FLAG_STACK_REENTRY , %esi # Check if stack has already been set
628 jc fam12_skipClearingBit4
629 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
630 _WRMSR
631
632fam12_skipClearingBit4:
633 mov $DE_CFG, %ecx # MSR:C001_1029
634 _RDMSR
635 bts $CL_FLUSH_SERIALIZE, %eax # Serialize all CL Flush actions
636 _WRMSR
637
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100638fam12_enable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800639.endm
640
641/*****************************************************************************
642*
643* AMD_DISABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless
644*
645* Return any family specific controls to their 'standard'
646* settings for using cache with main memory.
647*
648* Inputs:
649* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
650* Outputs:
651* none
652*
653* Family 12h requirements:
654* * INVD or WBINVD
655* * MSRC001_0015[INVD_WBINVD]=1
656* * MSRC001_1020[DIS_SS]=0
657* * MSRC001_1021[IC_DIS_SPEC_TLB_RLD]=0
658* * MSRC001_1022[DC_DIS_SPEC_TLB_RLD]=0
659* * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
660* * MSRC001_1022[DIS_HW_PF]=0
661* * MSRC001_1029[ClflushSerialize]=0
662*****************************************************************************/
663.macro AMD_DISABLE_STACK_FAMILY_HOOK_F12
zbao7d94cf92012-07-02 14:19:14 +0800664
665 AMD_CPUID $CPUID_MODEL
666 shr $20, %eax # AL = cpu extended family
667 cmp $0x03, %al # Is this family 12h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100668 jnz fam12_disable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800669
670 mov $DC_CFG, %ecx # MSR:C001_1022
671 _RDMSR
672 btr $DC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative DC-TLB reloads
673 btr $DIS_CLR_WBTOL2_SMC_HIT, %eax # Enable self modifying code check buffer
674 btr $DIS_HW_PF, %eax # Enable Hardware prefetches
675 _WRMSR
676
677 dec %cx #IC_CFG # MSR:C001_1021
678 _RDMSR
679 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative IC-TLB reloads
680 _WRMSR
681
682 dec %cx #LS_CFG # MSR:C001_1020
683 _RDMSR
684 btr $DIS_SS, %eax # Turn on Streaming store functionality
685 _WRMSR
686
687 mov $DE_CFG, %ecx # MSR:C001_1029
688 _RDMSR
689 btr $CL_FLUSH_SERIALIZE, %eax
690 _WRMSR
691
692 #--------------------------------------------------------------------------
693 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
694 #--------------------------------------------------------------------------
695
696 mov $HWCR, %ecx # MSR:0000_0015h
697 _RDMSR
698 mov %ax, %bx # Save INVD -> WBINVD bit
699 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
700 _WRMSR
701 invd # Clear the cache tag RAMs
702 mov %bx, %ax # Restore INVD -> WBINVD bit
703 _WRMSR
704
705 #--------------------------------------------------------------------------
706 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
707 #--------------------------------------------------------------------------
708
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100709fam12_disable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800710.endm
711
712/*****************************************************************************
713*
714* GET_NODE_ID_CORE_ID_F12 Macro - Stackless
715*
716* Read family specific values to determine the node and core
717* numbers for the core executing this code.
718*
719* Inputs:
720* none
721* Outputs:
722* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
723*****************************************************************************/
724.macro GET_NODE_ID_CORE_ID_F12
725
zbao7d94cf92012-07-02 14:19:14 +0800726
727 cmp $-1, %si # Has node/core already been discovered?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100728 jnz node_core_f12_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800729
730 AMD_CPUID $CPUID_MODEL
731 shr $20, %eax # AL = cpu extended family
732 cmp $0x03, %al # Is this family 12h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100733 jnz node_core_f12_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800734
735 shr $24, %ebx # CPUID_0000_0001_EBX[31:24]: initial local APIC physical ID
736 bts $FLAG_IS_PRIMARY, %ebx # all family 12h cores are primary
737 mov %ebx, %esi # ESI = Node#=0, core number
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100738node_core_f12_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800739.endm
740
741/*****************************************************************************
742** Family 14h MACROS
743*****************************************************************************/
744/*****************************************************************************
745*
746* AMD_ENABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
747*
748* Set any family specific controls needed to enable the use of
749* cache as general storage before main memory is available.
750*
751* Inputs:
752* ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
753* Outputs:
754* none
755*
756* Family 14h requirements (BKDG section 2.3.3):
757* * Paging must be disabled.
758* * MSRC001_0015[INVD_WBINVD]=0.
759* * MSRC001_1020[DisStreamSt]=1.
760* * MSRC001_1021[DIS_SPEC_TLB_RLD]=1. Disable speculative ITLB reloads.
761* * MSRC001_1022[DIS_HW_PF]=1.
762* * No INVD or WBINVD, no exceptions, page faults or interrupts
763*****************************************************************************/
764.macro AMD_ENABLE_STACK_FAMILY_HOOK_F14
zbao7d94cf92012-07-02 14:19:14 +0800765
766 AMD_CPUID $CPUID_MODEL
767 shr $20, %eax # AL = cpu extended family
768 cmp $0x05, %al # Is this family 14h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100769 jnz fam14_enable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800770
771 mov $DC_CFG, %ecx # MSR:C001_1022
772 _RDMSR
773 bts $DIS_HW_PF, %eax # Disable hardware prefetches
774 _WRMSR
775
776 dec %cx #IC_CFG # MSR:C001_1021
777 _RDMSR
778 bts $IC_DIS_SPEC_TLB_RLD, %eax # Disable speculative TLB reloads
779 _WRMSR
780
781 dec %cx #LS_CFG # MSR:C001_1020
782 _RDMSR
783 bts $DIS_STREAM_ST, %eax # Disabled Streaming store functionality
784 _WRMSR
785
786 mov $HWCR, %ecx # MSR C001_0015
787 _RDMSR
788 bt $FLAG_STACK_REENTRY, %esi # Check if stack has already been set
789 jc fam14_skipClearingBit4
790 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
791 _WRMSR
792fam14_skipClearingBit4: # Keeping this label
793
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100794fam14_enable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800795.endm
796
797/*****************************************************************************
798*
799* AMD_DISABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
800*
801* Return any family specific controls to their 'standard'
802* settings for using cache with main memory.
803*
804* Inputs:
805* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
806* Outputs:
807* none
808*
809* Family 14h requirements:
810* * INVD or WBINVD
811* * MSRC001_0015[INVD_WBINVD]=1.
812* * MSRC001_1020[DisStreamSt]=0.
813* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0.
814* * MSRC001_1022[DIS_HW_PF]=0.
815*****************************************************************************/
816.macro AMD_DISABLE_STACK_FAMILY_HOOK_F14
zbao7d94cf92012-07-02 14:19:14 +0800817
818 AMD_CPUID $CPUID_MODEL
819 shr $20, %eax # AL = cpu extended family
820 cmp $0x05, %al # Is this family 14h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100821 jnz fam14_disable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800822
823 mov $LS_CFG, %ecx # MSR:C001_1020
824 _RDMSR
825 btr $DIS_STREAM_ST, %eax # Turn on Streaming store functionality
826 _WRMSR
827
828 inc %cx #IC_CFG # MSR:C001_1021
829 _RDMSR
830 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative DC-TLB reloads
831 _WRMSR
832
833 inc %cx #DC_CFG # MSR:C001_1022
834 _RDMSR
835 btr $DIS_HW_PF, %eax # Turn on hardware prefetches
836 _WRMSR
837
838 #--------------------------------------------------------------------------
839 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
840 #--------------------------------------------------------------------------
841
842 mov $HWCR, %ecx # MSR:C001_0015h
843 _RDMSR
844 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
845 _WRMSR
846 invd # Clear the cache tag RAMs
847 bts $INVD_WBINVD, %eax # Turn on Conversion of INVD to WBINVD
848 _WRMSR
849
850 #--------------------------------------------------------------------------
851 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
852 #--------------------------------------------------------------------------
853
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100854fam14_disable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800855.endm
856
857/*****************************************************************************
858*
859* GET_NODE_ID_CORE_ID_F14 Macro - Stackless
860*
861* Read family specific values to determine the node and core
862* numbers for the core executing this code.
863*
864* Inputs:
865* none
866* Outputs:
867* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
868*****************************************************************************/
869.macro GET_NODE_ID_CORE_ID_F14
870
zbao7d94cf92012-07-02 14:19:14 +0800871
Edward O'Callaghan9cd96b42014-02-21 12:43:07 +1100872 cmp $-1, %si # Has node/core already been discovered?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100873 jnz node_core_f14_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800874
875 AMD_CPUID $CPUID_MODEL
876 shr $20, %eax # AL = cpu extended family
877 cmp $0x05, %al # Is this family 14h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100878 jnz node_core_f14_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800879
880 xor %esi, %esi # Node must be 0
881 bts $FLAG_IS_PRIMARY, %esi # all family 14h cores are primary
882 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
883 _RDMSR
884 bt $APIC_BSC, %eax # Is this the BSC?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100885 jc node_core_f14_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +0800886 inc %si # Set core to 1
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100887node_core_f14_exit\@:
zbao7d94cf92012-07-02 14:19:14 +0800888.endm
889
890/*****************************************************************************
891** Family 15h MACROS
892*****************************************************************************/
893/*****************************************************************************
894*
895* AMD_ENABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
896*
897* Set any family specific controls needed to enable the use of
898* cache as general storage before main memory is available.
899*
900* Inputs:
901* ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
902* Outputs:
903* none
904*
905* Family 15h requirements (BKDG #42301 section 2.3.3):
906* * Paging must be disabled.
907* * MSRC001_0015[INVD_WBINVD]=0
908* * MSRC001_1020[DisSS]=1
909* * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
910* * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
911* * MSRC001_1022[DisHwPf]=1
912* * No INVD or WBINVD, no exceptions, page faults or interrupts
913*****************************************************************************/
914.macro AMD_ENABLE_STACK_FAMILY_HOOK_F15
zbao7d94cf92012-07-02 14:19:14 +0800915
916 AMD_CPUID $CPUID_MODEL
917 mov %eax, %ebx # Save revision info to EBX
918 shr $20, %eax # AL = cpu extended family
919 cmp $0x06, %al # Is this family 15h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +0100920 jnz fam15_enable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +0800921
922 bt $FLAG_STACK_REENTRY , %esi # Check if stack has already been set
923 jc fam15_skipClearingBit4
924 mov $HWCR, %ecx # MSR C001_0015
925 _RDMSR
926 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
927 _WRMSR
928
929fam15_skipClearingBit4:
930 mov $LS_CFG, %ecx # MSR:C001_1020
931 _RDMSR
932 bts $DIS_SS, %eax # Turn on Streaming store functionality disabled bit
933 _WRMSR
934
935 inc %ecx #IC_CFG # MSR:C001_1021
936 _RDMSR
937 bts $IC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative IC-TLB reloads bit
938 _WRMSR
939
940 mov %ebx, %eax # Restore revision info to EAX
941 shr $16, %eax
942 and $0x0F, %al # AL = cpu extended model
943
944 inc %ecx #DC_CFG # MSR:C001_1022
945 _RDMSR
946 bts $DC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative DC-TLB reloads bit
947 bts $DIS_HW_PF, %eax # Turn on Disable hardware prefetches bit
948 _WRMSR # Remove KM in PI 1.1.0.0
949
950 mov %ebx, %eax # Restore revision info to EAX
951 shr $16, %eax
952 and $0xF, %al
953 #.if (al == 01h) || (al == 03h) Is this TN or KV?
954 cmp $1, %eax
955 jz 1f
956 cmp $3, %eax
957 jz 3f # Skip if it is KV, it is only for TN from Label 1 to 3
958 jmp 2f
9591: #.if (al == 01h) # TN only
960 #Enable MSRC001_001F[EnableCf8ExtCfg]
961 mov $NB_CFG, %ecx # MSR:C001_001F
Arthur Heymans3a077962022-03-23 21:35:32 +0100962 _RDMSR
zbao7d94cf92012-07-02 14:19:14 +0800963 bts $(ENABLE_CF8_EXT_CFG - 32), %edx
Arthur Heymans3a077962022-03-23 21:35:32 +0100964 _WRMSR
zbao7d94cf92012-07-02 14:19:14 +0800965 # Set F3x44[6, CpuErrDis] = 1
966 MAKE_EXT_PCI_ADDR 0, 0, 24, FUNC_3, 0x44 //MCA_NB_CFG
967 //mov $(1 << 31 | 2 << 28 | (((MCA_NB_CFG) & (0x0F00)) >> 8) << 24 | 2 << 16 | 1 << 11 | FUNC_3 << 8), %eax
968
969 mov $0xCF8, %dx
970 out %eax, %dx
971 add $4, %dx
972 in %dx, %eax
973 bts $CPU_ERR_DIS, %eax
974 out %eax, %dx
975
9763: mov $CU_CFG, %ecx # TN or KV
977 _RDMSR
978 bt $L2_WAY_LOCK_EN, %eax
979 #.if (!carry?)
980 jc 2f
981 bts $L2_WAY_LOCK_EN, %eax
982 or $L2_FIRST_LOCKED_WAY_OR_MASK, %eax
983 _WRMSR
984 #.endif
985 #.endif
9862:
987 mov %ebx, %eax # Restore revision info to EAX
988 xchg %ah, %al
989 shr $8, %eax
990 and $0xF, %al
991 #.if (ax == 6100h) ; Is this TN-A0?
992 cmp $0x6100, %ax
993 jnz 2f
994 MAKE_EXT_PCI_ADDR 0, 0, 24, FUNC_3, PRODUCT_INFO_REG1
995 mov $0xCF8, %dx
996 out %eax, %dx
997 add $4, %dx
998 in %dx, %eax
999 bt $21, %eax
1000 jc 2f
1001 mov $CU_CFG2, %ecx #MSR:C001_102A
1002 _RDMSR
1003 bts $8, %eax
1004 _WRMSR
1005 # .endif
1006
10072: # Do Standard Family 15 work
1008
1009 mov $CU_CFG3, %ecx # MSR:C001_102B
1010 _RDMSR
1011 btr $(COMBINE_CR0_CD - 32), %edx # Clear CombineCr0Cd bit
1012 _WRMSR
1013
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001014fam15_enable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +08001015.endm
1016
1017/*****************************************************************************
1018*
1019* AMD_DISABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
1020*
1021* Return any family specific controls to their 'standard'
1022* settings for using cache with main memory.
1023*
1024* Inputs:
1025* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
1026* Outputs:
1027* none
1028*
1029* Family 15h requirements:
1030* * INVD or WBINVD
1031* * MSRC001_0015[INVD_WBINVD]=1
1032* * MSRC001_1020[DisSS]=0
1033* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
1034* * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
1035* * MSRC001_1022[DIS_HW_PF]=0
1036*****************************************************************************/
1037.macro AMD_DISABLE_STACK_FAMILY_HOOK_F15
zbao7d94cf92012-07-02 14:19:14 +08001038
1039 AMD_CPUID $CPUID_MODEL
1040 mov %eax, %ebx # Save revision info to EBX
1041 shr $20, %eax # AL = cpu extended family
1042 cmp $0x06, %al # Is this family 15h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001043 jnz fam15_disable_stack_hook_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +08001044
1045 mov %ebx, %edi # Save revision info to EDI
1046 AMD_CPUID $AMD_CPUID_APIC
1047 mov %cl, %al # AL = number of cores - 1
1048 shr $APIC_ID_CORE_ID_SIZE, %cx # CL = ApicIdCoreIdSize
1049 mov $1, %bx
1050 shl %cl, %bl # BL = theoretical number of cores on socket
1051 dec %bx # BL = core number on socket mask
1052 mov %bl, %ah # AH = core number on socket mask
1053 mov %edi, %ebx # Restore revision info to EBX
1054 mov %ax, %di # DI[15:8] = core number mask, DI[7:0] = number of cores - 1
1055
1056 and $0x0F00FF, %ebx
1057 mov %ebx, %eax
1058 shr $8, %eax
1059 or %ax, %bx # Save Extended Model, Model and Stepping to BX
1060 # [11:8] = Extended Model, [7:4] = Model, [3:0] = Stepping (bx=0000000000010100, ok)
1061
1062 mov $APIC_BASE_ADDRESS, %ecx
1063 _RDMSR # dx=0 ax=fee00800
1064 mov %bx, %dx # Save Extended Model, Model and Stepping to DX
1065 shl $16, %edx #EDX[31:16] = Extended Model, Model and Stepping
1066 mov %eax ,%ebx # EBX = LAPIC base
1067 xor %ecx ,%ecx # Zero out CU flags
1068 bts $AMD_CU_NEED_TO_WAIT, %ecx # Default to waiting
1069 bts $AMD_CU_SEND_INVD_MSG, %ecx # Default to signaling
1070 mov %cr0, %eax
1071 bt $CR0_PE, %ax # Are we in protected mode?
1072 # .if (!carry?)
1073 jc 1f
1074 bts $AMD_CU_RESTORE_ES, %ecx # Indicate ES restore is required
1075 mov %es, %cx # Save ES segment register to CX
1076 xor %ax, %ax
1077 mov %ax, %es # Set ES to big real mode selector for 4GB access
1078 # .endif
1079
10801:
1081 and $0x0F000, %bx # EBX = LAPIC base, offset 0
1082 or $APIC_ID_REG, %bl #
1083 mov %es:(%ebx), %eax # EAX[31:24] = APIC ID
1084 shr $APIC20_APICID, %eax # AL = APIC ID
1085 mov %al, %ah # AH = APIC ID
1086 mov %di, %dx # DH = core mask
1087 and %dh, %ah # AH = core number # ax=111 dx=01000F03
1088
1089 # .if (zero?)
1090 jnz 1f
1091 # Core 0 of a socket
1092 btr $AMD_CU_SEND_INVD_MSG, %ecx # No need to signal after INVD
1093 #.if (dl != 0)
1094 cmp $0, %dl
1095 jz 2f
1096 # This socket has multiple cores
1097 and $0xf000, %bx # EBX = LAPIC base, offset 0
1098 or $APIC_MSG_REG, %bx
1099 mov $APIC_MSG, %edi
1100 mov %edi, %es:(%ebx) # Signal for non core 0s to complete CAR breakdown
1101 jmp 1f
1102 #.else
11032: btr $AMD_CU_NEED_TO_WAIT, %ecx # No need to wait on a single core CPU
1104 #.endif
1105 # .endif
11061:
1107
1108 bt $AMD_CU_NEED_TO_WAIT, %ecx #cx = c0000000
1109 #.if (carry?)
1110 jnc 1f
1111 #.if (ah == dl)
1112 cmp %dl, %ah
1113 jnz 2f
1114 # This is the highest numbered core on this socket -- wait on core 0
1115 not %dh # Flip the mask to determine local core 0's APID ID
1116 and %dh, %al # AL = target APIC ID # ax=310
1117 jmp 3f
11182: #.else
1119 # All other cores (including core 0) wait on the next highest core.
1120 # In this way, cores will halt in a cascading fashion down to 0.
1121 inc %al
1122 #.endif
11233:
1124 shl $APIC20_APICID, %eax
1125 and $0x0F000, %bx
1126 or $APIC_CMD_HI_REG, %bx
1127 mov %eax, %es:(%ebx) # Set target APIC ID
1128
1129 # Use bits 23:16 as a timeout for unresponsive cores
1130 ror $8, %ecx
1131 mov $0xFF, %ch
1132 stc
1133
1134 #.while (carry?)
11355: jnc 4f
1136 and $0xF000, %bx #EBX = LAPIC base, offset 0
1137 or $APIC_CMD_LO_REG, %bx # bx = 00000000FEE00300
1138 mov $CMD_REG_TO_READ_DATA, %eax
1139 mov %eax, %es:(%ebx) #Fire remove read IPI
1140 inc %ch #Pre increment the timeout
1141 stc
1142 #.while (carry?)
11437: jnc 6f
1144 dec %ch #Check the timeout
1145 jz fam15_disable_stack_remote_read_exit
1146 mov %es:(%ebx), %eax # ax = 0000000000020338
1147 bt $DELIVERY_STS_BIT, %eax
1148 jmp 7b
11496: #.endw
1150 stc
1151 #.while (carry?)
11527: jnc 6f
1153 mov %es:(%ebx), %eax
1154 and $REMOTE_READ_STS, %eax
1155 #.if (eax == REMOTE_DELIVERY_PEND)
1156 cmp $REMOTE_DELIVERY_PEND, %eax
1157 jnz 8f
1158 dec %ch # Check the timeout
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001159 jz fam15_disable_stack_hook_exit\@ # Branch if there is an unreponsive core
zbao7d94cf92012-07-02 14:19:14 +08001160 stc
1161 jmp 9f
11628: #.else
1163 clc
11649: #.endif
1165 jmp 7b
11666: #.endw
1167 #.if (eax == REMOTE_DELIVERY_DONE)
1168 cmp $REMOTE_DELIVERY_DONE, %eax
1169 jnz 6f
1170 and $0x0F000, %bx #EBX = LAPIC base, offset 0
1171 or $APIC_REMOTE_READ_REG, %bl
1172 mov %es:(%ebx), %eax
1173 #.if (eax == APIC_MSG)
1174 cmp $APIC_MSG, %eax # ax=00000000FFC5BBB2
1175 jnz 8f
1176 clc
1177 jmp 9f
1178 #.else
11798: stc
11809: #.endif
1181 jmp 7f
11826: #.else
1183 dec %ch
1184 jz fam15_disable_stack_remote_read_exit
1185 stc
11867: #.endif
1187 jmp 5b
11884: #.endw
1189
1190fam15_disable_stack_remote_read_exit:
1191 rol $8, %ecx # Restore ECX
1192
11931: #.endif
1194
1195 bt $AMD_CU_RESTORE_ES, %ecx
1196 #.if (carry?)
1197 jnc 1f
1198 mov %cx, %es
11991:
1200 mov %ecx, %edi
1201 shr $16, %edx
1202 mov %dx, %bx
1203
1204 #Handshaking complete. Continue tearing down CAR.
1205
1206 mov $LS_CFG, %ecx # MSR:C001_1020
1207 #.if (bx != 0) ; Is this OR A0?
1208 cmp $0x0, %bx
1209 jz 0f
1210 _RDMSR
1211 btr $DIS_SS, %eax # Turn on Streaming store functionality
1212 _WRMSR
1213 #.endif
12140: # End workaround for errata 495 and 496
1215
1216 inc %ecx #IC_CFG # MSR:C001_1021
1217 _RDMSR
1218 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
1219 _WRMSR
1220
1221 inc %ecx #DC_CFG # MSR:C001_1022
1222 _RDMSR
1223 btr $DC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
1224 #.if (bx != 0) # Is this rev A0?
1225 cmp $0, %bx
1226 jz 0f
1227 btr $DIS_HW_PF, %eax # Turn on hardware prefetches
1228 #.endif # End workaround for erratum 498
1229 0:
1230 _WRMSR
1231 #--------------------------------------------------------------------------
1232 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
1233 #--------------------------------------------------------------------------
1234
1235 mov $HWCR, %ecx # MSR:C001_0015h
1236 _RDMSR
1237 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
1238 _WRMSR
Kyösti Mälkki0f6c0b12017-09-07 06:46:46 +03001239 invd # Clear the cache tag RAMs
zbao7d94cf92012-07-02 14:19:14 +08001240 #.if (bh == 01h) || (bh == 03h) ; Is this TN or KM?
1241 cmp $01, %bh
1242 jz 4f
1243 cmp $03, %bh
1244 jnz 1f
12454: mov $CU_CFG, %ecx # MSR:C001_1023
1246 _RDMSR
1247 shr $L2_FIRST_LOCKED_WAY, %eax
1248 and $0x1F, %eax
1249 #.if (eax == 01Fh)
1250 cmp $0x1F, %eax #Check if way 15 of the L2 needs to be reserved
1251 jnz 3f
1252 _RDMSR
1253 btr $L2_WAY_LOCK_EN, %eax
1254 _WRMSR
12553: #.endif
1256
12571: #.endif
1258 #Do Standard Family 15 work
1259 mov $HWCR, %ecx # MSR:C001_0015h
1260 _RDMSR
1261 bts $INVD_WBINVD, %eax # Turn on Conversion of INVD to WBINVD
1262 _WRMSR
1263 #.endif # end
1264 0:
1265//
1266// #--------------------------------------------------------------------------
1267// # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
1268// #--------------------------------------------------------------------------
1269//
1270 mov $CU_CFG3, %ecx # MSR:C001_102B
1271 _RDMSR
1272 bts $(COMBINE_CR0_CD - 32), %edx # Set CombineCr0Cd bit
1273 _WRMSR
1274
1275 bt $AMD_CU_SEND_INVD_MSG, %edi
1276 #.if (carry?)
1277 jnc 1f
1278 # Non core zero needs to signal to core 0 to proceed
1279 mov $APIC_BASE_ADDRESS, %ecx
1280 _RDMSR
1281 mov %eax, %ebx # EBX = LAPIC base
1282 and $0x0F000, %bx # EBX = LAPIC base, offset 0
1283 or $APIC_MSG_REG, %bx
1284 mov $APIC_MSG, %eax
1285 mov %eax, %es:(%ebx) # Signal for core 0 to complete CAR breakdown
1286
12871: #.endif
1288
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001289fam15_disable_stack_hook_exit\@:
zbao7d94cf92012-07-02 14:19:14 +08001290.endm
1291
1292/*****************************************************************************
1293*
1294* GET_NODE_ID_CORE_ID_F15 Macro - Stackless
1295*
1296* Read family specific values to determine the node and core
1297* numbers for the core executing this code.
1298*
1299* Inputs:
1300* none
1301* Outputs:
1302* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
1303*****************************************************************************/
1304.macro GET_NODE_ID_CORE_ID_F15
1305
zbao7d94cf92012-07-02 14:19:14 +08001306
1307#define F15_L2Size 512
1308#define F15_ShareCores 2
1309#define F15_AllocMem 0
1310#define F15_AllocExe 0
1311#define F15_SzAddrBus 48
1312#define F15_pad 0
1313 cmp $-1, %si # Has node/core already been discovered?
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001314 jnz node_core_f15_exit\@ # Br if yes
zbao7d94cf92012-07-02 14:19:14 +08001315
1316 AMD_CPUID $CPUID_MODEL
1317 shr $12, %eax # AL = cpu extended family
1318 cmp $06, %ah # Is this family 15h?
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001319 jnz node_core_f15_exit\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +08001320 shr $4, %al # AL = cpu extended model
1321 shr $16, %ebx # BH = LocalApicId
1322 mov %al, %bl # BL = cpu extended model
1323
1324 # LoadTableAddress(FAM15H_INFO_STRUCT)
1325 # movd mm5, eax # load pointer to Family Info Struc
1326
1327 xor %esi, %esi # Assume BSC, clear local flags
1328 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
1329 _RDMSR
1330 bt $APIC_BSC, %eax # Is this the BSC?
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001331 jnc node_core_f15_AP\@ # Br if no
zbao7d94cf92012-07-02 14:19:14 +08001332
1333 # This is the BSP.
1334 # Enable routing tables on BSP (just in case the HT init code has not yet enabled them)
1335 mov $0x8000C06C, %eax # PCI address for D18F0x6C Link Initialization Control Register
1336 mov $0x0CF8, %dx
1337 out %eax, %dx
1338 add $4, %dx
1339 in %dx, %eax
1340 btr $0, %eax # Set LinkInitializationControl[RouteTblDis] = 0
1341 out %eax, %dx
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001342 jmp node_core_f15_shared\@ #
zbao7d94cf92012-07-02 14:19:14 +08001343
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001344node_core_f15_AP\@:
zbao7d94cf92012-07-02 14:19:14 +08001345 mov %bl, %al # AL = cpu extended model
1346 shr $8, %bx # BL = CPUID Fn0000_0001_EBX[LocalApicId]
1347 cmp $1, %al # Is This TN?
1348 jz 4f
1349 cmp $3, %al
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001350 jnz node_core_f15_AP_not_TN\@
zbao7d94cf92012-07-02 14:19:14 +080013514: mov %bx, %si
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001352 jmp node_core_f15_shared\@
zbao7d94cf92012-07-02 14:19:14 +08001353 #
1354 # This is an AP. Routing tables have been enabled by the HT Init process.
1355 # Also, the MailBox register was set by the BSP during early init
1356 # The Mailbox register content is formatted as follows:
1357 # UINT32 Node:4; // The node id of Core's node.
1358 # UINT32 Socket:4; // The socket of this Core's node.
1359 # UINT32 Module:2; // The internal module number for Core's node.
1360 # UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1.
1361 # UINT32 :20; // Reserved
1362 #
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001363node_core_f15_AP_not_TN\@:
zbao7d94cf92012-07-02 14:19:14 +08001364 mov $0x0C0000408, %ecx # Read the family 15h mailbox
1365 _RDMSR # MC4_MISC1[63:32]
1366 mov %dx, %si # SI = raw mailbox contents (will extract node# from this)
1367 shr $24, %ebx # BL = CPUID Fn0000_0001_EBX[LocalApicId]
1368 mov %bx, %di # DI = Initial APIC ID (will extract core# from this)
1369
1370 AMD_CPUID $AMD_CPUID_APIC #
1371 shr $4, %ch # CH = ApicIdSize, #bits in APIC ID that show core#
1372 inc %cl # CL = Number of enabled cores in the socket
1373 mov %cx, %bx
1374
1375 mov $NB_CFG, %ecx
1376 _RDMSR # EDX has InitApicIdCpuIdLo bit
1377
1378 mov %bh, %cl # CL = APIC ID size
1379 mov $1, %al # Convert APIC ID size to an AND mask
1380 shl %cl, %al # AL = 2^APIC ID size
1381 dec %al # AL = mask for relative core number
1382 xor %ah, %ah # AX = mask for relative core number
1383 bt $(INIT_APIC_ID_CPU_ID_LO-32), %edx # InitApicIdCpuIdLo == 1?
1384 #.if (!carry?) # Br if yes
1385 jc 0f
1386 mov $8, %ch # Calculate core number shift count
1387 sub %cl, %ch # CH = core shift count
1388 mov %ch, %cl
1389 shr %cl, %di # Right justify core number
1390 #.endif
1391 0:
1392 and %ax, %di # DI = socket-relative core number
1393
1394 mov %si, %cx # CX = raw mailbox value
1395 shr $10, %cx # CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM)
1396 and $3, %cl # Isolate ModuleType
1397 xor %bh, %bh # BX = Number of enabled cores in the socket
1398 shr %cl, %bx # BX = Number of enabled cores per node
1399 xor %dx, %dx # Clear upper word for div
1400 mov %di, %ax # AX = socket-relative core number
1401 div %bx # DX = node-relative core number
1402 movzx %si, %eax # Prepare return value
1403 and $0x000F, %ax # AX = node number
1404 shl $8,%ax # [15:8]=node#
1405 mov %dl, %al # [7:0]=core# (relative to node)
1406 mov %eax, %esi # ESI = node-relative core number
1407
1408 #
1409 # determine if this core shares MTRRs
1410 #
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001411node_core_f15_shared\@:
zbao7d94cf92012-07-02 14:19:14 +08001412 mov $0x8000C580, %eax # Compute Unit Status
1413 mov %si, %bx
1414 shl $3, %bh # Move node# to PCI Dev# field
1415 add %bh, %ah # Adjust for node number
1416 mov $0x0CF8, %dx
1417 out %eax, %dx
1418 add $4, %dx
1419 in %dx, %eax # [3:0]=Enabled# [19:16]=DualCore
1420
1421 # BL is MyCore#
1422 mov $0x06, %cx # Use CH as 'first of pair' core#
1423 #.while (cl > 0)
1424 jmp 0f
1425 8:
1426 bt $0, %eax # Is pair enabled?
1427 #.if (carry?) #
1428 jnc 1f
1429 mov $0x01, %bh # flag core as primary
1430 bt $16, %eax # Is there a 2nd in the pair?
1431 #.if (carry?) #
1432 jnc 4f
1433 #.break .if (ch == bl) # Does 1st match MyCore#?
1434 cmp %bl, %ch
1435 je 9f
1436 inc %ch
1437 xor %bh, %bh # flag core as NOT primary
1438 #.break .if (ch == bl) # Does 2nd match MyCore#?
1439 cmp %bl, %ch
1440 je 9f
1441 jmp 2f
1442 #.else # No 2nd core
1443 4:
1444 #.break .if (ch == bl) # Does 1st match MyCore#?
1445 cmp %bl, %ch
1446 je 9f
1447 #.endif
1448 2:
1449 inc %ch
1450 #.endif
1451 1:
1452 shr $1, %eax
1453 dec %cl
1454 #.endw
1455 0:
1456 #.if (cl == 0)
1457 cmp $0x0, %cl
1458 ja 8b
1459 9:
1460 or %cl, %cl
1461 jne 1f
1462 #Error - core# didn't match Compute Unit Status content
1463 bts $FLAG_CORE_NOT_IDENTIFIED, %esi
1464 bts $FLAG_IS_PRIMARY, %esi # Set Is_Primary for unknowns
1465 #.endif
1466 1:
1467 #.if (bh != 0) # Check state of primary for the matched core
1468 or %bh, %bh
1469 je 2f
1470 bts $FLAG_IS_PRIMARY, %esi # Set shared flag into return value
1471 #.endif
1472 2:
1473
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001474node_core_f15_exit\@:
zbao7d94cf92012-07-02 14:19:14 +08001475
1476.endm
1477
1478/*****************************************************************************
1479* AMD_ENABLE_STACK: Setup a stack
1480*
1481* In:
Kyösti Mälkkifec6fa72017-07-12 16:30:47 +03001482* No inputs
zbao7d94cf92012-07-02 14:19:14 +08001483*
1484* Out:
1485* SS:ESP - Our new private stack location
1486*
1487* EAX = AGESA_STATUS
1488*
1489* ECX = Stack size in bytes
1490*
1491* Requirements:
1492* * This routine presently is limited to a max of 64 processor cores
zbao7d94cf92012-07-02 14:19:14 +08001493* Destroyed:
Kyösti Mälkkifec6fa72017-07-12 16:30:47 +03001494* EBX, EDX, EDI, ESI, EBP, DS, ES
zbao7d94cf92012-07-02 14:19:14 +08001495*
1496* Description:
1497* Fixed MTRR address allocation to cores:
1498* The BSP gets 64K of stack, Core0 of each node gets 16K of stack, all other cores get 4K.
1499* There is a max of 1 BSP, 7 core0s and 56 other cores.
1500* Although each core has it's own cache storage, they share the address space. Each core must
1501* be assigned a private and unique address space for its stack. To support legacy systems,
1502* the stack needs to be within the legacy address space (1st 1Meg). Room must also be reserved
1503* for the other legacy elements (Interrupt vectors, BIOS ROM, video buffer, etc.)
1504*
1505* 80000h 40000h 00000h
1506* +----------+----------+----------+----------+----------+----------+----------+----------+
1507* 64K | | | | | | | | | 64K ea
1508* ea +----------+----------+----------+----------+----------+----------+----------+----------+
1509* | MTRR 0000_0250 MTRRfix64K_00000 |
1510* +----------+----------+----------+----------+----------+----------+----------+----------+
1511* | 7 , 6 | 5 , 4 | 3 , 2 | 1 , 0 | 0 | | | | <-node
1512* |7..1,7..1 |7..1,7..1 |7..1,7..1 |7..1,7..1 | 0 | | | | <-core
1513* +----------+----------+----------+----------+----------+----------+----------+----------+
1514*
1515* C0000h B0000h A0000h 90000h 80000h
1516* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1517*16K | | | | | | | | | | | | | | | | |
1518* ea +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1519* | MTRR 0259 MTRRfix16K_A0000 | MTRR 0258 MTRRfix16K_80000 |
1520* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1521* | > Dis|play B|uffer | < | | | | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | <-node
1522* | > T| e m |p o r |a r y | B u |f f e |r A |r e a<| 0 | 0 | 0 | 0 | 0 | 0 | 0 | | <-core
1523* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1524*
1525* E0000h D0000h C0000h
1526* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1527* 4K | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4K ea
1528* ea +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1529* | 026B MTRRfix4K_D8000 | 026A MTRRfix4K_D0000 | 0269 MTRRfix4K_C8000 | 0268 MTRRfix4K_C0000 |
1530* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1531* | | | | | | | | | | | | | | | | | >| V| I| D| E| O| |B |I |O |S | |A |r |e |a<|
1532* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1533*
1534* 100000h F0000h E0000h
1535* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1536* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4K ea
1537* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1538* | 026F MTRRfix4K_F8000 | 026E MTRRfix4K_F0000 | 026D MTRRfix4K_E8000 | 026C MTRRfix4K_E0000 |
1539* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1540* | >|MA|IN| B|IO|S |RA|NG|E | | | | | | |< | >|EX|TE|ND|ED| B|IO|S |ZO|NE| | | | | |< |
1541* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1542*****************************************************************************/
1543.macro AMD_ENABLE_STACK
1544
1545# These are local labels. Declared so linker doesn't cause 'redefined label' errors
zbao7d94cf92012-07-02 14:19:14 +08001546
1547# Note that SS:ESP will be default stack. Note that this stack
1548# routine will not be used after memory has been initialized. Because
1549# of its limited lifetime, it will not conflict with typical PCI devices.
zbao7d94cf92012-07-02 14:19:14 +08001550
1551 # get node id and core id of current executing core
1552 GET_NODE_ID_CORE_ID # Sets ESI[23:16]=Shared core## SI[15,8]= Node## SI[7,0]= core# (relative to node)
1553 # Note: ESI[31:24] are used for flags: Unrecognized Family, Is_Primary core, Stack already established
1554
1555 # determine if stack is already enabled. We are using the DefType MSR for this determination.
1556 # It is =0 after reset; CAR setup sets it to enable the MTRRs
1557 mov %cr0, %eax
1558 test $CR0_MASK, %eax # Is cache disabled? (CD & NW bits)
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001559 jnz SetupStack\@ # Jump if yes
zbao7d94cf92012-07-02 14:19:14 +08001560 mov $AMD_MTRR_DEFTYPE, %ecx # MSR:0000_02FF
1561 _RDMSR
1562 test $MSR_MASK, %eax # Are the default types enabled? (MTRR_DEF_TYPE_EN + MTRR_DEF_TYPE_FIX_EN)
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001563 jz SetupStack\@ # Jump if no
zbao7d94cf92012-07-02 14:19:14 +08001564 or $FLAG_STACK_REENTRY, %esi # Bit25, indicate stack has already been initialized
1565
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001566SetupStack\@:
zbao7d94cf92012-07-02 14:19:14 +08001567 # Set node to map the first 16MB to node 0# 0000_0000 to 00FF_FFFF as DRAM
1568 mov %esi, %ebx # Get my Node/Core info
1569 xor %bl, %bl
1570 shl $3, %bh # Isolate my node#, match alignment for PCI Dev#
1571 mov $0x8000C144, %eax # D18F1x44:DRAM Base/Limit# N is Base, N+4 is Limit
1572 add %bh, %ah
1573 mov %eax, %ebx # Save PCI address for Base/Limit pair
1574
1575 mov $0x0CF8, %dx
1576 out %eax, %dx
1577 add $4, %dx
1578 xor %eax, %eax # Least Significant bit is AD24 so 0 sets mask of 00FF_FFFF (16MB)
1579 out %eax, %dx # DRAM Limit = node0, no interleave
1580
1581 mov %ebx, %eax
1582 sub $4, %eax # Now point to the Base register
1583 mov $0x0CF8, %dx
1584 out %eax, %dx
1585 add $4, %dx
1586 mov $0x00000003, %eax # Set the read and write enable bits
1587 out %eax, %dx # DRAM Base = 0x0000, R/W
1588
1589 AMD_ENABLE_STACK_FAMILY_HOOK
1590
1591 # Init CPU MSRs for our init routines
1592 mov $MTRR_SYS_CFG, %ecx # SYS_CFG
1593 _RDMSR
1594 bts $MTRR_FIX_DRAM_MOD_EN, %eax # Turn on modification enable bit
1595 _WRMSR
1596
1597 mov %esi, %eax
1598 bt $FLAG_STACK_REENTRY, %eax # Is this a 2nd entry?
1599 #.if (!carry?) # On a re-entry, do not clear MTRRs or reset TOM; just reset the stack SS:ESP
1600 jc 0f
1601 bt $FLAG_IS_PRIMARY, %eax # Is this core the primary in a compute unit?
1602 #.if (carry?) # Families using shared groups do not need to clear the MTRRs since that is done at power-on reset
1603 # Note: Relying on MSRs to be cleared to 0's at reset for families w/shared cores
1604 # Clear all variable and Fixed MTRRs for non-shared cores
1605 jnc 0f
1606 mov $AMD_MTRR_VARIABLE_BASE0, %ecx
1607 xor %eax, %eax
1608 xor %edx, %edx
1609 #.while (cl != 10h) # Variable MTRRphysBase[n] and MTRRphysMask[n]
1610 jmp 1f
1611 2:
1612 _WRMSR
1613 inc %cl
1614 #.endw
1615 1:
1616 cmp $0x10, %cl
1617 jne 2b
1618 mov $AMD_MTRR_FIX64k_00000, %cx # MSR:0000_0250
1619 _WRMSR
1620 mov $AMD_MTRR_FIX16k_80000, %cx # MSR:0000_0258
1621 _WRMSR
1622 mov $AMD_MTRR_FIX16k_A0000, %cx # MSR:0000_0259
1623 _WRMSR
1624 mov $AMD_MTRR_FIX4k_C0000, %cx # Fixed 4Ks: MTRRfix4K_C0000 to MTRRfix4K_F8000
1625 #.while (cl != 70h)
1626 jmp 3f
1627 4:
1628 _WRMSR
1629 inc %cl
1630 #.endw
1631 3:
1632 cmp $0x70, %cl
1633 jne 4b
1634 # Set TOP_MEM (C001_001A) for non-shared cores to 16M. This will be increased at heap init.
1635 # - not strictly needed since the FixedMTRRs take presedence.
1636 mov $(16 * 1024 * 1024), %eax
1637 mov $TOP_MEM, %ecx # MSR:C001_001A
1638 _WRMSR
1639 #.endif # End Is_Primary
1640 #.endif # End Stack_ReEntry
1641 0:
1642 # Clear IORRs (C001_0016-19) and TOM2(C001_001D) for all cores
1643 xor %eax, %eax
1644 xor %edx, %edx
1645 mov $IORR_BASE, %ecx # MSR:C001_0016 - 0019
1646 #.while (cl != 1Ah)
1647 jmp 1f
1648 2:
1649 _WRMSR
1650 inc %cl
1651 #.endw
1652 1:
1653 cmp $0x1A, %cl
1654 jne 2b
1655 mov $TOP_MEM2, %ecx # MSR:C001_001D
1656 _WRMSR
1657
Paul Menzel2e0d9442014-01-25 15:59:31 +01001658 # setup MTRRs for stacks
zbao7d94cf92012-07-02 14:19:14 +08001659 # A speculative read can be generated by a speculative fetch mis-aligned in a code zone
1660 # or due to a data zone being interpreted as code. When a speculative read occurs outside a
1661 # controlled region (intentionally used by software), it could cause an unwanted cache eviction.
1662 # To prevent speculative reads from causing an eviction, the unused cache ranges are set
1663 # to UC type. Only the actively used regions (stack, heap) are reflected in the MTRRs.
1664 # Note: some core stack regions will share an MTRR since the control granularity is much
1665 # larger than the allocated stack zone. The allocation algorithm must account for this 'extra'
1666 # space covered by the MTRR when parseling out cache space for the various uses. In some cases
1667 # this could reduce the amount of EXE cache available to a core. see cpuCacheInit.c
1668 #
1669 # Outcome of this block is that: (Note the MTRR map at the top of the file)
1670 # ebp - start address of stack block
1671 # ebx - [31:16] - MTRR MSR address
1672 # - [15:8] - slot# in MTRR register
1673 # - [7:0] - block size in #4K blocks
1674 # review: ESI[31:24]=Flags; SI[15,8]= Node#; SI[7,0]= core# (relative to node)
1675 #
1676
1677 mov %si, %ax # Load node, core
1678 #.if (al == 0) # Is a core 0?
1679 or %al, %al
1680 jne 1f
1681 #.if (ah == 0) # Is Node 0? (BSP)
1682 or %ah, %ah
1683 jne 2f
1684 # Is BSP, assign a 64K stack
Stefan Reinauer4a45ec42015-07-07 00:54:05 +02001685 mov $((AMD_MTRR_FIX64k_00000 << 16) + (3 << 8) + (BSP_STACK_SIZE >> 12)), %ebx
zbao7d94cf92012-07-02 14:19:14 +08001686 mov $BSP_STACK_BASE_ADDR, %ebp
1687 jmp 0f
1688 #.else # node 1 to 7, core0
1689 2:
1690 # Is a Core0 of secondary node, assign 16K stacks
1691 mov $AMD_MTRR_FIX16k_80000, %bx
1692 shl $16, %ebx #
1693 mov %ah, %bh # Node# is used as slot#
Stefan Reinauer4a45ec42015-07-07 00:54:05 +02001694 mov $(CORE0_STACK_SIZE >> 12), %bl
zbao7d94cf92012-07-02 14:19:14 +08001695 mov %ah, %al # Base = (Node# * Size)#
1696 mul %bl #
1697 movzx %ax, %eax #
1698 shl $12, %eax # Expand back to full byte count (* 4K)
1699 add $CORE0_STACK_BASE_ADDR, %eax
1700 mov %eax, %ebp
1701 #.endif
1702 jmp 0f
1703 #.else #core 1 thru core 7
1704 1:
1705 # Is core 1-7 of any node, assign 4K stacks
1706 mov $8, %al # CoreIndex = ( (Node# * 8) ...
1707 mul %ah #
1708 mov %si, %bx #
1709 add %bl, %al # ... + Core#)#
1710
1711 mov $AMD_MTRR_FIX64k_00000, %bx
1712 shl $16, %ebx #
1713 mov %al, %bh # Slot# = (CoreIndex / 16) + 4#
1714 shr $4, %bh #
1715 add $4, %bh #
Stefan Reinauer4a45ec42015-07-07 00:54:05 +02001716 mov $(CORE1_STACK_SIZE >> 12), %bl
zbao7d94cf92012-07-02 14:19:14 +08001717
1718 mul %bl # Base = ( (CoreIndex * Size) ...
1719 movzx %ax, %eax #
1720 shl $12, %eax # Expand back to full byte count (* 4K)
1721 add $CORE1_STACK_BASE_ADDR, %eax # ... + Base_Addr)#
1722 mov %eax, %ebp
1723 #.endif
1724 0:
1725
1726 # Now set the MTRR. Add this to already existing settings (don't clear any MTRR)
1727 mov $WB_DRAM_TYPE, %edi # Load Cache type in 1st slot
1728 mov %bh, %cl # ShiftCount = ((slot# ...
1729 and $0x03, %cl # ... % 4) ...
1730 shl $0x03, %cl # ... * 8)#
1731 shl %cl, %edi # Cache type is now in correct position
1732 ror $16, %ebx # Get the MTRR address
1733 movzx %bx, %ecx #
1734 rol $16, %ebx # Put slot# & size back in BX
1735 _RDMSR # Read-modify-write the MSR
1736 #.if (bh < 4) # Is value in lower or upper half of MSR?
1737 cmp $4, %bh
1738 jae 1f
1739 or %edi, %eax #
1740 jmp 0f
1741 #.else
1742 1: #
1743 or %edi, %edx #
1744 #.endif #
1745 0:
1746 _WRMSR #
1747
1748 # Enable MTRR defaults as UC type
1749 mov $AMD_MTRR_DEFTYPE, %ecx # MSR:0000_02FF
1750 _RDMSR # Read-modify-write the MSR
1751 bts $MTRR_DEF_TYPE_EN, %eax # MtrrDefTypeEn
1752 bts $MTRR_DEF_TYPE_FIX_EN, %eax # MtrrDefTypeFixEn
1753 _WRMSR
1754
1755 # Close the modification window on the Fixed MTRRs
1756 mov $MTRR_SYS_CFG, %ecx # MSR:0C001_0010
1757 _RDMSR
1758 bts $MTRR_FIX_DRAM_EN, %eax # MtrrFixDramEn
1759 bts $MTRR_VAR_DRAM_EN, %eax # variable MTRR enable bit
1760 btr $MTRR_FIX_DRAM_MOD_EN, %eax # Turn off modification enable bit
1761 _WRMSR
1762
1763 # Enable caching in CR0
1764 mov %cr0, %eax # Enable WT/WB cache
1765 btr $CR0_PG, %eax # Make sure paging is disabled
1766 btr $CR0_CD, %eax # Clear CR0 NW and CD
1767 btr $CR0_NW, %eax
1768 mov %eax, %cr0
1769
1770 # Use the Stack Base & size to calculate SS and ESP values
1771 # review:
1772 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1773 # ebp - start address of stack block
1774 # ebx - [31:16] - MTRR MSR address
1775 # - [15:8] - slot# in MTRR register
1776 # - [7:0] - block size in #4K blocks
1777 #
1778 mov %ebp, %esp # Initialize the stack pointer
1779 mov %esp, %edi # Copy the stack start to edi
1780 movzx %bl, %bx
1781 movzx %bx, %ebx # Clear upper ebx, don't need MSR addr anymore
1782 shl $12, %ebx # Make size full byte count (* 4K)
1783 add %ebx, %esp # Set the Stack Pointer as full linear address
1784 sub $4, %esp
1785 #
1786 # review:
1787 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1788 # edi - 32b start address of stack block
1789 # ebx - size of stack block
1790 # esp - 32b linear stack pointer
1791 #
1792
1793 # Determine mode for SS base;
1794 mov %cr0, %ecx # Check for 32-bit protect mode
1795 bt $CR0_PE, %ecx #
1796 #.if (!carry?) # PE=0 means real mode
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001797 jc Protected32Mode\@
zbao7d94cf92012-07-02 14:19:14 +08001798 mov %cs, %cx # PE=1
1799 cmp $0x0D000, %cx # Check for CS
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001800 jb Protected32Mode\@ # If CS < D000, it is a selector instead of a segment
zbao7d94cf92012-07-02 14:19:14 +08001801 # alter SS:ESP for 16b Real Mode:
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001802Real16bMode\@:
zbao7d94cf92012-07-02 14:19:14 +08001803 mov %edi, %eax
1804 shr $4, %eax # Create a Real Mode segment for ss, ds, es
1805 mov %ax, %ss
1806 mov %ax, %ds
1807 mov %ax, %es
1808 shl $4, %eax
1809 sub %eax, %edi # Adjust the clearing pointer for Seg:Offset mode
1810 mov %ebx, %esp # Make SP an offset from SS
1811 sub $4, %esp #
1812 # .endif # endif
1813 # #else
1814 # Default is to use Protected 32b Mode
1815 #.endif
1816 ;
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001817Protected32Mode\@:
zbao7d94cf92012-07-02 14:19:14 +08001818 #
1819 # Clear The Stack
1820 # Now that we have set the location and the MTRRs, initialize the cache by
1821 # reading then writing to zero all of the stack area.
1822 # review:
1823 # ss - Stack base
1824 # esp - stack pointer
1825 # ebx - size of stack block
1826 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1827 # edi - address of start of stack block
1828 #
1829
Arthur Heymans4bf582f2022-03-23 21:36:24 +01001830ClearTheStack\@: # Stack base is in SS, stack pointer is in ESP
zbao7d94cf92012-07-02 14:19:14 +08001831 shr $2, %ebx # ebx = stack block size in dwords
1832 mov %bx, %cx #
1833 # Check our flags - Don't clear an existing stack
1834 #.if ( !(esi & 0FF000000h)) # Check our flags
1835 test $(1 << FLAG_STACK_REENTRY), %esi
1836 jne 1f
1837 cld
1838 mov %edi, %esi
1839 rep lodsl (%esi) # Pre-load the range
1840 xor %eax, %eax
1841 mov %bx, %cx
1842 mov %edi, %esi # Preserve base for push on stack
1843 rep stosl (%edi) # Clear the range
1844 movl $0x0ABCDDCBA, (%esp) # Put marker in top stack dword
1845 shl $2, %ebx # Put stack size and base
1846 push %ebx # in top of stack
1847 push %esi
1848
1849 mov %ebx, %ecx # Return size of stack in bytes
1850 xor %eax, %eax # eax = 0 : no error return code
1851 jmp 0f
1852 #.else
1853 1:
1854 movzx %cx, %ecx
1855 shl $2, %ecx # Return size of stack in bytes
1856 mov %esi, %eax
1857 shr $24, %eax # Keep the flags as part of the error report
1858 or $0x40000000, %eax # eax = AGESA_WARNING (Stack has already been set up)
1859 #.endif
1860 0:
zbao7d94cf92012-07-02 14:19:14 +08001861.endm
1862
1863/*****************************************************************************
Kyösti Mälkki0f6c0b12017-09-07 06:46:46 +03001864* AMD_DISABLE_STACK: Destroy the stack inside the cache. This routine
1865* should only be executed on the BSP
zbao7d94cf92012-07-02 14:19:14 +08001866*
1867* In:
1868* none
1869*
1870* Out:
Kyösti Mälkkifec6fa72017-07-12 16:30:47 +03001871* none
zbao7d94cf92012-07-02 14:19:14 +08001872*
1873* Preserved:
Kyösti Mälkkifec6fa72017-07-12 16:30:47 +03001874* ESP
zbao7d94cf92012-07-02 14:19:14 +08001875* Destroyed:
Kyösti Mälkkifec6fa72017-07-12 16:30:47 +03001876* EAX, EBX, ECX, EDX, EDI, ESI
zbao7d94cf92012-07-02 14:19:14 +08001877*****************************************************************************/
1878.macro AMD_DISABLE_STACK
1879
zbao7d94cf92012-07-02 14:19:14 +08001880 # get node/core/flags of current executing core
1881 GET_NODE_ID_CORE_ID # Sets ESI[15,8]= Node#; ESI[7,0]= core# (relative to node)
1882
1883 # Turn on modification enable bit
1884 mov $MTRR_SYS_CFG, %ecx # MSR:C001_0010
1885 _RDMSR
1886 bts $MTRR_FIX_DRAM_MOD_EN, %eax # Enable modifications
1887 _WRMSR
1888
1889 # Set lower 640K MTRRs for Write-Back memory caching
1890 mov $AMD_MTRR_FIX64k_00000, %ecx
1891 mov $0x1E1E1E1E, %eax
1892 mov %eax, %edx
1893 _WRMSR # 0 - 512K = WB Mem
1894 mov $AMD_MTRR_FIX16k_80000, %ecx
1895 _WRMSR # 512K - 640K = WB Mem
1896
1897 # Turn off modification enable bit
1898 mov $MTRR_SYS_CFG, %ecx # MSR:C001_0010
1899 _RDMSR
1900 btr $MTRR_FIX_DRAM_MOD_EN, %eax # Disable modification
1901 _WRMSR
1902
1903 AMD_DISABLE_STACK_FAMILY_HOOK # Re-Enable 'normal' cache operations
1904
zbao7d94cf92012-07-02 14:19:14 +08001905.endm