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
|
jmp $ ; Never reach here
|
||||||
RendezvousFunnelProcEnd:
|
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);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -60,5 +60,26 @@ typedef struct {
|
||||||
} MP_CPU_EXCHANGE_INFO;
|
} MP_CPU_EXCHANGE_INFO;
|
||||||
|
|
||||||
#pragma pack()
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,60 @@ CProcedureInvoke:
|
||||||
|
|
||||||
RendezvousFunnelProcEnd:
|
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);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue