mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code
AsmRelocateApLoop() is used to place APs into MWAIT-loop if MonitorMwait feature is supported before hand-off to OS, or place APs into HLT-loop if MonitorMwait feature is not supported. If the current mode is long mode, we will switch APs to protected mode before placing APs in MWAIT-loop or HLT-loop. Thus, once APs wakeup from loop, APs needn't the page table that may be crashed by OS. v3: 1. Rename AsmRellocateApLoop to AsmRelocateApLoop. 2. Fix typo Proteced to Protected. 3. Fix typo segement to segment 4. Use word MONITOR instead of mwait-monitor. Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
5c66d125ea
commit
7615702169
|
@ -168,6 +168,30 @@ CProcedureInvoke:
|
|||
jmp $ ; Never reach here
|
||||
RendezvousFunnelProcEnd:
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
|
||||
;-------------------------------------------------------------------------------------
|
||||
global ASM_PFX(AsmRelocateApLoop)
|
||||
ASM_PFX(AsmRelocateApLoop):
|
||||
AsmRelocateApLoopStart:
|
||||
cmp byte [esp + 4], 1
|
||||
jnz HltLoop
|
||||
MwaitLoop:
|
||||
mov eax, esp
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
monitor
|
||||
mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4]
|
||||
shl eax, 4
|
||||
mwait
|
||||
jmp MwaitLoop
|
||||
HltLoop:
|
||||
cli
|
||||
hlt
|
||||
jmp HltLoop
|
||||
ret
|
||||
AsmRelocateApLoopEnd:
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
; AsmGetAddressMap (&AddressMap);
|
||||
;-------------------------------------------------------------------------------------
|
||||
|
|
|
@ -60,5 +60,26 @@ typedef struct {
|
|||
} MP_CPU_EXCHANGE_INFO;
|
||||
|
||||
#pragma pack()
|
||||
/**
|
||||
Assembly code to place AP into safe loop mode.
|
||||
|
||||
Place AP into targeted C-State if MONITOR is supported, otherwise
|
||||
place AP into hlt state.
|
||||
Place AP in protected mode if the current is long mode. Due to AP maybe
|
||||
wakeup by some hardware event. It could avoid accessing page table that
|
||||
may not available during booting to OS.
|
||||
|
||||
@param[in] MwaitSupport TRUE indicates MONITOR is supported.
|
||||
FALSE indicates MONITOR is not supported.
|
||||
@param[in] ApTargetCState Target C-State value.
|
||||
@param[in] PmCodeSegment Protected mode code segment value.
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI * ASM_RELOCATE_AP_LOOP) (
|
||||
IN BOOLEAN MwaitSupport,
|
||||
IN UINTN ApTargetCState,
|
||||
IN UINTN PmCodeSegment
|
||||
);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -176,6 +176,60 @@ CProcedureInvoke:
|
|||
|
||||
RendezvousFunnelProcEnd:
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
|
||||
;-------------------------------------------------------------------------------------
|
||||
global ASM_PFX(AsmRelocateApLoop)
|
||||
ASM_PFX(AsmRelocateApLoop):
|
||||
AsmRelocateApLoopStart:
|
||||
push rcx
|
||||
push rdx
|
||||
|
||||
lea rsi, [PmEntry] ; rsi <- The start address of transition code
|
||||
|
||||
push r8
|
||||
push rsi
|
||||
DB 0x48
|
||||
retf
|
||||
BITS 32
|
||||
PmEntry:
|
||||
mov eax, cr0
|
||||
btr eax, 31 ; Clear CR0.PG
|
||||
mov cr0, eax ; Disable paging and caches
|
||||
|
||||
mov ebx, edx ; Save EntryPoint to rbx, for rdmsr will overwrite rdx
|
||||
mov ecx, 0xc0000080
|
||||
rdmsr
|
||||
and ah, ~ 1 ; Clear LME
|
||||
wrmsr
|
||||
mov eax, cr4
|
||||
and al, ~ (1 << 5) ; Clear PAE
|
||||
mov cr4, eax
|
||||
|
||||
pop edx
|
||||
add esp, 4
|
||||
pop ecx,
|
||||
add esp, 4
|
||||
cmp cl, 1 ; Check mwait-monitor support
|
||||
jnz HltLoop
|
||||
mov ebx, edx ; Save C-State to ebx
|
||||
MwaitLoop:
|
||||
mov eax, esp ; Set Monitor Address
|
||||
xor ecx, ecx ; ecx = 0
|
||||
xor edx, edx ; edx = 0
|
||||
monitor
|
||||
shl ebx, 4
|
||||
mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]
|
||||
mwait
|
||||
jmp MwaitLoop
|
||||
HltLoop:
|
||||
cli
|
||||
hlt
|
||||
jmp HltLoop
|
||||
ret
|
||||
BITS 64
|
||||
AsmRelocateApLoopEnd:
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
; AsmGetAddressMap (&AddressMap);
|
||||
;-------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue