| ;***************************************************************************** |
| ; 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 <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 |
| |
| |
| |