* [PATCH 3/6] UefiCpuPkg/MpInitLib: Remove CPU information from CPU_AP_DATA
2016-11-14 3:46 [PATCH 0/6] UefiCpuPkg/MpInitLib: Program AP stack in fixed address Jeff Fan
2016-11-14 3:46 ` [PATCH 1/6] UefiCpuPkg/MpInitLib: Fixed offset error on Cr3Location Jeff Fan
2016-11-14 3:46 ` [PATCH 2/6] UefiCpuPkg/MpInitLib: Force sending INIT-SIPI-SIPI to reset APs Jeff Fan
@ 2016-11-14 3:46 ` Jeff Fan
2016-11-14 3:46 ` [PATCH 4/6] UefiCpuPkg/MpInitLib: Add InitFlag and CpuInfo in MP_CPU_EXCHANGE_INFO Jeff Fan
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jeff Fan @ 2016-11-14 3:46 UTC (permalink / raw)
To: edk2-devel; +Cc: Feng Tian, Michael D Kinney
Some CPU information (InitialApicId/ApicId/Health) are duplicated in CPU_AP_DATA
and CPU_INFO_IN_HOB.
This update is to remove the ones from CPU_AP_DATA and update MpInitLib to
consume the ones from CPU_INFO_IN_HOB.
Cc: Feng Tian <feng.tian@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 73 +++++++++++++++++++-----------------
UefiCpuPkg/Library/MpInitLib/MpLib.h | 3 --
2 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 9641e5e..dc4216c 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -253,7 +253,7 @@ SortApicId (
UINTN Index2;
UINTN Index3;
UINT32 ApicId;
- CPU_AP_DATA CpuData;
+ CPU_INFO_IN_HOB CpuInfo;
UINT32 ApCount;
CPU_INFO_IN_HOB *CpuInfoInHob;
@@ -265,21 +265,22 @@ SortApicId (
//
// Sort key is the hardware default APIC ID
//
- ApicId = CpuMpData->CpuData[Index1].ApicId;
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+ ApicId = CpuInfoInHob[Index1].ApicId;
for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) {
- if (ApicId > CpuMpData->CpuData[Index2].ApicId) {
+ if (ApicId > CpuInfoInHob[Index2].ApicId) {
Index3 = Index2;
- ApicId = CpuMpData->CpuData[Index2].ApicId;
+ ApicId = CpuInfoInHob[Index2].ApicId;
}
}
if (Index3 != Index1) {
- CopyMem (&CpuData, &CpuMpData->CpuData[Index3], sizeof (CPU_AP_DATA));
+ CopyMem (&CpuInfo, &CpuInfoInHob[Index3], sizeof (CPU_INFO_IN_HOB));
CopyMem (
- &CpuMpData->CpuData[Index3],
- &CpuMpData->CpuData[Index1],
- sizeof (CPU_AP_DATA)
+ &CpuInfoInHob[Index3],
+ &CpuInfoInHob[Index1],
+ sizeof (CPU_INFO_IN_HOB)
);
- CopyMem (&CpuMpData->CpuData[Index1], &CpuData, sizeof (CPU_AP_DATA));
+ CopyMem (&CpuInfoInHob[Index1], &CpuInfo, sizeof (CPU_INFO_IN_HOB));
}
}
@@ -288,18 +289,11 @@ SortApicId (
//
ApicId = GetInitialApicId ();
for (Index1 = 0; Index1 < CpuMpData->CpuCount; Index1++) {
- if (CpuMpData->CpuData[Index1].ApicId == ApicId) {
+ if (CpuInfoInHob[Index1].ApicId == ApicId) {
CpuMpData->BspNumber = (UINT32) Index1;
break;
}
}
-
- CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
- for (Index1 = 0; Index1 < CpuMpData->CpuCount; Index1++) {
- CpuInfoInHob[Index1].InitialApicId = CpuMpData->CpuData[Index1].InitialApicId;
- CpuInfoInHob[Index1].ApicId = CpuMpData->CpuData[Index1].ApicId;
- CpuInfoInHob[Index1].Health = CpuMpData->CpuData[Index1].Health;
- }
}
}
@@ -358,10 +352,13 @@ GetProcessorNumber (
{
UINTN TotalProcessorNumber;
UINTN Index;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
+
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
TotalProcessorNumber = CpuMpData->CpuCount;
for (Index = 0; Index < TotalProcessorNumber; Index ++) {
- if (CpuMpData->CpuData[Index].ApicId == GetApicId ()) {
+ if (CpuInfoInHob[Index].ApicId == GetApicId ()) {
*ProcessorNumber = Index;
return EFI_SUCCESS;
}
@@ -439,12 +436,16 @@ InitializeApData (
IN UINT32 BistData
)
{
+ CPU_INFO_IN_HOB *CpuInfoInHob;
+
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+ CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ CpuInfoInHob[ProcessorNumber].ApicId = GetApicId ();
+ CpuInfoInHob[ProcessorNumber].Health = BistData;
+
CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
- CpuMpData->CpuData[ProcessorNumber].Health = BistData;
CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;
- CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
- CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
- if (CpuMpData->CpuData[ProcessorNumber].InitialApicId >= 0xFF) {
+ if (CpuInfoInHob[ProcessorNumber].InitialApicId >= 0xFF) {
//
// Set x2APIC mode if there are any logical processor reporting
// an Initial APIC ID of 255 or greater.
@@ -477,6 +478,7 @@ ApWakeupFunction (
VOID *Parameter;
UINT32 BistData;
volatile UINT32 *ApStartupSignalBuffer;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
//
// AP finished assembly code and begin to execute C code
@@ -547,8 +549,9 @@ ApWakeupFunction (
//
// Re-get the CPU APICID and Initial APICID
//
- CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
- CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+ CpuInfoInHob[ProcessorNumber].ApicId = GetApicId ();
+ CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId ();
}
}
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateFinished);
@@ -696,6 +699,7 @@ WakeUpAP (
UINTN Index;
CPU_AP_DATA *CpuData;
BOOLEAN ResetVectorRequired;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
CpuMpData->FinishedCount = 0;
ResetVectorRequired = FALSE;
@@ -760,8 +764,9 @@ WakeUpAP (
ASSERT (CpuMpData->InitFlag != ApInitConfig);
*(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
if (ResetVectorRequired) {
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
SendInitSipiSipi (
- CpuData->ApicId,
+ CpuInfoInHob[ProcessorNumber].ApicId,
(UINT32) ExchangeInfo->BufferStart
);
}
@@ -1229,16 +1234,14 @@ MpInitLibInitialize (
CpuMpData->CpuCount = OldCpuMpData->CpuCount;
CpuMpData->BspNumber = OldCpuMpData->BspNumber;
CpuMpData->InitFlag = ApInitReconfig;
- CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) OldCpuMpData->CpuInfoInHob;
+ CpuMpData->CpuInfoInHob = OldCpuMpData->CpuInfoInHob;
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock);
- CpuMpData->CpuData[Index].ApicId = CpuInfoInHob[Index].ApicId;
- CpuMpData->CpuData[Index].InitialApicId = CpuInfoInHob[Index].InitialApicId;
- if (CpuMpData->CpuData[Index].InitialApicId >= 255) {
+ if (CpuInfoInHob[Index].InitialApicId >= 255) {
CpuMpData->X2ApicEnable = TRUE;
}
- CpuMpData->CpuData[Index].Health = CpuInfoInHob[Index].Health;
- CpuMpData->CpuData[Index].CpuHealthy = (CpuMpData->CpuData[Index].Health == 0)? TRUE:FALSE;
+ CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE;
CpuMpData->CpuData[Index].ApFunction = 0;
CopyMem (
&CpuMpData->CpuData[Index].VolatileRegisters,
@@ -1299,8 +1302,10 @@ MpInitLibGetProcessorInfo (
{
CPU_MP_DATA *CpuMpData;
UINTN CallerNumber;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
CpuMpData = GetCpuMpData ();
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
//
// Check whether caller processor is BSP
@@ -1318,7 +1323,7 @@ MpInitLibGetProcessorInfo (
return EFI_NOT_FOUND;
}
- ProcessorInfoBuffer->ProcessorId = (UINT64) CpuMpData->CpuData[ProcessorNumber].ApicId;
+ ProcessorInfoBuffer->ProcessorId = (UINT64) CpuInfoInHob[ProcessorNumber].ApicId;
ProcessorInfoBuffer->StatusFlag = 0;
if (ProcessorNumber == CpuMpData->BspNumber) {
ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
@@ -1336,14 +1341,14 @@ MpInitLibGetProcessorInfo (
// Get processor location information
//
GetProcessorLocationByApicId (
- CpuMpData->CpuData[ProcessorNumber].ApicId,
+ CpuInfoInHob[ProcessorNumber].ApicId,
&ProcessorInfoBuffer->Location.Package,
&ProcessorInfoBuffer->Location.Core,
&ProcessorInfoBuffer->Location.Thread
);
if (HealthData != NULL) {
- HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health;
+ HealthData->Uint32 = CpuInfoInHob[ProcessorNumber].Health;
}
return EFI_SUCCESS;
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index ae78c59..f107b6d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -112,9 +112,6 @@ typedef struct {
volatile UINT32 *StartupApSignal;
volatile UINTN ApFunction;
volatile UINTN ApFunctionArgument;
- UINT32 InitialApicId;
- UINT32 ApicId;
- UINT32 Health;
BOOLEAN CpuHealthy;
volatile CPU_STATE State;
CPU_VOLATILE_REGISTERS VolatileRegisters;
--
2.9.3.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] UefiCpuPkg/MpInitLib: Program AP stack in fixed address
2016-11-14 3:46 [PATCH 0/6] UefiCpuPkg/MpInitLib: Program AP stack in fixed address Jeff Fan
` (3 preceding siblings ...)
2016-11-14 3:46 ` [PATCH 4/6] UefiCpuPkg/MpInitLib: Add InitFlag and CpuInfo in MP_CPU_EXCHANGE_INFO Jeff Fan
@ 2016-11-14 3:47 ` Jeff Fan
2016-11-14 3:47 ` [PATCH 6/6] UefiCpuPkg/MpInitLib: Update AP information when BSP switched Jeff Fan
2016-11-16 8:00 ` [PATCH 0/6] UefiCpuPkg/MpInitLib: Program AP stack in fixed address Tian, Feng
6 siblings, 0 replies; 8+ messages in thread
From: Jeff Fan @ 2016-11-14 3:47 UTC (permalink / raw)
To: edk2-devel; +Cc: Feng Tian, Michael D Kinney
Currently, MpInitLib will program AP stack in dynamic address. Each processor
will calculate its stack address by adding stack size based on the last stack
address. That means AP may have the different stack address everytime it is
wakeup by INIT-SIPI-SIPI.
When all APs have wakeup to execute AP task, each each has been assigned one
stack address. Once the timeout happened on some of APs, BSP will send INIT-
SIPI-SIPI to wake up APs. We need to re-assign stack for APs. Based on the
current implementation, we might assign one stack address used by other APs.
It will cause the unexpected stack overlapped issue.
This fix changed the stack assignment policy. We will record the stack address
assigned to AP at first time AP wakeup. When AP failed on AP task, BSP could
reassigned the same stack for it.
Getting initial APIC ID in assembly code could help AP to get saved its stack
address.
Cc: Feng Tian <feng.tian@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 65 +++++++++++++++++++-----
UefiCpuPkg/Library/MpInitLib/MpLib.c | 12 +++--
UefiCpuPkg/Library/MpInitLib/MpLib.h | 1 +
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 68 +++++++++++++++++++++-----
4 files changed, 119 insertions(+), 27 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 8f6f0bf..4bfa084 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -114,7 +114,12 @@ Flat32Start: ; protected mode entry point
mov cr0, eax
SkipEnableExecuteDisable:
+ mov edi, esi
+ add edi, InitFlagLocation
+ cmp dword [edi], 1 ; 1 == ApInitConfig
+ jnz GetApicId
+ ; AP init
mov edi, esi
add edi, LockLocation
mov eax, NotVacantFlag
@@ -124,27 +129,65 @@ TestLock:
cmp eax, NotVacantFlag
jz TestLock
- mov edi, esi
- add edi, NumApsExecutingLocation
- inc dword [edi]
- mov ebx, [edi]
+ mov ecx, esi
+ add ecx, NumApsExecutingLocation
+ inc dword [ecx]
+ mov ebx, [ecx]
+
+Releaselock:
+ mov eax, VacantFlag
+ xchg [edi], eax
-ProgramStack:
mov edi, esi
add edi, StackSizeLocation
mov eax, [edi]
+ mov ecx, ebx
+ inc ecx
+ mul ecx ; EAX = StackSize * (CpuNumber + 1)
mov edi, esi
add edi, StackStartAddressLocation
add eax, [edi]
mov esp, eax
- mov [edi], eax
+ jmp CProcedureInvoke
+
+GetApicId:
+ mov eax, 0
+ cpuid
+ cmp eax, 0bh
+ jnb X2Apic
+ ; Processor is not x2APIC capable, so get 8-bit APIC ID
+ mov eax, 1
+ cpuid
+ shr ebx, 24
+ mov edx, ebx
+ jmp GetProcessorNumber
+
+X2Apic:
+ ; Processor is x2APIC capable, so get 32-bit x2APIC ID
+ mov eax, 0bh
+ xor ecx, ecx
+ cpuid
+ ; edx save x2APIC ID
+
+GetProcessorNumber:
+ ;
+ ; Get processor number for this AP
+ ; Note that BSP may become an AP due to SwitchBsp()
+ ;
+ xor ebx, ebx
+ lea eax, [esi + CpuInfoLocation]
+ mov edi, [eax]
-Releaselock:
- mov eax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg [edi], eax
+GetNextProcNumber:
+ cmp [edi], edx ; APIC ID match?
+ jz ProgramStack
+ add edi, 16
+ inc ebx
+ jmp GetNextProcNumber
+ProgramStack:
+ mov esp, [edi + 12]
+
CProcedureInvoke:
push ebp ; push BIST data at top of AP stack
xor ebp, ebp ; clear ebp for call stack trace
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index da814c6..748c8e7 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -433,7 +433,8 @@ VOID
InitializeApData (
IN OUT CPU_MP_DATA *CpuMpData,
IN UINTN ProcessorNumber,
- IN UINT32 BistData
+ IN UINT32 BistData,
+ IN UINTN ApTopOfStack
)
{
CPU_INFO_IN_HOB *CpuInfoInHob;
@@ -442,6 +443,7 @@ InitializeApData (
CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId ();
CpuInfoInHob[ProcessorNumber].ApicId = GetApicId ();
CpuInfoInHob[ProcessorNumber].Health = BistData;
+ CpuInfoInHob[ProcessorNumber].ApTopOfStack = (UINT32) ApTopOfStack;
CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;
@@ -479,6 +481,7 @@ ApWakeupFunction (
UINT32 BistData;
volatile UINT32 *ApStartupSignalBuffer;
CPU_INFO_IN_HOB *CpuInfoInHob;
+ UINTN ApTopOfStack;
//
// AP finished assembly code and begin to execute C code
@@ -497,7 +500,8 @@ ApWakeupFunction (
//
// This is first time AP wakeup, get BIST information from AP stack
//
- BistData = *(UINT32 *) (CpuMpData->Buffer + ProcessorNumber * CpuMpData->CpuApStackSize - sizeof (UINTN));
+ ApTopOfStack = CpuMpData->Buffer + (ProcessorNumber + 1) * CpuMpData->CpuApStackSize;
+ BistData = *(UINT32 *) (ApTopOfStack - sizeof (UINTN));
//
// Do some AP initialize sync
//
@@ -506,7 +510,7 @@ ApWakeupFunction (
// Sync BSP's Control registers to APs
//
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
- InitializeApData (CpuMpData, ProcessorNumber, BistData);
+ InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
} else {
//
@@ -1195,7 +1199,7 @@ MpInitLibInitialize (
//
// Set BSP basic information
//
- InitializeApData (CpuMpData, 0, 0);
+ InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer);
//
// Save assembly code information
//
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a58c855..f81c819 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -133,6 +133,7 @@ typedef struct {
UINT32 InitialApicId;
UINT32 ApicId;
UINT32 Health;
+ UINT32 ApTopOfStack;
} CPU_INFO_IN_HOB;
//
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 090e9fa..bfc3ff1 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -120,6 +120,12 @@ LongModeStart:
mov ss, ax
mov esi, ebx
+ lea edi, [esi + InitFlagLocation]
+ cmp qword [edi], 1 ; ApInitConfig
+ jnz GetApicId
+
+ ; AP init
+ mov esi, ebx
mov edi, esi
add edi, LockLocation
mov rax, NotVacantFlag
@@ -129,26 +135,64 @@ TestLock:
cmp rax, NotVacantFlag
jz TestLock
- mov edi, esi
- add edi, NumApsExecutingLocation
- inc dword [edi]
- mov ebx, [edi]
+ lea ecx, [esi + InitFlagLocation]
+ inc dword [ecx]
+ mov ebx, [ecx]
-ProgramStack:
+Releaselock:
+ mov rax, VacantFlag
+ xchg qword [edi], rax
+ ; program stack
mov edi, esi
add edi, StackSizeLocation
- mov rax, qword [edi]
+ mov eax, dword [edi]
+ mov ecx, ebx
+ inc ecx
+ mul ecx ; EAX = StackSize * (CpuNumber + 1)
mov edi, esi
add edi, StackStartAddressLocation
add rax, qword [edi]
mov rsp, rax
- mov qword [edi], rax
+ jmp CProcedureInvoke
+
+GetApicId:
+ mov eax, 0
+ cpuid
+ cmp eax, 0bh
+ jnb X2Apic
+ ; Processor is not x2APIC capable, so get 8-bit APIC ID
+ mov eax, 1
+ cpuid
+ shr ebx, 24
+ mov edx, ebx
+ jmp GetProcessorNumber
+
+X2Apic:
+ ; Processor is x2APIC capable, so get 32-bit x2APIC ID
+ mov eax, 0bh
+ xor ecx, ecx
+ cpuid
+ ; edx save x2APIC ID
+
+GetProcessorNumber:
+ ;
+ ; Get processor number for this AP
+ ; Note that BSP may become an AP due to SwitchBsp()
+ ;
+ xor ebx, ebx
+ lea eax, [esi + CpuInfoLocation]
+ mov edi, [eax]
-Releaselock:
- mov rax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg qword [edi], rax
+GetNextProcNumber:
+ cmp dword [edi], edx ; APIC ID match?
+ jz ProgramStack
+ add edi, 16
+ inc ebx
+ jmp GetNextProcNumber
+
+ProgramStack:
+ xor rsp, rsp
+ mov esp, dword [edi + 12]
CProcedureInvoke:
push rbp ; Push BIST data at top of AP stack
--
2.9.3.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread