mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-24 22:24:37 +02:00
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:
parent
e59760f87e
commit
2fba7d4ee4
@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# MP Initialize Library instance for DXE driver.
|
# 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
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -22,14 +22,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
Ia32/MpEqu.inc
|
|
||||||
Ia32/MpFuncs.nasm
|
Ia32/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/MpEqu.inc
|
|
||||||
X64/MpFuncs.nasm
|
X64/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.common]
|
||||||
|
MpEqu.inc
|
||||||
DxeMpLib.c
|
DxeMpLib.c
|
||||||
MpLib.c
|
MpLib.c
|
||||||
MpLib.h
|
MpLib.h
|
||||||
|
@ -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
|
|
||||||
|
|
@ -39,21 +39,21 @@ BITS 16
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov si, BufferStartLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (BufferStart)
|
||||||
mov ebx, [si]
|
mov ebx, [si]
|
||||||
|
|
||||||
mov si, DataSegmentLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (DataSegment)
|
||||||
mov edx, [si]
|
mov edx, [si]
|
||||||
|
|
||||||
;
|
;
|
||||||
; Get start address of 32-bit code in low memory (<1MB)
|
; 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]
|
o32 lgdt [cs:si]
|
||||||
|
|
||||||
mov si, IdtrLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (IdtrProfile)
|
||||||
o32 lidt [cs:si]
|
o32 lidt [cs:si]
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -82,7 +82,7 @@ Flat32Start: ; protected mode entry point
|
|||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, EnableExecuteDisableLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (EnableExecuteDisable)
|
||||||
cmp byte [edi], 0
|
cmp byte [edi], 0
|
||||||
jz SkipEnableExecuteDisable
|
jz SkipEnableExecuteDisable
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ Flat32Start: ; protected mode entry point
|
|||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, Cr3Location
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Cr3)
|
||||||
mov eax, dword [edi]
|
mov eax, dword [edi]
|
||||||
mov cr3, eax
|
mov cr3, eax
|
||||||
|
|
||||||
@ -110,35 +110,35 @@ Flat32Start: ; protected mode entry point
|
|||||||
|
|
||||||
SkipEnableExecuteDisable:
|
SkipEnableExecuteDisable:
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, InitFlagLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)
|
||||||
cmp dword [edi], 1 ; 1 == ApInitConfig
|
cmp dword [edi], 1 ; 1 == ApInitConfig
|
||||||
jnz GetApicId
|
jnz GetApicId
|
||||||
|
|
||||||
; Increment the number of APs executing here as early as possible
|
; Increment the number of APs executing here as early as possible
|
||||||
; This is decremented in C code when AP is finished executing
|
; This is decremented in C code when AP is finished executing
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (NumApsExecuting)
|
||||||
lock inc dword [edi]
|
lock inc dword [edi]
|
||||||
|
|
||||||
; AP init
|
; AP init
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
|
||||||
mov eax, NotVacantFlag
|
mov eax, NotVacantFlag
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApIndexLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
|
||||||
mov ebx, 1
|
mov ebx, 1
|
||||||
lock xadd dword [edi], ebx ; EBX = ApIndex++
|
lock xadd dword [edi], ebx ; EBX = ApIndex++
|
||||||
inc ebx ; EBX is CpuNumber
|
inc ebx ; EBX is CpuNumber
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
inc ecx
|
inc ecx
|
||||||
mul ecx ; EAX = StackSize * (CpuNumber + 1)
|
mul ecx ; EAX = StackSize * (CpuNumber + 1)
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackStart)
|
||||||
add eax, [edi]
|
add eax, [edi]
|
||||||
mov esp, eax
|
mov esp, eax
|
||||||
jmp CProcedureInvoke
|
jmp CProcedureInvoke
|
||||||
@ -171,18 +171,18 @@ GetProcessorNumber:
|
|||||||
; Note that BSP may become an AP due to SwitchBsp()
|
; Note that BSP may become an AP due to SwitchBsp()
|
||||||
;
|
;
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
lea eax, [esi + CpuInfoLocation]
|
lea eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (CpuInfo)]
|
||||||
mov edi, [eax]
|
mov edi, [eax]
|
||||||
|
|
||||||
GetNextProcNumber:
|
GetNextProcNumber:
|
||||||
cmp [edi], edx ; APIC ID match?
|
cmp dword [edi + CPU_INFO_IN_HOB.InitialApicId], edx ; APIC ID match?
|
||||||
jz ProgramStack
|
jz ProgramStack
|
||||||
add edi, 20
|
add edi, CPU_INFO_IN_HOB_size
|
||||||
inc ebx
|
inc ebx
|
||||||
jmp GetNextProcNumber
|
jmp GetNextProcNumber
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov esp, [edi + 12]
|
mov esp, dword [edi + CPU_INFO_IN_HOB.ApTopOfStack]
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push ebp ; push BIST data at top of AP stack
|
push ebp ; push BIST data at top of AP stack
|
||||||
@ -195,11 +195,11 @@ CProcedureInvoke:
|
|||||||
|
|
||||||
push ebx ; Push ApIndex
|
push ebx ; Push ApIndex
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
add eax, LockLocation
|
add eax, MP_CPU_EXCHANGE_INFO_OFFSET
|
||||||
push eax ; push address of exchange info data buffer
|
push eax ; push address of exchange info data buffer
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (CFunction)
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
|
|
||||||
call eax ; Invoke C function
|
call eax ; Invoke C function
|
||||||
@ -262,17 +262,17 @@ ASM_PFX(AsmGetAddressMap):
|
|||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
|
||||||
mov ebx, [ebp + 24h]
|
mov ebx, [ebp + 24h]
|
||||||
mov dword [ebx], RendezvousFunnelProcStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 0Ch], AsmRelocateApLoopStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], AsmRelocateApLoopStart
|
||||||
mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
|
||||||
mov dword [ebx + 14h], Flat32Start - RendezvousFunnelProcStart
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 18h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart
|
||||||
mov dword [ebx + 1Ch], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 20h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start
|
||||||
mov dword [ebx + 24h], 0 ; SwitchToRealPM16ModeOffset
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], 0
|
||||||
mov dword [ebx + 28h], 0 ; SwitchToRealPM16ModeSize
|
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], 0
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
@ -302,18 +302,18 @@ ASM_PFX(AsmExchangeRole):
|
|||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
sgdt [esi + 8]
|
sgdt [esi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
|
||||||
sidt [esi + 14]
|
sidt [esi + CPU_EXCHANGE_ROLE_INFO.Idtr]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov [esi + 4],esp
|
mov [esi + CPU_EXCHANGE_ROLE_INFO.StackPointer],esp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; 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:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; 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
|
jz OtherStored
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
@ -321,21 +321,21 @@ WaitForOtherStored:
|
|||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt [edi + 8]
|
lgdt [edi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt [edi + 14]
|
lidt [edi + CPU_EXCHANGE_ROLE_INFO.Idtr]
|
||||||
|
|
||||||
; load its future StackPointer
|
; 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
|
; 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:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; 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
|
jz OtherLoaded
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
103
UefiCpuPkg/Library/MpInitLib/MpEqu.inc
Normal file
103
UefiCpuPkg/Library/MpInitLib/MpEqu.inc
Normal 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)
|
@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# MP Initialize Library instance for PEI driver.
|
# 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
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@ -22,14 +22,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
Ia32/MpEqu.inc
|
|
||||||
Ia32/MpFuncs.nasm
|
Ia32/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/MpEqu.inc
|
|
||||||
X64/MpFuncs.nasm
|
X64/MpFuncs.nasm
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.common]
|
||||||
|
MpEqu.inc
|
||||||
PeiMpLib.c
|
PeiMpLib.c
|
||||||
MpLib.c
|
MpLib.c
|
||||||
MpLib.h
|
MpLib.h
|
||||||
|
@ -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
|
|
@ -43,21 +43,21 @@ BITS 16
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov si, BufferStartLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (BufferStart)
|
||||||
mov ebx, [si]
|
mov ebx, [si]
|
||||||
|
|
||||||
mov si, DataSegmentLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (DataSegment)
|
||||||
mov edx, [si]
|
mov edx, [si]
|
||||||
|
|
||||||
;
|
;
|
||||||
; Get start address of 32-bit code in low memory (<1MB)
|
; 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]
|
o32 lgdt [cs:si]
|
||||||
|
|
||||||
mov si, IdtrLocation
|
mov si, MP_CPU_EXCHANGE_INFO_FIELD (IdtrProfile)
|
||||||
o32 lidt [cs:si]
|
o32 lidt [cs:si]
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -85,7 +85,7 @@ Flat32Start: ; protected mode entry point
|
|||||||
;
|
;
|
||||||
; Enable execute disable bit
|
; Enable execute disable bit
|
||||||
;
|
;
|
||||||
mov esi, EnableExecuteDisableLocation
|
mov esi, MP_CPU_EXCHANGE_INFO_FIELD (EnableExecuteDisable)
|
||||||
cmp byte [ebx + esi], 0
|
cmp byte [ebx + esi], 0
|
||||||
jz SkipEnableExecuteDisableBit
|
jz SkipEnableExecuteDisableBit
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ SkipEnableExecuteDisableBit:
|
|||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
bts eax, 5
|
bts eax, 5
|
||||||
|
|
||||||
mov esi, Enable5LevelPagingLocation
|
mov esi, MP_CPU_EXCHANGE_INFO_FIELD (Enable5LevelPaging)
|
||||||
cmp byte [ebx + esi], 0
|
cmp byte [ebx + esi], 0
|
||||||
jz SkipEnable5LevelPaging
|
jz SkipEnable5LevelPaging
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ SkipEnable5LevelPaging:
|
|||||||
;
|
;
|
||||||
; Load page table
|
; 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 ecx, [ebx + esi]
|
||||||
mov cr3, ecx ; Load CR3
|
mov cr3, ecx ; Load CR3
|
||||||
|
|
||||||
@ -139,47 +139,47 @@ SkipEnable5LevelPaging:
|
|||||||
;
|
;
|
||||||
; Far jump to 64-bit code
|
; Far jump to 64-bit code
|
||||||
;
|
;
|
||||||
mov edi, ModeHighMemoryLocation
|
mov edi, MP_CPU_EXCHANGE_INFO_FIELD (ModeHighMemory)
|
||||||
add edi, ebx
|
add edi, ebx
|
||||||
jmp far [edi]
|
jmp far [edi]
|
||||||
|
|
||||||
BITS 64
|
BITS 64
|
||||||
LongModeStart:
|
LongModeStart:
|
||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
lea edi, [esi + InitFlagLocation]
|
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]
|
||||||
cmp qword [edi], 1 ; ApInitConfig
|
cmp qword [edi], 1 ; ApInitConfig
|
||||||
jnz GetApicId
|
jnz GetApicId
|
||||||
|
|
||||||
; Increment the number of APs executing here as early as possible
|
; Increment the number of APs executing here as early as possible
|
||||||
; This is decremented in C code when AP is finished executing
|
; This is decremented in C code when AP is finished executing
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (NumApsExecuting)
|
||||||
lock inc dword [edi]
|
lock inc dword [edi]
|
||||||
|
|
||||||
; AP init
|
; AP init
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
|
||||||
mov rax, NotVacantFlag
|
mov rax, NotVacantFlag
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApIndexLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
|
||||||
mov ebx, 1
|
mov ebx, 1
|
||||||
lock xadd dword [edi], ebx ; EBX = ApIndex++
|
lock xadd dword [edi], ebx ; EBX = ApIndex++
|
||||||
inc ebx ; EBX is CpuNumber
|
inc ebx ; EBX is CpuNumber
|
||||||
|
|
||||||
; program stack
|
; program stack
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
|
||||||
mov eax, dword [edi]
|
mov eax, dword [edi]
|
||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
inc ecx
|
inc ecx
|
||||||
mul ecx ; EAX = StackSize * (CpuNumber + 1)
|
mul ecx ; EAX = StackSize * (CpuNumber + 1)
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackStart)
|
||||||
add rax, qword [edi]
|
add rax, qword [edi]
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
|
||||||
lea edi, [esi + SevEsIsEnabledLocation]
|
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
|
||||||
cmp byte [edi], 1 ; SevEsIsEnabled
|
cmp byte [edi], 1 ; SevEsIsEnabled
|
||||||
jne CProcedureInvoke
|
jne CProcedureInvoke
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ LongModeStart:
|
|||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
|
mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, GhcbBaseLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
|
||||||
add rax, qword [edi]
|
add rax, qword [edi]
|
||||||
mov rdx, rax
|
mov rdx, rax
|
||||||
shr rdx, 32
|
shr rdx, 32
|
||||||
@ -202,7 +202,7 @@ LongModeStart:
|
|||||||
jmp CProcedureInvoke
|
jmp CProcedureInvoke
|
||||||
|
|
||||||
GetApicId:
|
GetApicId:
|
||||||
lea edi, [esi + SevEsIsEnabledLocation]
|
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
|
||||||
cmp byte [edi], 1 ; SevEsIsEnabled
|
cmp byte [edi], 1 ; SevEsIsEnabled
|
||||||
jne DoCpuid
|
jne DoCpuid
|
||||||
|
|
||||||
@ -296,18 +296,18 @@ GetProcessorNumber:
|
|||||||
; Note that BSP may become an AP due to SwitchBsp()
|
; Note that BSP may become an AP due to SwitchBsp()
|
||||||
;
|
;
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
lea eax, [esi + CpuInfoLocation]
|
lea eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (CpuInfo)]
|
||||||
mov rdi, [eax]
|
mov rdi, [eax]
|
||||||
|
|
||||||
GetNextProcNumber:
|
GetNextProcNumber:
|
||||||
cmp dword [rdi], edx ; APIC ID match?
|
cmp dword [rdi + CPU_INFO_IN_HOB.InitialApicId], edx ; APIC ID match?
|
||||||
jz ProgramStack
|
jz ProgramStack
|
||||||
add rdi, 20
|
add rdi, CPU_INFO_IN_HOB_size
|
||||||
inc ebx
|
inc ebx
|
||||||
jmp GetNextProcNumber
|
jmp GetNextProcNumber
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov rsp, qword [rdi + 12]
|
mov rsp, qword [rdi + CPU_INFO_IN_HOB.ApTopOfStack]
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push rbp ; Push BIST data at top of AP stack
|
push rbp ; Push BIST data at top of AP stack
|
||||||
@ -315,17 +315,17 @@ CProcedureInvoke:
|
|||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
mov rax, qword [esi + InitializeFloatingPointUnitsAddress]
|
mov rax, qword [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitializeFloatingPointUnits)]
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
call rax ; Call assembly function to initialize FPU per UEFI spec
|
call rax ; Call assembly function to initialize FPU per UEFI spec
|
||||||
add rsp, 20h
|
add rsp, 20h
|
||||||
|
|
||||||
mov edx, ebx ; edx is ApIndex
|
mov edx, ebx ; edx is ApIndex
|
||||||
mov ecx, esi
|
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
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, MP_CPU_EXCHANGE_INFO_FIELD (CFunction)
|
||||||
mov rax, qword [edi]
|
mov rax, qword [edi]
|
||||||
|
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
@ -661,18 +661,18 @@ AsmRelocateApLoopEnd:
|
|||||||
global ASM_PFX(AsmGetAddressMap)
|
global ASM_PFX(AsmGetAddressMap)
|
||||||
ASM_PFX(AsmGetAddressMap):
|
ASM_PFX(AsmGetAddressMap):
|
||||||
lea rax, [ASM_PFX(RendezvousFunnelProc)]
|
lea rax, [ASM_PFX(RendezvousFunnelProc)]
|
||||||
mov qword [rcx], rax
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], rax
|
||||||
mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], LongModeStart - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
lea rax, [ASM_PFX(AsmRelocateApLoop)]
|
lea rax, [ASM_PFX(AsmRelocateApLoop)]
|
||||||
mov qword [rcx + 18h], rax
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], rax
|
||||||
mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
|
||||||
mov qword [rcx + 28h], Flat32Start - RendezvousFunnelProcStart
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 30h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart
|
||||||
mov qword [rcx + 38h], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 40h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start
|
||||||
mov qword [rcx + 48h], PM16Mode - RendezvousFunnelProcStart ; SwitchToRealPM16ModeOffset
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], PM16Mode - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 50h], SwitchToRealProcEnd - PM16Mode ; SwitchToRealPM16ModeSize
|
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], SwitchToRealProcEnd - PM16Mode
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
@ -715,18 +715,18 @@ ASM_PFX(AsmExchangeRole):
|
|||||||
|
|
||||||
;Store EFLAGS, GDTR and IDTR regiter to stack
|
;Store EFLAGS, GDTR and IDTR regiter to stack
|
||||||
pushfq
|
pushfq
|
||||||
sgdt [rsi + 16]
|
sgdt [rsi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
|
||||||
sidt [rsi + 26]
|
sidt [rsi + CPU_EXCHANGE_ROLE_INFO.Idtr]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov [rsi + 8], rsp
|
mov [rsi + CPU_EXCHANGE_ROLE_INFO.StackPointer], rsp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; 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:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; 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
|
jz OtherStored
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
@ -734,21 +734,21 @@ WaitForOtherStored:
|
|||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt [rdi + 16]
|
lgdt [rdi + CPU_EXCHANGE_ROLE_INFO.Gdtr]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt [rdi + 26]
|
lidt [rdi + CPU_EXCHANGE_ROLE_INFO.Idtr]
|
||||||
|
|
||||||
; load its future StackPointer
|
; 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
|
; 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:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; 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
|
jz OtherLoaded
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
Loading…
x
Reference in New Issue
Block a user