blob: d6c627850b8e347a18c923821339b983ca307069 [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 */
45CORE1_STACK_SIZE = 0x1000 /* 4KB for each AP cores */
46
47APIC_BASE_ADDRESS = 0x0000001B
48 APIC_BSC = 8 /* Boot Strap Core */
49
50APIC_MSG_REG = 0x380 # Location of BSC message
51 APIC_MSG = 0x00DE00AD # Message data
52APIC_CMD_LO_REG = 0x300 # APIC command low
53APIC_CMD_HI_REG = 0x310 # APIC command high
54 CMD_REG_TO_READ_DATA = 0x00000338 # APIC command for remote read of APIC_MSG_REG
55 REMOTE_READ_STS = 0x00030000 # Remote read status mask
56 REMOTE_DELIVERY_PEND = 0x00010000 # Remote read is pending
57 REMOTE_DELIVERY_DONE = 0x00020000 # Remote read is complete
58 DELIVERY_STS_BIT = 12 #Delivery status valid bit
59APIC_ID_REG = 0x0020 # Local APIC ID offset
60 APIC20_APICID = 24
61APIC_REMOTE_READ_REG = 0x00C0 # Remote read offset
62
63# Flags can only run from bits 31 to 24. Bits 23:0 are in use.
64AMD_CU_NEED_TO_WAIT = 31
65AMD_CU_SEND_INVD_MSG = 30
66AMD_CU_RESTORE_ES = 29
67
68AMD_MTRR_VARIABLE_BASE0 = 0x0200
69AMD_MTRR_VARIABLE_BASE6 = 0x020C
70AMD_MTRR_VARIABLE_BASE7 = 0x020E
71 VMTRR_VALID = 11
72 MTRR_TYPE_WB = 0x06
73 MTRR_TYPE_WP = 0x05
74 MTRR_TYPE_WT = 0x04
75 MTRR_TYPE_UC = 0x00
76AMD_MTRR_VARIABLE_MASK7 = 0x020F
77AMD_MTRR_FIX64k_00000 = 0x0250
78AMD_MTRR_FIX16k_80000 = 0x0258
79AMD_MTRR_FIX16k_A0000 = 0x0259
80AMD_MTRR_FIX4k_C0000 = 0x0268
81AMD_MTRR_FIX4k_C8000 = 0x0269
82AMD_MTRR_FIX4k_D0000 = 0x026A
83AMD_MTRR_FIX4k_D8000 = 0x026B
84AMD_MTRR_FIX4k_E0000 = 0x026C
85AMD_MTRR_FIX4k_E8000 = 0x026D
86AMD_MTRR_FIX4k_F0000 = 0x026E
87AMD_MTRR_FIX4k_F8000 = 0x026F
88
89/* Reproduced from AGESA.h */
90AMD_AP_MTRR_FIX64k_00000 = 0x00000250
91AMD_AP_MTRR_FIX16k_80000 = 0x00000258
92AMD_AP_MTRR_FIX16k_A0000 = 0x00000259
93AMD_AP_MTRR_FIX4k_C0000 = 0x00000268
94AMD_AP_MTRR_FIX4k_C8000 = 0x00000269
95AMD_AP_MTRR_FIX4k_D0000 = 0x0000026A
96AMD_AP_MTRR_FIX4k_D8000 = 0x0000026B
97AMD_AP_MTRR_FIX4k_E0000 = 0x0000026C
98AMD_AP_MTRR_FIX4k_E8000 = 0x0000026D
99AMD_AP_MTRR_FIX4k_F0000 = 0x0000026E
100AMD_AP_MTRR_FIX4k_F8000 = 0x0000026F
101CPU_LIST_TERMINAL = 0xFFFFFFFF
102
103AMD_MTRR_DEFTYPE = 0x02FF
104 WB_DRAM_TYPE = 0x1E /* MemType - memory type */
105 MTRR_DEF_TYPE_EN = 11 /* MtrrDefTypeEn - variable and fixed MTRRs default enabled */
106 MTRR_DEF_TYPE_FIX_EN = 10 /* MtrrDefTypeEn - fixed MTRRs default enabled */
107
108HWCR = 0x0C0010015 /* Hardware Configuration */
109 INVD_WBINVD = 0x04 /* INVD to WBINVD conversion */
110
111IORR_BASE = 0x0C0010016 /* IO Range Regusters Base/Mask, 2 pairs */
112 /* uses 16h - 19h */
113TOP_MEM = 0x0C001001A /* Top of Memory */
114TOP_MEM2 = 0x0C001001D /* Top of Memory2 */
115
116LS_CFG = 0x0C0011020 /* Load-Store Configuration */
117 DIS_SS = 28 /* Family 10h,12h,15h:Disable Streng Store functionality */
118 DIS_STREAM_ST = 28 /* Family 14h:DisStreamSt - Disable Streaming Store functionality */
119
120IC_CFG = 0x0C0011021 /* Instruction Cache Config Register */
121 IC_DIS_SPEC_TLB_RLD = 9 /* Disable speculative TLB reloads */
122 DIS_IND = 14 /* Family 10-14h:Disable Indirect Branch Predictor */
123 DIS_I_CACHE = 14 /* Family 15h:DisICache - Disable Indirect Branch Predictor */
124
125DC_CFG = 0x0C0011022 /* Data Cache Configuration */
126 DC_DIS_SPEC_TLB_RLD = 4 /* Disable speculative TLB reloads */
127 DIS_CLR_WBTOL2_SMC_HIT = 8 /* self modifying code check buffer bit */
128 DIS_HW_PF = 13 /* Hardware prefetches bit */
129
130CU_CFG = 0x0C0011023 /* Family 15h: Combined Unit Configuration */
131 L2_WAY_LOCK_EN = 23 /* L2WayLock - L2 way lock enable */
132 L2_FIRST_LOCKED_WAY = 19 /* L2FirstLockedWay - first L2 way lockedh */
133 L2_FIRST_LOCKED_WAY_OR_MASK = 0x000780000
134
135DE_CFG = 0x0C0011029 /* Decode Configuration */
136 CL_FLUSH_SERIALIZE = 23 /* Family 12h,15h: CL Flush Serialization */
137
138BU_CFG2 = 0x0C001102A /* Family 10h: Bus Unit Configuration 2 */
139CU_CFG2 = 0x0C001102A /* Family 15h: Combined Unit Configuration 2 */
140 F10_CL_LINES_TO_NB_DIS = 15 /* ClLinesToNbDis - allows WP code to be cached in L2 */
141 IC_DIS_SPEC_TLB_WR = 35 /* IcDisSpecTlbWr - ITLB speculative writes */
142
143CU_CFG3 = 0x0C001102B /* Combined Unit Configuration 3 */
144 COMBINE_CR0_CD = 49 /* Combine CR0.CD for both cores of a compute unit */
145
146CR0_PE = 0 # Protection Enable
147CR0_NW = 29 # Not Write-through
148CR0_CD = 30 # Cache Disable
149CR0_PG = 31 # Paging Enable
150
151/* CPUID Functions */
152
153CPUID_MODEL = 1
154AMD_CPUID_FMF = 0x80000001 /* Family Model Features information */
155AMD_CPUID_L2Cache = 0X80000006 /* L2/L3 cache info */
156AMD_CPUID_APIC = 0x80000008 /* Long Mode and APIC info., core count */
157 APIC_ID_CORE_ID_SIZE = 12 /* ApicIdCoreIdSize bit position */
158
159NB_CFG = 0x0C001001F /* Northbridge Configuration Register */
160 INIT_APIC_ID_CPU_ID_LO = 54 /* InitApicIdCpuIdLo - is core# in high or low half of APIC ID? */
161 ENABLE_CF8_EXT_CFG = 46 /* EnableCf8ExtCfg - enable CF8 extended configuration cycles */
162
163MTRR_SYS_CFG = 0x0C0010010 /* System Configuration Register */
164 CHX_TO_DIRTY_DIS = 16 /* ChxToDirtyDis Change to dirty disable */
165 SYS_UC_LOCK_EN = 17 /* SysUcLockEn System lock command enable */
166 MTRR_FIX_DRAM_EN = 18 /* MtrrFixDramEn MTRR fixed RdDram and WrDram attributes enable */
167 MTRR_FIX_DRAM_MOD_EN = 19 /* MtrrFixDramModEn MTRR fixed RdDram and WrDram modification enable */
168 MTRR_VAR_DRAM_EN = 20 /* MtrrVarDramEn MTRR variable DRAM enable */
169 MTRR_TOM2_EN = 21 /* MtrrTom2En MTRR top of memory 2 enable */
170
171PERF_CONTROL3 = 0x0C0010003 /* Performance event control three */
172 PERF_CONTROL3_RESERVE_L = 0x00200000 /* Preserve the reserved bits */
173 PERF_CONTROL3_RESERVE_H = 0x0FCF0 /* Preserve the reserved bits */
174 CONFIG_EVENT_L = 0x0F0E2 /* All cores with level detection */
175 CONFIG_EVENT_H = 4 /* Increment count by number of event */
176 /* occured in clock cycle */
177 EVENT_ENABLE = 22 /* Enable the event */
178PERF_COUNTER3 = 0x0C0010007 /* Performance event counter three */
179
180FUNC_3 = 3
181MCA_NB_CFG = 0x44 /* MCA NB Configuration */
182CPU_ERR_DIS = 6 /* CPU error response disable */
183PRODUCT_INFO_REG1 = 0x1FC /* Product Information Register 1 */
184
185# Local use flags, in upper most byte if ESI
186FLAG_UNKNOWN_FAMILY = 24 # Signals that the family# of the installed processor is not recognized
187FLAG_STACK_REENTRY = 25 # Signals that the environment has made a re-entry (2nd) call to set up the stack
188FLAG_IS_PRIMARY = 26 # Signals that this core is the primary within the comoute unit
189FLAG_CORE_NOT_IDENTIFIED = 27 # Signals that the cores/compute units of the installed processor is not recognized
190FLAG_FORCE_32K_STACK = 28 # Signals that to force 32KB stack size for BSP core
191CR0_MASK = ((1 << CR0_CD) | (1 << CR0_NW))
192MSR_MASK = ((1 << MTRR_DEF_TYPE_EN)+(1 << MTRR_DEF_TYPE_FIX_EN))
193
194/****************************************************************************
195 *
196 * CPU MACROS - PUBLIC
197 *
198 ****************************************************************************/
199.macro _WRMSR
200 .byte 0x0f, 0x30
201.endm
202
203.macro _RDMSR
204 .byte 0x0F, 0x32
205.endm
206
207.macro AMD_CPUID arg0
208 .ifb \arg0
209 mov $0x1, %eax
210 .byte 0x0F, 0x0A2 /* Execute instruction */
211 bswap %eax
212 xchg %ah, %al /* Ext model in al now */
213 rol $0x08, %eax /* Ext model in ah, model in al */
214 and $0x0FFCF, ax /* Keep 23:16, 7:6, 3:0 */
215 .else
216 mov \arg0, %eax
217 .byte 0x0F, 0x0A2
218 .endif
219.endm
220
221.macro MAKE_EXT_PCI_ADDR Seg, Bus, Dev, Func, Offset
222 mov $(1 << 31 | (Seg) << 28 | (((Offset) & (0x0F00)) >> 8) << 24 | (Bus) << 16 | (Dev) << 11 | (Func) << 8) | ((Offset) & (0xFC)), %eax
223.endm
224/****************************************************************************
225*
226* AMD_ENABLE_STACK_FAMILY_HOOK Macro - Stackless
227*
228* Set any family specific controls needed to enable the use of
229* cache as general storage before main memory is available.
230*
231* Inputs:
232* none
233* Outputs:
234* none
235 ****************************************************************************/
236.macro AMD_ENABLE_STACK_FAMILY_HOOK
237
238 AMD_ENABLE_STACK_FAMILY_HOOK_F10
239 AMD_ENABLE_STACK_FAMILY_HOOK_F12
240 AMD_ENABLE_STACK_FAMILY_HOOK_F14
241 AMD_ENABLE_STACK_FAMILY_HOOK_F15
242.endm
243
244/****************************************************************************
245*
246* AMD_DISABLE_STACK_FAMILY_HOOK Macro - Stackless
247*
248* Return any family specific controls to their 'standard'
249* settings for using cache with main memory.
250*
251* Inputs:
252* none
253* Outputs:
254* none
255 ****************************************************************************/
256.macro AMD_DISABLE_STACK_FAMILY_HOOK
257
258 AMD_DISABLE_STACK_FAMILY_HOOK_F10
259 AMD_DISABLE_STACK_FAMILY_HOOK_F12
260 AMD_DISABLE_STACK_FAMILY_HOOK_F14
261 AMD_DISABLE_STACK_FAMILY_HOOK_F15
262
263.endm
264
265/****************************************************************************
266*
267* GET_NODE_ID_CORE_ID Macro - Stackless
268*
269* Read family specific values to determine the node and core
270* numbers for the core executing this code.
271*
272* Inputs:
273* none
274* Outputs:
275* SI[7:0] = Core# (0..N, relative to node)
276* SI[15:8]= Node# (0..N)
277* SI[23:16]= reserved
278* SI[24]= flag: 1=Family Unrecognized
279* SI[25]= flag: 1=Interface re-entry call
280* SI[26]= flag: 1=Core is primary of compute unit
281* SI[31:27]= reserved, =0
282****************************************************************************/
283.macro GET_NODE_ID_CORE_ID
284 LOCAL node_core_exit
285
286 mov $-1, %si
287 GET_NODE_ID_CORE_ID_F10
288 GET_NODE_ID_CORE_ID_F12
289 GET_NODE_ID_CORE_ID_F14
290 GET_NODE_ID_CORE_ID_F15
291 /*
292 * Check for unrecognized Family
293 */
294 cmp $-1, %si # Has family (node/core) already been discovered?
295 jnz node_core_exit # Br if yes
296
297 mov $((1 << FLAG_UNKNOWN_FAMILY)+(1 << FLAG_IS_PRIMARY)), %esi # No, Set error code, Only let BSP continue
298
299 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
300 _RDMSR
301 bt $APIC_BSC, %eax # Is this the BSC?
302 jc node_core_exit # Br if yes
303 hlt # Kill APs
304node_core_exit:
305
306.endm
307
308/****************************************************************************
309## Family 10h MACROS
310##***************************************************************************
311#---------------------------------------------------
312#
313# AMD_ENABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
314#
315# Set any family specific controls needed to enable the use of
316# cache as general storage before main memory is available.
317#
318# Inputs:
319# ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
320# Outputs:
321# none
322#
323# Family 10h requirements (BKDG section 2.3.3):
324# * Paging disabled
325# * MSRC001_0015[INVDWBINVD]=0
326# * MSRC001_1021[DIS_IND]=1
327# * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
328# * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
329# * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1
330# * MSRC001_1022[DIS_HW_PF]=1
331# * MSRC001_102A[IcDisSpecTlbWr]=1
332# * MSRC001_102A[ClLinesToNbDis]=1
333# * No INVD or WBINVD, no exceptions, page faults or interrupts
334****************************************************************************/
335.macro AMD_ENABLE_STACK_FAMILY_HOOK_F10
336 LOCAL fam10_enable_stack_hook_exit
337
338 AMD_CPUID $CPUID_MODEL
339 shr $20, %eax # AL = cpu extended family
340 cmp $0x01, %al # Is this family 10h?
341 jnz fam10_enable_stack_hook_exit # Br if no
342
343 mov $DC_CFG, %ecx # MSR:C001_1022
344 _RDMSR
345 bts $DC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative DTLB reloads bit
346 bts $DIS_CLR_WBTOL2_SMC_HIT, %eax # Turn on Disable the self modifying code check buffer bit
347 bts $DIS_HW_PF, %eax # Turn on Disable hardware prefetches bit
348 _WRMSR
349
350 dec %cx # MSR:C001_1021
351 _RDMSR
352 bts $IC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative TLB reloads bit
353 bts $DIS_IND, %eax # Turn on Disable indirect branch predictor
354 _WRMSR
355
356 mov $BU_CFG2, %ecx # MSR C001_102A
357 _RDMSR
358 bts $F10_CL_LINES_TO_NB_DIS, %eax # Allow BIOS ROM to be cached in the IC
359 bts $(IC_DIS_SPEC_TLB_WR-32), %edx #Disable speculative writes to the ITLB
360 _WRMSR
361
362 mov $HWCR, %ecx # MSR C001_0015
363 _RDMSR
364 bt $FLAG_STACK_REENTRY, %esi # Check if stack has already been set
365 jc fam10_skipClearingBit4
366 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
367 _WRMSR
368
369fam10_skipClearingBit4:
370 mov %esi, %eax # load core#
371 or %al, %al # If (BSP)
372 jne fam10_enable_stack_hook_exit
373 mov $PERF_COUNTER3, %ecx # Select performance counter three
374 # to count number of CAR evictions
375 xor %eax, %eax # Initialize the lower part of the counter to zero
376 xor %edx, %edx # Initializa the upper part of the counter to zero
377 _WRMSR # Save it
378 mov $PERF_CONTROL3, %ecx # Select the event control three
379 _RDMSR # Get the current setting
380 and $PERF_CONTROL3_RESERVE_L, %eax # Preserve the reserved bits
381 or $CONFIG_EVENT_L, %eax # Set the lower part of event register to
382 # select CAR Corruption occurred by any cores
383 and $PERF_CONTROL3_RESERVE_H, %dx # Preserve the reserved bits
384 or $CONFIG_EVENT_H, %dx # Set the upper part of event register
385 _WRMSR # Save it
386 bts $EVENT_ENABLE, %eax # Enable it
387 _WRMSR # Save it
388
389fam10_enable_stack_hook_exit:
390.endm
391
392/****************************************************************************
393*
394* AMD_DISABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
395*
396* Return any family specific controls to their 'standard'
397* settings for using cache with main memory.
398*
399* Inputs:
400* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
401* Outputs:
402* none
403*
404* Family 10h requirements:
405* * INVD or WBINVD
406* * MSRC001_0015[INVD_WBINVD]=1
407* * MSRC001_1021[DIS_IND]=0
408* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
409* * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
410* * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
411* * MSRC001_1022[DIS_HW_PF]=0
412* * MSRC001_102A[IcDisSpecTlbWr]=0
413* * MSRC001_102A[ClLinesToNbDis]=0
414*****************************************************************************/
415
416.macro AMD_DISABLE_STACK_FAMILY_HOOK_F10
417 LOCAL fam10_disable_stack_hook_exit
418
Damien Zammit9e818872014-11-19 00:20:08 +1100419 AMD_CPUID $CPUID_MODEL
zbao7d94cf92012-07-02 14:19:14 +0800420 shr $20, %eax # AL = cpu extended family
421 cmp $0x01, %al # Is this family 10h?
422 jnz fam10_disable_stack_hook_exit # Br if no
423
424 mov $DC_CFG, %ecx # MSR:C001_1022
425 _RDMSR
426 btr $DC_DIS_SPEC_TLB_RLD, %eax # Enable speculative TLB reloads
427 btr $DIS_CLR_WBTOL2_SMC_HIT, %eax # Allow self modifying code check buffer
428 btr $DIS_HW_PF, %eax # Allow hardware prefetches
429 _WRMSR
430
431 dec %cx # MSR:C001_1021
432 _RDMSR
433 btr $DIS_IND, %eax # Turn on indirect branch predictor
434 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
435 _WRMSR
436
437 mov $BU_CFG2, %ecx # MSR:C001_102A
438 _RDMSR
439 btr $F10_CL_LINES_TO_NB_DIS, %eax # Return L3 to normal mode
440 btr $(IC_DIS_SPEC_TLB_WR-32), %edx #Re-enable speculative writes to the ITLB
441 _WRMSR
442
443 #--------------------------------------------------------------------------
444 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
445 #--------------------------------------------------------------------------
446
447 mov $HWCR, %ecx # MSR:0000_0015
448 _RDMSR
449 mov %ax, %bx # Save INVD -> WBINVD bit
450 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion for the invd instruction.
451 _WRMSR
452 invd # Clear the cache tag RAMs
453 mov %bx, %ax # Restore INVD -> WBINVD bit
454 _WRMSR
455
456 #--------------------------------------------------------------------------
457 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
458 #--------------------------------------------------------------------------
459
460 mov $PERF_CONTROL3, %ecx # Select the event control three
461 _RDMSR # Retrieve the current value
462 btc $EVENT_ENABLE, %eax # Is event enable, complement it as well
463 jnc fam10_disable_stack_hook_exit # No
464 cmp $CONFIG_EVENT_L, %ax # Is the lower part of event set to capture the CAR Corruption
465 jne fam10_disable_stack_hook_exit # No
466 cmp $CONFIG_EVENT_H, %dl # Is the upper part of event set to capture the CAR Corruption
467 jne fam10_disable_stack_hook_exit # No
468 _WRMSR # Disable the event
469
470fam10_disable_stack_hook_exit:
471.endm
472
473/****************************************************************************
474*
475* GET_NODE_ID_CORE_ID_F10 Macro - Stackless
476*
477* Read family specific values to determine the node and core
478* numbers for the core executing this code.
479*
480* Inputs:
481* none
482* Outputs:
483* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
484*****************************************************************************/
485.macro GET_NODE_ID_CORE_ID_F10
486
487 LOCAL node_core_f10_exit
488 LOCAL node_core_f10_AP
489
490 cmp $-1, %si # Has node/core already been discovered?
491 jnz node_core_f10_exit # Br if yes
492
493 AMD_CPUID $CPUID_MODEL
494 shr $20, %eax # AL = cpu extended family
495 cmp $0x01, %al # Is this family 10h?
496 jnz node_core_f10_exit # Br if no
497
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?
502 jnc node_core_f10_AP # Br if no
503
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
515node_core_f10_AP:
516 #
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
571node_core_f10_exit:
572.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
602 LOCAL fam12_enable_stack_hook_exit
603
604 AMD_CPUID $CPUID_MODEL
605 shr $20, %eax # AL = cpu extended family
606 cmp $0x03, %al # Is this family 12h?
607 jnz fam12_enable_stack_hook_exit # Br if no
608
609 mov $DC_CFG, %ecx # MSR:C001_1022
610 _RDMSR
611 bts $DC_DIS_SPEC_TLB_RLD, %eax # Disable speculative DC-TLB reloads
612 bts $DIS_CLR_WBTOL2_SMC_HIT, %eax # Disable self modifying code check buffer
613 bts $DIS_HW_PF, %eax # Disable hardware prefetches
614 _WRMSR
615
616 dec %cx #IC_CFG # MSR:C001_1021
617 _RDMSR
618 bts $IC_DIS_SPEC_TLB_RLD, %eax # Disable speculative IC-TLB reloads
619 _WRMSR
620
621 dec %cx #LS_CFG # MSR:C001_1020
622 _RDMSR
623 bts $DIS_SS, %eax # Disabled Streaming store functionality
624 _WRMSR
625
626 mov $HWCR, %ecx # MSR C001_0015
627 _RDMSR
628 bt $FLAG_STACK_REENTRY , %esi # Check if stack has already been set
629 jc fam12_skipClearingBit4
630 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
631 _WRMSR
632
633fam12_skipClearingBit4:
634 mov $DE_CFG, %ecx # MSR:C001_1029
635 _RDMSR
636 bts $CL_FLUSH_SERIALIZE, %eax # Serialize all CL Flush actions
637 _WRMSR
638
639fam12_enable_stack_hook_exit:
640.endm
641
642/*****************************************************************************
643*
644* AMD_DISABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless
645*
646* Return any family specific controls to their 'standard'
647* settings for using cache with main memory.
648*
649* Inputs:
650* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
651* Outputs:
652* none
653*
654* Family 12h requirements:
655* * INVD or WBINVD
656* * MSRC001_0015[INVD_WBINVD]=1
657* * MSRC001_1020[DIS_SS]=0
658* * MSRC001_1021[IC_DIS_SPEC_TLB_RLD]=0
659* * MSRC001_1022[DC_DIS_SPEC_TLB_RLD]=0
660* * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
661* * MSRC001_1022[DIS_HW_PF]=0
662* * MSRC001_1029[ClflushSerialize]=0
663*****************************************************************************/
664.macro AMD_DISABLE_STACK_FAMILY_HOOK_F12
665 LOCAL fam12_disable_stack_hook_exit
666
667 AMD_CPUID $CPUID_MODEL
668 shr $20, %eax # AL = cpu extended family
669 cmp $0x03, %al # Is this family 12h?
670 jnz fam12_disable_stack_hook_exit # Br if no
671
672 mov $DC_CFG, %ecx # MSR:C001_1022
673 _RDMSR
674 btr $DC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative DC-TLB reloads
675 btr $DIS_CLR_WBTOL2_SMC_HIT, %eax # Enable self modifying code check buffer
676 btr $DIS_HW_PF, %eax # Enable Hardware prefetches
677 _WRMSR
678
679 dec %cx #IC_CFG # MSR:C001_1021
680 _RDMSR
681 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative IC-TLB reloads
682 _WRMSR
683
684 dec %cx #LS_CFG # MSR:C001_1020
685 _RDMSR
686 btr $DIS_SS, %eax # Turn on Streaming store functionality
687 _WRMSR
688
689 mov $DE_CFG, %ecx # MSR:C001_1029
690 _RDMSR
691 btr $CL_FLUSH_SERIALIZE, %eax
692 _WRMSR
693
694 #--------------------------------------------------------------------------
695 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
696 #--------------------------------------------------------------------------
697
698 mov $HWCR, %ecx # MSR:0000_0015h
699 _RDMSR
700 mov %ax, %bx # Save INVD -> WBINVD bit
701 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
702 _WRMSR
703 invd # Clear the cache tag RAMs
704 mov %bx, %ax # Restore INVD -> WBINVD bit
705 _WRMSR
706
707 #--------------------------------------------------------------------------
708 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
709 #--------------------------------------------------------------------------
710
711fam12_disable_stack_hook_exit:
712.endm
713
714/*****************************************************************************
715*
716* GET_NODE_ID_CORE_ID_F12 Macro - Stackless
717*
718* Read family specific values to determine the node and core
719* numbers for the core executing this code.
720*
721* Inputs:
722* none
723* Outputs:
724* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
725*****************************************************************************/
726.macro GET_NODE_ID_CORE_ID_F12
727
728 LOCAL node_core_f12_exit
729
730 cmp $-1, %si # Has node/core already been discovered?
731 jnz node_core_f12_exit # Br if yes
732
733 AMD_CPUID $CPUID_MODEL
734 shr $20, %eax # AL = cpu extended family
735 cmp $0x03, %al # Is this family 12h?
736 jnz node_core_f12_exit # Br if no
737
738 shr $24, %ebx # CPUID_0000_0001_EBX[31:24]: initial local APIC physical ID
739 bts $FLAG_IS_PRIMARY, %ebx # all family 12h cores are primary
740 mov %ebx, %esi # ESI = Node#=0, core number
741node_core_f12_exit:
742.endm
743
744/*****************************************************************************
745** Family 14h MACROS
746*****************************************************************************/
747/*****************************************************************************
748*
749* AMD_ENABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
750*
751* Set any family specific controls needed to enable the use of
752* cache as general storage before main memory is available.
753*
754* Inputs:
755* ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
756* Outputs:
757* none
758*
759* Family 14h requirements (BKDG section 2.3.3):
760* * Paging must be disabled.
761* * MSRC001_0015[INVD_WBINVD]=0.
762* * MSRC001_1020[DisStreamSt]=1.
763* * MSRC001_1021[DIS_SPEC_TLB_RLD]=1. Disable speculative ITLB reloads.
764* * MSRC001_1022[DIS_HW_PF]=1.
765* * No INVD or WBINVD, no exceptions, page faults or interrupts
766*****************************************************************************/
767.macro AMD_ENABLE_STACK_FAMILY_HOOK_F14
768 LOCAL fam14_enable_stack_hook_exit
769
770 AMD_CPUID $CPUID_MODEL
771 shr $20, %eax # AL = cpu extended family
772 cmp $0x05, %al # Is this family 14h?
773 jnz fam14_enable_stack_hook_exit # Br if no
774
775 mov $DC_CFG, %ecx # MSR:C001_1022
776 _RDMSR
777 bts $DIS_HW_PF, %eax # Disable hardware prefetches
778 _WRMSR
779
780 dec %cx #IC_CFG # MSR:C001_1021
781 _RDMSR
782 bts $IC_DIS_SPEC_TLB_RLD, %eax # Disable speculative TLB reloads
783 _WRMSR
784
785 dec %cx #LS_CFG # MSR:C001_1020
786 _RDMSR
787 bts $DIS_STREAM_ST, %eax # Disabled Streaming store functionality
788 _WRMSR
789
790 mov $HWCR, %ecx # MSR C001_0015
791 _RDMSR
792 bt $FLAG_STACK_REENTRY, %esi # Check if stack has already been set
793 jc fam14_skipClearingBit4
794 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
795 _WRMSR
796fam14_skipClearingBit4: # Keeping this label
797
798fam14_enable_stack_hook_exit:
799.endm
800
801/*****************************************************************************
802*
803* AMD_DISABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
804*
805* Return any family specific controls to their 'standard'
806* settings for using cache with main memory.
807*
808* Inputs:
809* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
810* Outputs:
811* none
812*
813* Family 14h requirements:
814* * INVD or WBINVD
815* * MSRC001_0015[INVD_WBINVD]=1.
816* * MSRC001_1020[DisStreamSt]=0.
817* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0.
818* * MSRC001_1022[DIS_HW_PF]=0.
819*****************************************************************************/
820.macro AMD_DISABLE_STACK_FAMILY_HOOK_F14
821 LOCAL fam14_disable_stack_hook_exit
822
823 AMD_CPUID $CPUID_MODEL
824 shr $20, %eax # AL = cpu extended family
825 cmp $0x05, %al # Is this family 14h?
826 jnz fam14_disable_stack_hook_exit # Br if no
827
828 mov $LS_CFG, %ecx # MSR:C001_1020
829 _RDMSR
830 btr $DIS_STREAM_ST, %eax # Turn on Streaming store functionality
831 _WRMSR
832
833 inc %cx #IC_CFG # MSR:C001_1021
834 _RDMSR
835 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative DC-TLB reloads
836 _WRMSR
837
838 inc %cx #DC_CFG # MSR:C001_1022
839 _RDMSR
840 btr $DIS_HW_PF, %eax # Turn on hardware prefetches
841 _WRMSR
842
843 #--------------------------------------------------------------------------
844 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
845 #--------------------------------------------------------------------------
846
847 mov $HWCR, %ecx # MSR:C001_0015h
848 _RDMSR
849 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
850 _WRMSR
851 invd # Clear the cache tag RAMs
852 bts $INVD_WBINVD, %eax # Turn on Conversion of INVD to WBINVD
853 _WRMSR
854
855 #--------------------------------------------------------------------------
856 # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
857 #--------------------------------------------------------------------------
858
859fam14_disable_stack_hook_exit:
860.endm
861
862/*****************************************************************************
863*
864* GET_NODE_ID_CORE_ID_F14 Macro - Stackless
865*
866* Read family specific values to determine the node and core
867* numbers for the core executing this code.
868*
869* Inputs:
870* none
871* Outputs:
872* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
873*****************************************************************************/
874.macro GET_NODE_ID_CORE_ID_F14
875
876 LOCAL node_core_f14_exit
877
Edward O'Callaghan9cd96b42014-02-21 12:43:07 +1100878 cmp $-1, %si # Has node/core already been discovered?
zbao7d94cf92012-07-02 14:19:14 +0800879 jnz node_core_f14_exit # Br if yes
880
881 AMD_CPUID $CPUID_MODEL
882 shr $20, %eax # AL = cpu extended family
883 cmp $0x05, %al # Is this family 14h?
884 jnz node_core_f14_exit # Br if no
885
886 xor %esi, %esi # Node must be 0
887 bts $FLAG_IS_PRIMARY, %esi # all family 14h cores are primary
888 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
889 _RDMSR
890 bt $APIC_BSC, %eax # Is this the BSC?
891 jc node_core_f14_exit # Br if yes
892 inc %si # Set core to 1
893node_core_f14_exit:
894.endm
895
896/*****************************************************************************
897** Family 15h MACROS
898*****************************************************************************/
899/*****************************************************************************
900*
901* AMD_ENABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
902*
903* Set any family specific controls needed to enable the use of
904* cache as general storage before main memory is available.
905*
906* Inputs:
907* ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
908* Outputs:
909* none
910*
911* Family 15h requirements (BKDG #42301 section 2.3.3):
912* * Paging must be disabled.
913* * MSRC001_0015[INVD_WBINVD]=0
914* * MSRC001_1020[DisSS]=1
915* * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
916* * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
917* * MSRC001_1022[DisHwPf]=1
918* * No INVD or WBINVD, no exceptions, page faults or interrupts
919*****************************************************************************/
920.macro AMD_ENABLE_STACK_FAMILY_HOOK_F15
921 LOCAL fam15_enable_stack_hook_exit
922
923 AMD_CPUID $CPUID_MODEL
924 mov %eax, %ebx # Save revision info to EBX
925 shr $20, %eax # AL = cpu extended family
926 cmp $0x06, %al # Is this family 15h?
927 jnz fam15_enable_stack_hook_exit # Br if no
928
929 bt $FLAG_STACK_REENTRY , %esi # Check if stack has already been set
930 jc fam15_skipClearingBit4
931 mov $HWCR, %ecx # MSR C001_0015
932 _RDMSR
933 btr $INVD_WBINVD, %eax # disable INVD -> WBINVD conversion
934 _WRMSR
935
936fam15_skipClearingBit4:
937 mov $LS_CFG, %ecx # MSR:C001_1020
938 _RDMSR
939 bts $DIS_SS, %eax # Turn on Streaming store functionality disabled bit
940 _WRMSR
941
942 inc %ecx #IC_CFG # MSR:C001_1021
943 _RDMSR
944 bts $IC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative IC-TLB reloads bit
945 _WRMSR
946
947 mov %ebx, %eax # Restore revision info to EAX
948 shr $16, %eax
949 and $0x0F, %al # AL = cpu extended model
950
951 inc %ecx #DC_CFG # MSR:C001_1022
952 _RDMSR
953 bts $DC_DIS_SPEC_TLB_RLD, %eax # Turn on Disable speculative DC-TLB reloads bit
954 bts $DIS_HW_PF, %eax # Turn on Disable hardware prefetches bit
955 _WRMSR # Remove KM in PI 1.1.0.0
956
957 mov %ebx, %eax # Restore revision info to EAX
958 shr $16, %eax
959 and $0xF, %al
960 #.if (al == 01h) || (al == 03h) Is this TN or KV?
961 cmp $1, %eax
962 jz 1f
963 cmp $3, %eax
964 jz 3f # Skip if it is KV, it is only for TN from Label 1 to 3
965 jmp 2f
9661: #.if (al == 01h) # TN only
967 #Enable MSRC001_001F[EnableCf8ExtCfg]
968 mov $NB_CFG, %ecx # MSR:C001_001F
969 _rdmsr
970 bts $(ENABLE_CF8_EXT_CFG - 32), %edx
971 _wrmsr
972 # Set F3x44[6, CpuErrDis] = 1
973 MAKE_EXT_PCI_ADDR 0, 0, 24, FUNC_3, 0x44 //MCA_NB_CFG
974 //mov $(1 << 31 | 2 << 28 | (((MCA_NB_CFG) & (0x0F00)) >> 8) << 24 | 2 << 16 | 1 << 11 | FUNC_3 << 8), %eax
975
976 mov $0xCF8, %dx
977 out %eax, %dx
978 add $4, %dx
979 in %dx, %eax
980 bts $CPU_ERR_DIS, %eax
981 out %eax, %dx
982
9833: mov $CU_CFG, %ecx # TN or KV
984 _RDMSR
985 bt $L2_WAY_LOCK_EN, %eax
986 #.if (!carry?)
987 jc 2f
988 bts $L2_WAY_LOCK_EN, %eax
989 or $L2_FIRST_LOCKED_WAY_OR_MASK, %eax
990 _WRMSR
991 #.endif
992 #.endif
9932:
994 mov %ebx, %eax # Restore revision info to EAX
995 xchg %ah, %al
996 shr $8, %eax
997 and $0xF, %al
998 #.if (ax == 6100h) ; Is this TN-A0?
999 cmp $0x6100, %ax
1000 jnz 2f
1001 MAKE_EXT_PCI_ADDR 0, 0, 24, FUNC_3, PRODUCT_INFO_REG1
1002 mov $0xCF8, %dx
1003 out %eax, %dx
1004 add $4, %dx
1005 in %dx, %eax
1006 bt $21, %eax
1007 jc 2f
1008 mov $CU_CFG2, %ecx #MSR:C001_102A
1009 _RDMSR
1010 bts $8, %eax
1011 _WRMSR
1012 # .endif
1013
10142: # Do Standard Family 15 work
1015
1016 mov $CU_CFG3, %ecx # MSR:C001_102B
1017 _RDMSR
1018 btr $(COMBINE_CR0_CD - 32), %edx # Clear CombineCr0Cd bit
1019 _WRMSR
1020
1021fam15_enable_stack_hook_exit:
1022.endm
1023
1024/*****************************************************************************
1025*
1026* AMD_DISABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
1027*
1028* Return any family specific controls to their 'standard'
1029* settings for using cache with main memory.
1030*
1031* Inputs:
1032* ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
1033* Outputs:
1034* none
1035*
1036* Family 15h requirements:
1037* * INVD or WBINVD
1038* * MSRC001_0015[INVD_WBINVD]=1
1039* * MSRC001_1020[DisSS]=0
1040* * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
1041* * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
1042* * MSRC001_1022[DIS_HW_PF]=0
1043*****************************************************************************/
1044.macro AMD_DISABLE_STACK_FAMILY_HOOK_F15
1045 LOCAL fam15_disable_stack_hook_exit
1046 LOCAL fam15_disable_stack_remote_read_exit
1047
1048 AMD_CPUID $CPUID_MODEL
1049 mov %eax, %ebx # Save revision info to EBX
1050 shr $20, %eax # AL = cpu extended family
1051 cmp $0x06, %al # Is this family 15h?
1052 jnz fam15_disable_stack_hook_exit # Br if no
1053
1054 mov %ebx, %edi # Save revision info to EDI
1055 AMD_CPUID $AMD_CPUID_APIC
1056 mov %cl, %al # AL = number of cores - 1
1057 shr $APIC_ID_CORE_ID_SIZE, %cx # CL = ApicIdCoreIdSize
1058 mov $1, %bx
1059 shl %cl, %bl # BL = theoretical number of cores on socket
1060 dec %bx # BL = core number on socket mask
1061 mov %bl, %ah # AH = core number on socket mask
1062 mov %edi, %ebx # Restore revision info to EBX
1063 mov %ax, %di # DI[15:8] = core number mask, DI[7:0] = number of cores - 1
1064
1065 and $0x0F00FF, %ebx
1066 mov %ebx, %eax
1067 shr $8, %eax
1068 or %ax, %bx # Save Extended Model, Model and Stepping to BX
1069 # [11:8] = Extended Model, [7:4] = Model, [3:0] = Stepping (bx=0000000000010100, ok)
1070
1071 mov $APIC_BASE_ADDRESS, %ecx
1072 _RDMSR # dx=0 ax=fee00800
1073 mov %bx, %dx # Save Extended Model, Model and Stepping to DX
1074 shl $16, %edx #EDX[31:16] = Extended Model, Model and Stepping
1075 mov %eax ,%ebx # EBX = LAPIC base
1076 xor %ecx ,%ecx # Zero out CU flags
1077 bts $AMD_CU_NEED_TO_WAIT, %ecx # Default to waiting
1078 bts $AMD_CU_SEND_INVD_MSG, %ecx # Default to signaling
1079 mov %cr0, %eax
1080 bt $CR0_PE, %ax # Are we in protected mode?
1081 # .if (!carry?)
1082 jc 1f
1083 bts $AMD_CU_RESTORE_ES, %ecx # Indicate ES restore is required
1084 mov %es, %cx # Save ES segment register to CX
1085 xor %ax, %ax
1086 mov %ax, %es # Set ES to big real mode selector for 4GB access
1087 # .endif
1088
10891:
1090 and $0x0F000, %bx # EBX = LAPIC base, offset 0
1091 or $APIC_ID_REG, %bl #
1092 mov %es:(%ebx), %eax # EAX[31:24] = APIC ID
1093 shr $APIC20_APICID, %eax # AL = APIC ID
1094 mov %al, %ah # AH = APIC ID
1095 mov %di, %dx # DH = core mask
1096 and %dh, %ah # AH = core number # ax=111 dx=01000F03
1097
1098 # .if (zero?)
1099 jnz 1f
1100 # Core 0 of a socket
1101 btr $AMD_CU_SEND_INVD_MSG, %ecx # No need to signal after INVD
1102 #.if (dl != 0)
1103 cmp $0, %dl
1104 jz 2f
1105 # This socket has multiple cores
1106 and $0xf000, %bx # EBX = LAPIC base, offset 0
1107 or $APIC_MSG_REG, %bx
1108 mov $APIC_MSG, %edi
1109 mov %edi, %es:(%ebx) # Signal for non core 0s to complete CAR breakdown
1110 jmp 1f
1111 #.else
11122: btr $AMD_CU_NEED_TO_WAIT, %ecx # No need to wait on a single core CPU
1113 #.endif
1114 # .endif
11151:
1116
1117 bt $AMD_CU_NEED_TO_WAIT, %ecx #cx = c0000000
1118 #.if (carry?)
1119 jnc 1f
1120 #.if (ah == dl)
1121 cmp %dl, %ah
1122 jnz 2f
1123 # This is the highest numbered core on this socket -- wait on core 0
1124 not %dh # Flip the mask to determine local core 0's APID ID
1125 and %dh, %al # AL = target APIC ID # ax=310
1126 jmp 3f
11272: #.else
1128 # All other cores (including core 0) wait on the next highest core.
1129 # In this way, cores will halt in a cascading fashion down to 0.
1130 inc %al
1131 #.endif
11323:
1133 shl $APIC20_APICID, %eax
1134 and $0x0F000, %bx
1135 or $APIC_CMD_HI_REG, %bx
1136 mov %eax, %es:(%ebx) # Set target APIC ID
1137
1138 # Use bits 23:16 as a timeout for unresponsive cores
1139 ror $8, %ecx
1140 mov $0xFF, %ch
1141 stc
1142
1143 #.while (carry?)
11445: jnc 4f
1145 and $0xF000, %bx #EBX = LAPIC base, offset 0
1146 or $APIC_CMD_LO_REG, %bx # bx = 00000000FEE00300
1147 mov $CMD_REG_TO_READ_DATA, %eax
1148 mov %eax, %es:(%ebx) #Fire remove read IPI
1149 inc %ch #Pre increment the timeout
1150 stc
1151 #.while (carry?)
11527: jnc 6f
1153 dec %ch #Check the timeout
1154 jz fam15_disable_stack_remote_read_exit
1155 mov %es:(%ebx), %eax # ax = 0000000000020338
1156 bt $DELIVERY_STS_BIT, %eax
1157 jmp 7b
11586: #.endw
1159 stc
1160 #.while (carry?)
11617: jnc 6f
1162 mov %es:(%ebx), %eax
1163 and $REMOTE_READ_STS, %eax
1164 #.if (eax == REMOTE_DELIVERY_PEND)
1165 cmp $REMOTE_DELIVERY_PEND, %eax
1166 jnz 8f
1167 dec %ch # Check the timeout
1168 jz fam15_disable_stack_hook_exit # Branch if there is an unreponsive core
1169 stc
1170 jmp 9f
11718: #.else
1172 clc
11739: #.endif
1174 jmp 7b
11756: #.endw
1176 #.if (eax == REMOTE_DELIVERY_DONE)
1177 cmp $REMOTE_DELIVERY_DONE, %eax
1178 jnz 6f
1179 and $0x0F000, %bx #EBX = LAPIC base, offset 0
1180 or $APIC_REMOTE_READ_REG, %bl
1181 mov %es:(%ebx), %eax
1182 #.if (eax == APIC_MSG)
1183 cmp $APIC_MSG, %eax # ax=00000000FFC5BBB2
1184 jnz 8f
1185 clc
1186 jmp 9f
1187 #.else
11888: stc
11899: #.endif
1190 jmp 7f
11916: #.else
1192 dec %ch
1193 jz fam15_disable_stack_remote_read_exit
1194 stc
11957: #.endif
1196 jmp 5b
11974: #.endw
1198
1199fam15_disable_stack_remote_read_exit:
1200 rol $8, %ecx # Restore ECX
1201
12021: #.endif
1203
1204 bt $AMD_CU_RESTORE_ES, %ecx
1205 #.if (carry?)
1206 jnc 1f
1207 mov %cx, %es
12081:
1209 mov %ecx, %edi
1210 shr $16, %edx
1211 mov %dx, %bx
1212
1213 #Handshaking complete. Continue tearing down CAR.
1214
1215 mov $LS_CFG, %ecx # MSR:C001_1020
1216 #.if (bx != 0) ; Is this OR A0?
1217 cmp $0x0, %bx
1218 jz 0f
1219 _RDMSR
1220 btr $DIS_SS, %eax # Turn on Streaming store functionality
1221 _WRMSR
1222 #.endif
12230: # End workaround for errata 495 and 496
1224
1225 inc %ecx #IC_CFG # MSR:C001_1021
1226 _RDMSR
1227 btr $IC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
1228 _WRMSR
1229
1230 inc %ecx #DC_CFG # MSR:C001_1022
1231 _RDMSR
1232 btr $DC_DIS_SPEC_TLB_RLD, %eax # Turn on speculative TLB reloads
1233 #.if (bx != 0) # Is this rev A0?
1234 cmp $0, %bx
1235 jz 0f
1236 btr $DIS_HW_PF, %eax # Turn on hardware prefetches
1237 #.endif # End workaround for erratum 498
1238 0:
1239 _WRMSR
1240 #--------------------------------------------------------------------------
1241 # Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
1242 #--------------------------------------------------------------------------
1243
1244 mov $HWCR, %ecx # MSR:C001_0015h
1245 _RDMSR
1246 btr $INVD_WBINVD, %eax # Disable INVD -> WBINVD conversion
1247 _WRMSR
1248 wbinvd # Clear the cache tag RAMs
1249 #.if (bh == 01h) || (bh == 03h) ; Is this TN or KM?
1250 cmp $01, %bh
1251 jz 4f
1252 cmp $03, %bh
1253 jnz 1f
12544: mov $CU_CFG, %ecx # MSR:C001_1023
1255 _RDMSR
1256 shr $L2_FIRST_LOCKED_WAY, %eax
1257 and $0x1F, %eax
1258 #.if (eax == 01Fh)
1259 cmp $0x1F, %eax #Check if way 15 of the L2 needs to be reserved
1260 jnz 3f
1261 _RDMSR
1262 btr $L2_WAY_LOCK_EN, %eax
1263 _WRMSR
12643: #.endif
1265
12661: #.endif
1267 #Do Standard Family 15 work
1268 mov $HWCR, %ecx # MSR:C001_0015h
1269 _RDMSR
1270 bts $INVD_WBINVD, %eax # Turn on Conversion of INVD to WBINVD
1271 _WRMSR
1272 #.endif # end
1273 0:
1274//
1275// #--------------------------------------------------------------------------
1276// # End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
1277// #--------------------------------------------------------------------------
1278//
1279 mov $CU_CFG3, %ecx # MSR:C001_102B
1280 _RDMSR
1281 bts $(COMBINE_CR0_CD - 32), %edx # Set CombineCr0Cd bit
1282 _WRMSR
1283
1284 bt $AMD_CU_SEND_INVD_MSG, %edi
1285 #.if (carry?)
1286 jnc 1f
1287 # Non core zero needs to signal to core 0 to proceed
1288 mov $APIC_BASE_ADDRESS, %ecx
1289 _RDMSR
1290 mov %eax, %ebx # EBX = LAPIC base
1291 and $0x0F000, %bx # EBX = LAPIC base, offset 0
1292 or $APIC_MSG_REG, %bx
1293 mov $APIC_MSG, %eax
1294 mov %eax, %es:(%ebx) # Signal for core 0 to complete CAR breakdown
1295
12961: #.endif
1297
1298fam15_disable_stack_hook_exit:
1299.endm
1300
1301/*****************************************************************************
1302*
1303* GET_NODE_ID_CORE_ID_F15 Macro - Stackless
1304*
1305* Read family specific values to determine the node and core
1306* numbers for the core executing this code.
1307*
1308* Inputs:
1309* none
1310* Outputs:
1311* SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
1312*****************************************************************************/
1313.macro GET_NODE_ID_CORE_ID_F15
1314
1315 LOCAL node_core_f15_exit
1316 LOCAL node_core_f15_AP
1317 LOCAL node_core_f15_shared
1318 LOCAL node_core_f15_AP_not_TN
1319
1320#define F15_L2Size 512
1321#define F15_ShareCores 2
1322#define F15_AllocMem 0
1323#define F15_AllocExe 0
1324#define F15_SzAddrBus 48
1325#define F15_pad 0
1326 cmp $-1, %si # Has node/core already been discovered?
1327 jnz node_core_f15_exit # Br if yes
1328
1329 AMD_CPUID $CPUID_MODEL
1330 shr $12, %eax # AL = cpu extended family
1331 cmp $06, %ah # Is this family 15h?
1332 jnz node_core_f15_exit # Br if no
1333 shr $4, %al # AL = cpu extended model
1334 shr $16, %ebx # BH = LocalApicId
1335 mov %al, %bl # BL = cpu extended model
1336
1337 # LoadTableAddress(FAM15H_INFO_STRUCT)
1338 # movd mm5, eax # load pointer to Family Info Struc
1339
1340 xor %esi, %esi # Assume BSC, clear local flags
1341 mov $APIC_BASE_ADDRESS, %ecx # MSR:0000_001B
1342 _RDMSR
1343 bt $APIC_BSC, %eax # Is this the BSC?
1344 jnc node_core_f15_AP # Br if no
1345
1346 # This is the BSP.
1347 # Enable routing tables on BSP (just in case the HT init code has not yet enabled them)
1348 mov $0x8000C06C, %eax # PCI address for D18F0x6C Link Initialization Control Register
1349 mov $0x0CF8, %dx
1350 out %eax, %dx
1351 add $4, %dx
1352 in %dx, %eax
1353 btr $0, %eax # Set LinkInitializationControl[RouteTblDis] = 0
1354 out %eax, %dx
1355 jmp node_core_f15_shared #
1356
1357node_core_f15_AP:
1358 mov %bl, %al # AL = cpu extended model
1359 shr $8, %bx # BL = CPUID Fn0000_0001_EBX[LocalApicId]
1360 cmp $1, %al # Is This TN?
1361 jz 4f
1362 cmp $3, %al
1363 jnz node_core_f15_AP_not_TN
13644: mov %bx, %si
1365 jmp node_core_f15_shared
1366 #
1367 # This is an AP. Routing tables have been enabled by the HT Init process.
1368 # Also, the MailBox register was set by the BSP during early init
1369 # The Mailbox register content is formatted as follows:
1370 # UINT32 Node:4; // The node id of Core's node.
1371 # UINT32 Socket:4; // The socket of this Core's node.
1372 # UINT32 Module:2; // The internal module number for Core's node.
1373 # UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1.
1374 # UINT32 :20; // Reserved
1375 #
1376node_core_f15_AP_not_TN:
1377 mov $0x0C0000408, %ecx # Read the family 15h mailbox
1378 _RDMSR # MC4_MISC1[63:32]
1379 mov %dx, %si # SI = raw mailbox contents (will extract node# from this)
1380 shr $24, %ebx # BL = CPUID Fn0000_0001_EBX[LocalApicId]
1381 mov %bx, %di # DI = Initial APIC ID (will extract core# from this)
1382
1383 AMD_CPUID $AMD_CPUID_APIC #
1384 shr $4, %ch # CH = ApicIdSize, #bits in APIC ID that show core#
1385 inc %cl # CL = Number of enabled cores in the socket
1386 mov %cx, %bx
1387
1388 mov $NB_CFG, %ecx
1389 _RDMSR # EDX has InitApicIdCpuIdLo bit
1390
1391 mov %bh, %cl # CL = APIC ID size
1392 mov $1, %al # Convert APIC ID size to an AND mask
1393 shl %cl, %al # AL = 2^APIC ID size
1394 dec %al # AL = mask for relative core number
1395 xor %ah, %ah # AX = mask for relative core number
1396 bt $(INIT_APIC_ID_CPU_ID_LO-32), %edx # InitApicIdCpuIdLo == 1?
1397 #.if (!carry?) # Br if yes
1398 jc 0f
1399 mov $8, %ch # Calculate core number shift count
1400 sub %cl, %ch # CH = core shift count
1401 mov %ch, %cl
1402 shr %cl, %di # Right justify core number
1403 #.endif
1404 0:
1405 and %ax, %di # DI = socket-relative core number
1406
1407 mov %si, %cx # CX = raw mailbox value
1408 shr $10, %cx # CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM)
1409 and $3, %cl # Isolate ModuleType
1410 xor %bh, %bh # BX = Number of enabled cores in the socket
1411 shr %cl, %bx # BX = Number of enabled cores per node
1412 xor %dx, %dx # Clear upper word for div
1413 mov %di, %ax # AX = socket-relative core number
1414 div %bx # DX = node-relative core number
1415 movzx %si, %eax # Prepare return value
1416 and $0x000F, %ax # AX = node number
1417 shl $8,%ax # [15:8]=node#
1418 mov %dl, %al # [7:0]=core# (relative to node)
1419 mov %eax, %esi # ESI = node-relative core number
1420
1421 #
1422 # determine if this core shares MTRRs
1423 #
1424node_core_f15_shared:
1425 mov $0x8000C580, %eax # Compute Unit Status
1426 mov %si, %bx
1427 shl $3, %bh # Move node# to PCI Dev# field
1428 add %bh, %ah # Adjust for node number
1429 mov $0x0CF8, %dx
1430 out %eax, %dx
1431 add $4, %dx
1432 in %dx, %eax # [3:0]=Enabled# [19:16]=DualCore
1433
1434 # BL is MyCore#
1435 mov $0x06, %cx # Use CH as 'first of pair' core#
1436 #.while (cl > 0)
1437 jmp 0f
1438 8:
1439 bt $0, %eax # Is pair enabled?
1440 #.if (carry?) #
1441 jnc 1f
1442 mov $0x01, %bh # flag core as primary
1443 bt $16, %eax # Is there a 2nd in the pair?
1444 #.if (carry?) #
1445 jnc 4f
1446 #.break .if (ch == bl) # Does 1st match MyCore#?
1447 cmp %bl, %ch
1448 je 9f
1449 inc %ch
1450 xor %bh, %bh # flag core as NOT primary
1451 #.break .if (ch == bl) # Does 2nd match MyCore#?
1452 cmp %bl, %ch
1453 je 9f
1454 jmp 2f
1455 #.else # No 2nd core
1456 4:
1457 #.break .if (ch == bl) # Does 1st match MyCore#?
1458 cmp %bl, %ch
1459 je 9f
1460 #.endif
1461 2:
1462 inc %ch
1463 #.endif
1464 1:
1465 shr $1, %eax
1466 dec %cl
1467 #.endw
1468 0:
1469 #.if (cl == 0)
1470 cmp $0x0, %cl
1471 ja 8b
1472 9:
1473 or %cl, %cl
1474 jne 1f
1475 #Error - core# didn't match Compute Unit Status content
1476 bts $FLAG_CORE_NOT_IDENTIFIED, %esi
1477 bts $FLAG_IS_PRIMARY, %esi # Set Is_Primary for unknowns
1478 #.endif
1479 1:
1480 #.if (bh != 0) # Check state of primary for the matched core
1481 or %bh, %bh
1482 je 2f
1483 bts $FLAG_IS_PRIMARY, %esi # Set shared flag into return value
1484 #.endif
1485 2:
1486
1487node_core_f15_exit:
1488
1489.endm
1490
1491/*****************************************************************************
1492* AMD_ENABLE_STACK: Setup a stack
1493*
1494* In:
1495* EBX = Return address (preserved)
1496*
1497* Out:
1498* SS:ESP - Our new private stack location
1499*
1500* EAX = AGESA_STATUS
1501*
1502* ECX = Stack size in bytes
1503*
1504* Requirements:
1505* * This routine presently is limited to a max of 64 processor cores
1506* Preserved:
1507* ebx ebp
1508* Destroyed:
1509* eax, ecx, edx, edi, esi, ds, es, ss, esp
1510* mmx0, mmx1
1511*
1512* Description:
1513* Fixed MTRR address allocation to cores:
1514* The BSP gets 64K of stack, Core0 of each node gets 16K of stack, all other cores get 4K.
1515* There is a max of 1 BSP, 7 core0s and 56 other cores.
1516* Although each core has it's own cache storage, they share the address space. Each core must
1517* be assigned a private and unique address space for its stack. To support legacy systems,
1518* the stack needs to be within the legacy address space (1st 1Meg). Room must also be reserved
1519* for the other legacy elements (Interrupt vectors, BIOS ROM, video buffer, etc.)
1520*
1521* 80000h 40000h 00000h
1522* +----------+----------+----------+----------+----------+----------+----------+----------+
1523* 64K | | | | | | | | | 64K ea
1524* ea +----------+----------+----------+----------+----------+----------+----------+----------+
1525* | MTRR 0000_0250 MTRRfix64K_00000 |
1526* +----------+----------+----------+----------+----------+----------+----------+----------+
1527* | 7 , 6 | 5 , 4 | 3 , 2 | 1 , 0 | 0 | | | | <-node
1528* |7..1,7..1 |7..1,7..1 |7..1,7..1 |7..1,7..1 | 0 | | | | <-core
1529* +----------+----------+----------+----------+----------+----------+----------+----------+
1530*
1531* C0000h B0000h A0000h 90000h 80000h
1532* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1533*16K | | | | | | | | | | | | | | | | |
1534* ea +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1535* | MTRR 0259 MTRRfix16K_A0000 | MTRR 0258 MTRRfix16K_80000 |
1536* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1537* | > Dis|play B|uffer | < | | | | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | <-node
1538* | > 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
1539* +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1540*
1541* E0000h D0000h C0000h
1542* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1543* 4K | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4K ea
1544* ea +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1545* | 026B MTRRfix4K_D8000 | 026A MTRRfix4K_D0000 | 0269 MTRRfix4K_C8000 | 0268 MTRRfix4K_C0000 |
1546* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1547* | | | | | | | | | | | | | | | | | >| V| I| D| E| O| |B |I |O |S | |A |r |e |a<|
1548* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1549*
1550* 100000h F0000h E0000h
1551* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1552* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4K ea
1553* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1554* | 026F MTRRfix4K_F8000 | 026E MTRRfix4K_F0000 | 026D MTRRfix4K_E8000 | 026C MTRRfix4K_E0000 |
1555* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1556* | >|MA|IN| B|IO|S |RA|NG|E | | | | | | |< | >|EX|TE|ND|ED| B|IO|S |ZO|NE| | | | | |< |
1557* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1558*****************************************************************************/
1559.macro AMD_ENABLE_STACK
1560
1561# These are local labels. Declared so linker doesn't cause 'redefined label' errors
1562 LOCAL SetupStack
1563 LOCAL Real16bMode
1564 LOCAL Protected32Mode
1565 LOCAL ClearTheStack
1566
1567# Note that SS:ESP will be default stack. Note that this stack
1568# routine will not be used after memory has been initialized. Because
1569# of its limited lifetime, it will not conflict with typical PCI devices.
1570 movd %ebx, %mm0 # Put return address in a safe place
1571 movd %ebp, %mm1 # Save some other user registers
1572
1573 # get node id and core id of current executing core
1574 GET_NODE_ID_CORE_ID # Sets ESI[23:16]=Shared core## SI[15,8]= Node## SI[7,0]= core# (relative to node)
1575 # Note: ESI[31:24] are used for flags: Unrecognized Family, Is_Primary core, Stack already established
1576
1577 # determine if stack is already enabled. We are using the DefType MSR for this determination.
1578 # It is =0 after reset; CAR setup sets it to enable the MTRRs
1579 mov %cr0, %eax
1580 test $CR0_MASK, %eax # Is cache disabled? (CD & NW bits)
1581 jnz SetupStack # Jump if yes
1582 mov $AMD_MTRR_DEFTYPE, %ecx # MSR:0000_02FF
1583 _RDMSR
1584 test $MSR_MASK, %eax # Are the default types enabled? (MTRR_DEF_TYPE_EN + MTRR_DEF_TYPE_FIX_EN)
1585 jz SetupStack # Jump if no
1586 or $FLAG_STACK_REENTRY, %esi # Bit25, indicate stack has already been initialized
1587
1588SetupStack:
1589 # Set node to map the first 16MB to node 0# 0000_0000 to 00FF_FFFF as DRAM
1590 mov %esi, %ebx # Get my Node/Core info
1591 xor %bl, %bl
1592 shl $3, %bh # Isolate my node#, match alignment for PCI Dev#
1593 mov $0x8000C144, %eax # D18F1x44:DRAM Base/Limit# N is Base, N+4 is Limit
1594 add %bh, %ah
1595 mov %eax, %ebx # Save PCI address for Base/Limit pair
1596
1597 mov $0x0CF8, %dx
1598 out %eax, %dx
1599 add $4, %dx
1600 xor %eax, %eax # Least Significant bit is AD24 so 0 sets mask of 00FF_FFFF (16MB)
1601 out %eax, %dx # DRAM Limit = node0, no interleave
1602
1603 mov %ebx, %eax
1604 sub $4, %eax # Now point to the Base register
1605 mov $0x0CF8, %dx
1606 out %eax, %dx
1607 add $4, %dx
1608 mov $0x00000003, %eax # Set the read and write enable bits
1609 out %eax, %dx # DRAM Base = 0x0000, R/W
1610
1611 AMD_ENABLE_STACK_FAMILY_HOOK
1612
1613 # Init CPU MSRs for our init routines
1614 mov $MTRR_SYS_CFG, %ecx # SYS_CFG
1615 _RDMSR
1616 bts $MTRR_FIX_DRAM_MOD_EN, %eax # Turn on modification enable bit
1617 _WRMSR
1618
1619 mov %esi, %eax
1620 bt $FLAG_STACK_REENTRY, %eax # Is this a 2nd entry?
1621 #.if (!carry?) # On a re-entry, do not clear MTRRs or reset TOM; just reset the stack SS:ESP
1622 jc 0f
1623 bt $FLAG_IS_PRIMARY, %eax # Is this core the primary in a compute unit?
1624 #.if (carry?) # Families using shared groups do not need to clear the MTRRs since that is done at power-on reset
1625 # Note: Relying on MSRs to be cleared to 0's at reset for families w/shared cores
1626 # Clear all variable and Fixed MTRRs for non-shared cores
1627 jnc 0f
1628 mov $AMD_MTRR_VARIABLE_BASE0, %ecx
1629 xor %eax, %eax
1630 xor %edx, %edx
1631 #.while (cl != 10h) # Variable MTRRphysBase[n] and MTRRphysMask[n]
1632 jmp 1f
1633 2:
1634 _WRMSR
1635 inc %cl
1636 #.endw
1637 1:
1638 cmp $0x10, %cl
1639 jne 2b
1640 mov $AMD_MTRR_FIX64k_00000, %cx # MSR:0000_0250
1641 _WRMSR
1642 mov $AMD_MTRR_FIX16k_80000, %cx # MSR:0000_0258
1643 _WRMSR
1644 mov $AMD_MTRR_FIX16k_A0000, %cx # MSR:0000_0259
1645 _WRMSR
1646 mov $AMD_MTRR_FIX4k_C0000, %cx # Fixed 4Ks: MTRRfix4K_C0000 to MTRRfix4K_F8000
1647 #.while (cl != 70h)
1648 jmp 3f
1649 4:
1650 _WRMSR
1651 inc %cl
1652 #.endw
1653 3:
1654 cmp $0x70, %cl
1655 jne 4b
1656 # Set TOP_MEM (C001_001A) for non-shared cores to 16M. This will be increased at heap init.
1657 # - not strictly needed since the FixedMTRRs take presedence.
1658 mov $(16 * 1024 * 1024), %eax
1659 mov $TOP_MEM, %ecx # MSR:C001_001A
1660 _WRMSR
1661 #.endif # End Is_Primary
1662 #.endif # End Stack_ReEntry
1663 0:
1664 # Clear IORRs (C001_0016-19) and TOM2(C001_001D) for all cores
1665 xor %eax, %eax
1666 xor %edx, %edx
1667 mov $IORR_BASE, %ecx # MSR:C001_0016 - 0019
1668 #.while (cl != 1Ah)
1669 jmp 1f
1670 2:
1671 _WRMSR
1672 inc %cl
1673 #.endw
1674 1:
1675 cmp $0x1A, %cl
1676 jne 2b
1677 mov $TOP_MEM2, %ecx # MSR:C001_001D
1678 _WRMSR
1679
1680 # setup MTTRs for stacks
1681 # A speculative read can be generated by a speculative fetch mis-aligned in a code zone
1682 # or due to a data zone being interpreted as code. When a speculative read occurs outside a
1683 # controlled region (intentionally used by software), it could cause an unwanted cache eviction.
1684 # To prevent speculative reads from causing an eviction, the unused cache ranges are set
1685 # to UC type. Only the actively used regions (stack, heap) are reflected in the MTRRs.
1686 # Note: some core stack regions will share an MTRR since the control granularity is much
1687 # larger than the allocated stack zone. The allocation algorithm must account for this 'extra'
1688 # space covered by the MTRR when parseling out cache space for the various uses. In some cases
1689 # this could reduce the amount of EXE cache available to a core. see cpuCacheInit.c
1690 #
1691 # Outcome of this block is that: (Note the MTRR map at the top of the file)
1692 # ebp - start address of stack block
1693 # ebx - [31:16] - MTRR MSR address
1694 # - [15:8] - slot# in MTRR register
1695 # - [7:0] - block size in #4K blocks
1696 # review: ESI[31:24]=Flags; SI[15,8]= Node#; SI[7,0]= core# (relative to node)
1697 #
1698
1699 mov %si, %ax # Load node, core
1700 #.if (al == 0) # Is a core 0?
1701 or %al, %al
1702 jne 1f
1703 #.if (ah == 0) # Is Node 0? (BSP)
1704 or %ah, %ah
1705 jne 2f
1706 # Is BSP, assign a 64K stack
1707 mov $((AMD_MTRR_FIX64k_00000 << 16) + (3 << 8) + (BSP_STACK_SIZE / 0x1000)), %ebx
1708 mov $BSP_STACK_BASE_ADDR, %ebp
1709 jmp 0f
1710 #.else # node 1 to 7, core0
1711 2:
1712 # Is a Core0 of secondary node, assign 16K stacks
1713 mov $AMD_MTRR_FIX16k_80000, %bx
1714 shl $16, %ebx #
1715 mov %ah, %bh # Node# is used as slot#
1716 mov $(CORE0_STACK_SIZE / 0x1000), %bl
1717 mov %ah, %al # Base = (Node# * Size)#
1718 mul %bl #
1719 movzx %ax, %eax #
1720 shl $12, %eax # Expand back to full byte count (* 4K)
1721 add $CORE0_STACK_BASE_ADDR, %eax
1722 mov %eax, %ebp
1723 #.endif
1724 jmp 0f
1725 #.else #core 1 thru core 7
1726 1:
1727 # Is core 1-7 of any node, assign 4K stacks
1728 mov $8, %al # CoreIndex = ( (Node# * 8) ...
1729 mul %ah #
1730 mov %si, %bx #
1731 add %bl, %al # ... + Core#)#
1732
1733 mov $AMD_MTRR_FIX64k_00000, %bx
1734 shl $16, %ebx #
1735 mov %al, %bh # Slot# = (CoreIndex / 16) + 4#
1736 shr $4, %bh #
1737 add $4, %bh #
1738 mov $(CORE1_STACK_SIZE / 0x1000), %bl
1739
1740 mul %bl # Base = ( (CoreIndex * Size) ...
1741 movzx %ax, %eax #
1742 shl $12, %eax # Expand back to full byte count (* 4K)
1743 add $CORE1_STACK_BASE_ADDR, %eax # ... + Base_Addr)#
1744 mov %eax, %ebp
1745 #.endif
1746 0:
1747
1748 # Now set the MTRR. Add this to already existing settings (don't clear any MTRR)
1749 mov $WB_DRAM_TYPE, %edi # Load Cache type in 1st slot
1750 mov %bh, %cl # ShiftCount = ((slot# ...
1751 and $0x03, %cl # ... % 4) ...
1752 shl $0x03, %cl # ... * 8)#
1753 shl %cl, %edi # Cache type is now in correct position
1754 ror $16, %ebx # Get the MTRR address
1755 movzx %bx, %ecx #
1756 rol $16, %ebx # Put slot# & size back in BX
1757 _RDMSR # Read-modify-write the MSR
1758 #.if (bh < 4) # Is value in lower or upper half of MSR?
1759 cmp $4, %bh
1760 jae 1f
1761 or %edi, %eax #
1762 jmp 0f
1763 #.else
1764 1: #
1765 or %edi, %edx #
1766 #.endif #
1767 0:
1768 _WRMSR #
1769
1770 # Enable MTRR defaults as UC type
1771 mov $AMD_MTRR_DEFTYPE, %ecx # MSR:0000_02FF
1772 _RDMSR # Read-modify-write the MSR
1773 bts $MTRR_DEF_TYPE_EN, %eax # MtrrDefTypeEn
1774 bts $MTRR_DEF_TYPE_FIX_EN, %eax # MtrrDefTypeFixEn
1775 _WRMSR
1776
1777 # Close the modification window on the Fixed MTRRs
1778 mov $MTRR_SYS_CFG, %ecx # MSR:0C001_0010
1779 _RDMSR
1780 bts $MTRR_FIX_DRAM_EN, %eax # MtrrFixDramEn
1781 bts $MTRR_VAR_DRAM_EN, %eax # variable MTRR enable bit
1782 btr $MTRR_FIX_DRAM_MOD_EN, %eax # Turn off modification enable bit
1783 _WRMSR
1784
1785 # Enable caching in CR0
1786 mov %cr0, %eax # Enable WT/WB cache
1787 btr $CR0_PG, %eax # Make sure paging is disabled
1788 btr $CR0_CD, %eax # Clear CR0 NW and CD
1789 btr $CR0_NW, %eax
1790 mov %eax, %cr0
1791
1792 # Use the Stack Base & size to calculate SS and ESP values
1793 # review:
1794 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1795 # ebp - start address of stack block
1796 # ebx - [31:16] - MTRR MSR address
1797 # - [15:8] - slot# in MTRR register
1798 # - [7:0] - block size in #4K blocks
1799 #
1800 mov %ebp, %esp # Initialize the stack pointer
1801 mov %esp, %edi # Copy the stack start to edi
1802 movzx %bl, %bx
1803 movzx %bx, %ebx # Clear upper ebx, don't need MSR addr anymore
1804 shl $12, %ebx # Make size full byte count (* 4K)
1805 add %ebx, %esp # Set the Stack Pointer as full linear address
1806 sub $4, %esp
1807 #
1808 # review:
1809 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1810 # edi - 32b start address of stack block
1811 # ebx - size of stack block
1812 # esp - 32b linear stack pointer
1813 #
1814
1815 # Determine mode for SS base;
1816 mov %cr0, %ecx # Check for 32-bit protect mode
1817 bt $CR0_PE, %ecx #
1818 #.if (!carry?) # PE=0 means real mode
1819 jc Protected32Mode
1820 mov %cs, %cx # PE=1
1821 cmp $0x0D000, %cx # Check for CS
1822 jb Protected32Mode # If CS < D000, it is a selector instead of a segment
1823 # alter SS:ESP for 16b Real Mode:
1824Real16bMode:
1825 mov %edi, %eax
1826 shr $4, %eax # Create a Real Mode segment for ss, ds, es
1827 mov %ax, %ss
1828 mov %ax, %ds
1829 mov %ax, %es
1830 shl $4, %eax
1831 sub %eax, %edi # Adjust the clearing pointer for Seg:Offset mode
1832 mov %ebx, %esp # Make SP an offset from SS
1833 sub $4, %esp #
1834 # .endif # endif
1835 # #else
1836 # Default is to use Protected 32b Mode
1837 #.endif
1838 ;
1839Protected32Mode:
1840 #
1841 # Clear The Stack
1842 # Now that we have set the location and the MTRRs, initialize the cache by
1843 # reading then writing to zero all of the stack area.
1844 # review:
1845 # ss - Stack base
1846 # esp - stack pointer
1847 # ebx - size of stack block
1848 # esi[31:24]=Flags; esi[15,8]= Node#; esi[7,0]= core# (relative to node)
1849 # edi - address of start of stack block
1850 #
1851
1852ClearTheStack: # Stack base is in SS, stack pointer is in ESP
1853 shr $2, %ebx # ebx = stack block size in dwords
1854 mov %bx, %cx #
1855 # Check our flags - Don't clear an existing stack
1856 #.if ( !(esi & 0FF000000h)) # Check our flags
1857 test $(1 << FLAG_STACK_REENTRY), %esi
1858 jne 1f
1859 cld
1860 mov %edi, %esi
1861 rep lodsl (%esi) # Pre-load the range
1862 xor %eax, %eax
1863 mov %bx, %cx
1864 mov %edi, %esi # Preserve base for push on stack
1865 rep stosl (%edi) # Clear the range
1866 movl $0x0ABCDDCBA, (%esp) # Put marker in top stack dword
1867 shl $2, %ebx # Put stack size and base
1868 push %ebx # in top of stack
1869 push %esi
1870
1871 mov %ebx, %ecx # Return size of stack in bytes
1872 xor %eax, %eax # eax = 0 : no error return code
1873 jmp 0f
1874 #.else
1875 1:
1876 movzx %cx, %ecx
1877 shl $2, %ecx # Return size of stack in bytes
1878 mov %esi, %eax
1879 shr $24, %eax # Keep the flags as part of the error report
1880 or $0x40000000, %eax # eax = AGESA_WARNING (Stack has already been set up)
1881 #.endif
1882 0:
1883
1884 movd %mm0, %ebx # Restore return address
1885 movd %mm1, %ebp
1886.endm
1887
1888/*****************************************************************************
1889* AMD_DISABLE_STACK: Destroy the stack inside the cache. This routine
1890* should only be executed on the BSP
1891*
1892* In:
1893* none
1894*
1895* Out:
1896* EAX = AGESA_SUCCESS
1897*
1898* Preserved:
1899* ebx
1900* Destroyed:
1901* eax, ecx, edx, esp
1902*****************************************************************************/
1903.macro AMD_DISABLE_STACK
1904
1905 mov %ebx, %esp # Save return address
1906
1907 # get node/core/flags of current executing core
1908 GET_NODE_ID_CORE_ID # Sets ESI[15,8]= Node#; ESI[7,0]= core# (relative to node)
1909
1910 # Turn on modification enable bit
1911 mov $MTRR_SYS_CFG, %ecx # MSR:C001_0010
1912 _RDMSR
1913 bts $MTRR_FIX_DRAM_MOD_EN, %eax # Enable modifications
1914 _WRMSR
1915
1916 # Set lower 640K MTRRs for Write-Back memory caching
1917 mov $AMD_MTRR_FIX64k_00000, %ecx
1918 mov $0x1E1E1E1E, %eax
1919 mov %eax, %edx
1920 _WRMSR # 0 - 512K = WB Mem
1921 mov $AMD_MTRR_FIX16k_80000, %ecx
1922 _WRMSR # 512K - 640K = WB Mem
1923
1924 # Turn off modification enable bit
1925 mov $MTRR_SYS_CFG, %ecx # MSR:C001_0010
1926 _RDMSR
1927 btr $MTRR_FIX_DRAM_MOD_EN, %eax # Disable modification
1928 _WRMSR
1929
1930 AMD_DISABLE_STACK_FAMILY_HOOK # Re-Enable 'normal' cache operations
1931
1932 mov %esp, %ebx
1933 xor %eax, %eax
1934
1935.endm
1936