#include <Library/UefiLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/DebugAgentLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
\r
#include <Protocol/Timer.h>\r
\r
IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS Address;\r
- UINTN ApSafeBufferSize;\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS Address;\r
+ UINTN ApSafeBufferSize;\r
+ UINTN Index;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;\r
+ UINTN StackBase;\r
+ CPU_INFO_IN_HOB *CpuInfoInHob;\r
\r
SaveCpuMpData (CpuMpData);\r
\r
return;\r
}\r
\r
+ if (PcdGetBool (PcdCpuStackGuard)) {\r
+ //\r
+ // One extra page at the bottom of the stack is needed for Guard page.\r
+ //\r
+ if (CpuMpData->CpuApStackSize <= EFI_PAGE_SIZE) {\r
+ DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n"));\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ //\r
+ // DXE will reuse stack allocated for APs at PEI phase if it's available.\r
+ // Let's check it here.\r
+ //\r
+ // Note: BSP's stack guard is set at DxeIpl phase. But for the sake of\r
+ // BSP/AP exchange, stack guard for ApTopOfStack of cpu 0 will still be\r
+ // set here.\r
+ //\r
+ CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;\r
+ for (Index = 0; Index < CpuMpData->CpuCount; ++Index) {\r
+ if (CpuInfoInHob != NULL && CpuInfoInHob[Index].ApTopOfStack != 0) {\r
+ StackBase = (UINTN)CpuInfoInHob[Index].ApTopOfStack - CpuMpData->CpuApStackSize;\r
+ } else {\r
+ StackBase = CpuMpData->Buffer + Index * CpuMpData->CpuApStackSize;\r
+ }\r
+\r
+ Status = gDS->GetMemorySpaceDescriptor (StackBase, &MemDesc);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gDS->SetMemorySpaceAttributes (\r
+ StackBase,\r
+ EFI_PAGES_TO_SIZE (1),\r
+ MemDesc.Attributes | EFI_MEMORY_RP\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n",\r
+ (UINT64)StackBase, (UINT64)Index));\r
+ }\r
+ }\r
+\r
//\r
// Avoid APs access invalid buffer data which allocated by BootServices,\r
// so we will allocate reserved data for AP loop code. We also need to\r