;***************************************************************************** ; AMD Generic Encapsulated Software Architecture ; ; $Workfile:: cpcar.inc ; ; Description: CPCAR.INC - AGESA cache-as-RAM setup Include File ; ;***************************************************************************** ; ; Copyright (c) 2011, Advanced Micro Devices, Inc. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: ; * Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; * Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; * Neither the name of Advanced Micro Devices, Inc. nor the names of ; its contributors may be used to endorse or promote products derived ; from this software without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;***************************************************************************** BSP_STACK_BASE_ADDR EQU 30000h ; Base address for primary cores stack BSP_STACK_SIZE EQU 10000h ; 64KB for BSP core CORE0_STACK_BASE_ADDR EQU 80000h ; Base address for primary cores stack CORE0_STACK_SIZE EQU 4000h ; 16KB for primary cores CORE1_STACK_BASE_ADDR EQU 40000h ; Base address for AP cores CORE1_STACK_SIZE EQU 1000h ; 4KB for each AP cores APIC_BASE_ADDRESS EQU 0000001Bh APIC_BSC EQU 8 ; Boot Strap Core AMD_MTRR_VARIABLE_BASE0 EQU 0200h AMD_MTRR_VARIABLE_BASE6 EQU 020Ch AMD_MTRR_FIX64k_00000 EQU 0250h AMD_MTRR_FIX16k_80000 EQU 0258h AMD_MTRR_FIX16k_A0000 EQU 0259h AMD_MTRR_FIX4k_C0000 EQU 0268h AMD_MTRR_FIX4k_C8000 EQU 0269h AMD_MTRR_FIX4k_D0000 EQU 026Ah AMD_MTRR_FIX4k_D8000 EQU 026Bh AMD_MTRR_FIX4k_E0000 EQU 026Ch AMD_MTRR_FIX4k_E8000 EQU 026Dh AMD_MTRR_FIX4k_F0000 EQU 026Eh AMD_MTRR_FIX4k_F8000 EQU 026Fh AMD_MTRR_DEFTYPE EQU 02FFh WB_DRAM_TYPE EQU 1Eh ; MemType - memory type MTRR_DEF_TYPE_EN EQU 11 ; MtrrDefTypeEn - variable and fixed MTRRs default enabled MTRR_DEF_TYPE_FIX_EN EQU 10 ; MtrrDefTypeEn - fixed MTRRs default enabled HWCR EQU 0C0010015h ; Hardware Configuration INVD_WBINVD EQU 4 ; INVD to WBINVD conversion IORR_BASE EQU 0C0010016h ; IO Range Regusters Base/Mask, 2 pairs ; uses 16h - 19h TOP_MEM EQU 0C001001Ah ; Top of Memory TOP_MEM2 EQU 0C001001Dh ; Top of Memory2 LS_CFG EQU 0C0011020h ; Load-Store Configuration DIS_SS EQU 28 ; Family 10h,12h,15h:Disable Streaming Store functionality DIS_STREAM_ST EQU 28 ; Family 14h:DisStreamSt - Disable Streaming Store functionality IC_CFG EQU 0C0011021h ; Instruction Cache Config Register IC_DIS_SPEC_TLB_RLD EQU 9 ; Disable speculative TLB reloads DIS_IND EQU 14 ; Family 10-14h:Disable Indirect Branch Predictor DIS_I_CACHE EQU 14 ; Family 15h:DisICache - Disable Indirect Branch Predictor DC_CFG EQU 0C0011022h ; Data Cache Configuration DC_DIS_SPEC_TLB_RLD EQU 4 ; Disable speculative TLB reloads DIS_CLR_WBTOL2_SMC_HIT EQU 8 ; self modifying code check buffer bit DIS_HW_PF EQU 13 ; Hardware prefetches bit DE_CFG EQU 0C0011029h ; Decode Configuration CL_FLUSH_SERIALIZE EQU 23 ; Family 12h,15h: CL Flush Serialization BU_CFG2 EQU 0C001102Ah ; Family 10h: Bus Unit Configuration 2 CU_CFG2 EQU 0C001102Ah ; Family 15h: Combined Unit Configuration 2 F10_CL_LINES_TO_NB_DIS EQU 15 ; ClLinesToNbDis - allows WP code to be cached in L2 IC_DIS_SPEC_TLB_WR EQU 35 ; IcDisSpecTlbWr - ITLB speculative writes CU_CFG3 EQU 0C001102Bh ; Combined Unit Configuration 3 COMBINE_CR0_CD EQU 49 ; Combine CR0.CD for both cores of a compute unit CR0_PE EQU 0 ; Protection Enable CR0_NW EQU 29 ; Not Write-through CR0_CD EQU 30 ; Cache Disable CR0_PG EQU 31 ; Paging Enable ; CPUID Functions CPUID_MODEL EQU 1 AMD_CPUID_FMF EQU 80000001h ; Family Model Features information AMD_CPUID_APIC EQU 80000008h ; Long Mode and APIC info., core count NB_CFG EQU 0C001001Fh ; Northbridge Configuration Register INIT_APIC_ID_CPU_ID_LO EQU 54 ; InitApicIdCpuIdLo - is core# in high or low half of APIC ID? MTRR_SYS_CFG EQU 0C0010010h ; System Configuration Register CHX_TO_DIRTY_DIS EQU 16 ; ChxToDirtyDis Change to dirty disable SYS_UC_LOCK_EN EQU 17 ; SysUcLockEn System lock command enable MTRR_FIX_DRAM_EN EQU 18 ; MtrrFixDramEn MTRR fixed RdDram and WrDram attributes enable MTRR_FIX_DRAM_MOD_EN EQU 19 ; MtrrFixDramModEn MTRR fixed RdDram and WrDram modification enable MTRR_VAR_DRAM_EN EQU 20 ; MtrrVarDramEn MTRR variable DRAM enable MTRR_TOM2_EN EQU 21 ; MtrrTom2En MTRR top of memory 2 enable PERF_CONTROL3 EQU 0C0010003h ; Performance event control three PERF_CONTROL3_RESERVE_L EQU 00200000h ; Preserve the reserved bits PERF_CONTROL3_RESERVE_H EQU 0FCF0h ; Preserve the reserved bits CONFIG_EVENT_L EQU 0F0E2h ; All cores with level detection CONFIG_EVENT_H EQU 4 ; Increment count by number of event ; occured in clock cycle EVENT_ENABLE EQU 22 ; Enable the event PERF_COUNTER3 EQU 0C0010007h ; Performance event counter three ; Local use flags, in upper most byte if ESI FLAG_UNKNOWN_FAMILY EQU 24 ; Signals that the family# of the installed processor is not recognized FLAG_STACK_REENTRY EQU 25 ; Signals that the environment has made a re-entry (2nd) call to set up the stack FLAG_IS_PRIMARY EQU 26 ; Signals that this core is the primary within the comoute unit ; AGESA_STATUS values IFNDEF AGESA_SUCCESS AGESA_SUCCESS EQU 0 ENDIF IFNDEF AGESA_WARNING AGESA_WARNING EQU 4 ENDIF IFNDEF AGESA_FATAL AGESA_FATAL EQU 7 ENDIF ;;*************************************************************************** ;; ;; CPU MACROS - PUBLIC ;; ;;*************************************************************************** _WRMSR macro db 0Fh, 30h endm _RDMSR macro db 0Fh, 32h endm AMD_CPUID MACRO arg0 IFB mov eax, 1 db 0Fh, 0A2h ; Execute instruction bswap eax xchg al, ah ; Ext model in al now rol eax, 8 ; Ext model in ah, model in al and ax, 0FFCFh ; Keep 23:16, 7:6, 3:0 ELSE mov eax, arg0 db 0Fh, 0A2h ENDIF ENDM ;--------------------------------------------------- ; ; AMD_ENABLE_STACK_FAMILY_HOOK Macro - Stackless ; ; Set any family specific controls needed to enable the use of ; cache as general storage before main memory is available. ; ; Inputs: ; none ; Outputs: ; none ;--------------------------------------------------- AMD_ENABLE_STACK_FAMILY_HOOK MACRO AMD_ENABLE_STACK_FAMILY_HOOK_F10 AMD_ENABLE_STACK_FAMILY_HOOK_F12 AMD_ENABLE_STACK_FAMILY_HOOK_F14 AMD_ENABLE_STACK_FAMILY_HOOK_F15 ENDM ;---------------------------------------------- ; ; AMD_DISABLE_STACK_FAMILY_HOOK Macro - Stackless ; ; Return any family specific controls to their 'standard' ; settings for using cache with main memory. ; ; Inputs: ; none ; Outputs: ; none ;---------------------------------------------- AMD_DISABLE_STACK_FAMILY_HOOK MACRO AMD_DISABLE_STACK_FAMILY_HOOK_F10 AMD_DISABLE_STACK_FAMILY_HOOK_F12 AMD_DISABLE_STACK_FAMILY_HOOK_F14 AMD_DISABLE_STACK_FAMILY_HOOK_F15 ENDM ;--------------------------------------------------- ; ; GET_NODE_ID_CORE_ID Macro - Stackless ; ; Read family specific values to determine the node and core ; numbers for the core executing this code. ; ; Inputs: ; none ; Outputs: ; SI[7:0] = Core# (0..N, relative to node) ; SI[15:8]= Node# (0..N) ; SI[23:16]= reserved ; SI[24]= flag: 1=Family Unrecognized ; SI[25]= flag: 1=Interface re-entry call ; SI[26]= flag: 1=Core is primary of compute unit ; SI[31:27]= reserved, =0 ;--------------------------------------------------- GET_NODE_ID_CORE_ID MACRO mov si, -1 GET_NODE_ID_CORE_ID_F10 GET_NODE_ID_CORE_ID_F12 GET_NODE_ID_CORE_ID_F14 GET_NODE_ID_CORE_ID_F15 ; ; Check for unrecognized Family ; .if (si == -1) ; Has family (node/core) been discovered? mov esi, ( (1 SHL FLAG_UNKNOWN_FAMILY)+(1 SHL FLAG_IS_PRIMARY) ) ; No, Set error code, Only let BSP continue mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B _RDMSR bt eax, APIC_BSC ; Is this the BSC? .if (!carry?) ; No, this is an AP hlt ; Kill APs .endif .endif ENDM ;;*************************************************************************** ;; Family 10h MACROS ;;*************************************************************************** ;--------------------------------------------------- ; ; AMD_ENABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless ; ; Set any family specific controls needed to enable the use of ; cache as general storage before main memory is available. ; ; Inputs: ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID ; Outputs: ; none ; ; Family 10h requirements (BKDG section 2.3.3): ; * Paging disabled ; * MSRC001_0015[INVDWBINVD]=0 ; * MSRC001_1021[DIS_IND]=1 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1 ; * MSRC001_1022[DIS_HW_PF]=1 ; * MSRC001_102A[IcDisSpecTlbWr]=1 ; * MSRC001_102A[ClLinesToNbDis]=1 ; * No INVD or WBINVD, no exceptions, page faults or interrupts ;--------------------------------------------------- AMD_ENABLE_STACK_FAMILY_HOOK_F10 MACRO local fam10_enable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 01h ; Is this family 10h? jnz fam10_enable_stack_hook_exit ; Br if no mov ecx, DC_CFG ; MSR:C001_1022 _RDMSR bts eax, DC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative DTLB reloads bit bts eax, DIS_CLR_WBTOL2_SMC_HIT ; Turn on Disable the self modifying code check buffer bit bts eax, DIS_HW_PF ; Turn on Disable hardware prefetches bit _WRMSR dec cx ; MSR:C001_1021 _RDMSR bts eax, IC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative TLB reloads bit bts eax, DIS_IND ; Turn on Disable indirect branch predictor _WRMSR mov ecx, BU_CFG2 ; MSR C001_102A _RDMSR bts eax, F10_CL_LINES_TO_NB_DIS ; Allow BIOS ROM to be cached in the IC bts edx, (IC_DIS_SPEC_TLB_WR-32) ;Disable speculative writes to the ITLB _WRMSR mov ecx, HWCR ; MSR C001_0015 _RDMSR bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set .if (!carry?) btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion _WRMSR .endif mov eax, esi ; load core# .if (al == 0) ; If (BSP) mov ecx, PERF_COUNTER3 ; Select performance counter three ; to count number of CAR evictions xor eax, eax ; Initialize the lower part of the counter to zero xor edx, edx ; Initializa the upper part of the counter to zero _WRMSR ; Save it mov ecx, PERF_CONTROL3 ; Select the event control three _RDMSR ; Get the current setting and eax, PERF_CONTROL3_RESERVE_L ; Preserve the reserved bits or eax, CONFIG_EVENT_L ; Set the lower part of event register to ; select CAR Corruption occurred by any cores and dx, PERF_CONTROL3_RESERVE_H ; Preserve the reserved bits or dx, CONFIG_EVENT_H ; Set the upper part of event register _WRMSR ; Save it bts eax, EVENT_ENABLE ; Enable it _WRMSR ; Save it .endif ; endif fam10_enable_stack_hook_exit: ENDM ;---------------------------------------------- ; ; AMD_DISABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless ; ; Return any family specific controls to their 'standard' ; settings for using cache with main memory. ; ; Inputs: ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core# ; Outputs: ; none ; ; Family 10h requirements: ; * INVD or WBINVD ; * MSRC001_0015[INVD_WBINVD]=1 ; * MSRC001_1021[DIS_IND]=0 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0 ; * MSRC001_1022[DIS_HW_PF]=0 ; * MSRC001_102A[IcDisSpecTlbWr]=0 ; * MSRC001_102A[ClLinesToNbDis]=0 ;---------------------------------------------- AMD_DISABLE_STACK_FAMILY_HOOK_F10 MACRO local fam10_disable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 01h ; Is this family 10h? jnz fam10_disable_stack_hook_exit ; Br if no mov ecx, DC_CFG ; MSR:C001_1022 _RDMSR btr eax, DC_DIS_SPEC_TLB_RLD ; Enable speculative TLB reloads btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Allow self modifying code check buffer btr eax, DIS_HW_PF ; Allow hardware prefetches _WRMSR dec cx ; MSR:C001_1021 _RDMSR btr eax, DIS_IND ; Turn on indirect branch predictor btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads _WRMSR mov ecx, BU_CFG2 ; MSR:C001_102A _RDMSR btr eax, F10_CL_LINES_TO_NB_DIS ; Return L3 to normal mode btr edx, (IC_DIS_SPEC_TLB_WR-32) ;Re-enable speculative writes to the ITLB _WRMSR ;-------------------------------------------------------------------------- ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- mov ecx, HWCR ; MSR:0000_0015 _RDMSR mov bx, ax ; Save INVD -> WBINVD bit btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion for the invd instruction. _WRMSR invd ; Clear the cache tag RAMs mov ax, bx ; Restore INVD -> WBINVD bit _WRMSR ;-------------------------------------------------------------------------- ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- mov ecx, PERF_CONTROL3 ; Select the event control three _RDMSR ; Retrieve the current value btc eax, EVENT_ENABLE ; Is event enable, complement it as well jnc fam10_disable_stack_hook_exit ; No cmp ax, CONFIG_EVENT_L ; Is the lower part of event set to capture the CAR Corruption jne fam10_disable_stack_hook_exit ; No cmp dl, CONFIG_EVENT_H ; Is the upper part of event set to capture the CAR Corruption jne fam10_disable_stack_hook_exit ; No _WRMSR ; Disable the event fam10_disable_stack_hook_exit: ENDM ;--------------------------------------------------- ; ; GET_NODE_ID_CORE_ID_F10 Macro - Stackless ; ; Read family specific values to determine the node and core ; numbers for the core executing this code. ; ; Inputs: ; none ; Outputs: ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above) ;--------------------------------------------------- GET_NODE_ID_CORE_ID_F10 MACRO local node_core_f10_exit cmp si, -1 ; Has node/core already been discovered? jnz node_core_f10_exit ; Br if yes AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 01h ; Is this family 10h? jnz node_core_f10_exit ; Br if no xor esi, esi ; Assume BSC, clear flags mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B _RDMSR bt eax, APIC_BSC ; Is this the BSC? .if (carry?) ; This is the BSP. ; Enable routing tables on BSP (just in case the HT init code has not yet enabled them) mov eax, 8000C06Ch ; PCI address for D18F0x6C Link Initialization Control Register mov dx, 0CF8h out dx, eax add dx, 4 in eax, dx btr eax, 0 ; Set LinkInitializationControl[RouteTblDis] = 0 out dx, eax .else ; This is an AP. Routing tables have been enabled by the HT Init process. ; Also, the MailBox register was set by the BSP during early init ; The Mailbox register content is formatted as follows: ; UINT32 Node:4; // The node id of Core's node. ; UINT32 Socket:4; // The socket of this Core's node. ; UINT32 Module:2; // The internal module number for Core's node. ; UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1. ; UINT32 :20; // Reserved ; mov ecx, 0C0000408h ; Read the family 10h mailbox _RDMSR ; MC4_MISC1[63:32] mov si, dx ; SI = raw mailbox contents (will extract node# from this) shr ebx, 24 ; BL = CPUID Fn0000_0001_EBX[LocalApicId] mov di, bx ; DI = Initial APIC ID (will extract core# from this) AMD_CPUID AMD_CPUID_APIC ; shr ch, 4 ; CH = ApicIdSize, #bits in APIC ID that show core# inc cl ; CL = Number of enabled cores in the socket mov bx, cx mov ecx, NB_CFG ; MSR:C001_001F _RDMSR ; EDX has InitApicIdCpuIdLo bit mov cl, bh ; CL = APIC ID size mov al, 1 ; Convert APIC ID size to an AND mask shl al, cl ; AL = 2^APIC ID size dec al ; AL = mask for relative core number xor ah, ah ; AX = mask for relative core number bt edx, (INIT_APIC_ID_CPU_ID_LO-32) ; InitApicIdCpuIdLo == 1? .if (!carry?) ; Br if yes mov ch, 8 ; Calculate core number shift count sub ch, cl ; CH = core shift count mov cl, ch shr di, cl ; Right justify core number .endif and di, ax ; DI = socket-relative core number mov cx, si ; CX = raw mailbox value shr cx, 10 ; CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM) and cl, 3 ; Isolate ModuleType xor bh, bh ; BX = Number of enabled cores in the socket shr bx, cl ; BX = Number of enabled cores per node xor dx, dx ; Clear upper word for div mov ax, di ; AX = socket-relative core number div bx ; DX = node-relative core number movzx eax, si ; prepare return value (clears flags) and ax, 000Fh ; AX = node number shl ax, 8 ; [15:8]=node# mov al, dl ; [7:0]=core# (relative to node) mov esi, eax ; ESI = return value .endif ; end: Is_AP bts esi, FLAG_IS_PRIMARY ; all Family 10h cores are primary node_core_f10_exit: ENDM ;;*************************************************************************** ;; Family 12h MACROS ;;*************************************************************************** ;--------------------------------------------------- ; ; AMD_ENABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless ; ; Set any family specific controls needed to enable the use of ; cache as general storage before main memory is available. ; ; Inputs: ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID ; Outputs: ; none ; ; Family 12h requirements (BKDG section 2.3.3): ; The following requirements must be satisfied prior to using the cache as general storage: ; * Paging must be disabled. ; * MSRC001_0015[INVD_WBINVD]=0 ; * MSRC001_1020[DIS_SS]=1 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1 ; * MSRC001_1022[DIS_HW_PF]=1 ; * MSRC001_1029[ClflushSerialize]=1 ; * No INVD or WBINVD, no exceptions, page faults or interrupts ;--------------------------------------------------- AMD_ENABLE_STACK_FAMILY_HOOK_F12 MACRO local fam12_enable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 03h ; Is this family 12h? jnz fam12_enable_stack_hook_exit ; Br if no mov ecx, DC_CFG ; MSR:C001_1022 _RDMSR bts eax, DC_DIS_SPEC_TLB_RLD ; Disable speculative DC-TLB reloads bts eax, DIS_CLR_WBTOL2_SMC_HIT ; Disable self modifying code check buffer bts eax, DIS_HW_PF ; Disable hardware prefetches _WRMSR dec cx ;IC_CFG ; MSR:C001_1021 _RDMSR bts eax, IC_DIS_SPEC_TLB_RLD ; Disable speculative IC-TLB reloads _WRMSR dec cx ;LS_CFG ; MSR:C001_1020 _RDMSR bts eax, DIS_SS ; Disabled Streaming store functionality _WRMSR mov ecx, HWCR ; MSR C001_0015 _RDMSR bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set .if (!carry?) btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion _WRMSR .endif mov ecx, DE_CFG ; MSR:C001_1029 _RDMSR bts eax, CL_FLUSH_SERIALIZE ; Serialize all CL Flush actions _WRMSR fam12_enable_stack_hook_exit: ENDM ;---------------------------------------------- ; ; AMD_DISABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless ; ; Return any family specific controls to their 'standard' ; settings for using cache with main memory. ; ; Inputs: ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core# ; Outputs: ; none ; ; Family 12h requirements: ; * INVD or WBINVD ; * MSRC001_0015[INVD_WBINVD]=1 ; * MSRC001_1020[DIS_SS]=0 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0 ; * MSRC001_1022[DIS_HW_PF]=0 ; * MSRC001_1029[ClflushSerialize]=0 ;--------------------------------------------------- AMD_DISABLE_STACK_FAMILY_HOOK_F12 MACRO local fam12_disable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 03h ; Is this family 12h? jnz fam12_disable_stack_hook_exit ; Br if no mov ecx, DC_CFG ; MSR:C001_1022 _RDMSR btr eax, DC_DIS_SPEC_TLB_RLD ; Turn on speculative DC-TLB reloads btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Enable self modifying code check buffer btr eax, DIS_HW_PF ; Enable Hardware prefetches _WRMSR dec cx ;IC_CFG ; MSR:C001_1021 _RDMSR btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative IC-TLB reloads _WRMSR dec cx ;LS_CFG ; MSR:C001_1020 _RDMSR btr eax, DIS_SS ; Turn on Streaming store functionality _WRMSR mov ecx, DE_CFG ; MSR:C001_1029 _RDMSR btr eax, CL_FLUSH_SERIALIZE _WRMSR ;-------------------------------------------------------------------------- ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- mov ecx, HWCR ; MSR:0000_0015h _RDMSR mov bx, ax ; Save INVD -> WBINVD bit btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion _WRMSR invd ; Clear the cache tag RAMs mov ax, bx ; Restore INVD -> WBINVD bit _WRMSR ;-------------------------------------------------------------------------- ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- fam12_disable_stack_hook_exit: ENDM ;--------------------------------------------------- ; ; GET_NODE_ID_CORE_ID_F12 Macro - Stackless ; ; Read family specific values to determine the node and core ; numbers for the core executing this code. ; ; Inputs: ; none ; Outputs: ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above) ;--------------------------------------------------- GET_NODE_ID_CORE_ID_F12 MACRO local node_core_f12_exit cmp si, -1 ; Has node/core already been discovered? jnz node_core_f12_exit ; Br if yes AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 03h ; Is this family 12h? jnz node_core_f12_exit ; Br if no shr ebx, 24 ; CPUID_0000_0001_EBX[31:24]: initial local APIC physical ID bts ebx, FLAG_IS_PRIMARY ; all family 12h cores are primary mov esi, ebx ; ESI = Node#=0, core number node_core_f12_exit: ENDM ;;*************************************************************************** ;; Family 14h MACROS ;;*************************************************************************** ;--------------------------------------------------- ; ; AMD_ENABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless ; ; Set any family specific controls needed to enable the use of ; cache as general storage before main memory is available. ; ; Inputs: ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID ; Outputs: ; none ; ; Family 14h requirements (BKDG section 2.3.3): ; * Paging must be disabled. ; * MSRC001_0015[INVD_WBINVD]=0. ; * MSRC001_1020[DisStreamSt]=1. ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1. Disable speculative ITLB reloads. ; * MSRC001_1022[DIS_HW_PF]=1. ; * No INVD or WBINVD, no exceptions, page faults or interrupts ;--------------------------------------------------- AMD_ENABLE_STACK_FAMILY_HOOK_F14 MACRO local fam14_enable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 05h ; Is this family 14h? jnz fam14_enable_stack_hook_exit ; Br if no mov ecx, DC_CFG ; MSR:C001_1022 _RDMSR bts eax, DIS_HW_PF ; Disable hardware prefetches _WRMSR dec cx ;IC_CFG ; MSR:C001_1021 _RDMSR bts eax, IC_DIS_SPEC_TLB_RLD ; Disable speculative TLB reloads _WRMSR dec cx ;LS_CFG ; MSR:C001_1020 _RDMSR bts eax, DIS_STREAM_ST ; Disabled Streaming store functionality _WRMSR mov ecx, HWCR ; MSR C001_0015 _RDMSR bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set .if (!carry?) btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion _WRMSR .endif fam14_enable_stack_hook_exit: ENDM ;---------------------------------------------- ; ; AMD_DISABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless ; ; Return any family specific controls to their 'standard' ; settings for using cache with main memory. ; ; Inputs: ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core# ; Outputs: ; none ; ; Family 14h requirements: ; * INVD or WBINVD ; * MSRC001_0015[INVD_WBINVD]=1. ; * MSRC001_1020[DisStreamSt]=0. ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0. ; * MSRC001_1022[DIS_HW_PF]=0. ;--------------------------------------------------- AMD_DISABLE_STACK_FAMILY_HOOK_F14 MACRO local fam14_disable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 05h ; Is this family 14h? jnz fam14_disable_stack_hook_exit ; Br if no mov ecx, LS_CFG ; MSR:C001_1020 _RDMSR btr eax, DIS_STREAM_ST ; Turn on Streaming store functionality _WRMSR inc cx ;IC_CFG ; MSR:C001_1021 _RDMSR btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative DC-TLB reloads _WRMSR inc cx ;DC_CFG ; MSR:C001_1022 _RDMSR btr eax, DIS_HW_PF ; Turn on hardware prefetches _WRMSR ;-------------------------------------------------------------------------- ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- mov ecx, HWCR ; MSR:C001_0015h _RDMSR btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion _WRMSR invd ; Clear the cache tag RAMs bts eax, INVD_WBINVD ; Turn on Conversion of INVD to WBINVD _WRMSR ;-------------------------------------------------------------------------- ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- fam14_disable_stack_hook_exit: ENDM ;--------------------------------------------------- ; ; GET_NODE_ID_CORE_ID_F14 Macro - Stackless ; ; Read family specific values to determine the node and core ; numbers for the core executing this code. ; ; Inputs: ; none ; Outputs: ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above) ;--------------------------------------------------- GET_NODE_ID_CORE_ID_F14 MACRO local node_core_f14_exit cmp si, -1 ; Has node/core already been discovered? jnz node_core_f14_exit ; Br if yes AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 05h ; Is this family 14h? jnz node_core_f14_exit ; Br if no xor esi, esi ; Node must be 0 bts esi, FLAG_IS_PRIMARY ; all family 14h cores are primary mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B _RDMSR bt eax, APIC_BSC ; .if (!carry?) ; Is this the BSC? ; No, this is an AP inc si ; Set core to 1 .endif ; node_core_f14_exit: ENDM ;;*************************************************************************** ;; Family 15h MACROS ;;*************************************************************************** ;--------------------------------------------------- ; ; AMD_ENABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless ; ; Set any family specific controls needed to enable the use of ; cache as general storage before main memory is available. ; ; Inputs: ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID ; Outputs: ; none ; ; Family 15h requirements (BKDG #42301 section 2.3.3): ; * Paging must be disabled. ; * MSRC001_0015[INVD_WBINVD]=0 ; * MSRC001_1020[DisSS]=1 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1 ; * MSRC001_1022[DisHwPf]=1 ; * No INVD or WBINVD, no exceptions, page faults or interrupts ;--------------------------------------------------- AMD_ENABLE_STACK_FAMILY_HOOK_F15 MACRO local fam15_enable_stack_hook_exit AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 06h ; Is this family 15h? jnz fam15_enable_stack_hook_exit ; Br if no bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set .if (!carry?) mov ecx, HWCR ; MSR C001_0015 _RDMSR btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion _WRMSR .endif mov ecx, LS_CFG ; MSR:C001_1020 _RDMSR bts eax, DIS_SS ; Turn on Streaming store functionality disabled bit _WRMSR inc ecx ;IC_CFG ; MSR:C001_1021 _RDMSR bts eax, IC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative IC-TLB reloads bit _WRMSR inc ecx ;DC_CFG ; MSR:C001_1022 _RDMSR bts eax, DC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative DC-TLB reloads bit bts eax, DIS_HW_PF ; Turn on Disable hardware prefetches bit _WRMSR mov ecx, CU_CFG3 ; MSR:C001_102B _RDMSR btr edx, (COMBINE_CR0_CD - 32) ; Clear CombineCr0Cd bit _WRMSR fam15_enable_stack_hook_exit: ENDM ;---------------------------------------------- ; ; AMD_DISABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless ; ; Return any family specific controls to their 'standard' ; settings for using cache with main memory. ; ; Inputs: ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core# ; Outputs: ; none ; ; Family 15h requirements: ; * INVD or WBINVD ; * MSRC001_0015[INVD_WBINVD]=1 ; * MSRC001_1020[DisSS]=0 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0 ; * MSRC001_1022[DIS_HW_PF]=0 ;--------------------------------------------------- AMD_DISABLE_STACK_FAMILY_HOOK_F15 MACRO local fam15_disable_stack_hook_exit AMD_CPUID CPUID_MODEL mov ebx, eax ; Save revision info to EBX shr eax, 20 ; AL = cpu extended family cmp al, 06h ; Is this family 15h? jnz fam15_disable_stack_hook_exit ; Br if no mov ecx, LS_CFG ; MSR:C001_1020 .if (ebx != 00600F00h) ; Is this rev A0? _RDMSR btr eax, DIS_SS ; Turn on Streaming store functionality _WRMSR .endif ; End workaround for errata 495 and 496 inc ecx ;IC_CFG ; MSR:C001_1021 _RDMSR btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads _WRMSR inc ecx ;DC_CFG ; MSR:C001_1022 _RDMSR btr eax, DC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads .if (ebx != 00600F00h) ; Is this rev A0? btr eax, DIS_HW_PF ; Turn on hardware prefetches .endif ; End workaround for erratum 498 _WRMSR ;-------------------------------------------------------------------------- ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- bt esi, FLAG_IS_PRIMARY .if (carry?) ; Only clear cache from primary core mov ecx, HWCR ; MSR:C001_0015h _RDMSR btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion _WRMSR invd ; Clear the cache tag RAMs bts eax, INVD_WBINVD ; Turn on Conversion of INVD to WBINVD _WRMSR .endif ; end ;-------------------------------------------------------------------------- ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved. ;-------------------------------------------------------------------------- mov ecx, CU_CFG3 ; MSR:C001_102B _RDMSR bts edx, (COMBINE_CR0_CD - 32) ; Set CombineCr0Cd bit _WRMSR fam15_disable_stack_hook_exit: ENDM ;--------------------------------------------------- ; ; GET_NODE_ID_CORE_ID_F15 Macro - Stackless ; ; Read family specific values to determine the node and core ; numbers for the core executing this code. ; ; Inputs: ; none ; Outputs: ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above) ;--------------------------------------------------- GET_NODE_ID_CORE_ID_F15 MACRO local node_core_f15_exit cmp si, -1 ; Has node/core already been discovered? jnz node_core_f15_exit ; Br if yes AMD_CPUID CPUID_MODEL shr eax, 20 ; AL = cpu extended family cmp al, 06h ; Is this family 15h? jnz node_core_f15_exit ; Br if no xor esi, esi ; Assume BSC, clear local flags mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B _RDMSR bt eax, APIC_BSC ; Is this the BSC? .if (carry?) ; This is the BSP. ; Enable routing tables on BSP (just in case the HT init code has not yet enabled them) mov eax, 8000C06Ch ; PCI address for D18F0x6C Link Initialization Control Register mov dx, 0CF8h out dx, eax add dx, 4 in eax, dx btr eax, 0 ; Set LinkInitializationControl[RouteTblDis] = 0 out dx, eax .else ; ; This is an AP. Routing tables have been enabled by the HT Init process. ; Also, the MailBox register was set by the BSP during early init ; The Mailbox register content is formatted as follows: ; UINT32 Node:4; // The node id of Core's node. ; UINT32 Socket:4; // The socket of this Core's node. ; UINT32 Module:2; // The internal module number for Core's node. ; UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1. ; UINT32 :20; // Reserved ; mov ecx, 0C0000408h ; Read the family 15h mailbox _RDMSR ; MC4_MISC1[63:32] mov si, dx ; SI = raw mailbox contents (will extract node# from this) shr ebx, 24 ; BL = CPUID Fn0000_0001_EBX[LocalApicId] mov di, bx ; DI = Initial APIC ID (will extract core# from this) AMD_CPUID AMD_CPUID_APIC ; shr ch, 4 ; CH = ApicIdSize, #bits in APIC ID that show core# inc cl ; CL = Number of enabled cores in the socket mov bx, cx mov ecx, NB_CFG _RDMSR ; EDX has InitApicIdCpuIdLo bit mov cl, bh ; CL = APIC ID size mov al, 1 ; Convert APIC ID size to an AND mask shl al, cl ; AL = 2^APIC ID size dec al ; AL = mask for relative core number xor ah, ah ; AX = mask for relative core number bt edx, (INIT_APIC_ID_CPU_ID_LO-32) ; InitApicIdCpuIdLo == 1? .if (!carry?) ; Br if yes mov ch, 8 ; Calculate core number shift count sub ch, cl ; CH = core shift count mov cl, ch ; shr di, cl ; Right justify core number .endif ; and di, ax ; DI = socket-relative core number mov cx, si ; CX = raw mailbox value shr cx, 10 ; CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM) and cl, 3 ; Isolate ModuleType xor bh, bh ; BX = Number of enabled cores in the socket shr bx, cl ; BX = Number of enabled cores per node xor dx, dx ; Clear upper word for div mov ax, di ; AX = socket-relative core number div bx ; DX = node-relative core number movzx eax, si ; Prepare return value and ax, 000Fh ; AX = node number shl ax, 8 ; [15:8]=node# mov al, dl ; [7:0]=core# (relative to node) mov esi, eax ; ESI = node-relative core number .endif ; end ; ; determine if this core shares MTRRs ; mov eax, 8000C580h ; Compute Unit Status mov bx, si ; load node#(bh), core#(bl) shl bh, 3 ; Move node# to PCI Dev# field add ah, bh ; Adjust PCI adress for node number mov dx, 0CF8h out dx, eax add dx, 4 in eax, dx ; [3:0]=Enabled; [19:16]=DualCore ; ; BL is MyCore# , BH is primary flag mov cx, 06h ; Use CH as 'first of pair' core# .while (cl > 0) bt eax, 0 ; Is pair enabled? .if (carry?) ; mov bh, 01h ; flag core as primary bt eax, 16 ; Is there a 2nd in the pair? .if (carry?) ; .break .if (ch == bl) ; Does 1st match MyCore#? inc ch xor bh, bh ; flag core as NOT primary .break .if (ch == bl) ; Does 2nd match MyCore#? .else ; No 2nd core .break .if (ch == bl) ; Does 1st match MyCore#? .endif inc ch .endif shr eax, 1 dec cl .endw .if (cl == 0) ;Error - core# didn't match Compute Unit Status content bts esi, FLAG_UNKNOWN_FAMILY bts esi, FLAG_IS_PRIMARY ; Set Is_Primary for unknowns .endif .if (bh != 0) ; Check state of primary for the matched core bts esi, FLAG_IS_PRIMARY ; Set shared flag into return value .endif ; node_core_f15_exit: ENDM