UefiCpuPkg/MpInitLib: Use NASM struc to avoid hardcode offset

In Windows environment, "dumpbin /disasm" is used to verify the
disassembly before and after using NASM struc doesn't change.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
This commit is contained in:
Ray Ni 2021-02-09 21:58:01 +08:00 committed by mergify[bot]
parent e59760f87e
commit 2fba7d4ee4
7 changed files with 193 additions and 180 deletions

View File

@ -1,7 +1,7 @@
## @file
# MP Initialize Library instance for DXE driver.
#
# Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@ -22,14 +22,13 @@
#
[Sources.IA32]
Ia32/MpEqu.inc
Ia32/MpFuncs.nasm
[Sources.X64]
X64/MpEqu.inc
X64/MpFuncs.nasm
[Sources.common]
MpEqu.inc
DxeMpLib.c
MpLib.c
MpLib.h

View File

@ -1,43 +0,0 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; MpEqu.inc
;
; Abstract:
;
; This is the equates file for Multiple Processor support
;
;-------------------------------------------------------------------------------
VacantFlag equ 00h
NotVacantFlag equ 0ffh
CPU_SWITCH_STATE_IDLE equ 0
CPU_SWITCH_STATE_STORED equ 1
CPU_SWITCH_STATE_LOADED equ 2
LockLocation equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)
StackStartAddressLocation equ LockLocation + 04h
StackSizeLocation equ LockLocation + 08h
ApProcedureLocation equ LockLocation + 0Ch
GdtrLocation equ LockLocation + 10h
IdtrLocation equ LockLocation + 16h
BufferStartLocation equ LockLocation + 1Ch
ModeOffsetLocation equ LockLocation + 20h
ApIndexLocation equ LockLocation + 24h
CodeSegmentLocation equ LockLocation + 28h
DataSegmentLocation equ LockLocation + 2Ch
EnableExecuteDisableLocation equ LockLocation + 30h
Cr3Location equ LockLocation + 34h
InitFlagLocation equ LockLocation + 38h
CpuInfoLocation equ LockLocation + 3Ch
NumApsExecutingLocation equ LockLocation + 40h
InitializeFloatingPointUnitsAddress equ LockLocation + 48h
ModeTransitionMemoryLocation equ LockLocation + 4Ch
ModeTransitionSegmentLocation equ LockLocation + 50h
ModeHighMemoryLocation equ LockLocation + 52h
ModeHighSegmentLocation equ LockLocation + 56h

View File

@ -39,21 +39,21 @@ BITS 16
mov fs, ax
mov gs, ax
mov si, BufferStartLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (BufferStart)
mov ebx, [si]
mov si, DataSegmentLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (DataSegment)
mov edx, [si]
;
; Get start address of 32-bit code in low memory (<1MB)
;
mov edi, ModeTransitionMemoryLocation
mov edi, MP_CPU_EXCHANGE_INFO_FIELD (ModeTransitionMemory)
mov si, GdtrLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (GdtrProfile)
o32 lgdt [cs:si]
mov si, IdtrLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (IdtrProfile)
o32 lidt [cs:si]
;
@ -82,7 +82,7 @@ Flat32Start: ; protected mode entry point
mov esi, ebx
mov edi, esi
add edi, EnableExecuteDisableLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (EnableExecuteDisable)
cmp byte [edi], 0
jz SkipEnableExecuteDisable
@ -96,7 +96,7 @@ Flat32Start: ; protected mode entry point
wrmsr
mov edi, esi
add edi, Cr3Location
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Cr3)
mov eax, dword [edi]
mov cr3, eax
@ -110,35 +110,35 @@ Flat32Start: ; protected mode entry point
SkipEnableExecuteDisable:
mov edi, esi
add edi, InitFlagLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)
cmp dword [edi], 1 ; 1 == ApInitConfig
jnz GetApicId
; Increment the number of APs executing here as early as possible
; This is decremented in C code when AP is finished executing
mov edi, esi
add edi, NumApsExecutingLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (NumApsExecuting)
lock inc dword [edi]
; AP init
mov edi, esi
add edi, LockLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
mov eax, NotVacantFlag
mov edi, esi
add edi, ApIndexLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
mov ebx, 1
lock xadd dword [edi], ebx ; EBX = ApIndex++
inc ebx ; EBX is CpuNumber
mov edi, esi
add edi, StackSizeLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
mov eax, [edi]
mov ecx, ebx
inc ecx
mul ecx ; EAX = StackSize * (CpuNumber + 1)
mov edi, esi
add edi, StackStartAddressLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackStart)
add eax, [edi]
mov esp, eax
jmp CProcedureInvoke
@ -171,18 +171,18 @@ GetProcessorNumber:
; Note that BSP may become an AP due to SwitchBsp()
;
xor ebx, ebx
lea eax, [esi + CpuInfoLocation]
lea eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (CpuInfo)]
mov edi, [eax]
GetNextProcNumber:
cmp [edi], edx ; APIC ID match?
cmp dword [edi + CPU_INFO_IN_HOB.InitialApicId], edx ; APIC ID match?
jz ProgramStack
add edi, 20
add edi, CPU_INFO_IN_HOB_size
inc ebx
jmp GetNextProcNumber
ProgramStack:
mov esp, [edi + 12]
mov esp, dword [edi + CPU_INFO_IN_HOB.ApTopOfStack]
CProcedureInvoke:
push ebp ; push BIST data at top of AP stack
@ -195,11 +195,11 @@ CProcedureInvoke:
push ebx ; Push ApIndex
mov eax, esi
add eax, LockLocation
add eax, MP_CPU_EXCHANGE_INFO_OFFSET
push eax ; push address of exchange info data buffer
mov edi, esi
add edi, ApProcedureLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (CFunction)
mov eax, [edi]
call eax ; Invoke C function
@ -262,17 +262,17 @@ ASM_PFX(AsmGetAddressMap):
mov ebp,esp
mov ebx, [ebp + 24h]
mov dword [ebx], RendezvousFunnelProcStart
mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
mov dword [ebx + 0Ch], AsmRelocateApLoopStart
mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov dword [ebx + 14h], Flat32Start - RendezvousFunnelProcStart
mov dword [ebx + 18h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
mov dword [ebx + 1Ch], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
mov dword [ebx + 20h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
mov dword [ebx + 24h], 0 ; SwitchToRealPM16ModeOffset
mov dword [ebx + 28h], 0 ; SwitchToRealPM16ModeSize
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], RendezvousFunnelProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], Flat32Start - RendezvousFunnelProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], AsmRelocateApLoopStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], 0
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], 0
popad
ret
@ -302,18 +302,18 @@ ASM_PFX(AsmExchangeRole):
mov eax, cr0
push eax
sgdt [esi + 8]
sidt [esi + 14]
sgdt [esi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
sidt [esi + CPU_EXCHANGE_ROLE_INFO.Idtr]
; Store the its StackPointer
mov [esi + 4],esp
mov [esi + CPU_EXCHANGE_ROLE_INFO.StackPointer],esp
; update its switch state to STORED
mov byte [esi], CPU_SWITCH_STATE_STORED
mov byte [esi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_STORED
WaitForOtherStored:
; wait until the other CPU finish storing its state
cmp byte [edi], CPU_SWITCH_STATE_STORED
cmp byte [edi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_STORED
jz OtherStored
pause
jmp WaitForOtherStored
@ -321,21 +321,21 @@ WaitForOtherStored:
OtherStored:
; Since another CPU already stored its state, load them
; load GDTR value
lgdt [edi + 8]
lgdt [edi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
; load IDTR value
lidt [edi + 14]
lidt [edi + CPU_EXCHANGE_ROLE_INFO.Idtr]
; load its future StackPointer
mov esp, [edi + 4]
mov esp, [edi + CPU_EXCHANGE_ROLE_INFO.StackPointer]
; update the other CPU's switch state to LOADED
mov byte [edi], CPU_SWITCH_STATE_LOADED
mov byte [edi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_LOADED
WaitForOtherLoaded:
; wait until the other CPU finish loading new state,
; otherwise the data in stack may corrupt
cmp byte [esi], CPU_SWITCH_STATE_LOADED
cmp byte [esi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_LOADED
jz OtherLoaded
pause
jmp WaitForOtherLoaded

View File

@ -0,0 +1,103 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; MpEqu.inc
;
; Abstract:
;
; This is the equates file for Multiple Processor support
;
;-------------------------------------------------------------------------------
%include "Nasm.inc"
VacantFlag equ 00h
NotVacantFlag equ 0ffh
CPU_SWITCH_STATE_IDLE equ 0
CPU_SWITCH_STATE_STORED equ 1
CPU_SWITCH_STATE_LOADED equ 2
;
; Equivalent NASM structure of MP_ASSEMBLY_ADDRESS_MAP
;
struc MP_ASSEMBLY_ADDRESS_MAP
.RendezvousFunnelAddress CTYPE_UINTN 1
.ModeEntryOffset CTYPE_UINTN 1
.RendezvousFunnelSize CTYPE_UINTN 1
.RelocateApLoopFuncAddress CTYPE_UINTN 1
.RelocateApLoopFuncSize CTYPE_UINTN 1
.ModeTransitionOffset CTYPE_UINTN 1
.SwitchToRealSize CTYPE_UINTN 1
.SwitchToRealOffset CTYPE_UINTN 1
.SwitchToRealNoNxOffset CTYPE_UINTN 1
.SwitchToRealPM16ModeOffset CTYPE_UINTN 1
.SwitchToRealPM16ModeSize CTYPE_UINTN 1
endstruc
;
; Equivalent NASM structure of IA32_DESCRIPTOR
;
struc IA32_DESCRIPTOR
.Limit CTYPE_UINT16 1
.Base CTYPE_UINTN 1
endstruc
;
; Equivalent NASM structure of CPU_EXCHANGE_ROLE_INFO
;
struc CPU_EXCHANGE_ROLE_INFO
; State is defined as UINT8 in C header file
; Define it as UINTN here to guarantee the fields that follow State
; is naturally aligned. The structure layout doesn't change.
.State CTYPE_UINTN 1
.StackPointer CTYPE_UINTN 1
.Gdtr CTYPE_UINT8 IA32_DESCRIPTOR_size
.Idtr CTYPE_UINT8 IA32_DESCRIPTOR_size
endstruc
;
; Equivalent NASM structure of CPU_INFO_IN_HOB
;
struc CPU_INFO_IN_HOB
.InitialApicId CTYPE_UINT32 1
.ApicId CTYPE_UINT32 1
.Health CTYPE_UINT32 1
.ApTopOfStack CTYPE_UINT64 1
endstruc
;
; Equivalent NASM structure of MP_CPU_EXCHANGE_INFO
;
struc MP_CPU_EXCHANGE_INFO
.Lock: CTYPE_UINTN 1
.StackStart: CTYPE_UINTN 1
.StackSize: CTYPE_UINTN 1
.CFunction: CTYPE_UINTN 1
.GdtrProfile: CTYPE_UINT8 IA32_DESCRIPTOR_size
.IdtrProfile: CTYPE_UINT8 IA32_DESCRIPTOR_size
.BufferStart: CTYPE_UINTN 1
.ModeOffset: CTYPE_UINTN 1
.ApIndex: CTYPE_UINTN 1
.CodeSegment: CTYPE_UINTN 1
.DataSegment: CTYPE_UINTN 1
.EnableExecuteDisable: CTYPE_UINTN 1
.Cr3: CTYPE_UINTN 1
.InitFlag: CTYPE_UINTN 1
.CpuInfo: CTYPE_UINTN 1
.NumApsExecuting: CTYPE_UINTN 1
.CpuMpData: CTYPE_UINTN 1
.InitializeFloatingPointUnits: CTYPE_UINTN 1
.ModeTransitionMemory: CTYPE_UINT32 1
.ModeTransitionSegment: CTYPE_UINT16 1
.ModeHighMemory: CTYPE_UINT32 1
.ModeHighSegment: CTYPE_UINT16 1
.Enable5LevelPaging: CTYPE_BOOLEAN 1
.SevEsIsEnabled: CTYPE_BOOLEAN 1
.GhcbBase: CTYPE_UINTN 1
endstruc
MP_CPU_EXCHANGE_INFO_OFFSET equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)
%define MP_CPU_EXCHANGE_INFO_FIELD(Field) (MP_CPU_EXCHANGE_INFO_OFFSET + MP_CPU_EXCHANGE_INFO. %+ Field)

View File

@ -1,7 +1,7 @@
## @file
# MP Initialize Library instance for PEI driver.
#
# Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@ -22,14 +22,13 @@
#
[Sources.IA32]
Ia32/MpEqu.inc
Ia32/MpFuncs.nasm
[Sources.X64]
X64/MpEqu.inc
X64/MpFuncs.nasm
[Sources.common]
MpEqu.inc
PeiMpLib.c
MpLib.c
MpLib.h

View File

@ -1,45 +0,0 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; MpEqu.inc
;
; Abstract:
;
; This is the equates file for Multiple Processor support
;
;-------------------------------------------------------------------------------
VacantFlag equ 00h
NotVacantFlag equ 0ffh
CPU_SWITCH_STATE_IDLE equ 0
CPU_SWITCH_STATE_STORED equ 1
CPU_SWITCH_STATE_LOADED equ 2
LockLocation equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)
StackStartAddressLocation equ LockLocation + 08h
StackSizeLocation equ LockLocation + 10h
ApProcedureLocation equ LockLocation + 18h
GdtrLocation equ LockLocation + 20h
IdtrLocation equ LockLocation + 2Ah
BufferStartLocation equ LockLocation + 34h
ModeOffsetLocation equ LockLocation + 3Ch
ApIndexLocation equ LockLocation + 44h
CodeSegmentLocation equ LockLocation + 4Ch
DataSegmentLocation equ LockLocation + 54h
EnableExecuteDisableLocation equ LockLocation + 5Ch
Cr3Location equ LockLocation + 64h
InitFlagLocation equ LockLocation + 6Ch
CpuInfoLocation equ LockLocation + 74h
NumApsExecutingLocation equ LockLocation + 7Ch
InitializeFloatingPointUnitsAddress equ LockLocation + 8Ch
ModeTransitionMemoryLocation equ LockLocation + 94h
ModeTransitionSegmentLocation equ LockLocation + 98h
ModeHighMemoryLocation equ LockLocation + 9Ah
ModeHighSegmentLocation equ LockLocation + 9Eh
Enable5LevelPagingLocation equ LockLocation + 0A0h
SevEsIsEnabledLocation equ LockLocation + 0A1h
GhcbBaseLocation equ LockLocation + 0A2h

View File

@ -43,21 +43,21 @@ BITS 16
mov fs, ax
mov gs, ax
mov si, BufferStartLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (BufferStart)
mov ebx, [si]
mov si, DataSegmentLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (DataSegment)
mov edx, [si]
;
; Get start address of 32-bit code in low memory (<1MB)
;
mov edi, ModeTransitionMemoryLocation
mov edi, MP_CPU_EXCHANGE_INFO_FIELD (ModeTransitionMemory)
mov si, GdtrLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (GdtrProfile)
o32 lgdt [cs:si]
mov si, IdtrLocation
mov si, MP_CPU_EXCHANGE_INFO_FIELD (IdtrProfile)
o32 lidt [cs:si]
;
@ -85,7 +85,7 @@ Flat32Start: ; protected mode entry point
;
; Enable execute disable bit
;
mov esi, EnableExecuteDisableLocation
mov esi, MP_CPU_EXCHANGE_INFO_FIELD (EnableExecuteDisable)
cmp byte [ebx + esi], 0
jz SkipEnableExecuteDisableBit
@ -101,7 +101,7 @@ SkipEnableExecuteDisableBit:
mov eax, cr4
bts eax, 5
mov esi, Enable5LevelPagingLocation
mov esi, MP_CPU_EXCHANGE_INFO_FIELD (Enable5LevelPaging)
cmp byte [ebx + esi], 0
jz SkipEnable5LevelPaging
@ -117,7 +117,7 @@ SkipEnable5LevelPaging:
;
; Load page table
;
mov esi, Cr3Location ; Save CR3 in ecx
mov esi, MP_CPU_EXCHANGE_INFO_FIELD (Cr3) ; Save CR3 in ecx
mov ecx, [ebx + esi]
mov cr3, ecx ; Load CR3
@ -139,47 +139,47 @@ SkipEnable5LevelPaging:
;
; Far jump to 64-bit code
;
mov edi, ModeHighMemoryLocation
mov edi, MP_CPU_EXCHANGE_INFO_FIELD (ModeHighMemory)
add edi, ebx
jmp far [edi]
BITS 64
LongModeStart:
mov esi, ebx
lea edi, [esi + InitFlagLocation]
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]
cmp qword [edi], 1 ; ApInitConfig
jnz GetApicId
; Increment the number of APs executing here as early as possible
; This is decremented in C code when AP is finished executing
mov edi, esi
add edi, NumApsExecutingLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (NumApsExecuting)
lock inc dword [edi]
; AP init
mov edi, esi
add edi, LockLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
mov rax, NotVacantFlag
mov edi, esi
add edi, ApIndexLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
mov ebx, 1
lock xadd dword [edi], ebx ; EBX = ApIndex++
inc ebx ; EBX is CpuNumber
; program stack
mov edi, esi
add edi, StackSizeLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
mov eax, dword [edi]
mov ecx, ebx
inc ecx
mul ecx ; EAX = StackSize * (CpuNumber + 1)
mov edi, esi
add edi, StackStartAddressLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackStart)
add rax, qword [edi]
mov rsp, rax
lea edi, [esi + SevEsIsEnabledLocation]
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
cmp byte [edi], 1 ; SevEsIsEnabled
jne CProcedureInvoke
@ -193,7 +193,7 @@ LongModeStart:
mov ecx, ebx
mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
mov edi, esi
add edi, GhcbBaseLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
add rax, qword [edi]
mov rdx, rax
shr rdx, 32
@ -202,7 +202,7 @@ LongModeStart:
jmp CProcedureInvoke
GetApicId:
lea edi, [esi + SevEsIsEnabledLocation]
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
cmp byte [edi], 1 ; SevEsIsEnabled
jne DoCpuid
@ -296,18 +296,18 @@ GetProcessorNumber:
; Note that BSP may become an AP due to SwitchBsp()
;
xor ebx, ebx
lea eax, [esi + CpuInfoLocation]
lea eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (CpuInfo)]
mov rdi, [eax]
GetNextProcNumber:
cmp dword [rdi], edx ; APIC ID match?
cmp dword [rdi + CPU_INFO_IN_HOB.InitialApicId], edx ; APIC ID match?
jz ProgramStack
add rdi, 20
add rdi, CPU_INFO_IN_HOB_size
inc ebx
jmp GetNextProcNumber
ProgramStack:
mov rsp, qword [rdi + 12]
mov rsp, qword [rdi + CPU_INFO_IN_HOB.ApTopOfStack]
CProcedureInvoke:
push rbp ; Push BIST data at top of AP stack
@ -315,17 +315,17 @@ CProcedureInvoke:
push rbp
mov rbp, rsp
mov rax, qword [esi + InitializeFloatingPointUnitsAddress]
mov rax, qword [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitializeFloatingPointUnits)]
sub rsp, 20h
call rax ; Call assembly function to initialize FPU per UEFI spec
add rsp, 20h
mov edx, ebx ; edx is ApIndex
mov ecx, esi
add ecx, LockLocation ; rcx is address of exchange info data buffer
add ecx, MP_CPU_EXCHANGE_INFO_OFFSET ; rcx is address of exchange info data buffer
mov edi, esi
add edi, ApProcedureLocation
add edi, MP_CPU_EXCHANGE_INFO_FIELD (CFunction)
mov rax, qword [edi]
sub rsp, 20h
@ -661,18 +661,18 @@ AsmRelocateApLoopEnd:
global ASM_PFX(AsmGetAddressMap)
ASM_PFX(AsmGetAddressMap):
lea rax, [ASM_PFX(RendezvousFunnelProc)]
mov qword [rcx], rax
mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], rax
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], LongModeStart - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
lea rax, [ASM_PFX(AsmRelocateApLoop)]
mov qword [rcx + 18h], rax
mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov qword [rcx + 28h], Flat32Start - RendezvousFunnelProcStart
mov qword [rcx + 30h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
mov qword [rcx + 38h], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
mov qword [rcx + 40h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
mov qword [rcx + 48h], PM16Mode - RendezvousFunnelProcStart ; SwitchToRealPM16ModeOffset
mov qword [rcx + 50h], SwitchToRealProcEnd - PM16Mode ; SwitchToRealPM16ModeSize
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], rax
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], PM16Mode - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], SwitchToRealProcEnd - PM16Mode
ret
;-------------------------------------------------------------------------------------
@ -715,18 +715,18 @@ ASM_PFX(AsmExchangeRole):
;Store EFLAGS, GDTR and IDTR regiter to stack
pushfq
sgdt [rsi + 16]
sidt [rsi + 26]
sgdt [rsi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
sidt [rsi + CPU_EXCHANGE_ROLE_INFO.Idtr]
; Store the its StackPointer
mov [rsi + 8], rsp
mov [rsi + CPU_EXCHANGE_ROLE_INFO.StackPointer], rsp
; update its switch state to STORED
mov byte [rsi], CPU_SWITCH_STATE_STORED
mov byte [rsi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_STORED
WaitForOtherStored:
; wait until the other CPU finish storing its state
cmp byte [rdi], CPU_SWITCH_STATE_STORED
cmp byte [rdi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_STORED
jz OtherStored
pause
jmp WaitForOtherStored
@ -734,21 +734,21 @@ WaitForOtherStored:
OtherStored:
; Since another CPU already stored its state, load them
; load GDTR value
lgdt [rdi + 16]
lgdt [rdi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
; load IDTR value
lidt [rdi + 26]
lidt [rdi + CPU_EXCHANGE_ROLE_INFO.Idtr]
; load its future StackPointer
mov rsp, [rdi + 8]
mov rsp, [rdi + CPU_EXCHANGE_ROLE_INFO.StackPointer]
; update the other CPU's switch state to LOADED
mov byte [rdi], CPU_SWITCH_STATE_LOADED
mov byte [rdi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_LOADED
WaitForOtherLoaded:
; wait until the other CPU finish loading new state,
; otherwise the data in stack may corrupt
cmp byte [rsi], CPU_SWITCH_STATE_LOADED
cmp byte [rsi + CPU_EXCHANGE_ROLE_INFO.State], CPU_SWITCH_STATE_LOADED
jz OtherLoaded
pause
jmp WaitForOtherLoaded