summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc')
-rw-r--r--ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc1024
1 files changed, 1024 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc
new file mode 100644
index 0000000..7b9dea4
--- /dev/null
+++ b/ReferenceCode/Haswell/SampleCode/SecCore/Sec/Ia32/SecFlat32.inc
@@ -0,0 +1,1024 @@
+;
+; This file contains a 'Sample Driver' and is licensed as such
+; under the terms of your license agreement with Intel or your
+; vendor. This file may be modified by the user, subject to
+; the additional terms of the license agreement
+;
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 1999 - 2012, Intel Corporation. All rights reserved.<BR>
+; This software and associated documentation (if any) is furnished
+; under a license and may only be used or copied in accordance
+; with the terms of the license. Except as permitted by such
+; license, no part of this software or documentation may be
+; reproduced, stored in a retrieval system, or transmitted in any
+; form or by any means without the express written consent of
+; Intel Corporation.
+;
+; Module Name:
+;
+; SecFlat32.inc
+;
+; Abstract:
+;
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector.
+;
+;------------------------------------------------------------------------------
+
+CALL_MMX macro RoutineLabel
+
+ local ReturnAddress
+ mov esi, offset ReturnAddress
+ movd mm7, esi ; save ReturnAddress into MM7
+ jmp RoutineLabel
+ReturnAddress:
+
+endm
+
+RET_ESI macro
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+endm
+
+CALL_EBP macro RoutineLabel
+
+ local ReturnAddress
+ mov ebp, offset ReturnAddress
+ jmp RoutineLabel
+ReturnAddress:
+
+endm
+
+RET_EBP macro
+
+ jmp ebp ; restore ESP from EBP
+
+endm
+
+align 4
+ProtectedModeSECStart PROC NEAR PUBLIC
+ STATUS_CODE (02h)
+ CALL_MMX EnableAccessCSR
+
+;(AMI_CHG+)>
+ STATUS_CODE (07h)
+ CALL_MMX VeryEarlyMicrocodeUpdate
+;<(AMI_CHG+)
+
+ CALL_MMX DetectNumOfCPUSocket
+
+ STATUS_CODE (03h)
+;(AMI_CHG+)>
+ ;-Things in PlatformInitialization are ready done in chipset part
+ ;-CALL_MMX PlatformInitialization
+;<(AMI_CHG+)
+ STATUS_CODE (09h)
+ CALL_MMX InitializeNEM
+
+ STATUS_CODE (0Bh)
+ jmp CallPeiCoreEntryPoint
+
+ProtectedModeSECStart ENDP
+
+EnableAccessCSR PROC NEAR PRIVATE
+ ;
+ ; get Bus number from CPUID[1] EBX[31:24]
+ ;
+
+ mov eax, 0Bh
+ mov ecx, 1
+ cpuid
+ mov esi, eax
+
+ mov eax, 1 ; bus 0
+ cpuid
+ bswap ebx
+ movzx eax, bl
+ movzx ebx, bl
+ shl eax, BSPApicIDSaveStart ; Save current BSP APIC ID in MM1[31:24]
+ mov cx, si
+ shr bl, cl ; get Bus number in BL
+ or eax, ebx
+ movd mm1, eax ; save Bus number MM1[7:0]
+
+ ;
+ ; Enable MM PCI-E Config Space
+ ; --cr-- use register symbol name; should upper 32 bit be cleared
+ ;
+ mov eax, 080000060h ; MCHBAR
+ mov dx, 0CF8h
+ out dx, eax
+ mov dx, 0CFCh
+ mov eax, MMCFG_LENGTH_BIT_SETTING
+ out dx, eax
+ in eax, dx
+ or eax, MMCFG_BASE OR ENABLE
+ out dx, eax
+
+ ; Clear reset flag
+ movd eax, mm1
+ and eax, NOT BIT18+BIT19
+ movd mm1, eax
+ RET_ESI
+
+EnableAccessCSR ENDP
+
+; STATUS_CODE (03h)
+;PlatformInitialization PROC NEAR PRIVATE
+;
+; ;
+; ; Program PCI Express base address
+; ;
+;
+; mov eax, 80000060h ; 0:0:0:60
+; mov dx, 0CF8h
+; out dx, eax
+; mov dx, 0CFCh
+; ;using Pcd instead
+; ;mov eax, 0e0000000h OR 00h OR 1
+;; mov eax, DWORD PTR PcdGet64 (PcdPciExpressBaseAddress)
+; mov eax, DWORD PTR PCIEXPRESS_BASE_ADDRESS
+; or eax, (PCIEX_LENGTH_BIT_SETTING OR 1)
+; out dx, eax
+;
+; ;
+; ; Enable Mch Bar
+; ;
+; mov esi, MCHBAR_REG
+; mov eax, (MCH_BASE_ADDRESS + 1)
+; mov Dword Ptr [esi], eax
+;
+; ;
+; ; Enable RCRB in PCH.
+; ;
+; mov esi, PCH_LPC_RCRB_PCI_ADDR
+; mov eax, PCH_RCRB_BASE + 1
+; mov Dword Ptr [esi], eax
+;
+; ;
+; ; Configure GPIO to be able to initiate LVL change for GPIO48 for S3 resume time calculation.
+; ;
+; ; Enable GPIO BASE I/O registers
+; ;
+; mov eax, PCI_LPC_BASE + 48h
+; mov dx, 0CF8h
+; out dx, eax
+; mov eax, GPIO_BASE_ADDRESS
+; add dx, 4
+; out dx, eax
+;
+; mov eax, PCI_LPC_BASE + 4Ch
+; mov dx, 0CF8h
+; out dx, eax
+; add dx, 4
+; in al, dx
+; or al, BIT4 ; GPIOBASE Enable
+; out dx, al
+;
+; ;GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
+; mov dx, GPIO_BASE_ADDRESS + R_GPIO_USE_SEL2
+; in eax, dx
+; or eax, 010000h ;Enable GPIO48
+; out dx, eax
+;
+; ;GP_IO_SEL2 Register -> 1 = Input 0 = Output (if Native Mode don't care)
+; mov dx, GPIO_BASE_ADDRESS + R_GPIO_IO_SEL2
+; in eax, dx
+; and eax, 0FFFEFFFFh ;Configure GPIO48 as Output
+; out dx, eax
+;
+; mov dx, GPIO_BASE_ADDRESS + R_GPIO_LVL2
+; in eax, dx
+; or eax, 010000h ;Configure GPIO48 as High
+; out dx, eax
+;
+; ;
+; ; Program and Enable ACPI PM Base.
+; ;
+; mov esi, PCH_LPC_PMBASE_PCI_ADDR
+; mov eax, PCH_ACPI_BASE_ADDRESS + 1
+; mov Dword Ptr [esi], eax
+; mov esi, PCH_LPC_ACPICNTL_PCI_ADDR
+; or Dword Ptr [esi], 00000080h
+;
+; ;
+; ; PCH BIOS Spec Rev 0.5.0 Section 12.9
+; ; Additional Programming Requirements for USB Support
+; ; Step 2.b
+; ; Clear RCBA + 3598h [0] to 0b
+; ;
+; mov esi, PCH_RCRB_BASE + 3598h
+; mov eax, 0
+; mov Dword Ptr [esi], eax
+;
+; ;
+; ; Enable HPET decode in PCH.
+; ;
+; mov esi, PCH_RCRB_BASE + PCH_RCRB_HPET
+; mov eax, PCH_RCRB_HPET_DECODE
+; mov Dword Ptr [esi], eax
+; mov eax, Dword ptr [esi]
+; xor eax, eax
+; mov esi, HPET_COMP_1
+; mov Dword Ptr [esi], eax
+; mov esi, HPET_COMP_2
+; mov Dword ptr [esi], eax
+;
+; ;
+; ; Enable the upper 128-byte bank of RTC RAM.
+; ;
+; mov esi, PCH_RCRB_BASE + PCH_RCRB_RTC_CONF
+; mov eax, Dword Ptr [esi]
+; or eax, PCH_RCRB_RTC_CONF_UCMOS_EN
+; mov Dword Ptr [esi], eax
+;
+; ;
+; ; Choose Port80 Route
+; ;
+; mov esi, PCH_RCRB_BASE + PCH_RCRB_GCS
+; mov ebx, Dword Ptr [esi]
+; or bl, BIT5
+;
+; ;
+; ; check SETUP option - PchPort80Route
+; ; 0 = LPC {Default]; 1 = PCI
+; ;
+;; mov al, CMOS_PCH_PORT80_OFFSET ; CMOS Offset = 17h
+;; mov dx, RTC_UPPER_INDEX
+;; out dx, al
+;; inc dx
+;; in al, dx
+;; test al, BIT0
+;; jnz @F
+; and bl, NOT (BIT2) ; Port80h to LPC
+;;@@:
+; mov Dword Ptr [esi], ebx
+;
+; ;
+; ; Halt TCO Timer
+; ;
+; mov dx, 0468h
+; in ax, dx
+; or ax, BIT11
+; out dx, ax
+;
+; ;
+; ; Clear the Second TO status bit
+; ;
+; mov dx, 0466h
+; in ax, dx
+; or ax, BIT1
+; out dx, ax
+;
+; RET_ESI
+;
+;PlatformInitialization ENDP
+
+; STATUS_CODE (03h)
+DetectNumOfCPUSocket PROC NEAR PRIVATE
+
+ ; only one socket
+ movd eax, mm1 ; get MM1 value into EAX
+ mov ah, 01
+ movd mm1, eax ; save CPU pkg count into MM1[15:8]
+
+ RET_ESI
+
+DetectNumOfCPUSocket ENDP
+
+; STATUS_CODE (07h)
+VeryEarlyMicrocodeUpdate PROC NEAR PRIVATE
+; (AMI_CHG+)>
+ public FindMicrocodeEnd
+ mov ecx,08bh
+ rdmsr
+ or dx,dx
+ jnz uc_exit
+ jmp FindMicrocode ;return to MicroCodeUpdateEnd
+FindMicrocodeEnd::
+ or eax, eax
+ jz uc_exit ;No microcode found:
+
+ ;Update microcode
+ mov ecx, 79h
+ xor edx, edx
+ add eax, 48 ;eax = Update data
+ wrmsr ;Update microcode
+uc_exit:
+ RET_ESI
+
+;-IF EARLY_MICROCODE_SUPPORT
+;- mov ecx, IA32_BIOS_SIGN_ID
+;- rdmsr ; CPU PatchID -> EDX
+;- cmp edx, 0 ; If microcode has been updated
+;- jnz luExit ; Skip if patch already loaded
+;-
+;- mov ecx, IA32_PLATFORM_ID ; To get Platform ID.
+;- rdmsr
+;- shr edx, 18 ; EDX[0-2] = Platform ID.
+;- and dx, 07h ; DX = Platform ID.
+;- mov si, dx ; Save Platform ID in FS.
+;- mov eax, 01h ; To get CPU signature.
+;- cpuid ; EAX = CPU signature.
+;- mov cx, si ; CX = Platform ID
+;- xor edx, edx
+;- bts dx, cx ; EDX = Platform ID bit.
+;-
+; mov esi, PcdGet32 (PcdFlashMicrocodeFvBase)
+;- mov esi, MICROCODE_FV_BASE_ADDRESS
+;-
+;- mov ebx, esi
+;- mov bx, FVHEADER_LEN_OFF
+;- movzx ebx, WORD PTR [ebx]
+;- add esi, ebx
+;- add si, FFSHEADER_LEN ; add FFS header
+;-
+;- mov edi, PcdGet32 (PcdFlashMicrocodeFvBase)
+;- mov ebx, PcdGet32 (PcdFlashMicrocodeFvSize)
+;- mov edi, MICROCODE_FV_BASE_ADDRESS
+;- mov ebx, MICROCODE_FV_SIZE
+;- add edi, ebx ;End addr of uCodes.
+;-
+;- ; EAX = CPU signature.
+;- ; EDX = Platform ID bit.
+;- ; ESI = Abs addr of contiguous uCode blocks.
+;- ; EDI = Abs addr of contiguous uCode blocks end.
+;-
+;-luCheckPatch:
+;- cmp (UpdateHeaderStruc PTR ds:[esi]).dProcessorSignature, eax;Sig matched?
+;- jnz luCheckUnprogrammed ; No.
+;- test (UpdateHeaderStruc PTR ds:[esi]).dProcessorFlags, edx;Platform matched?
+;- jnz luFoundMatch ; Yes.
+;-
+;-luCheckUnprogrammed:
+;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dDataSize
+;- cmp ebx, 0FFFFFFFFh
+;- je luUnprogrammed
+;- cmp (UpdateHeaderStruc PTR ds:[esi]).dLoaderRevision, 1
+;- je luCheckExtdHdrs
+;-
+;-luUnprogrammed:
+;- mov ebx, 1024 ; Unprogrammed space, 1KB checks
+;- jmp luPoinToNextBlock ; for backword compatibility.
+;-
+;-luCheckExtdHdrs:
+;- add ebx, SIZEOF(UpdateHeaderStruc)
+;- cmp ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize
+;- jae luTryNextPatch ; No extd hdrs.
+;-
+;- mov ecx, DWORD PTR ds:[esi + ebx]
+;- jcxz luTryNextPatch ; No extd hdrs. (OK to use CX instead of ECX).
+;- add ebx, 20 ; Point to the first Extd Sig.
+;-luNextSig:
+;- cmp eax, DWORD PTR ds:[esi + ebx] ;Sig matched?
+;- jne lu_00
+;- test edx, DWORD PTR ds:[esi + ebx + 4] ;Platform matched?
+;- jnz luFoundMatch
+;-lu_00:
+;- add ebx, 12
+;- loop luNextSig
+;-
+;-luTryNextPatch:
+;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dTotalSize
+;- or ebx, ebx
+;- jnz luPoinToNextBlock ; Variable size uCode format.
+;- mov ebx, BLOCK_LENGTH_BYTES ; Fixed size uCode format.
+
+;
+; Add alignment check - begin
+;
+;- test ebx, 0400h
+;- jz @F
+;- add ebx, 0400h
+;-@@:
+;
+; Add alignment check - end
+;
+
+;-luPoinToNextBlock:
+;- add esi, ebx
+;- cmp esi, edi
+;- jb luCheckPatch ; Check with all patches.
+;-
+;- ; Check possible multiple patch
+;- movd eax, mm3
+;- movd esi, mm4
+;- or eax, eax
+;- jnz luLoadPatch
+;- jmp luExit ; No matching patch found.
+;-
+;-luFoundMatch:
+;-; MM3 = Patch Revision
+;-; MM4 = Patch Pointer
+;- movd ebx, mm3
+;- cmp (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision, ebx
+;- jb luTryNextPatch
+;-
+;- mov ebx, (UpdateHeaderStruc PTR ds:[esi]).dUpdateRevision
+;-
+;-luStoreRevPtr:
+;- movd mm3, ebx ; save Patch Revision
+;- movd mm4, esi ; save Patch Pointer
+;- jmp luTryNextPatch
+;-
+;-luLoadPatch:
+;- mov ecx, IA32_BIOS_UPDT_TRIG
+;- mov eax, esi ; EAX - Abs addr of uCode patch.
+;- add eax, SIZEOF(UpdateHeaderStruc) ; EAX - Abs addr of uCode data.
+;- xor edx, edx ; EDX:EAX - Abs addr of uCode data.
+;- wrmsr ; Trigger uCode load.
+;-
+;-luExit:
+;-ENDIF
+;-
+;- RET_EBP
+;<(AMI_CHG+)
+VeryEarlyMicrocodeUpdate ENDP
+; STATUS_CODE (09h)
+;************************************************************
+; Description:
+;
+; This function initializes the Cache for Data, Stack, and Code
+; as specified in the BIOS Writer's Guide.
+;************************************************************
+InitializeNEM PROC NEAR PRIVATE
+IFDEF ANC_SUPPORT_FLAG
+ ;
+ ; Detect AnC Boot
+ ;
+ mov ecx, MSR_ANC_SACM_INFO ;
+ rdmsr
+ and eax, 01h
+ jnz AncNemSetup
+ENDIF
+
+ ;
+ ; Enable cache for use as stack and for caching code
+ ; The algorithm is specified in the processor BIOS writer's guide
+ ;
+
+ ;
+ ; Ensure that the system is in flat 32 bit protected mode.
+ ;
+ ; Platform Specific - configured earlier
+ ;
+ ; Ensure that only one logical processor in the system is the BSP.
+ ; (Required step for clustered systems).
+ ;
+ ; Platform Specific - configured earlier
+
+ ; Ensure all APs are in the Wait for SIPI state.
+ ; This includes all other logical processors in the same physical processor
+ ; as the BSP and all logical processors in other physical processors.
+ ; If any APs are awake, the BIOS must put them back into the Wait for
+ ; SIPI state by issuing a broadcast INIT IPI to all excluding self.
+ ;
+ mov edi, APIC_ICR_LO ; 0FEE00300h - Send INIT IPI to all excluding self
+ mov eax, ORAllButSelf + ORSelfINIT ; 0000C4500h
+ mov [edi], eax
+
+@@:
+ mov eax, [edi]
+ bt eax, 12 ; Check if send is in progress
+ jc @B ; Loop until idle
+
+ ;
+ ; Load microcode update into BSP.
+ ;
+ ; Ensure that all variable-range MTRR valid flags are clear and
+ ; IA32_MTRR_DEF_TYPE MSR E flag is clear. Note: This is the default state
+ ; after hardware reset.
+ ;
+ ; Platform Specific - MTRR are usually in default state.
+ ;
+
+ ;
+ ; Initialize all fixed-range and variable-range MTRR register fields to 0.
+ ;
+ mov ecx, IA32_MTRR_CAP ; get variable MTRR support
+ rdmsr
+ movzx ebx, al ; EBX = number of variable MTRR pairs
+ shl ebx, 2 ; *4 for Base/Mask pair and WORD size
+ add ebx, MtrrCountFixed * 2 ; EBX = size of Fixed and Variable MTRRs
+
+ xor eax, eax ; Clear the low dword to write
+ xor edx, edx ; Clear the high dword to write
+ ;;;mov ebx, MtrrCount * 2 ; ebx <- sizeof MtrrInitTable
+InitMtrrLoop:
+ add ebx, -2
+ movzx ecx, WORD PTR cs:MtrrInitTable[ebx] ; ecx <- address of mtrr to zero
+ wrmsr
+ jnz InitMtrrLoop ; loop through the whole table
+
+ ;
+ ; Configure the default memory type to un-cacheable (UC) in the
+ ; IA32_MTRR_DEF_TYPE MSR.
+ ;
+ mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index
+ rdmsr
+ and eax, NOT (00000CFFh) ; Clear the enable bits and def type UC.
+ wrmsr
+
+ ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+ ; based on the physical address size supported for this processor
+ ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
+ ;
+ ; Examples:
+ ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
+ ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
+ ;
+ mov eax, 80000008h ; Address sizes leaf
+ cpuid
+ sub al, 32
+ movzx eax, al
+ xor esi, esi
+ bts esi, eax
+ dec esi ; esi <- MTRR_PHYS_MASK_HIGH
+
+ ;
+ ; Configure the DataStack region as write-back (WB) cacheable memory type
+ ; using the variable range MTRRs.
+ ;
+
+ ;
+ ; Set the base address of the DataStack cache range
+ ;
+; mov eax, PcdGet32 (PcdTemporaryRamBase)
+ mov eax, TEMPORARY_RAM_BASE_ADDRESS
+ or eax, MTRR_MEMORY_TYPE_WB
+ ; Load the write-back cache value
+ xor edx, edx ; clear upper dword
+ mov ecx, MTRR_PHYS_BASE_0 ; Load the MTRR index
+ wrmsr ; the value in MTRR_PHYS_BASE_0
+
+ ;
+ ; Set the mask for the DataStack cache range
+ ; Compute MTRR mask value: Mask = NOT (Size - 1)
+ ;
+; mov eax, PcdGet32 (PcdTemporaryRamSize)
+ mov eax, TEMPORARY_RAM_SIZE
+ dec eax
+ not eax
+ or eax, MTRR_PHYS_MASK_VALID
+ ; turn on the Valid flag
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+ mov ecx, MTRR_PHYS_MASK_0 ; For proper addressing above 4GB
+ wrmsr ; the value in MTRR_PHYS_BASE_0
+
+ ;
+ ; Configure the BIOS code region as write-protected (WP) cacheable
+ ; memory type using a single variable range MTRR.
+ ;
+ ; Platform Specific - ensure region to cache meets MTRR requirements for
+ ; size and alignment.
+ ;
+
+ ;
+ ; Set the base address of the CodeRegion cache range part 1
+ ;
+ mov eax, CODE_REGION_BASE_ADDRESS_PART1 OR MTRR_MEMORY_TYPE_WP
+ ; Load the write-protected cache value
+ xor edx, edx ; clear upper dword
+ mov ecx, MTRR_PHYS_BASE_1 ; Load the MTRR index
+ wrmsr ; the value in MTRR_PHYS_BASE_1
+
+ ;
+ ; Set the mask for the CodeRegion cache range part 1
+ ;
+ mov eax, CODE_REGION_SIZE_MASK_PART1 OR MTRR_PHYS_MASK_VALID
+ ; turn on the Valid flag
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+ mov ecx, MTRR_PHYS_MASK_1 ; Load the MTRR index
+ wrmsr ; the value in MTRR_PHYS_BASE_1
+
+;(AMI_CHG)>
+IF MKF_CODE_CACHE_PART2_BASE
+ ;
+ ; Set the base address of the CodeRegion cache range part 2
+ ;
+ mov eax, CODE_REGION_BASE_ADDRESS_PART2 OR MTRR_MEMORY_TYPE_WP
+ ; Load the write-protected cache value
+ xor edx, edx ; clear upper dword
+;- mov ecx, MTRR_PHYS_BASE_2 ; Load the MTRR index
+ inc ecx
+ wrmsr ; the value in MTRR_PHYS_BASE_2
+
+ ;
+ ; Set the mask for the CodeRegion cache range part 2
+ ;
+ mov eax, CODE_REGION_SIZE_MASK_PART2 OR MTRR_PHYS_MASK_VALID
+ ; turn on the Valid flag
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+;- mov ecx, MTRR_PHYS_MASK_2 ; Load the MTRR index
+ inc ecx
+ wrmsr ; the value in MTRR_PHYS_BASE_1
+ENDIF
+
+IF MKF_WDB_REGION_BASE_ADDRESS
+ ;
+ ; Set the base address of the WDB range
+ ;
+ mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC
+ ; Load the write-combined cache value
+ xor edx, edx ; clear upper dword
+;- mov ecx, MTRR_PHYS_BASE_3 ; Load the MTRR index
+ inc ecx
+ wrmsr ; the value in MTRR_PHYS_BASE_2
+
+ ;
+ ; Set the mask for the WDB range
+ ;
+ mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID
+ ; turn on the Valid flag
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+;- mov ecx, MTRR_PHYS_MASK_3 ; Load the MTRR index
+ inc ecx
+ wrmsr ; the value in MTRR_PHYS_BASE_1
+ENDIF
+;<(AMI_CHG)
+
+ ;
+ ; Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag.
+ ;
+ mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index
+ rdmsr
+ or eax, MTRR_DEF_TYPE_E ; Enable variable range MTRRs
+ wrmsr
+
+ ;
+ ; Enable the logical processor's (BSP) cache: execute INVD and set
+ ; CR0.CD = 0, CR0.NW = 0.
+ ;
+ mov eax, cr0
+ and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE)
+ invd
+ mov cr0, eax
+ ;
+ ; Enable No-Eviction Mode Setup State by setting
+ ; NO_EVICT_MODE MSR 2E0h bit [0] = '1'.
+ ;
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ or eax, 1
+ wrmsr
+
+ ;
+ ; One location in each 64-byte cache line of the DataStack region
+ ; must be written to set all cache values to the modified state.
+ ;
+; mov edi, PcdGet32 (PcdTemporaryRamBase)
+; mov ecx, PcdGet32 (PcdTemporaryRamSize)
+ mov edi, TEMPORARY_RAM_BASE_ADDRESS
+ mov ecx, TEMPORARY_RAM_SIZE
+ shr ecx, 6
+ mov eax, CACHE_INIT_VALUE
+@@:
+ mov [edi], eax
+ sfence
+ add edi, 64
+ loopd @b
+
+ ;
+ ; Enable No-Eviction Mode Run State by setting
+ ; NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
+ ;
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ or eax, 2
+ wrmsr
+
+IFDEF ANC_SUPPORT_FLAG
+ jmp FinishedCacheConfig
+
+ ;
+ ; Jump to here when AnC boot and NEM is initialized by AnC ACM
+ ;
+AncNemSetup:
+ ;
+ ; Finished with cache configuration
+ ;
+ ; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+ ; based on the physical address size supported for this processor
+ ; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
+ ;
+ ; Examples:
+ ; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
+ ; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
+ ;
+ mov eax, 80000008h ; Address sizes leaf
+ cpuid
+ sub al, 32
+ movzx eax, al
+ xor esi, esi
+ bts esi, eax
+ dec esi ; esi <- MTRR_PHYS_MASK_HIGH
+
+ ;
+ ; Configure the DataStack region as write-back (WB) cacheable memory type
+ ; using the variable range MTRRs.
+ ;
+ ;
+ ; Find available MTRR
+ ;
+ CALL_EBP FindFreeMtrr
+
+ ;
+ ; Set the base address of the DataStack cache range
+ ;
+; mov eax, PcdGet32 (PcdTemporaryRamBase)
+ mov eax, TEMPORARY_RAM_BASE_ADDRESS
+ or eax, MTRR_MEMORY_TYPE_WB
+ ; Load the write-back cache value
+ xor edx, edx ; clear upper dword
+ wrmsr ; the value in MTRR_PHYS_BASE_0
+
+ ;
+ ; Set the mask for the DataStack cache range
+ ; Compute MTRR mask value: Mask = NOT (Size - 1)
+ ;
+; mov eax, PcdGet32 (PcdTemporaryRamSize)
+ mov eax, TEMPORARY_RAM_SIZE
+ dec eax
+ not eax
+ or eax, MTRR_PHYS_MASK_VALID
+ ; turn on the Valid flag
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+ inc ecx
+ wrmsr ; the value in MTRR_PHYS_BASE_0
+
+ ;
+ ; Program the variable MTRR's MASK register for WDB
+ ; (Write Data Buffer, used in MRC, must be WC type)
+ ;
+
+ ;
+ ; Find available MTRR
+ ;
+ CALL_EBP FindFreeMtrr
+
+FoundAvailableMtrr:
+ ;
+ ; Program the variable MTRR's BASE register for WDB
+ ;
+ xor edx, edx
+ mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC
+ wrmsr
+
+ inc ecx
+ mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
+ mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag
+ wrmsr
+
+ ;
+ ; One location in each 64-byte cache line of the DataStack region
+ ; must be written to set all cache values to the modified state.
+ ;
+; mov edi, PcdGet32 (PcdTemporaryRamBase)
+; mov ecx, PcdGet32 (PcdTemporaryRamSize)
+ mov edi, TEMPORARY_RAM_BASE_ADDRESS
+ mov ecx, TEMPORARY_RAM_SIZE
+ shr ecx, 6
+ mov eax, CACHE_INIT_VALUE
+@@:
+ mov [edi], eax
+ sfence
+ add edi, 64
+ loopd @b
+ENDIF
+
+ ;
+ ; Finished with cache configuration
+ ;
+FinishedCacheConfig:
+
+ ;
+ ; Optionally Test the Region...
+ ;
+
+ ;
+ ; Test area by writing and reading
+ ;
+ cld
+; mov edi, PcdGet32 (PcdTemporaryRamBase)
+; mov ecx, PcdGet32 (PcdTemporaryRamSize)
+ mov edi, TEMPORARY_RAM_BASE_ADDRESS
+ mov ecx, TEMPORARY_RAM_SIZE
+ shr ecx, 2
+ mov eax, CACHE_TEST_VALUE
+TestDataStackArea:
+ stosd
+ cmp eax, DWORD PTR [edi-4]
+ jnz DataStackTestFail
+ loop TestDataStackArea
+ jmp DataStackTestPass
+
+ ;
+ ; Cache test failed
+ ;
+DataStackTestFail:
+ STATUS_CODE (0D0h)
+ jmp $
+
+ ;
+ ; Configuration test failed
+ ;
+ConfigurationTestFailed:
+ STATUS_CODE (0D1h)
+ jmp $
+
+DataStackTestPass:
+
+ ;
+ ; At this point you may continue normal execution. Typically this would include
+ ; reserving stack, initializing the stack pointer, etc.
+ ;
+
+ ;
+ ; After memory initialization is complete, please follow the algorithm in the BIOS
+ ; Writer's Guide to properly transition to a normal system configuration.
+ ; The algorithm covers the required sequence to properly exit this mode.
+ ;
+
+ RET_ESI
+
+InitializeNEM ENDP
+
+; STATUS_CODE (09h)
+;-EstablishStack PROC NEAR PRIVATE
+;-
+;- ;
+;- ; Enable STACK
+;- ;
+;- RET_ESI
+;-
+;-EstablishStack ENDP
+;-
+;-FindFreeMtrr PROC NEAR PRIVATE
+;- mov ecx, MTRR_PHYS_MASK_0
+;-
+;-@@:
+;- rdmsr
+;- test eax, 800h
+;- jz FoundFreeMtrr
+;- add ecx, 2
+;- cmp ecx, MTRR_PHYS_MASK_9
+;- jbe @b
+;- ;
+;- ; No available MTRR, halt system
+;- ;
+;- jmp $
+;-
+;-FoundFreeMtrr:
+;- dec ecx
+;-
+;- RET_EBP
+;-
+;-FindFreeMtrr ENDP
+;-
+;-; STATUS_CODE (0Bh)
+;-CallPeiCoreEntryPoint PROC NEAR PRIVATE
+;- ;
+;- ; Set stack top pointer
+;- ;
+;-; mov esp, PcdGet32 (PcdTemporaryRamBase)
+;-; add esp, PcdGet32 (PcdTemporaryRamSize)
+;- mov esp, TEMPORARY_RAM_BASE_ADDRESS
+;- add esp, TEMPORARY_RAM_SIZE
+;-
+;- ;
+;- ; Push CPU count to stack first, then AP's (if there is one)
+;- ; BIST status, and then BSP's
+;- ;
+;-
+;- ;
+;- ; Here work around for BIST
+;- ;
+;- ; Get number of BSPs
+;- movd ecx, mm1
+;- movzx ecx, ch
+;-
+;- ; Save number of BSPs
+;- push ecx
+;-
+;-GetSBSPBist:
+;- ; Save SBSP BIST
+;- movd eax, mm0
+;- push eax
+;-
+;- ; Save SBSP APIC ID
+;- movd eax, mm1
+;- shr eax, BSPApicIDSaveStart ; Resume APIC ID
+;- push eax
+;-
+;- ; Save Time-Stamp Counter
+;- movd eax, mm5
+;- push eax
+;-
+;- movd eax, mm6
+;- push eax
+;-
+;-TransferToSecStartup:
+;-
+;-
+;-
+;- ; Switch to "C" code
+;- STATUS_CODE (0Ch)
+;- ;
+;- ; Pass entry point of the PEI core
+;- ;
+;- mov edi, PEI_CORE_ENTRY_BASE ; 0FFFFFFE0h
+;- push DWORD PTR ds:[edi]
+;-
+;- ;
+;- ; Pass BFV into the PEI Core
+;- ;
+;- mov edi, FV_MAIN_BASE ; 0FFFFFFFCh
+;- push DWORD PTR ds:[edi]
+;-
+;- ; ECPoverride: SecStartup entry point needs 4 parameters
+;-; push PcdGet32 (PcdTemporaryRamBase)
+;- push TEMPORARY_RAM_BASE_ADDRESS
+;-
+;- ;
+;- ; Pass stack size into the PEI Core
+;- ;
+;-; push PcdGet32 (PcdTemporaryRamSize)
+;- push TEMPORARY_RAM_SIZE
+;-
+;- ;
+;- ; Pass Control into the PEI Core
+;- ;
+;- call SecStartup
+;-CallPeiCoreEntryPoint ENDP
+;-
+;-StartUpAp PROC NEAR
+;-
+;- mov esi, HPET_COMP_2
+;- lock inc byte ptr [esi]
+;-
+;- DISABLE_CACHE
+;-;
+;-; Halt the AP and wait for the next SIPI
+;-;
+;-Ap_Halt:
+;- cli
+;-@@:
+;- hlt
+;- jmp @B
+;- ret
+;-StartUpAp ENDP
+;-
+;-
+;-CheckValidCMOS PROC NEAR PRIVATE
+;- ;
+;- ; Check CMOS Status
+;- ;
+;- mov esi, PCH_LPC_GEN_PMCON_3_ADDR
+;- mov eax, es:[esi]
+;-
+;- ; check PWR_FLR and RTC_PWR_STS status
+;- and eax, BIT2 + BIT1
+;-
+;- RET_EBP
+;-CheckValidCMOS ENDP
+
+MtrrInitTable LABEL BYTE
+ DW MTRR_DEF_TYPE
+ DW MTRR_FIX_64K_00000
+ DW MTRR_FIX_16K_80000
+ DW MTRR_FIX_16K_A0000
+ DW MTRR_FIX_4K_C0000
+ DW MTRR_FIX_4K_C8000
+ DW MTRR_FIX_4K_D0000
+ DW MTRR_FIX_4K_D8000
+ DW MTRR_FIX_4K_E0000
+ DW MTRR_FIX_4K_E8000
+ DW MTRR_FIX_4K_F0000
+ DW MTRR_FIX_4K_F8000
+
+MtrrCountFixed EQU (($ - MtrrInitTable) / 2)
+
+ DW MTRR_PHYS_BASE_0
+ DW MTRR_PHYS_MASK_0
+ DW MTRR_PHYS_BASE_1
+ DW MTRR_PHYS_MASK_1
+ DW MTRR_PHYS_BASE_2
+ DW MTRR_PHYS_MASK_2
+ DW MTRR_PHYS_BASE_3
+ DW MTRR_PHYS_MASK_3
+ DW MTRR_PHYS_BASE_4
+ DW MTRR_PHYS_MASK_4
+ DW MTRR_PHYS_BASE_5
+ DW MTRR_PHYS_MASK_5
+ DW MTRR_PHYS_BASE_6
+ DW MTRR_PHYS_MASK_6
+ DW MTRR_PHYS_BASE_7
+ DW MTRR_PHYS_MASK_7
+ DW MTRR_PHYS_BASE_8
+ DW MTRR_PHYS_MASK_8
+ DW MTRR_PHYS_BASE_9
+ DW MTRR_PHYS_MASK_9
+MtrrCount EQU (($ - MtrrInitTable) / 2)