mirror of https://github.com/acidanthera/audk.git
Fix the risk of AP stack conflict.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10714 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
28d1916584
commit
d6d858c4b7
|
@ -22,5 +22,5 @@ RendezvousProc equ LockLocation + 0Ch
|
||||||
GdtrProfile equ LockLocation + 10h
|
GdtrProfile equ LockLocation + 10h
|
||||||
IdtrProfile equ LockLocation + 16h
|
IdtrProfile equ LockLocation + 16h
|
||||||
BufferStart equ LockLocation + 1Ch
|
BufferStart equ LockLocation + 1Ch
|
||||||
|
ProcessorNumber equ LockLocation + 20h
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define GdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
|
#define GdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
|
||||||
#define IdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16
|
#define IdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16
|
||||||
#define BufferStart RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C
|
#define BufferStart RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C
|
||||||
|
#define ProcessorNumber, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------
|
||||||
#RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
#RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
||||||
|
@ -94,30 +95,33 @@ ProtectedModeStart: # protected mode entry point
|
||||||
.byte 0x66
|
.byte 0x66
|
||||||
movw %ax,%ss # Flat mode setup.
|
movw %ax,%ss # Flat mode setup.
|
||||||
|
|
||||||
|
#
|
||||||
|
# ProgramStack
|
||||||
|
#
|
||||||
|
movl $0x1b, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $0xfffff000, %eax
|
||||||
|
addl $0x20, %eax
|
||||||
|
movl (%eax), %ebx
|
||||||
|
shrl $24, %ebx
|
||||||
|
|
||||||
|
xorl %ecx, %ecx
|
||||||
movl %esi,%edi
|
movl %esi,%edi
|
||||||
addl $LockLocation, %edi
|
addl $ProcessorNumber, %edi
|
||||||
movb $NotVacantFlag, %al
|
movl (%edi, %ebx, 4), %ecx
|
||||||
TestLock:
|
|
||||||
xchgb (%edi), %al
|
|
||||||
cmpb $NotVacantFlag, %al
|
|
||||||
jz TestLock
|
|
||||||
|
|
||||||
ProgramStack:
|
|
||||||
movl %esi,%edi
|
movl %esi,%edi
|
||||||
addl $StackSize, %edi
|
addl $StackSize, %edi
|
||||||
movl (%edi), %eax
|
movl (%edi), %eax
|
||||||
|
incl %ecx
|
||||||
|
mull %ecx
|
||||||
|
|
||||||
movl %esi,%edi
|
movl %esi,%edi
|
||||||
addl $StackStart, %edi
|
addl $StackStart, %edi
|
||||||
addl (%edi), %eax
|
movl (%edi), %ebx
|
||||||
movl %eax,%esp
|
addl %ebx, %eax
|
||||||
movl %eax, (%edi)
|
|
||||||
|
|
||||||
Releaselock:
|
movl %eax, %esp
|
||||||
movb $VacantFlag, %al
|
|
||||||
movl %esi,%edi
|
|
||||||
addl $LockLocation, %edi
|
|
||||||
xchgb (%edi), %al
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Call C Function
|
# Call C Function
|
||||||
|
|
|
@ -85,31 +85,33 @@ ProtectedModeStart:: ; protected mode entry point
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax ; Flat mode setup.
|
mov ss, ax ; Flat mode setup.
|
||||||
|
|
||||||
|
;
|
||||||
|
; ProgramStack
|
||||||
|
;
|
||||||
|
mov ecx, 1bh ; Read IA32_APIC_BASE MSR
|
||||||
|
rdmsr
|
||||||
|
and eax, 0fffff000h
|
||||||
|
add eax, 20h
|
||||||
|
mov ebx, dword ptr [eax]
|
||||||
|
shr ebx, 24
|
||||||
|
|
||||||
|
xor ecx, ecx
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, ProcessorNumber
|
||||||
mov al, NotVacantFlag
|
mov ecx, dword ptr [edi + 4 * ebx] ; ECX = CpuNumber
|
||||||
TestLock::
|
|
||||||
xchg byte ptr [edi], al
|
|
||||||
cmp al, NotVacantFlag
|
|
||||||
jz TestLock
|
|
||||||
|
|
||||||
ProgramStack::
|
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSize
|
add edi, StackSize
|
||||||
mov eax, dword ptr [edi]
|
mov eax, dword ptr [edi]
|
||||||
|
inc ecx
|
||||||
|
mul ecx ; EAX = StackSize * (CpuNumber + 1)
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStart
|
add edi, StackStart
|
||||||
add eax, dword ptr [edi]
|
mov ebx, dword ptr [edi]
|
||||||
mov esp, eax
|
add eax, ebx ; EAX = StackStart + StackSize * (CpuNumber + 1)
|
||||||
mov dword ptr [edi], eax
|
|
||||||
|
|
||||||
Releaselock::
|
mov esp, eax
|
||||||
mov al, VacantFlag
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
xchg byte ptr [edi], al
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; Call C Function
|
; Call C Function
|
||||||
|
|
|
@ -22,7 +22,6 @@ EFI_HANDLE mHandle = NULL;
|
||||||
MP_SYSTEM_DATA mMPSystemData;
|
MP_SYSTEM_DATA mMPSystemData;
|
||||||
EFI_PHYSICAL_ADDRESS mStartupVector;
|
EFI_PHYSICAL_ADDRESS mStartupVector;
|
||||||
MP_CPU_EXCHANGE_INFO *mExchangeInfo;
|
MP_CPU_EXCHANGE_INFO *mExchangeInfo;
|
||||||
VOID *mStackStartAddress;
|
|
||||||
BOOLEAN mStopCheckAPsStatus = FALSE;
|
BOOLEAN mStopCheckAPsStatus = FALSE;
|
||||||
UINTN mNumberOfProcessors;
|
UINTN mNumberOfProcessors;
|
||||||
EFI_GENERIC_MEMORY_TEST_PROTOCOL *mGenMemoryTest;
|
EFI_GENERIC_MEMORY_TEST_PROTOCOL *mGenMemoryTest;
|
||||||
|
@ -1254,14 +1253,14 @@ ApProcWrapper (
|
||||||
|
|
||||||
This function sends INIT-SIPI-SIPI to AP, and assign procedure specified by ApFunction.
|
This function sends INIT-SIPI-SIPI to AP, and assign procedure specified by ApFunction.
|
||||||
|
|
||||||
@param Broadcast If TRUE, broadcase IPI to all APs; otherwise, send to specified AP.
|
@param ProcessorNumber The processor number of the specified AP.
|
||||||
@param ApicID The Local APIC ID of the specified AP. If Broadcast is TRUE, it is ignored.
|
@param ApicID The Local APIC ID of the specified AP.
|
||||||
@param ApFunction The procedure for AP to work on.
|
@param ApFunction The procedure for AP to work on.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
SendInitSipiSipi (
|
SendInitSipiSipi (
|
||||||
IN BOOLEAN Broadcast,
|
IN UINTN ProcessorNumber,
|
||||||
IN UINT32 ApicID,
|
IN UINT32 ApicID,
|
||||||
IN VOID *ApFunction
|
IN VOID *ApFunction
|
||||||
)
|
)
|
||||||
|
@ -1274,15 +1273,10 @@ SendInitSipiSipi (
|
||||||
UINT32 DeliveryMode;
|
UINT32 DeliveryMode;
|
||||||
|
|
||||||
mExchangeInfo->ApFunction = ApFunction;
|
mExchangeInfo->ApFunction = ApFunction;
|
||||||
mExchangeInfo->StackStart = mStackStartAddress;
|
mExchangeInfo->ProcessorNumber[ApicID] = (UINT32) ProcessorNumber;
|
||||||
|
|
||||||
if (Broadcast) {
|
|
||||||
ICRHigh = 0;
|
|
||||||
ICRLow = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
|
||||||
} else {
|
|
||||||
ICRHigh = ApicID << 24;
|
ICRHigh = ApicID << 24;
|
||||||
ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
||||||
}
|
|
||||||
|
|
||||||
VectorNumber = 0;
|
VectorNumber = 0;
|
||||||
DeliveryMode = DELIVERY_MODE_INIT;
|
DeliveryMode = DELIVERY_MODE_INIT;
|
||||||
|
@ -1300,11 +1294,7 @@ SendInitSipiSipi (
|
||||||
|
|
||||||
VectorNumber = (UINT32) RShiftU64 (mStartupVector, 12);
|
VectorNumber = (UINT32) RShiftU64 (mStartupVector, 12);
|
||||||
DeliveryMode = DELIVERY_MODE_SIPI;
|
DeliveryMode = DELIVERY_MODE_SIPI;
|
||||||
if (Broadcast) {
|
|
||||||
ICRLow = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
|
||||||
} else {
|
|
||||||
ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;
|
||||||
}
|
|
||||||
|
|
||||||
ICRLow |= VectorNumber | (DeliveryMode << 8);
|
ICRLow |= VectorNumber | (DeliveryMode << 8);
|
||||||
|
|
||||||
|
@ -1358,7 +1348,7 @@ WakeUpAp (
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
SendInitSipiSipi (
|
SendInitSipiSipi (
|
||||||
FALSE,
|
ProcessorNumber,
|
||||||
(UINT32) ProcessorInfoBuffer.ProcessorId,
|
(UINT32) ProcessorInfoBuffer.ProcessorId,
|
||||||
(VOID *) (UINTN) ApProcWrapper
|
(VOID *) (UINTN) ApProcWrapper
|
||||||
);
|
);
|
||||||
|
@ -1390,7 +1380,7 @@ ResetProcessorToIdleState (
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
SendInitSipiSipi (
|
SendInitSipiSipi (
|
||||||
FALSE,
|
ProcessorNumber,
|
||||||
(UINT32) ProcessorInfoBuffer.ProcessorId,
|
(UINT32) ProcessorInfoBuffer.ProcessorId,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
@ -1601,7 +1591,7 @@ PrepareAPStartupVector (
|
||||||
|
|
||||||
ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));
|
ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));
|
||||||
|
|
||||||
mStackStartAddress = AllocatePages (EFI_SIZE_TO_PAGES (MAX_CPU_NUMBER * AP_STACK_SIZE));
|
mExchangeInfo->StackStart = AllocatePages (EFI_SIZE_TO_PAGES (mNumberOfProcessors * AP_STACK_SIZE));
|
||||||
mExchangeInfo->StackSize = AP_STACK_SIZE;
|
mExchangeInfo->StackSize = AP_STACK_SIZE;
|
||||||
|
|
||||||
AsmReadGdtr (&GdtrForBSP);
|
AsmReadGdtr (&GdtrForBSP);
|
||||||
|
@ -1711,8 +1701,6 @@ InitializeMpServicesProtocol (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
PrepareMemoryForConfiguration ();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Locates Framework version MP Services Protocol
|
// Locates Framework version MP Services Protocol
|
||||||
//
|
//
|
||||||
|
@ -1734,6 +1722,8 @@ InitializeMpServicesProtocol (
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
ASSERT (mNumberOfProcessors < MAX_CPU_NUMBER);
|
ASSERT (mNumberOfProcessors < MAX_CPU_NUMBER);
|
||||||
|
|
||||||
|
PrepareMemoryForConfiguration ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create timer event to check AP state for non-blocking execution.
|
// Create timer event to check AP state for non-blocking execution.
|
||||||
//
|
//
|
||||||
|
|
|
@ -72,6 +72,7 @@ typedef struct {
|
||||||
IA32_DESCRIPTOR IdtrProfile;
|
IA32_DESCRIPTOR IdtrProfile;
|
||||||
UINT32 BufferStart;
|
UINT32 BufferStart;
|
||||||
UINT32 Cr3;
|
UINT32 Cr3;
|
||||||
|
UINT32 ProcessorNumber[MAX_CPU_NUMBER];
|
||||||
} MP_CPU_EXCHANGE_INFO;
|
} MP_CPU_EXCHANGE_INFO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -23,5 +23,6 @@ GdtrLocation equ LockLocation + 20h
|
||||||
IdtrLocation equ LockLocation + 2Ah
|
IdtrLocation equ LockLocation + 2Ah
|
||||||
BufferStartLocation equ LockLocation + 34h
|
BufferStartLocation equ LockLocation + 34h
|
||||||
Cr3OffsetLocation equ LockLocation + 38h
|
Cr3OffsetLocation equ LockLocation + 38h
|
||||||
|
ProcessorNumberLocation equ LockLocation + 3Ch
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
.equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A
|
.equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A
|
||||||
.equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34
|
.equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34
|
||||||
.equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38
|
.equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38
|
||||||
|
.equ ProcessorNumberLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -128,31 +129,33 @@ LongModeStart:
|
||||||
.byte 0x66
|
.byte 0x66
|
||||||
movw %ax,%ss
|
movw %ax,%ss
|
||||||
|
|
||||||
movl %esi, %edi
|
#
|
||||||
addl $LockLocation, %edi
|
# ProgramStack
|
||||||
movb $NotVacantFlag, %al
|
#
|
||||||
TestLock:
|
movl $0x1b, %ecx
|
||||||
xchgb (%edi), %al
|
rdmsr
|
||||||
cmpb $NotVacantFlag, %al
|
andl $0xfffff000, %eax
|
||||||
jz TestLock
|
addl $0x20, %eax
|
||||||
|
movl (%eax), %ebx
|
||||||
|
shrl $24, %ebx
|
||||||
|
|
||||||
ProgramStack:
|
xorq %rcx, %rcx
|
||||||
|
movl %esi,%edi
|
||||||
|
addl $ProcessorNumberLocation, %edi
|
||||||
|
movl (%edi, %ebx, 4), %ecx
|
||||||
|
|
||||||
movl %esi,%edi
|
movl %esi,%edi
|
||||||
addl $StackSizeLocation, %edi
|
addl $StackSizeLocation, %edi
|
||||||
movq (%edi), %rax
|
movq (%edi), %rax
|
||||||
|
incq %rcx
|
||||||
|
mulq %rcx
|
||||||
|
|
||||||
movl %esi,%edi
|
movl %esi,%edi
|
||||||
addl $StackStartAddressLocation, %edi
|
addl $StackStartAddressLocation, %edi
|
||||||
addq (%edi), %rax
|
movq (%edi), %rbx
|
||||||
|
addq %rbx, %rax
|
||||||
|
|
||||||
movq %rax, %rsp
|
movq %rax, %rsp
|
||||||
movq %rax, (%edi)
|
|
||||||
|
|
||||||
Releaselock:
|
|
||||||
|
|
||||||
movb $VacantFlag, %al
|
|
||||||
movl %esi, %edi
|
|
||||||
addl $LockLocation, %edi
|
|
||||||
xchgb (%edi), %al
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Call C Function
|
# Call C Function
|
||||||
|
|
|
@ -112,31 +112,33 @@ LongModeStart::
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov edi, esi
|
;
|
||||||
add edi, LockLocation
|
; ProgramStack
|
||||||
mov al, NotVacantFlag
|
;
|
||||||
TestLock::
|
mov ecx, 1bh ; Read IA32_APIC_BASE MSR
|
||||||
xchg byte ptr [edi], al
|
rdmsr
|
||||||
cmp al, NotVacantFlag
|
and eax, 0fffff000h
|
||||||
jz TestLock
|
add eax, 20h
|
||||||
|
mov ebx, dword ptr [eax]
|
||||||
|
shr ebx, 24
|
||||||
|
|
||||||
ProgramStack::
|
xor rcx, rcx
|
||||||
|
mov edi, esi
|
||||||
|
add edi, ProcessorNumberLocation
|
||||||
|
mov ecx, dword ptr [edi + 4 * ebx] ; RCX = CpuNumber
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, StackSizeLocation
|
||||||
mov rax, qword ptr [edi]
|
mov rax, qword ptr [edi]
|
||||||
|
inc rcx
|
||||||
|
mul rcx ; RAX = StackSize * (CpuNumber + 1)
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, StackStartAddressLocation
|
||||||
add rax, qword ptr [edi]
|
mov rbx, qword ptr [edi]
|
||||||
|
add rax, rbx ; RAX = StackStart + StackSize * (CpuNumber + 1)
|
||||||
|
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
mov qword ptr [edi], rax
|
|
||||||
|
|
||||||
Releaselock::
|
|
||||||
|
|
||||||
mov al, VacantFlag
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
xchg byte ptr [edi], al
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; Call C Function
|
; Call C Function
|
||||||
|
|
Loading…
Reference in New Issue