summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32')
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16305
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf35
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf35
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm1387
-rw-r--r--ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new69
5 files changed, 1831 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16 b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16
new file mode 100644
index 0000000..9855257
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.asm16
@@ -0,0 +1,305 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 Intel Corporation. All rights reserved
+; 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:
+;
+; TxtPeiAp.asm
+;
+; Abstract:
+;
+; This file contains AP initialization code in PEI phase
+;
+;--*/
+
+ .XLIST
+ include txt.inc
+ .LIST
+
+ .586p
+ .MMX
+
+TxtSegment16 SEGMENT PARA USE16 PUBLIC 'TXTCODE'
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure:
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Entry point of AP startup code. Target of SIPI vector.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+;
+; This point is 4K aligned somewhere in boot block.
+;
+ jmp code16bitStart
+
+ ORG 10h
+
+GDTAddress:
+ dw GDTLen ; The length of the GDT
+ dd OFFSET GDTStart ; The 32-bit physical address
+
+;
+; AP GDT table
+;
+ ALIGN 16
+GDTStart LABEL BYTE
+
+ SEG_DESCRIPTOR <> ; Unused (selector 0)
+
+;
+; Selector 8
+;
+TXT_DATA32 EQU $ - GDTStart
+
+TXT_DATA32_OFF SEG_DESCRIPTOR {0FFFFh,\
+ 0000h, \
+ 00h, \
+ <SEG_PRESENT, 0, APPLSEGMENT, DATATYPE>, \
+ <PAGEGRANULARITY, BIGSEGMENT,,,0Fh>, \
+ 00h}
+
+GDTLen EQU $ - GDTStart - 1
+
+
+code16bitStart:
+
+;L1: jmp $
+ cli
+
+ mov si, OFFSET GDTAddress
+ ;
+ ; Set DS and ES limits
+ ;
+ db 66h ; Force 32 bit load
+ lgdt FWORD PTR cs:[si]
+
+ mov eax, CR0 ; get CPU control word 0
+ or al, 01 ; enable CPU protected mode
+ mov CR0, eax ; write back to CPU control word 0
+ jmp target
+
+target:
+
+ mov ax, TXT_DATA32
+ mov ds, ax ; set DS limit
+ mov es, ax ; set ES limit
+ mov fs, ax ; set FS limit
+ mov gs, ax ; set GS limit
+ mov ss, ax ; set SS limit
+
+ ;
+ ; Disable protected mode
+ ;
+ mov eax, CR0 ; get CPU control word 0
+ and al, 0FEh ; disable CPU protected mode
+ mov CR0, eax ; write back to CPU control word 0
+ jmp target3
+
+target3:
+ xor ax, ax
+ mov ds, ax ; set flat DS
+ mov es, ax ; set flat ES
+
+ ;
+ ; Fall through to main code
+ ;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+;
+; Procedure: LoadVsmcuRetNS - Variable Size Processor Microcode Update (Stackless)
+;
+; Input: SP = Return address
+;
+; Output: None
+;
+; Registers: All but SP are modified
+;
+; Description:
+; Load MCU into processor.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LoadVsmcuRetNS PROC NEAR PUBLIC
+ ;
+ ; Check uCode was loaded or not
+ ;
+ xor eax, eax
+ xor edx, edx
+ mov ecx, MCU_REV_MSR
+ wrmsr
+ mov eax, 1
+ cpuid
+ mov ecx, MCU_REV_MSR
+ rdmsr
+ or edx, edx
+ jnz uCode_loaded
+
+ ;
+ ; Restore MCU address from scratch register
+ ;
+ mov eax, 1
+ cpuid
+
+ mov eax, TXT_PUBLIC_BASE + MCU_BASE_ADDR
+ mov eax, [eax]
+
+ lea eax, [eax + SIZEOF MCU] ; EAX -> MCU data (after header)
+ xor edx, edx
+ mov ecx, MCU_LOAD_MSR ; Trigger to load MCU
+
+ wrmsr ; Load MCU
+
+ mov eax, 1
+ cpuid
+uCode_loaded:
+ ;
+ ; Fall through
+ ;
+LoadVsmcuRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtPrepareCacheForAcModuleRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Cache initialization per TXT BIOS spec
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+TxtPrepareCacheForAcModuleRetNS PROC NEAR PUBLIC
+
+ ;
+ ; Ensure CR0.CD and CR0.NW are cleared
+ ;
+ mov eax, cr0 ;
+ and eax, NOT (CR0_CD_MASK + CR0_NW_MASK)
+ mov cr0, eax
+ ;
+ ; Fall through
+ ;
+TxtPrepareCacheForAcModuleRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtCleanMcaNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: MCA registers are cleaned
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+TxtCleanMcaNS PROC NEAR PUBLIC
+ ;
+ ; Clean MC[i]_STATUS MSR registers
+ ; SCLEAN will generate GPF otherwise
+ ;
+ mov ecx, MCG_CAP
+ rdmsr
+ movzx ebx, al ; Bank count to ebx
+ sub eax, eax ; Write 0 into all MCi_STATUS registers
+ sub edx, edx
+ mov ecx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec ebx
+ jz continue
+ add ecx, 4 ; Number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+continue:
+ ;
+ ; Fall through
+ ;
+TxtCleanMcaNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: TxtHaltLoopNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: APs enter halt loop
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+TxtHaltLoopNS PROC NEAR PUBLIC
+
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ mov eax, 1
+ cpuid
+ shr ebx, 24 ; ebx is initial APIC ID shifted rightmostly
+
+ ;
+ ; Since accesses to semaphore cannot be serialized, accesses among different CPUs
+ ; are orchestrated as following:
+ ; BSP will only READ semaphore
+ ; All APs will keep READING semaphore until its value EQUALS to that AP's
+ ; APIC ID minus 1. Only AFTER that AP will INCREMENT semaphore.
+ ; This allows BSP to judge WHEN all APs finished.
+ ;
+ mov ecx, [TXT_PUBLIC_BASE + SEMAPHORE]
+
+keepWaiting:
+ mov eax, [ecx]
+ inc eax
+ cmp eax, ebx
+ jb keepWaiting
+ ja hltLoop
+ mov [ecx], eax
+
+hltLoop:
+ cli
+ hlt
+ jmp hltLoop
+
+TxtHaltLoopNS ENDP
+
+TxtSegment16 ENDS
+
+END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf
new file mode 100644
index 0000000..a6e8185
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiAp.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for TXTPEIAP module
+#
+#@copyright
+# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+# 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.
+#
+# 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
+#
+
+[defines]
+BASE_NAME = TxtPeiAp
+FILE_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+COMPONENT_TYPE = USER_DEFINED
+
+[sources.common]
+
+[sources.ia32]
+ TxtPeiAp.asm16
+
+[includes.common]
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+
+[libraries.common]
+
+[nmake.common]
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf
new file mode 100644
index 0000000..e649127
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiApV7.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for TXTPEIAP module
+#
+#@copyright
+# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+# 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.
+#
+# 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
+#
+
+[defines]
+BASE_NAME = TxtPeiAp
+FILE_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+COMPONENT_TYPE = FILE
+BUILD_TYPE = MAKEFILE
+
+[sources.common]
+
+[sources.ia32]
+ TxtPeiAp.asm16
+
+[includes.common]
+
+[libraries.common]
+
+[nmake.common]
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm
new file mode 100644
index 0000000..066aedc
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/TxtPeiBsp.asm
@@ -0,0 +1,1387 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and uniquely
+; identified as "Intel Reference Module" and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;
+;/*++
+;
+; Copyright (c) 1999 - 2011 Intel Corporation. All rights reserved
+; 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:
+;
+; TxtPeiBsp.asm
+;
+; Abstract:
+;
+; This file contains the code to launch BIOS ACM functions in PEI phase
+;
+;--*/
+
+ .XLIST
+ include txt.inc
+ .LIST
+
+ .686P
+ .MMX
+ .XMM
+ .MODEL FLAT,C
+ .CODE
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: LaunchBiosAcmSclean
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc) and
+; invoke GETSEC:ENTERACCS with requested BIOS ACM entry point.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LaunchBiosAcmSclean PROC PUBLIC
+ ;
+ ; Tell where we are
+ ;
+ mov eax, 11110000h
+ in ax, 80h
+ mov ah, PORT80_CODE_PREFIX + TXT_LAUNCH_SCLEAN
+ out 80h, eax
+
+ ;
+ ; Enable SMXE, SSE and debug extensions always.
+ ;
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ ;
+ ; Prepare cache of BSP
+ ;
+ mov esi, TXT_PUBLIC_BASE + BIOACM_ADDR
+ mov edi, 0
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+ifdef MKF_TXT_RLP_INIT
+ if MKF_TXT_RLP_INIT
+ CALL_NS InitializeApsRetNS
+ endif
+endif
+
+
+ ;
+ ; Call GETSEC[ENTERACCS]
+ ;
+ cli
+ mov eax, ENTERACCS ; eax = ENTERACCS
+ mov ebx, TXT_PUBLIC_BASE + BIOACM_ADDR
+ mov ebx, [ebx]
+ mov ecx, [ebx].ACM_HEADER.AcmSize
+ shl ecx, 2
+ xor edx, edx
+ xor edi, edi
+ mov esi, 0
+
+ _GETSEC
+
+ jmp DoPowerCycleReset
+LaunchBiosAcmSclean ENDP
+
+DoGlobalReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ or eax, (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 6 ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoGlobalReset ENDP
+
+DoPowerCycleReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0Eh ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoPowerCycleReset ENDP
+
+DoHostReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - set bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 0 ; system must be reset.
+ out dx, al
+ mov dx, 0CF9h ; After return from SCLEAN function
+ mov al, 6 ; system must be reset.
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoHostReset ENDP
+
+DoCpuReset PROC PUBLIC
+ mov dx, 0CF8h ; Make warm system reset through port 0CF9h
+ mov eax, 8000F8ACh ; to be global system reset - clear bit 20
+ out dx, eax ; of device 1F
+ mov dx, 0CFCh
+ in eax, dx
+ and eax, NOT (1 SHL 20)
+ out dx, eax
+
+ mov dx, 0CF9h ; Issue a CPU only reset by CF9h
+ mov al, 0 ; toggle bit2 from 0 to 1
+ out dx, al
+ mov dx, 0CF9h ; Issue a CPU only reset by CF9h
+ mov al, 4 ;
+ out dx, al
+ cli
+ hlt
+ jmp $
+
+DoCpuReset ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: PrepareCacheForAcModuleRetNS
+;
+; Input: esi - bios acm address
+; edi - in memory flag
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: MTRRs are set per BIOS spec
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+PrepareCacheForAcModuleRetNS PROC FAR PUBLIC
+ ;
+ ; Enable local APIC
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov DWORD PTR [eax+SPURIOUS_VECTOR_1], 1FFh ; Enable APIC, keep spurious vector
+ ;
+ ; Disable cache
+ ;
+ mov eax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or eax, CR0_CD_MASK OR CR0_NE_MASK
+ and eax, NOT CR0_NW_MASK
+ mov cr0, eax
+ cmp edi, 0
+ je @F ; JIf stackless environment
+ wbinvd ; Invalidate the cache
+ jmp disableMtrrs
+
+@@:
+ invd
+
+disableMtrrs:
+ ;
+ ; Disable all MTRRs
+ ;
+ xor eax, eax
+ xor edx, edx
+ mov ecx, IA32_MTRR_DEF_TYPE
+ wrmsr
+
+ ;
+ ; Disable NEM
+ ;
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ and eax, NOT (BIT1)
+ wrmsr ; Clear No-Eviction Mode Run bit
+ mov ecx, NO_EVICT_MODE
+ rdmsr
+ and eax, NOT (BIT0)
+ wrmsr ; Clear No-Eviction Mode SETUP bit
+
+ invd
+
+ ;
+ ; Clear all variable MTRRs
+ ;
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+ xor eax, eax
+ xor edx, edx
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ wrmsr
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ ;
+ ; Determine size of AC module
+ ;
+ mov esi, [esi]
+ mov eax, [esi].ACM_HEADER.AcmSize
+ shl eax, 2 ; ...in bytes (ACM header has size in dwords)
+ ;
+ ; Round up to page size
+ ;
+ mov ecx, eax ; Save
+ and ecx, 0FFFFF000h ; Number of pages in AC module
+ and eax, 0FFFh ; Number of "less-than-page" bytes
+ jz rounded
+ mov eax, 1000h ; Add the whole page size
+
+rounded:
+ add eax, ecx ; eax - rounded up AC module size
+
+ ;
+ ; Define "local" vars for this routine
+ ;
+ ACM_SIZE_TO_CACHE TEXTEQU <mm0>
+ ACM_BASE_TO_CACHE TEXTEQU <mm1>
+ NEXT_MTRR_INDEX TEXTEQU <mm2>
+ NEXT_MTRR_SIZE TEXTEQU <mm3>
+ ;
+ ; Initialize "locals"
+ ;
+ sub ecx, ecx
+ movd NEXT_MTRR_INDEX, ecx ; Start from MTRR0
+
+ ;
+ ; Save remaining size to cache
+ ;
+ movd ACM_SIZE_TO_CACHE, eax ; Size of ACM that must be cached
+ movd ACM_BASE_TO_CACHE, esi ; Base ACM address
+
+nextMtrr:
+ ;
+ ; Get remaining size to cache
+ ;
+ movd eax, ACM_SIZE_TO_CACHE
+ and eax, eax
+ jz done ; If no left size - we are done
+ ;
+ ; Determine next size to cache.
+ ; We start from bottom up. Use the following algorythm:
+ ; 1. Get our own alignment. Max size we can cache equals to our alignment
+ ; 2. Determine what is bigger - alignment or remaining size to cache.
+ ; If aligment is bigger - cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; If remaining size to cache is bigger
+ ; Determine the biggest 2^N part of it and cache it.
+ ; Adjust remaing size to cache and base address
+ ; Loop to 1.
+ ; 3. End when there is no left size to cache or no left MTRRs
+ ;
+ movd esi, ACM_BASE_TO_CACHE
+ bsf ecx, esi ; Get index of lowest bit set in base address
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov edx, 1h
+ shl edx, cl ; Alignment is in edx
+ cmp edx, eax ; What is bigger, alignment or remaining size?
+ jbe gotSize ; JIf aligment is less
+ ;
+ ; Remaining size is bigger. Get the biggest part of it, 2^N in size
+ ;
+ bsr ecx, eax ; Get index of highest set bit
+ ;
+ ; Convert index into size to be cached by next MTRR
+ ;
+ mov edx, 1
+ shl edx, cl ; Size to cache
+
+gotSize:
+ mov eax, edx
+ movd NEXT_MTRR_SIZE, eax ; Save
+
+ ;
+ ; Compute MTRR mask value: Mask = NOT (Size - 1)
+ ;
+ dec eax ; eax - size to cache less one byte
+ not eax ; eax contains low 32 bits of mask
+ or eax, MTRR_VALID ; Set valid bit
+
+ ;
+ ; Program mask register
+ ;
+ mov ecx, IA32_MTRR_PHYSMASK0 ; setup variable mtrr
+ movd ebx, NEXT_MTRR_INDEX
+ add ecx, ebx
+
+ mov edx, 0Fh ; 8K range (FFFFFFE800)
+ wrmsr
+ ;
+ ; Program base register
+ ;
+ sub edx, edx
+ mov ecx, IA32_MTRR_PHYSBASE0 ; setup variable mtrr
+ add ecx, ebx ; ebx is still NEXT_MTRR_INDEX
+
+ movd eax, ACM_BASE_TO_CACHE
+ or eax, WB ; set type to write back
+ wrmsr
+ ;
+ ; Advance and loop
+ ; Reduce remaining size to cache
+ ;
+ movd ebx, ACM_SIZE_TO_CACHE
+ movd eax, NEXT_MTRR_SIZE
+ sub ebx, eax
+ movd ACM_SIZE_TO_CACHE, ebx
+
+ ;
+ ; Increment MTRR index
+ ;
+ movd ebx, NEXT_MTRR_INDEX
+ add ebx, 2
+ movd NEXT_MTRR_INDEX, ebx
+ ;
+ ; Increment base address to cache
+ ;
+ movd ebx, ACM_BASE_TO_CACHE
+ movd eax, NEXT_MTRR_SIZE
+ add ebx, eax
+ movd ACM_BASE_TO_CACHE, ebx
+
+ jmp nextMtrr
+
+done:
+ ;
+ ; Enable variable MTRRs
+ ;
+ xor edx, edx
+ mov eax, MTRR_ENABLE; enable mtrrs (but not fixed ones)
+ mov ecx, IA32_MTRR_DEF_TYPE
+ wrmsr
+ ;
+ ; Enable cache
+ ;
+ mov eax, cr0 ; Enable caching - WB (NW stays clear)
+ and eax, NOT CR0_CD_MASK
+ mov cr0, eax
+
+ RET_NS
+PrepareCacheForAcModuleRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: CleanMcaRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc)
+; invoke GETSEC:ENTERACCS with requested module
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+CleanMcaRetNS PROC NEAR PUBLIC
+
+ ;
+ ; Clean all MCi_STATUS MSR registers
+ ; SCLEAN will generate GPF otherwise
+ ;
+ mov ecx, MCG_CAP
+ rdmsr
+ movzx ebx, al ; Bank count to ebx
+ sub eax, eax ; Write 0 into all MCi_STATUS registers
+ sub edx, edx
+ mov ecx, MC0_STATUS
+
+McaErrorCleanLoopStart:
+ wrmsr
+ dec ebx
+ jz exit
+ add ecx, 4 ; Number of MSRs per bank
+ jmp McaErrorCleanLoopStart
+
+exit:
+ RET_NS
+CleanMcaRetNS ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: InitializeApsRetNS
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description:
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+InitializeApsRetNS PROC NEAR
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Init Timer 1
+ ;
+ mov al, 54h
+ out 43h, al
+ mov al, 12h
+ out 41h, al
+
+ ;
+ ; More than one thread
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+
+ mov esi, TXT_PUBLIC_BASE ; esi points to public space
+
+ ;
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+
+ ;
+ ; Broadcast INIT message to put all APs into Wait for SIPI state
+ ; C0500 -> Destination = All excl self, Delivery = INIT
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+ ;
+ ; Create vector used in the following SIPI message
+ ; Below address is the real mode address of AP code in Boot Block
+ ; LTCACHE.BIN containg AP thread code must be placed at the above address
+ ; in Boot block (FFFF0000h). See file LTCACHE.ASM
+ ;
+
+ mov ebx, [esi+APINIT_ADDR]
+ shr ebx, 12
+ and ebx, 0FFh
+ or ebx, 0C0600h ; This is message
+
+ ;
+ ; Broadcast SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait 200us as recommended
+ ;
+ mov edx, NeverStatusRetNS
+ mov ecx, 14
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Broadcast second SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait for semaphore reflect number of CPUs
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ dec bl ; bl is number of APs
+
+ mov edx, SemaphoreStatusRetNS
+ mov ecx, 6670
+ CALL_NS ltWaitStatusRetNS ; Wait for up to 100ms
+
+ ;
+ ; Broadcast INIT message to put all APs back into Wait for SIPI state
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+
+exit:
+ RET_NS
+InitializeApsRetNS ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SaveApConfig
+;
+; Input: ApCfg - pointer to save area
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Function is called in memory present environment on S3 resume
+; path. Saves contents of all MTRRs into table plus some registers.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SaveApConfig PROC NEAR PUBLIC, ApCfg:PTR QWORD
+
+ pushad
+
+ mov esi, ApCfg
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ rdmsr
+ mov [esi], eax
+ mov [esi+4], edx
+ add esi, SIZEOF QWORD
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ mov ecx, IA32_MTRR_DEF_TYPE
+ rdmsr
+ mov [esi], eax
+ mov [esi+4], edx
+
+ sidt [esi+8]
+
+ mov ecx, IA32_MISC_ENABLE_MSR
+ rdmsr
+ mov [esi+010h], eax
+ mov [esi+014h], edx
+
+ popad
+ ret
+SaveApConfig ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: StartupAllAPs
+;
+; Input: pFunction - pointer to function to execute on AP
+; pParam - pointre to pFunction parameters
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Procedure is called in memmory present enironment on S3
+; resume path and is executed on BSP
+; It saves memory at address 1000h into buffer
+; It then copies AP start-up code into address 1000h
+; Then variables in the 1000h area are updated and APs are started
+; After APs finish execution of function passed as parameter they
+; are halted. BSP restores contents 1000h area from buffer and
+; returns.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+Func TYPEDEF PROTO
+
+PFUNC TYPEDEF PTR Func
+
+StartUp STRUCT
+ db 0FAh ; cli
+ db 066h, 0BBh ; mov ebx, OFFSET gdtLim
+ db StartUp.gdtLim, 0,0,0
+ db 066h
+ db 067h, 02Eh, 00Fh, 001h, 013h ; lgdt FWORD PTR cs:[ebx]
+ db 00Fh, 020h, 0C0h ; mov eax, CR0
+ db 00Ch, 001h ; or al, 01
+ db 00Fh, 022h, 0C0h ; mov CR0, eax
+ ;
+ ; 32 bit jump to 32 bit Function handler
+ ;
+ db 066h
+ db 0eah
+fOff dd 0
+fCs dw 0
+
+ ALIGN 16
+fDs dw 0
+gdtLim dw ? ; Size of LT GDT in bytes
+gdtBas dd ? ; Physical address of LT GDT
+fParam dd ?
+smphr dd ?
+StartUp ENDS
+
+
+StartupAllAPs PROC NEAR, pFunction:PFUNC, pParam:PTR QWORD
+ LOCAL buffer:StartUp
+ LOCAL savedESP:DWORD
+
+ pushad
+ mov savedESP, esp
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Init Timer 1
+ ;
+ mov al, 54h
+ out 43h, al
+ mov al, 12h
+ out 41h, al
+
+ ;
+ ; More than one thread. Prepare Startup area
+ ;
+ mov esi, 1000h ; Source
+ lea edi, buffer ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+
+ mov esi, offset ApHandler16 ; Source
+ mov edi, 1000h ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+ ;
+ ; Update Srartup area variables
+ ;
+ mov edi, 1000h
+ mov ds:[edi].StartUp.fCs, cs
+ mov ds:[edi].StartUp.fDs, ds
+ mov eax, pFunction
+ mov ds:[edi].StartUp.fOff, eax
+ sub eax, eax
+ mov ds:[edi].StartUp.smphr, eax
+ mov eax, pParam
+ mov ds:[edi].StartUp.fParam, eax
+ sgdt ds:[edi].StartUp.gdtLim
+
+ ;
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+
+ ;
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+
+ ;
+ ; Broadcast INIT message to put all APs into Wait for SIPI state
+ ; C0500 -> Destination = All excl self, Delivery = INIT
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+ ;
+ ; Create vector used in the following SIPI message
+ ;
+ mov ebx, 0C0600h + (1000h SHR 12)
+ ;
+ ; Broadcast SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait 200us as recommended
+ ;
+ mov edx, NeverStatusRetNS
+ mov ecx, 14
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Broadcast second SIPI message with our vector
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov ICR_LOW[edi], ebx
+ ;
+ ; Wait for semaphore reflect number of CPUs
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ dec bl ; bl is number of APs
+
+ mov edx, SemaphoreStatus2RetNS
+ mov ecx, 6670
+ CALL_NS ltWaitStatusRetNS ; Wait for up to 100ms
+ ;
+ ; Restore StartUp area
+ ;
+ lea esi, buffer ; Source
+ mov edi, 1000h ; Destination
+ mov ecx, sizeof StartUp / 4
+ CALL_NS MemCopyRetNS
+
+exit:
+ mov esp, savedESP
+ popad
+ ret
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Section: ApHandler16
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: Irrelevant
+;
+; Description: This code is copied over address 0:1000. After recieving SIPI
+; AP is directed to this address where it starts execution in real mode.
+; AP first switches to protected mode, loads the same GDT which is used
+; by BSP and jumps to Procedure at fCs:fOff
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+ ALIGN 16
+ ;
+ ; Note After coppying this code must be aligned on page boundary!
+ ;
+
+ApHandler16 StartUp <>
+
+StartupAllAPs ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: PutApsInWfs
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Procedure is called in memory present environment on S3 resume path.
+; INIT SIPI message is sent to all APs.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+PutApsInWfs PROC PUBLIC
+ LOCAL savedESP:DWORD
+ pushad
+ mov savedESP, esp
+
+ mov eax, 1
+ cpuid
+ shr ebx, 16 ; Total Logical Proc Count in BL
+ cmp bl, 1 ; If 1 thread - nothing to do
+ je exit
+
+ ;
+ ; Get APIC address
+ ;
+ mov ecx, IA32_APIC_BASE
+ rdmsr ; Get APIC Base
+ and eax, BASE_ADDR_MASK ; Just need the address
+ mov edi, eax ; edi points to APIC base
+ ;
+ ; Broadcast INIT message to put all APs back into Wait for SIPI state
+ ; Wait for APIC ready
+ ;
+ mov edx, IcrStatusRetNs
+ mov ecx, 15
+ CALL_NS ltWaitStatusRetNS
+ ;
+ ; Send message
+ ;
+ mov DWORD PTR ICR_LOW[edi], 000C0500h
+
+ mov edx, NeverStatusRetNS
+ mov ecx, 667
+ CALL_NS ltWaitStatusRetNS ; Wait full 10ms
+
+exit:
+ mov esp, savedESP
+ popad
+ ret
+PutApsInWfs ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: LaunchBiosAcmScheck
+;
+; Input: None
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Setup GETSEC environment (protected mode, mtrrs, etc) and
+; invoke GETSEC:ENTERACCS with requested BIOS ACM entry point.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+LaunchBiosAcmScheck PROC PUBLIC, BiosAcAddr:PTR QWORD
+
+ LOCAL SavedGdtr:QWORD
+ LOCAL SavedSS:dword
+ LOCAL SavedESP:dword
+ LOCAL SavedCS:dword
+ LOCAL SavedCR3:dword
+ pushf
+ cli
+ pushad
+ ;
+ ; Tell where we are
+ ;
+ in ax, 80h
+ mov ah, PORT80_CODE_PREFIX + TXT_LAUNCH_SCHECK
+ out 80h, ax
+ ;
+ ; Save control registers
+ ;
+ mov eax, cr4
+ push eax
+ mov eax, cr0
+ push eax
+ ;
+ ; Save segment registers
+ ;
+ push ds
+ push es
+ push gs
+ push fs
+ ;
+ ; Save CS
+ ;
+ sub eax, eax ; Clean upper word
+ mov ax, cs
+ mov SavedCS, eax
+ ;
+ ; Save stack at this level
+ ;
+ mov ax, ss
+ mov SavedSS, eax
+ mov SavedESP, esp
+ mov eax, cr3
+ mov SavedCR3, eax
+
+ ;
+ ; Save GDT
+ ;
+ sgdt SavedGdtr ; save value of gdtr in local variable
+ ;
+ ; Define "local" vars for this routine
+ ;
+ SAVED_EBP TEXTEQU <mm4>
+ ;
+ ; Save ebp in MMX register
+ ;
+ movd SAVED_EBP, ebp ; Size of ACM that must be cached
+
+ ;
+ ; Enable SMXE, SSE and debug extensions always.
+ ;
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+ ;
+ ; Prepare cache of BSP
+ ;
+ mov esi, BiosAcAddr
+ mov edi, 1
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+ ;
+ ; Call GETSEC[ENTERACCS]
+ ;
+ mov eax, ENTERACCS ; eax = ENTERACCS
+ mov ebx, BiosAcAddr
+ mov ebx, [ebx]
+ mov ecx, [ebx].ACM_HEADER.AcmSize
+ shl ecx, 2
+ xor edx, edx
+ mov edi, S3_RESUME_PATH
+ mov esi, 4
+
+ _GETSEC
+
+ ;
+ ; Return point after ACEXIT.
+ ;
+ movd ebp, SAVED_EBP
+ lea eax, SavedGdtr
+ lgdt FWORD PTR [eax]
+ mov eax, SavedSS
+ mov ss, ax
+ mov esp, SavedESP
+ mov eax, SavedCR3
+ mov cr3, eax
+ ;
+ ; Restore segment registers
+ ;
+ pop fs
+ pop gs
+ pop es
+ pop ds
+ ;
+ ; Restore control registers
+ ;
+ pop eax
+ ;
+ ;remain cache disabled until MTRRs restored
+ ;
+ or eax, CR0_CD_MASK
+ and eax, NOT CR0_NW_MASK
+ wbinvd
+;
+ mov cr0, eax
+ pop eax
+ mov cr4, eax
+ ;
+ ; Restore CS
+ ;
+ mov eax, SavedCS
+ push eax
+ push OFFSET ReloadCS
+ retf
+
+ReloadCS:
+ popad
+ popf
+ emms
+
+ ret
+LaunchBiosAcmScheck ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreMtrrProgramming
+;
+; Input: ApMtrrTab - pointer to save area
+;
+; Output: None
+;
+; Registers: All are preserved
+;
+; Description: Function is executed on BSP in memory present environment on S3
+; resume path. Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreMtrrProgramming PROC NEAR PUBLIC, ApMtrrTab:PTR QWORD
+ LOCAL savedESP:DWORD
+ pushad
+ mov savedESP, esp
+
+ mov esi, ApMtrrTab
+ CALL_NS RestoreMtrrProgrammingRetNS
+
+ mov esp, savedESP
+ popad
+ ret
+RestoreMtrrProgramming ENDP
+
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreMtrrProgrammingRetNS
+;
+; Input: esi - pointer to save area
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreMtrrProgrammingRetNS PROC NEAR PUBLIC
+ mov eax, cr0 ; set CR0:CD and CR0:NE, clear CR0:NW
+ or eax, CR0_CD_MASK OR CR0_NE_MASK
+ and eax, NOT CR0_NW_MASK
+ mov cr0, eax
+ wbinvd ; flush and invalidate the cache
+
+ xor edx, edx
+ mov eax, MTRR_ENABLE + MTRR_FIXED_ENABLE ; enable mtrrs
+ mov ecx, 2FFh
+ wrmsr
+
+ mov ecx, IA32_MTRR_CAP
+ rdmsr
+ and eax, 0FFh
+ shl eax, 1
+ mov ecx, eax
+
+@@:
+ add ecx, IA32_MTRR_PHYSBASE0 - 1
+ mov eax, [esi]
+ mov edx, [esi+4]
+ wrmsr
+ add esi, SIZEOF QWORD
+ sub ecx, IA32_MTRR_PHYSBASE0 - 1
+ loop @B
+
+ mov ecx, IA32_MTRR_DEF_TYPE
+ mov eax, [esi]
+ mov edx, [esi+4]
+ wrmsr
+ mov ecx, IA32_MISC_ENABLE_MSR
+ mov eax, [esi+010h]
+ mov edx, [esi+014h]
+ wrmsr
+
+ mov eax, cr0 ; Enable caching - WB (NW stays clear)
+ and eax, NOT CR0_CD_MASK
+ mov cr0, eax
+
+ RET_NS
+RestoreMtrrProgrammingRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: RestoreApConfig
+;
+; Input: esi - pointer to save area
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Function is executed on AP in memory present environment on S3
+; resume path. Restores contents of all MTRRs from table
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+RestoreApConfig PROC NEAR PUBLIC
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE
+ mov CR4, eax
+
+ mov esi, 1000h
+ mov ds, cs:[esi].StartUp.fDs
+ mov es, cs:[esi].StartUp.fDs
+ mov fs, cs:[esi].StartUp.fDs
+ mov gs, cs:[esi].StartUp.fDs
+ mov ss, cs:[esi].StartUp.fDs
+
+ mov esi, [esi].StartUp.fParam
+
+ CALL_NS RestoreMtrrProgrammingRetNS
+
+ lidt FWORD PTR [esi+8]
+
+ jmp updateSemaphore
+
+RestoreApConfig ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: DoApInit
+;
+; Input: Contents of startup area at 1000h
+;
+; Output: None
+;
+; Registers: None are preserved
+;
+; Description: Executed on AP. Persforms CPU initialization for running
+; of GETSEC
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+DoApInit PROC NEAR PUBLIC
+ mov eax, CR4
+ or eax, CR4_OSFXSR + CR4_DE + CR4_SMXE
+ mov CR4, eax
+
+ mov esi, 1000h
+ mov ds, cs:[esi].StartUp.fDs
+
+ mov esi, [esi].StartUp.fParam
+ mov edi, 1
+
+ CALL_NS PrepareCacheForAcModuleRetNS
+
+ CALL_NS CleanMcaRetNS
+
+updateSemaphore::
+ mov ecx, 1000h + StartUp.smphr
+ lock inc DWORD PTR [ecx]
+
+hltLoop:
+ cli
+ hlt
+ jmp hltLoop
+
+DoApInit ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: MemCopyRetNS
+;
+; Input: esi - from linear address
+; edi - to linear address
+; ecx - swap size in dwords
+; ds - flat segment
+;
+; Output: None
+;
+; Registers: None
+;
+; Description: Swaps contents of two input buffers.
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+
+MemCopyRetNS PROC NEAR
+
+start:
+ mov eax, ds:[esi] ; source
+ mov ds:[edi], eax
+ add esi, 4
+ add edi, 4
+ loop start
+ RET_NS
+MemCopyRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: ltWaitStatusRetNS
+;
+; Input: cx - Refresh bit Toggle count
+; 750000us = 50000 toggles
+; edx - offset of Status procedure
+;
+; Output: Z if status is met
+; NZ - timeout occured
+; NC - always
+;
+; Stack: Not available
+;
+; Registers: cx, ax, esp
+;
+; Description: Calls status procedure. If status is met - returns Z and
+; NZ otherwise.
+; Status procedure is required to return Z if status is met and
+; NZ if not
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+ltWaitStatusRetNS PROC NEAR
+
+ in al, PORTB ; Read initial setting.
+ and al, PORTBMASK ; Keep what we care about.
+ mov ah, al ; Keep a copy of the data.
+
+waitLoop:
+ CALL_NS edx ; Call status procedure.
+ jz exit ; Z - status met
+
+waitLoop0:
+ in al, PORTB
+ and al, PORTBMASK
+ cmp al, ah ; Refresh bit changed ?
+ je waitLoop0
+
+ mov ah, al
+ loop waitLoop
+ or ax, 1 ; Clear the ZERO flag - timeout.
+ ; This also clears C flag
+exit:
+ RET_NS
+ltWaitStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: IcrStatusRetNS
+;
+; Input: ds: Flat, edi - xAPIC Base Address
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: all are preserved
+;
+; Description: Returns Z if ICR is idle
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+IcrStatusRetNS PROC NEAR PUBLIC
+ test DWORD PTR ICR_LOW[edi], BIT12
+ RET_NS
+IcrStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SemaphoreStatusRetNS
+;
+; Input: ds: Flat
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: all are preserved
+;
+; Description: Returns Z if semaphore is 0
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SemaphoreStatusRetNS PROC NEAR PUBLIC
+ bswap eax
+ mov al, BYTE PTR [esi+SEMAPHORE]
+ cmp al, bl
+ bswap eax
+ RET_NS
+SemaphoreStatusRetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: SemaphoreStatus2RetNS
+;
+; Input: ds: Flat
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: Upper byte of eax is modified
+;
+; Description: Returns Z if semaphore is 0
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+SemaphoreStatus2RetNS PROC NEAR PUBLIC
+ bswap eax
+ mov al, BYTE PTR [esi].StartUp.smphr
+ cmp al, bl
+ bswap eax
+ RET_NS
+SemaphoreStatus2RetNS ENDP
+
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+; Procedure: NeverStatusRetNS
+;
+; Input:
+;
+; Output: Z if status is met
+;
+; Stack: Not available
+;
+; Registers: All are preserved
+;
+; Description: Returns Z if ICR is idle
+;
+;-----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
+NeverStatusRetNS PROC NEAR PUBLIC
+ or dx, dx ; dx is never 0 so return is NZ
+ RET_NS
+NeverStatusRetNS ENDP
+
+
+
+END
diff --git a/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new
new file mode 100644
index 0000000..e27781e
--- /dev/null
+++ b/ReferenceCode/Haswell/Txt/TxtInit/Pei/Ia32/makefile.new
@@ -0,0 +1,69 @@
+#++
+# 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 - 2011 Intel Corporation. All rights reserved
+# 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:
+#
+# makefile.new
+#
+# Abstract:
+#
+# makefile for TxtPeiAp.asm16 file
+#
+#--
+
+
+#
+# Globals
+#
+BIN_DIR = $(BUILD_DIR)\$(PROCESSOR)
+TOOLCHAIN = TOOLCHAIN_$(PROCESSOR)
+
+TOOLBIN_DIR = $(BUILD_DIR)\Tools
+
+#
+# Include CommonTools.env enviroment
+#
+
+!INCLUDE $(BUILD_DIR)\PlatformTools.env
+
+AP_GUID = D1E59F50-E8C3-4545-BF61-11F002233C97
+
+all : $(BIN_DIR)\TxtPeiAp.bin
+
+$(BIN_DIR)\TxtPeiAp.bin: $(BIN_DIR)\TxtPeiAp.obj
+
+$(BIN_DIR)\TxtPeiAp.obj: $(SOURCE_DIR)\TxtPeiAp.asm16
+ $(ASM) /c /nologo /Fl /Sa /I$(SOURCE_DIR)\..\..\..\..\Include /Fo$(BIN_DIR)\TxtPeiAp.obj $(SOURCE_DIR)\TxtPeiAp.asm16
+ cd $(BIN_DIR)
+ $(ASMLINK) TxtPeiAp.obj, TxtPeiAp.com,,,,
+ copy TxtPeiAp.com TxtPeiAp.bin
+ $(GENFFSFILE) -B $(BIN_DIR) -V -P1 <<$(BIN_DIR)\txtpeiap.pkg
+PACKAGE.INF
+[.]
+BASE_NAME = TxtPeiAp
+FFS_FILEGUID = $(AP_GUID)
+FFS_FILETYPE = EFI_FV_FILETYPE_RAW
+FFS_ATTRIB_CHECKSUM = FALSE
+FFS_ALIGNMENT = 5
+
+IMAGE_SCRIPT =
+{
+ txtpeiap.bin
+}
+<<KEEP
+
+