\r
#include "InternalPeiServicesTablePointer.h"\r
\r
-\r
/**\r
\r
The function returns the pointer to PeiServicee following\r
)\r
{\r
EFI_PEI_SERVICES **PeiServices;\r
-\r
- PeiServices = (EFI_PEI_SERVICES **) AsmPeiSevicesTablePointer ();\r
+ IA32_DESCRIPTOR Idtr;\r
+ \r
+ AsmReadIdtr (&Idtr);\r
+ PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.Base - 4));\r
ASSERT (PeiServices != NULL);\r
return PeiServices;\r
}\r
\r
+/**\r
+ \r
+ The function returns the pointer to PeiServicee following\r
+ PI1.0.\r
+ \r
+ For IA32, the four-bytes field immediately prior to new IDT\r
+ base addres is used to save the EFI_PEI_SERVICES**.\r
+ For x64, the eight-bytes field immediately prior to new IDT\r
+ base addres is used to save the EFI_PEI_SERVICES**\r
+ @retval The pointer to PeiServices.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetPeiServicesTablePointer (\r
+ EFI_PEI_SERVICES ** PeiServicesTablePointer\r
+ )\r
+{\r
+ IA32_DESCRIPTOR Idtr;\r
+ \r
+ AsmReadIdtr (&Idtr);\r
+ (*(UINTN*)(Idtr.Base - 4)) = (UINTN)PeiServicesTablePointer;\r
+}\r
+\r
+/**\r
+ After memory initialization in PEI phase, the IDT table in temporary memory should \r
+ be migrated to memory, and the address of PeiServicesPointer also need to be updated \r
+ immediately preceding the new IDT table.\r
+ \r
+ @param PeiServices The address of PeiServices pointer.\r
+**/\r
+VOID\r
+MigrateIdtTable (\r
+ IN EFI_PEI_SERVICES **PeiServices\r
+ )\r
+{\r
+ UINTN Size;\r
+ VOID *NewBase;\r
+ EFI_STATUS Status;\r
+ IA32_DESCRIPTOR Idtr;\r
+ \r
+ AsmReadIdtr (&Idtr);\r
+ \r
+ Size = sizeof(UINTN) + (Idtr.Limit + 1); \r
+ \r
+ Status = PeiServicesAllocatePool (Size, &NewBase);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ CopyMem ((VOID*)((UINTN)NewBase + sizeof(UINTN)), (VOID*)Idtr.Base, (Idtr.Limit + 1));\r
+ \r
+ Idtr.Base = (UINTN)NewBase + sizeof(UINTN);\r
+ AsmWriteIdtr (&Idtr);\r
+ SetPeiServicesTablePointer(PeiServices); \r
+} \r
+\r