1 ;*****************************************************************************
2 ; AMD Generic Encapsulated Software Architecture
4 ; $Workfile:: cpcar.inc
6 ; Description: CPCAR.INC - AGESA cache-as-RAM setup Include File
8 ;*****************************************************************************
10 ; Copyright (c) 2011, Advanced Micro Devices, Inc.
11 ; All rights reserved.
13 ; Redistribution and use in source and binary forms, with or without
14 ; modification, are permitted provided that the following conditions are met:
15 ; * Redistributions of source code must retain the above copyright
16 ; notice, this list of conditions and the following disclaimer.
17 ; * Redistributions in binary form must reproduce the above copyright
18 ; notice, this list of conditions and the following disclaimer in the
19 ; documentation and/or other materials provided with the distribution.
20 ; * Neither the name of Advanced Micro Devices, Inc. nor the names of
21 ; its contributors may be used to endorse or promote products derived
22 ; from this software without specific prior written permission.
24 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
28 ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 ;*****************************************************************************
36 BSP_STACK_BASE_ADDR EQU 30000h ; Base address for primary cores stack
37 BSP_STACK_SIZE EQU 10000h ; 64KB for BSP core
38 CORE0_STACK_BASE_ADDR EQU 80000h ; Base address for primary cores stack
39 CORE0_STACK_SIZE EQU 4000h ; 16KB for primary cores
40 CORE1_STACK_BASE_ADDR EQU 40000h ; Base address for AP cores
41 CORE1_STACK_SIZE EQU 1000h ; 4KB for each AP cores
43 L3_CONTROL_REGISTER EQU 8100C3B8h ; Bus 0, Device 18h, Function 3, Offset 1B8h
45 APIC_BASE_ADDRESS EQU 0000001Bh
46 APIC_BSC EQU 8 ; Boot Strap Core
48 APIC_MSG_REG EQU 380h ; Location of BSC message
49 APIC_MSG EQU 00DE00ADh ; Message data
50 APIC_CMD_LO_REG EQU 300h ; APIC command low
51 APIC_CMD_HI_REG EQU 310h ; APIC command high
52 CMD_REG_TO_READ_DATA EQU 00000338h ; APIC command for remote read of APIC_MSG_REG
53 REMOTE_READ_STS EQU 00030000h ; Remote read status mask
54 REMOTE_DELIVERY_PEND EQU 00010000h ; Remote read is pending
55 REMOTE_DELIVERY_DONE EQU 00020000h ; Remote read is complete
56 DELIVERY_STS_BIT EQU 12 ; Delivery status valid bit
57 APIC_ID_REG EQU 0020h ; Local APIC ID offset
59 APIC_REMOTE_READ_REG EQU 00C0h ; Remote read offset
61 AMD_CU_NEED_TO_WAIT EQU 31
62 AMD_CU_SEND_INVD_MSG EQU 30
63 AMD_CU_RESTORE_ES EQU 29
65 AMD_MTRR_VARIABLE_BASE0 EQU 0200h
66 AMD_MTRR_VARIABLE_BASE6 EQU 020Ch
67 AMD_MTRR_VARIABLE_MASK7 EQU 020Fh
68 AMD_MTRR_FIX64k_00000 EQU 0250h
69 AMD_MTRR_FIX16k_80000 EQU 0258h
70 AMD_MTRR_FIX16k_A0000 EQU 0259h
71 AMD_MTRR_FIX4k_C0000 EQU 0268h
72 AMD_MTRR_FIX4k_C8000 EQU 0269h
73 AMD_MTRR_FIX4k_D0000 EQU 026Ah
74 AMD_MTRR_FIX4k_D8000 EQU 026Bh
75 AMD_MTRR_FIX4k_E0000 EQU 026Ch
76 AMD_MTRR_FIX4k_E8000 EQU 026Dh
77 AMD_MTRR_FIX4k_F0000 EQU 026Eh
78 AMD_MTRR_FIX4k_F8000 EQU 026Fh
80 AMD_MTRR_DEFTYPE EQU 02FFh
81 WB_DRAM_TYPE EQU 1Eh ; MemType - memory type
82 MTRR_DEF_TYPE_EN EQU 11 ; MtrrDefTypeEn - variable and fixed MTRRs default enabled
83 MTRR_DEF_TYPE_FIX_EN EQU 10 ; MtrrDefTypeEn - fixed MTRRs default enabled
85 HWCR EQU 0C0010015h ; Hardware Configuration
86 INVD_WBINVD EQU 4 ; INVD to WBINVD conversion
88 IORR_BASE EQU 0C0010016h ; IO Range Regusters Base/Mask, 2 pairs
90 TOP_MEM EQU 0C001001Ah ; Top of Memory
91 TOP_MEM2 EQU 0C001001Dh ; Top of Memory2
93 LS_CFG EQU 0C0011020h ; Load-Store Configuration
94 DIS_SS EQU 28 ; Family 10h,12h,15h:Disable Streaming Store functionality
95 DIS_STREAM_ST EQU 28 ; Family 14h:DisStreamSt - Disable Streaming Store functionality
97 IC_CFG EQU 0C0011021h ; Instruction Cache Config Register
98 IC_DIS_SPEC_TLB_RLD EQU 9 ; Disable speculative TLB reloads
99 DIS_IND EQU 14 ; Family 10-14h:Disable Indirect Branch Predictor
100 DIS_I_CACHE EQU 14 ; Family 15h:DisICache - Disable Indirect Branch Predictor
102 DC_CFG EQU 0C0011022h ; Data Cache Configuration
103 DC_DIS_SPEC_TLB_RLD EQU 4 ; Disable speculative TLB reloads
104 DIS_CLR_WBTOL2_SMC_HIT EQU 8 ; self modifying code check buffer bit
105 DIS_HW_PF EQU 13 ; Hardware prefetches bit
107 CU_CFG EQU 0C0011023h ; Family 15h: Combined Unit Configuration
108 L2_WAY_LOCK_EN EQU 23 ; L2WayLock - L2 way lock enable
109 L2_FIRST_LOCKED_WAY EQU 19 ; L2FirstLockedWay - first L2 way lockedh
110 L2_FIRST_LOCKED_WAY_OR_MASK EQU 000780000h
112 DE_CFG EQU 0C0011029h ; Decode Configuration
113 CL_FLUSH_SERIALIZE EQU 23 ; Family 12h,15h: CL Flush Serialization
115 BU_CFG2 EQU 0C001102Ah ; Family 10h: Bus Unit Configuration 2
116 CU_CFG2 EQU 0C001102Ah ; Family 15h: Combined Unit Configuration 2
117 F10_CL_LINES_TO_NB_DIS EQU 15 ; ClLinesToNbDis - allows WP code to be cached in L2
118 IC_DIS_SPEC_TLB_WR EQU 35 ; IcDisSpecTlbWr - ITLB speculative writes
120 CU_CFG3 EQU 0C001102Bh ; Combined Unit Configuration 3
121 COMBINE_CR0_CD EQU 49 ; Combine CR0.CD for both cores of a compute unit
124 CR0_PE EQU 0 ; Protection Enable
125 CR0_NW EQU 29 ; Not Write-through
126 CR0_CD EQU 30 ; Cache Disable
127 CR0_PG EQU 31 ; Paging Enable
132 AMD_CPUID_FMF EQU 80000001h ; Family Model Features information
133 AMD_CPUID_APIC EQU 80000008h ; Long Mode and APIC info., core count
134 APIC_ID_CORE_ID_SIZE EQU 12 ; ApicIdCoreIdSize bit position
136 NB_CFG EQU 0C001001Fh ; Northbridge Configuration Register
137 INIT_APIC_ID_CPU_ID_LO EQU 54 ; InitApicIdCpuIdLo - is core# in high or low half of APIC ID?
138 ENABLE_CF8_EXT_CFG EQU 46 ; EnableCf8ExtCfg - enable CF8 extended configuration cycles
140 MTRR_SYS_CFG EQU 0C0010010h ; System Configuration Register
141 CHX_TO_DIRTY_DIS EQU 16 ; ChxToDirtyDis Change to dirty disable
142 SYS_UC_LOCK_EN EQU 17 ; SysUcLockEn System lock command enable
143 MTRR_FIX_DRAM_EN EQU 18 ; MtrrFixDramEn MTRR fixed RdDram and WrDram attributes enable
144 MTRR_FIX_DRAM_MOD_EN EQU 19 ; MtrrFixDramModEn MTRR fixed RdDram and WrDram modification enable
145 MTRR_VAR_DRAM_EN EQU 20 ; MtrrVarDramEn MTRR variable DRAM enable
146 MTRR_TOM2_EN EQU 21 ; MtrrTom2En MTRR top of memory 2 enable
148 PERF_CONTROL3 EQU 0C0010003h ; Performance event control three
149 PERF_CONTROL3_RESERVE_L EQU 00200000h ; Preserve the reserved bits
150 PERF_CONTROL3_RESERVE_H EQU 0FCF0h ; Preserve the reserved bits
151 CONFIG_EVENT_L EQU 0F0E2h ; All cores with level detection
152 CONFIG_EVENT_H EQU 4 ; Increment count by number of event
153 ; occured in clock cycle
154 EVENT_ENABLE EQU 22 ; Enable the event
155 PERF_COUNTER3 EQU 0C0010007h ; Performance event counter three
157 ; Local use flags, in upper most byte if ESI
158 FLAG_UNKNOWN_FAMILY EQU 24 ; Signals that the family# of the installed processor is not recognized
159 FLAG_STACK_REENTRY EQU 25 ; Signals that the environment has made a re-entry (2nd) call to set up the stack
160 FLAG_IS_PRIMARY EQU 26 ; Signals that this core is the primary within the compute unit
161 FLAG_CORE_NOT_IDENTIFIED EQU 27 ; Signals that the cores/compute units of the installed processor is not recognized
163 ; Error code returned in EDX by AMD_ENABLE_STACK
164 IFNDEF CPU_EVENT_UNKNOWN_PROCESSOR_FAMILY
165 CPU_EVENT_UNKNOWN_PROCESSOR_FAMILY EQU 008010500h
167 IFNDEF CPU_EVENT_STACK_REENTRY
168 CPU_EVENT_STACK_REENTRY EQU 008020500h
170 IFNDEF CPU_EVENT_CORE_NOT_IDENTIFIED
171 CPU_EVENT_CORE_NOT_IDENTIFIED EQU 008030500h
174 ; AGESA_STATUS values
184 ;;***************************************************************************
186 ;; CPU MACROS - PUBLIC
188 ;;***************************************************************************
200 db 0Fh, 0A2h ; Execute instruction
202 xchg al, ah ; Ext model in al now
203 rol eax, 8 ; Ext model in ah, model in al
204 and ax, 0FFCFh ; Keep 23:16, 7:6, 3:0
212 ;---------------------------------------------------
214 ; AMD_ENABLE_STACK_FAMILY_HOOK Macro - Stackless
216 ; Set any family specific controls needed to enable the use of
217 ; cache as general storage before main memory is available.
223 ;---------------------------------------------------
224 AMD_ENABLE_STACK_FAMILY_HOOK MACRO
226 AMD_ENABLE_STACK_FAMILY_HOOK_F10
227 AMD_ENABLE_STACK_FAMILY_HOOK_F12
228 AMD_ENABLE_STACK_FAMILY_HOOK_F14
229 AMD_ENABLE_STACK_FAMILY_HOOK_F15
233 ;----------------------------------------------
235 ; AMD_DISABLE_STACK_FAMILY_HOOK Macro - Stackless
237 ; Return any family specific controls to their 'standard'
238 ; settings for using cache with main memory.
244 ;----------------------------------------------
245 AMD_DISABLE_STACK_FAMILY_HOOK MACRO
247 AMD_DISABLE_STACK_FAMILY_HOOK_F10
248 AMD_DISABLE_STACK_FAMILY_HOOK_F12
249 AMD_DISABLE_STACK_FAMILY_HOOK_F14
250 AMD_DISABLE_STACK_FAMILY_HOOK_F15
254 ;---------------------------------------------------
256 ; GET_NODE_ID_CORE_ID Macro - Stackless
258 ; Read family specific values to determine the node and core
259 ; numbers for the core executing this code.
264 ; SI[7:0] = Core# (0..N, relative to node)
265 ; SI[15:8]= Node# (0..N)
266 ; SI[23:16]= reserved
267 ; SI[24]= flag: 1=Family Unrecognized
268 ; SI[25]= flag: 1=Interface re-entry call
269 ; SI[26]= flag: 1=Core is primary of compute unit
270 ; SI[31:27]= reserved, =0
271 ;---------------------------------------------------
272 GET_NODE_ID_CORE_ID MACRO
275 GET_NODE_ID_CORE_ID_F10
276 GET_NODE_ID_CORE_ID_F12
277 GET_NODE_ID_CORE_ID_F14
278 GET_NODE_ID_CORE_ID_F15
280 ; Check for unrecognized Family
282 .if (si == -1) ; Has family (node/core) been discovered?
283 mov esi, ( (1 SHL FLAG_UNKNOWN_FAMILY)+(1 SHL FLAG_IS_PRIMARY) ) ; No, Set error code, Only let BSP continue
284 mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B
286 bt eax, APIC_BSC ; Is this the BSC?
297 ;;***************************************************************************
299 ;;***************************************************************************
300 ;---------------------------------------------------
302 ; AMD_ENABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
304 ; Set any family specific controls needed to enable the use of
305 ; cache as general storage before main memory is available.
308 ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
312 ; Family 10h requirements (BKDG section 2.3.3):
314 ; * MSRC001_0015[INVDWBINVD]=0
315 ; * MSRC001_1021[DIS_IND]=1
316 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
317 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
318 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1
319 ; * MSRC001_1022[DIS_HW_PF]=1
320 ; * MSRC001_102A[IcDisSpecTlbWr]=1
321 ; * MSRC001_102A[ClLinesToNbDis]=1
322 ; * No INVD or WBINVD, no exceptions, page faults or interrupts
323 ;---------------------------------------------------
324 AMD_ENABLE_STACK_FAMILY_HOOK_F10 MACRO
325 local fam10_enable_stack_hook_exit
327 AMD_CPUID CPUID_MODEL
328 mov ebx, eax ; Save revision info to EBX
329 shr eax, 20 ; AL = cpu extended family
330 cmp al, 01h ; Is this family 10h?
331 jnz fam10_enable_stack_hook_exit ; Br if no
334 ; F3x1B8[23] = 1 before enabling L3 cache through CR0[30](CD)
335 mov eax, ebx ; Restore revision info to EAX
336 .if (al >= 80h) ; Is this Revision D and later?
337 mov ecx, NB_CFG ; MSR:C001_001F
338 _RDMSR ; EDX has EnableCf8ExtCfg bit
339 bts edx, (ENABLE_CF8_EXT_CFG - 32)
342 mov eax, esi ; Get node# from esi[15:8]
344 shl eax, (11 - 8) ; Device#
345 add eax, L3_CONTROL_REGISTER
346 mov dx, 0CF8h ; PCI Read
351 or eax, (1 shl 23) ; F3x1B8[23] = 1
353 out dx, eax ; PCI Write
356 mov ecx, DC_CFG ; MSR:C001_1022
358 bts eax, DC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative DTLB reloads bit
359 bts eax, DIS_CLR_WBTOL2_SMC_HIT ; Turn on Disable the self modifying code check buffer bit
360 bts eax, DIS_HW_PF ; Turn on Disable hardware prefetches bit
363 dec cx ; MSR:C001_1021
365 bts eax, IC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative TLB reloads bit
366 bts eax, DIS_IND ; Turn on Disable indirect branch predictor
369 mov ecx, BU_CFG2 ; MSR C001_102A
371 bts eax, F10_CL_LINES_TO_NB_DIS ; Allow BIOS ROM to be cached in the IC
372 bts edx, (IC_DIS_SPEC_TLB_WR-32) ;Disable speculative writes to the ITLB
375 mov ecx, HWCR ; MSR C001_0015
378 bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set
380 btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion
384 mov eax, esi ; load core#
385 .if (al == 0) ; If (BSP)
386 mov ecx, PERF_COUNTER3 ; Select performance counter three
387 ; to count number of CAR evictions
388 xor eax, eax ; Initialize the lower part of the counter to zero
389 xor edx, edx ; Initializa the upper part of the counter to zero
391 mov ecx, PERF_CONTROL3 ; Select the event control three
392 _RDMSR ; Get the current setting
393 and eax, PERF_CONTROL3_RESERVE_L ; Preserve the reserved bits
394 or eax, CONFIG_EVENT_L ; Set the lower part of event register to
395 ; select CAR Corruption occurred by any cores
396 and dx, PERF_CONTROL3_RESERVE_H ; Preserve the reserved bits
397 or dx, CONFIG_EVENT_H ; Set the upper part of event register
399 bts eax, EVENT_ENABLE ; Enable it
403 fam10_enable_stack_hook_exit:
406 ;----------------------------------------------
408 ; AMD_DISABLE_STACK_FAMILY_HOOK_F10 Macro - Stackless
410 ; Return any family specific controls to their 'standard'
411 ; settings for using cache with main memory.
414 ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
418 ; Family 10h requirements:
420 ; * MSRC001_0015[INVD_WBINVD]=1
421 ; * MSRC001_1021[DIS_IND]=0
422 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
423 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
424 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
425 ; * MSRC001_1022[DIS_HW_PF]=0
426 ; * MSRC001_102A[IcDisSpecTlbWr]=0
427 ; * MSRC001_102A[ClLinesToNbDis]=0
428 ;----------------------------------------------
429 AMD_DISABLE_STACK_FAMILY_HOOK_F10 MACRO
430 local fam10_disable_stack_hook_exit
432 AMD_CPUID CPUID_MODEL
433 shr eax, 20 ; AL = cpu extended family
434 cmp al, 01h ; Is this family 10h?
435 jnz fam10_disable_stack_hook_exit ; Br if no
437 mov ecx, DC_CFG ; MSR:C001_1022
439 btr eax, DC_DIS_SPEC_TLB_RLD ; Enable speculative TLB reloads
440 btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Allow self modifying code check buffer
441 btr eax, DIS_HW_PF ; Allow hardware prefetches
444 dec cx ; MSR:C001_1021
446 btr eax, DIS_IND ; Turn on indirect branch predictor
447 btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads
450 mov ecx, BU_CFG2 ; MSR:C001_102A
452 btr eax, F10_CL_LINES_TO_NB_DIS ; Return L3 to normal mode
453 btr edx, (IC_DIS_SPEC_TLB_WR-32) ;Re-enable speculative writes to the ITLB
456 ;--------------------------------------------------------------------------
457 ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
458 ;--------------------------------------------------------------------------
459 mov ecx, HWCR ; MSR:0000_0015
461 mov bx, ax ; Save INVD -> WBINVD bit
462 btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion for the invd instruction.
464 invd ; Clear the cache tag RAMs
465 mov ax, bx ; Restore INVD -> WBINVD bit
468 ;--------------------------------------------------------------------------
469 ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
470 ;--------------------------------------------------------------------------
472 mov ecx, PERF_CONTROL3 ; Select the event control three
473 _RDMSR ; Retrieve the current value
474 btc eax, EVENT_ENABLE ; Is event enable, complement it as well
475 jnc fam10_disable_stack_hook_exit ; No
476 cmp ax, CONFIG_EVENT_L ; Is the lower part of event set to capture the CAR Corruption
477 jne fam10_disable_stack_hook_exit ; No
478 cmp dl, CONFIG_EVENT_H ; Is the upper part of event set to capture the CAR Corruption
479 jne fam10_disable_stack_hook_exit ; No
480 _WRMSR ; Disable the event
482 fam10_disable_stack_hook_exit:
485 ;---------------------------------------------------
487 ; GET_NODE_ID_CORE_ID_F10 Macro - Stackless
489 ; Read family specific values to determine the node and core
490 ; numbers for the core executing this code.
495 ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
496 ;---------------------------------------------------
497 GET_NODE_ID_CORE_ID_F10 MACRO
499 local node_core_f10_exit
501 cmp si, -1 ; Has node/core already been discovered?
502 jnz node_core_f10_exit ; Br if yes
504 AMD_CPUID CPUID_MODEL
505 shr eax, 20 ; AL = cpu extended family
506 cmp al, 01h ; Is this family 10h?
507 jnz node_core_f10_exit ; Br if no
509 xor esi, esi ; Assume BSC, clear flags
510 mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B
512 bt eax, APIC_BSC ; Is this the BSC?
515 ; Enable routing tables on BSP (just in case the HT init code has not yet enabled them)
516 mov eax, 8000C06Ch ; PCI address for D18F0x6C Link Initialization Control Register
521 btr eax, 0 ; Set LinkInitializationControl[RouteTblDis] = 0
524 ; This is an AP. Routing tables have been enabled by the HT Init process.
525 ; Also, the MailBox register was set by the BSP during early init
526 ; The Mailbox register content is formatted as follows:
527 ; UINT32 Node:4; // The node id of Core's node.
528 ; UINT32 Socket:4; // The socket of this Core's node.
529 ; UINT32 Module:2; // The internal module number for Core's node.
530 ; UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1.
531 ; UINT32 :20; // Reserved
533 mov ecx, 0C0000408h ; Read the family 10h mailbox
534 _RDMSR ; MC4_MISC1[63:32]
535 mov si, dx ; SI = raw mailbox contents (will extract node# from this)
536 shr ebx, 24 ; BL = CPUID Fn0000_0001_EBX[LocalApicId]
537 mov di, bx ; DI = Initial APIC ID (will extract core# from this)
539 AMD_CPUID AMD_CPUID_APIC ;
540 shr ch, 4 ; CH = ApicIdSize, #bits in APIC ID that show core#
541 inc cl ; CL = Number of enabled cores in the socket
544 mov ecx, NB_CFG ; MSR:C001_001F
545 _RDMSR ; EDX has InitApicIdCpuIdLo bit
547 mov cl, bh ; CL = APIC ID size
548 mov al, 1 ; Convert APIC ID size to an AND mask
549 shl al, cl ; AL = 2^APIC ID size
550 dec al ; AL = mask for relative core number
551 xor ah, ah ; AX = mask for relative core number
552 bt edx, (INIT_APIC_ID_CPU_ID_LO-32) ; InitApicIdCpuIdLo == 1?
553 .if (!carry?) ; Br if yes
554 mov ch, 8 ; Calculate core number shift count
555 sub ch, cl ; CH = core shift count
557 shr di, cl ; Right justify core number
559 and di, ax ; DI = socket-relative core number
561 mov cx, si ; CX = raw mailbox value
562 shr cx, 10 ; CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM)
563 and cl, 3 ; Isolate ModuleType
564 xor bh, bh ; BX = Number of enabled cores in the socket
565 shr bx, cl ; BX = Number of enabled cores per node
566 xor dx, dx ; Clear upper word for div
567 mov ax, di ; AX = socket-relative core number
568 div bx ; DX = node-relative core number
569 movzx eax, si ; prepare return value (clears flags)
570 and ax, 000Fh ; AX = node number
571 shl ax, 8 ; [15:8]=node#
572 mov al, dl ; [7:0]=core# (relative to node)
573 mov esi, eax ; ESI = return value
575 bts esi, FLAG_IS_PRIMARY ; all Family 10h cores are primary
581 ;;***************************************************************************
583 ;;***************************************************************************
584 ;---------------------------------------------------
586 ; AMD_ENABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless
588 ; Set any family specific controls needed to enable the use of
589 ; cache as general storage before main memory is available.
592 ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
596 ; Family 12h requirements (BKDG section 2.3.3):
597 ; The following requirements must be satisfied prior to using the cache as general storage:
598 ; * Paging must be disabled.
599 ; * MSRC001_0015[INVD_WBINVD]=0
600 ; * MSRC001_1020[DIS_SS]=1
601 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
602 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
603 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=1
604 ; * MSRC001_1022[DIS_HW_PF]=1
605 ; * MSRC001_1029[ClflushSerialize]=1
606 ; * No INVD or WBINVD, no exceptions, page faults or interrupts
607 ;---------------------------------------------------
608 AMD_ENABLE_STACK_FAMILY_HOOK_F12 MACRO
609 local fam12_enable_stack_hook_exit
611 AMD_CPUID CPUID_MODEL
612 shr eax, 20 ; AL = cpu extended family
613 cmp al, 03h ; Is this family 12h?
614 jnz fam12_enable_stack_hook_exit ; Br if no
616 mov ecx, DC_CFG ; MSR:C001_1022
618 bts eax, DC_DIS_SPEC_TLB_RLD ; Disable speculative DC-TLB reloads
619 bts eax, DIS_CLR_WBTOL2_SMC_HIT ; Disable self modifying code check buffer
620 bts eax, DIS_HW_PF ; Disable hardware prefetches
623 dec cx ;IC_CFG ; MSR:C001_1021
625 bts eax, IC_DIS_SPEC_TLB_RLD ; Disable speculative IC-TLB reloads
628 dec cx ;LS_CFG ; MSR:C001_1020
630 bts eax, DIS_SS ; Disabled Streaming store functionality
633 mov ecx, HWCR ; MSR C001_0015
635 bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set
637 btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion
641 mov ecx, DE_CFG ; MSR:C001_1029
643 bts eax, CL_FLUSH_SERIALIZE ; Serialize all CL Flush actions
646 fam12_enable_stack_hook_exit:
649 ;----------------------------------------------
651 ; AMD_DISABLE_STACK_FAMILY_HOOK_F12 Macro - Stackless
653 ; Return any family specific controls to their 'standard'
654 ; settings for using cache with main memory.
657 ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
661 ; Family 12h requirements:
663 ; * MSRC001_0015[INVD_WBINVD]=1
664 ; * MSRC001_1020[DIS_SS]=0
665 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
666 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
667 ; * MSRC001_1022[DIS_CLR_WBTOL2_SMC_HIT]=0
668 ; * MSRC001_1022[DIS_HW_PF]=0
669 ; * MSRC001_1029[ClflushSerialize]=0
670 ;---------------------------------------------------
671 AMD_DISABLE_STACK_FAMILY_HOOK_F12 MACRO
672 local fam12_disable_stack_hook_exit
674 AMD_CPUID CPUID_MODEL
675 shr eax, 20 ; AL = cpu extended family
676 cmp al, 03h ; Is this family 12h?
677 jnz fam12_disable_stack_hook_exit ; Br if no
679 mov ecx, DC_CFG ; MSR:C001_1022
681 btr eax, DC_DIS_SPEC_TLB_RLD ; Turn on speculative DC-TLB reloads
682 btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Enable self modifying code check buffer
683 btr eax, DIS_HW_PF ; Enable Hardware prefetches
686 dec cx ;IC_CFG ; MSR:C001_1021
688 btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative IC-TLB reloads
691 dec cx ;LS_CFG ; MSR:C001_1020
693 btr eax, DIS_SS ; Turn on Streaming store functionality
696 mov ecx, DE_CFG ; MSR:C001_1029
698 btr eax, CL_FLUSH_SERIALIZE
701 ;--------------------------------------------------------------------------
702 ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
703 ;--------------------------------------------------------------------------
705 mov ecx, HWCR ; MSR:0000_0015h
707 mov bx, ax ; Save INVD -> WBINVD bit
708 btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion
710 invd ; Clear the cache tag RAMs
711 mov ax, bx ; Restore INVD -> WBINVD bit
714 ;--------------------------------------------------------------------------
715 ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
716 ;--------------------------------------------------------------------------
718 fam12_disable_stack_hook_exit:
721 ;---------------------------------------------------
723 ; GET_NODE_ID_CORE_ID_F12 Macro - Stackless
725 ; Read family specific values to determine the node and core
726 ; numbers for the core executing this code.
731 ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
732 ;---------------------------------------------------
733 GET_NODE_ID_CORE_ID_F12 MACRO
735 local node_core_f12_exit
737 cmp si, -1 ; Has node/core already been discovered?
738 jnz node_core_f12_exit ; Br if yes
740 AMD_CPUID CPUID_MODEL
741 shr eax, 20 ; AL = cpu extended family
742 cmp al, 03h ; Is this family 12h?
743 jnz node_core_f12_exit ; Br if no
745 shr ebx, 24 ; CPUID_0000_0001_EBX[31:24]: initial local APIC physical ID
746 bts ebx, FLAG_IS_PRIMARY ; all family 12h cores are primary
747 mov esi, ebx ; ESI = Node#=0, core number
752 ;;***************************************************************************
754 ;;***************************************************************************
755 ;---------------------------------------------------
757 ; AMD_ENABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
759 ; Set any family specific controls needed to enable the use of
760 ; cache as general storage before main memory is available.
763 ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
767 ; Family 14h requirements (BKDG section 2.3.3):
768 ; * Paging must be disabled.
769 ; * MSRC001_0015[INVD_WBINVD]=0.
770 ; * MSRC001_1020[DisStreamSt]=1.
771 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1. Disable speculative ITLB reloads.
772 ; * MSRC001_1022[DIS_HW_PF]=1.
773 ; * No INVD or WBINVD, no exceptions, page faults or interrupts
774 ;---------------------------------------------------
775 AMD_ENABLE_STACK_FAMILY_HOOK_F14 MACRO
776 local fam14_enable_stack_hook_exit
778 AMD_CPUID CPUID_MODEL
779 shr eax, 20 ; AL = cpu extended family
780 cmp al, 05h ; Is this family 14h?
781 jnz fam14_enable_stack_hook_exit ; Br if no
783 mov ecx, DC_CFG ; MSR:C001_1022
785 bts eax, DIS_HW_PF ; Disable hardware prefetches
788 dec cx ;IC_CFG ; MSR:C001_1021
790 bts eax, IC_DIS_SPEC_TLB_RLD ; Disable speculative TLB reloads
793 dec cx ;LS_CFG ; MSR:C001_1020
795 bts eax, DIS_STREAM_ST ; Disabled Streaming store functionality
798 mov ecx, HWCR ; MSR C001_0015
800 bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set
802 btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion
806 fam14_enable_stack_hook_exit:
809 ;----------------------------------------------
811 ; AMD_DISABLE_STACK_FAMILY_HOOK_F14 Macro - Stackless
813 ; Return any family specific controls to their 'standard'
814 ; settings for using cache with main memory.
817 ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
821 ; Family 14h requirements:
823 ; * MSRC001_0015[INVD_WBINVD]=1.
824 ; * MSRC001_1020[DisStreamSt]=0.
825 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0.
826 ; * MSRC001_1022[DIS_HW_PF]=0.
827 ;---------------------------------------------------
828 AMD_DISABLE_STACK_FAMILY_HOOK_F14 MACRO
829 local fam14_disable_stack_hook_exit
831 AMD_CPUID CPUID_MODEL
832 shr eax, 20 ; AL = cpu extended family
833 cmp al, 05h ; Is this family 14h?
834 jnz fam14_disable_stack_hook_exit ; Br if no
836 mov ecx, LS_CFG ; MSR:C001_1020
838 btr eax, DIS_STREAM_ST ; Turn on Streaming store functionality
841 inc cx ;IC_CFG ; MSR:C001_1021
843 btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative DC-TLB reloads
846 inc cx ;DC_CFG ; MSR:C001_1022
848 btr eax, DIS_HW_PF ; Turn on hardware prefetches
851 ;--------------------------------------------------------------------------
852 ; Begin critical sequence in which EAX, BX, ECX, and EDX must be preserved.
853 ;--------------------------------------------------------------------------
855 mov ecx, HWCR ; MSR:C001_0015h
857 btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion
859 invd ; Clear the cache tag RAMs
860 bts eax, INVD_WBINVD ; Turn on Conversion of INVD to WBINVD
863 ;--------------------------------------------------------------------------
864 ; End critical sequence in which EAX, BX, ECX, and EDX must be preserved.
865 ;--------------------------------------------------------------------------
867 fam14_disable_stack_hook_exit:
870 ;---------------------------------------------------
872 ; GET_NODE_ID_CORE_ID_F14 Macro - Stackless
874 ; Read family specific values to determine the node and core
875 ; numbers for the core executing this code.
880 ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
881 ;---------------------------------------------------
882 GET_NODE_ID_CORE_ID_F14 MACRO
884 local node_core_f14_exit
886 cmp si, -1 ; Has node/core already been discovered?
887 jnz node_core_f14_exit ; Br if yes
889 AMD_CPUID CPUID_MODEL
890 shr eax, 20 ; AL = cpu extended family
891 cmp al, 05h ; Is this family 14h?
892 jnz node_core_f14_exit ; Br if no
894 shr ebx, 24 ; CPUID_0000_0001_EBX[31:24]: initial local APIC physical ID
895 bts ebx, FLAG_IS_PRIMARY ; all family 14h cores are primary
896 mov esi, ebx ; ESI = Node#=0, core number
902 ;;***************************************************************************
904 ;;***************************************************************************
905 ;---------------------------------------------------
907 ; AMD_ENABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
909 ; Set any family specific controls needed to enable the use of
910 ; cache as general storage before main memory is available.
913 ; ESI - node#, core#, flags from GET_NODE_ID_CORE_ID
917 ; Family 15h requirements (BKDG #42301 section 2.3.3):
918 ; * Paging must be disabled.
919 ; * MSRC001_0015[INVD_WBINVD]=0
920 ; * MSRC001_1020[DisSS]=1
921 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=1
922 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=1
923 ; * MSRC001_1022[DisHwPf]=1
924 ; * No INVD or WBINVD, no exceptions, page faults or interrupts
925 ;---------------------------------------------------
926 AMD_ENABLE_STACK_FAMILY_HOOK_F15 MACRO
927 local fam15_enable_stack_hook_exit
929 AMD_CPUID CPUID_MODEL
930 mov ebx, eax ; Save revision info to EBX
931 shr eax, 20 ; AL = cpu extended family
932 cmp al, 06h ; Is this family 15h?
933 jnz fam15_enable_stack_hook_exit ; Br if no
935 bt esi, FLAG_STACK_REENTRY ; Check if stack has already been set
937 mov ecx, HWCR ; MSR C001_0015
939 btr eax, INVD_WBINVD ; disable INVD -> WBINVD conversion
943 mov ecx, LS_CFG ; MSR:C001_1020
945 bts eax, DIS_SS ; Turn on Streaming store functionality disabled bit
948 inc ecx ;IC_CFG ; MSR:C001_1021
950 bts eax, IC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative IC-TLB reloads bit
953 inc ecx ;DC_CFG ; MSR:C001_1022
955 bts eax, DC_DIS_SPEC_TLB_RLD ; Turn on Disable speculative DC-TLB reloads bit
956 bts eax, DIS_HW_PF ; Turn on Disable hardware prefetches bit
959 mov ecx, CU_CFG3 ; MSR:C001_102B
961 btr edx, (COMBINE_CR0_CD - 32) ; Clear CombineCr0Cd bit
964 fam15_enable_stack_hook_exit:
968 ;----------------------------------------------
970 ; AMD_DISABLE_STACK_FAMILY_HOOK_F15 Macro - Stackless
972 ; Return any family specific controls to their 'standard'
973 ; settings for using cache with main memory.
976 ; ESI - [31:24] flags; [15,8]= Node#; [7,0]= core#
980 ; Family 15h requirements:
982 ; * MSRC001_0015[INVD_WBINVD]=1
983 ; * MSRC001_1020[DisSS]=0
984 ; * MSRC001_1021[DIS_SPEC_TLB_RLD]=0
985 ; * MSRC001_1022[DIS_SPEC_TLB_RLD]=0
986 ; * MSRC001_1022[DIS_HW_PF]=0
987 ;---------------------------------------------------
988 AMD_DISABLE_STACK_FAMILY_HOOK_F15 MACRO
989 local fam15_disable_stack_hook_exit
991 AMD_CPUID CPUID_MODEL
992 mov ebx, eax ; Save revision info to EBX
993 shr eax, 20 ; AL = cpu extended family
994 cmp al, 06h ; Is this family 15h?
995 jnz fam15_disable_stack_hook_exit ; Br if no
997 mov edi, ebx ; Save revision info to EDI
998 AMD_CPUID AMD_CPUID_APIC
999 mov al, cl ; AL = number of cores - 1
1000 shr cx, APIC_ID_CORE_ID_SIZE ; CL = ApicIdCoreIdSize
1002 shl bl, cl ; BL = theoretical number of cores on socket
1003 dec bx ; BL = core number on socket mask
1004 mov ah, bl ; AH = core number on socket mask
1005 mov ebx, edi ; Restore revision info to EBX
1006 mov di, ax ; DI[15:8] = core number mask, DI[7:0] = number of cores - 1
1011 or bx, ax ; Save Extended Model, Model and Stepping to BX
1012 ; [11:8] = Extended Model, [7:4] = Model, [3:0] = Stepping
1014 ;; A handshake is required to ensure that all cores on a node invalidate in sync.
1015 mov ecx, APIC_BASE_ADDRESS
1017 mov dx, bx ; Save Extended Model, Model and Stepping to DX
1018 shl edx, 16 ; EDX[31:16] = Extended Model, Model and Stepping
1019 mov ebx, eax ; EBX = LAPIC base
1020 xor ecx, ecx ; Zero out CU flags
1021 bts ecx, AMD_CU_NEED_TO_WAIT ; Default to waiting
1022 bts ecx, AMD_CU_SEND_INVD_MSG ; Default to signaling
1024 bt ax, CR0_PE ; Are we in protected mode?
1026 bts ecx, AMD_CU_RESTORE_ES ; Indicate ES restore is required
1027 mov cx, es ; Save ES segment register to CX
1029 mov es, ax ; Set ES to big real mode selector for 4GB access
1032 and bx, 0F000h ; EBX = LAPIC base, offset 0
1034 mov eax, es:[ebx] ; EAX[31:24] = APIC ID
1035 shr eax, APIC20_APICID ; AL = APIC ID
1036 mov ah, al ; AH = APIC ID
1037 mov dx, di ; DH = core mask
1038 and ah, dh ; AH = core number
1040 ;; Core 0 of a socket
1041 btr ecx, AMD_CU_SEND_INVD_MSG ; No need to signal after INVD
1043 ;; This socket has multiple cores
1044 and bx, 0F000h ; EBX = LAPIC base, offset 0
1047 mov es:[ebx], edi ; Signal for non core 0s to complete CAR breakdown
1049 btr ecx, AMD_CU_NEED_TO_WAIT ; No need to wait on a single core CPU
1053 bt ecx, AMD_CU_NEED_TO_WAIT
1056 ;; This is the highest numbered core on this socket -- wait on core 0
1057 not dh ; Flip the mask to determine local core 0's APIC ID
1058 and al, dh ; AL = target APIC ID
1060 ;; All other cores (including core 0) wait on the next highest core.
1061 ;; In this way, cores will halt in a cascading fashion down to 0.
1065 shl eax, APIC20_APICID
1067 or bx, APIC_CMD_HI_REG
1068 mov es:[ebx], eax ; Set target APIC ID
1072 and bx, 0F000h ; EBX = LAPIC base, offset 0
1073 or bx, APIC_CMD_LO_REG
1074 mov eax, CMD_REG_TO_READ_DATA
1075 mov es:[ebx], eax ; Fire remote read IPI
1079 bt eax, DELIVERY_STS_BIT
1084 and eax, REMOTE_READ_STS
1085 .if (eax == REMOTE_DELIVERY_PEND)
1091 .if (eax == REMOTE_DELIVERY_DONE)
1092 and bx, 0F000h ; EBX = LAPIC base, offset 0
1093 or bl, APIC_REMOTE_READ_REG
1095 .if (eax == APIC_MSG)
1105 bt ecx, AMD_CU_RESTORE_ES
1109 mov edi, ecx ; EDI = CU flags
1111 mov bx, dx ; Restore Extended Model, Model and Stepping
1113 ;; Handshaking complete. Continue tearing down CAR.
1114 mov ecx, LS_CFG ; MSR:C001_1020
1115 .if (bx != 0) ; Is this OR A0?
1117 btr eax, DIS_SS ; Turn on Streaming store functionality
1119 .endif ; End workaround for errata 495 and 496
1121 inc ecx ;IC_CFG ; MSR:C001_1021
1123 btr eax, IC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads
1126 inc ecx ;DC_CFG ; MSR:C001_1022
1128 btr eax, DC_DIS_SPEC_TLB_RLD ; Turn on speculative TLB reloads
1129 .if (bx != 0) ; Is this OR A0?
1130 btr eax, DIS_HW_PF ; Turn on hardware prefetches
1131 .endif ; End workaround for erratum 498
1134 mov ecx, HWCR ; MSR:C001_0015h
1136 btr eax, INVD_WBINVD ; Disable INVD -> WBINVD conversion
1138 invd ; Clear the cache tag RAMs
1140 ; Do Standard Family 15 work
1141 mov ecx, HWCR ; MSR:C001_0015h
1143 bts eax, INVD_WBINVD ; Turn on INVD -> WBINVD conversion
1146 mov ecx, CU_CFG3 ; MSR:C001_102B
1148 bts edx, (COMBINE_CR0_CD - 32) ; Set CombineCr0Cd bit
1151 bt edi, AMD_CU_SEND_INVD_MSG
1153 ;; Non core zero needs to signal to core 0 to proceed
1154 mov ecx, APIC_BASE_ADDRESS
1156 mov ebx, eax ; EBX = LAPIC base
1157 and bx, 0F000h ; EBX = LAPIC base, offset 0
1160 mov es:[ebx], eax ; Signal for core 0 to complete CAR breakdown
1163 fam15_disable_stack_hook_exit:
1167 ;---------------------------------------------------
1169 ; GET_NODE_ID_CORE_ID_F15 Macro - Stackless
1171 ; Read family specific values to determine the node and core
1172 ; numbers for the core executing this code.
1177 ; SI = core#, node# & flags (see GET_NODE_ID_CORE_ID macro above)
1178 ;---------------------------------------------------
1179 GET_NODE_ID_CORE_ID_F15 MACRO
1181 local node_core_f15_exit
1183 cmp si, -1 ; Has node/core already been discovered?
1184 jnz node_core_f15_exit ; Br if yes
1186 AMD_CPUID CPUID_MODEL
1187 shr eax, 20 ; AL = cpu extended family
1188 cmp al, 06h ; Is this family 15h?
1189 jnz node_core_f15_exit ; Br if no
1191 xor esi, esi ; Assume BSC, clear local flags
1192 mov ecx, APIC_BASE_ADDRESS ; MSR:0000_001B
1194 bt eax, APIC_BSC ; Is this the BSC?
1197 ; Enable routing tables on BSP (just in case the HT init code has not yet enabled them)
1198 mov eax, 8000C06Ch ; PCI address for D18F0x6C Link Initialization Control Register
1203 btr eax, 0 ; Set LinkInitializationControl[RouteTblDis] = 0
1206 ; This is an AP. Routing tables have been enabled by the HT Init process.
1207 ; Also, the MailBox register was set by the BSP during early init
1208 ; The Mailbox register content is formatted as follows:
1209 ; UINT32 Node:4; // The node id of Core's node.
1210 ; UINT32 Socket:4; // The socket of this Core's node.
1211 ; UINT32 Module:2; // The internal module number for Core's node.
1212 ; UINT32 ModuleType:2; // Single Module = 0, Multi-module = 1.
1213 ; UINT32 :20; // Reserved
1215 mov ecx, 0C0000408h ; Read the family 15h mailbox
1216 _RDMSR ; MC4_MISC1[63:32]
1217 mov si, dx ; SI = raw mailbox contents (will extract node# from this)
1218 shr ebx, 24 ; BL = CPUID Fn0000_0001_EBX[LocalApicId]
1219 mov di, bx ; DI = Initial APIC ID (will extract core# from this)
1221 AMD_CPUID AMD_CPUID_APIC ;
1222 shr ch, 4 ; CH = ApicIdSize, #bits in APIC ID that show core#
1223 inc cl ; CL = Number of enabled cores in the socket
1227 _RDMSR ; EDX has InitApicIdCpuIdLo bit
1229 mov cl, bh ; CL = APIC ID size
1230 mov al, 1 ; Convert APIC ID size to an AND mask
1231 shl al, cl ; AL = 2^APIC ID size
1232 dec al ; AL = mask for relative core number
1233 xor ah, ah ; AX = mask for relative core number
1234 bt edx, (INIT_APIC_ID_CPU_ID_LO-32) ; InitApicIdCpuIdLo == 1?
1235 .if (!carry?) ; Br if yes
1236 mov ch, 8 ; Calculate core number shift count
1237 sub ch, cl ; CH = core shift count
1239 shr di, cl ; Right justify core number
1241 and di, ax ; DI = socket-relative core number
1243 mov cx, si ; CX = raw mailbox value
1244 shr cx, 10 ; CL[1:0] = ModuleType or #nodes per socket (0-SCM, 1-MCM)
1245 and cl, 3 ; Isolate ModuleType
1246 xor bh, bh ; BX = Number of enabled cores in the socket
1247 shr bx, cl ; BX = Number of enabled cores per node
1248 xor dx, dx ; Clear upper word for div
1249 mov ax, di ; AX = socket-relative core number
1250 div bx ; DX = node-relative core number
1251 movzx eax, si ; Prepare return value
1252 and ax, 000Fh ; AX = node number
1253 shl ax, 8 ; [15:8]=node#
1254 mov al, dl ; [7:0]=core# (relative to node)
1255 mov esi, eax ; ESI = node-relative core number
1259 ; determine if this core shares MTRRs
1261 mov eax, 8000C580h ; Compute Unit Status
1262 mov bx, si ; load node#(bh), core#(bl)
1263 shl bh, 3 ; Move node# to PCI Dev# field
1264 add ah, bh ; Adjust PCI adress for node number
1268 in eax, dx ; [3:0]=Enabled; [19:16]=DualCore
1270 ; BL is MyCore# , BH is primary flag
1271 mov cx, 06h ; Use CH as 'first of pair' core#
1273 bt eax, 0 ; Is pair enabled?
1275 mov bh, 01h ; flag core as primary
1276 bt eax, 16 ; Is there a 2nd in the pair?
1278 .break .if (ch == bl) ; Does 1st match MyCore#?
1280 xor bh, bh ; flag core as NOT primary
1281 .break .if (ch == bl) ; Does 2nd match MyCore#?
1283 .break .if (ch == bl) ; Does 1st match MyCore#?
1291 ;Error - core# didn't match Compute Unit Status content
1292 bts esi, FLAG_CORE_NOT_IDENTIFIED
1293 bts esi, FLAG_IS_PRIMARY ; Set Is_Primary for unknowns
1295 .if (bh != 0) ; Check state of primary for the matched core
1296 bts esi, FLAG_IS_PRIMARY ; Set shared flag into return value