summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f14/cpcar.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/cpcar.inc')
-rw-r--r--src/vendorcode/amd/agesa/f14/cpcar.inc1124
1 files changed, 1124 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/cpcar.inc b/src/vendorcode/amd/agesa/f14/cpcar.inc
new file mode 100644
index 0000000000..b9aaa91a7b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/cpcar.inc
@@ -0,0 +1,1124 @@
+;*****************************************************************************
+; 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 1 ; 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 <arg0>
+ 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
+
+
+