diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index 9d73c53bb1..7294d85c6c 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -395,7 +395,8 @@ Returns: // Migrate IDT from CAR into real memory, so after stack switches to // the new memory, the caller can get memory version PeiServiceTable. // - //MigrateIdtTable (PeiServices); + MigrateIdtTable (PeiServices); + // // Since we are at dispatch level, only the Core's private data // is preserved, nobody else should have any data on the stack. diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index f858740971..4dd7f26c30 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -166,6 +166,11 @@ Returns: InitializePpiServices (&PrivateData, OldCoreData); + // + // Save PeiServicePointer so that it can be retrieved anywhere. + // + SetPeiServicesTablePointer(&PrivateData.PS); + if (OldCoreData != NULL) { PERF_END (NULL,"PreMem", NULL, 0); diff --git a/MdePkg/Include/Library/PeiServicesTablePointerLib.h b/MdePkg/Include/Library/PeiServicesTablePointerLib.h index 7a602f9041..f6ced47265 100644 --- a/MdePkg/Include/Library/PeiServicesTablePointerLib.h +++ b/MdePkg/Include/Library/PeiServicesTablePointerLib.h @@ -30,11 +30,29 @@ GetPeiServicesTablePointer ( VOID ); +/** + The function set the pointer of PEI services immediately preceding the IDT table + according to PI specification. + + @param PeiServices The address of PeiServices pointer. +**/ VOID EFIAPI SetPeiServicesTablePointer ( EFI_PEI_SERVICES ** PeiServicesTablePointer ); +/** + After memory initialization in PEI phase, the IDT table in temporary memory should + be migrated to memory, and the address of PeiServicesPointer also need to be updated + immediately preceding the new IDT table. + + @param PeiServices The address of PeiServices pointer. +**/ +VOID +MigrateIdtTable ( + IN EFI_PEI_SERVICES **PeiServices + ); + #endif diff --git a/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c index 54a500a732..871e52a25a 100644 --- a/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c @@ -20,6 +20,12 @@ static EFI_PEI_SERVICES **gPeiServices; +/** + The function set the pointer of PEI services immediately preceding the IDT table + according to PI specification. + + @param PeiServices The address of PeiServices pointer. +**/ VOID EFIAPI SetPeiServicesTablePointer ( @@ -70,3 +76,18 @@ PeiServicesTablePointerLibConstructor ( gPeiServices = PeiServices; return EFI_SUCCESS; } + +/** + After memory initialization in PEI phase, the IDT table in temporary memory should + be migrated to memory, and the address of PeiServicesPointer also need to be updated + immediately preceding the new IDT table. + + @param PeiServices The address of PeiServices pointer. +**/ +VOID +MigrateIdtTable ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ +} + diff --git a/MdePkg/Library/PeiServicesTablePointerLibIdt/InternalPeiServicesTablePointer.h b/MdePkg/Library/PeiServicesTablePointerLibIdt/InternalPeiServicesTablePointer.h index e1c74901ac..61bc1ebf41 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibIdt/InternalPeiServicesTablePointer.h +++ b/MdePkg/Library/PeiServicesTablePointerLibIdt/InternalPeiServicesTablePointer.h @@ -19,15 +19,11 @@ #include +#include #include #include +#include +#include -extern -EFI_PEI_SERVICES ** -EFIAPI -AsmPeiSevicesTablePointer ( - VOID - ); - - + #endif diff --git a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c index 6a52451381..2536d6a861 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c @@ -33,9 +33,66 @@ GetPeiServicesTablePointer ( ) { EFI_PEI_SERVICES **PeiServices; - - PeiServices = (EFI_PEI_SERVICES **) AsmPeiSevicesTablePointer (); + IA32_DESCRIPTOR Idtr; + + AsmReadIdtr (&Idtr); + PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.Base - 4)); ASSERT (PeiServices != NULL); return PeiServices; } +/** + + The function returns the pointer to PeiServicee following + PI1.0. + + For IA32, the four-bytes field immediately prior to new IDT + base addres is used to save the EFI_PEI_SERVICES**. + For x64, the eight-bytes field immediately prior to new IDT + base addres is used to save the EFI_PEI_SERVICES** + @retval The pointer to PeiServices. + +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + IA32_DESCRIPTOR Idtr; + + AsmReadIdtr (&Idtr); + (*(UINTN*)(Idtr.Base - 4)) = (UINTN)PeiServicesTablePointer; +} + +/** + After memory initialization in PEI phase, the IDT table in temporary memory should + be migrated to memory, and the address of PeiServicesPointer also need to be updated + immediately preceding the new IDT table. + + @param PeiServices The address of PeiServices pointer. +**/ +VOID +MigrateIdtTable ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINTN Size; + VOID *NewBase; + EFI_STATUS Status; + IA32_DESCRIPTOR Idtr; + + AsmReadIdtr (&Idtr); + + Size = sizeof(UINTN) + (Idtr.Limit + 1); + + Status = PeiServicesAllocatePool (Size, &NewBase); + ASSERT_EFI_ERROR (Status); + + CopyMem ((VOID*)((UINTN)NewBase + sizeof(UINTN)), (VOID*)Idtr.Base, (Idtr.Limit + 1)); + + Idtr.Base = (UINTN)NewBase + sizeof(UINTN); + AsmWriteIdtr (&Idtr); + SetPeiServicesTablePointer(PeiServices); +} + diff --git a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf index 049f8754e5..6baad7a600 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf +++ b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf @@ -31,16 +31,16 @@ [Packages] MdePkg/MdePkg.dec -[Sources.Ia32] - Ia32/AsmPeiSevicesTablePointer.c|MSFT - Ia32/AsmPeiSevicesTablePointer.S|GCC +[Sources] PeiServicesTablePointer.c + InternalPeiServicesTablePointer.h -[Sources.X64] - x64/AsmPeiSevicesTablePointer.asm|MSFT - x64/AsmPeiSevicesTablePointer.S|GCC - PeiServicesTablePointer.c [LibraryClasses] DebugLib + BaseMemoryLib + PeiServicesLib + BaseLib + + diff --git a/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c index 95d6d25447..5986e54af7 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c @@ -62,4 +62,18 @@ PeiServicesTablePointerLibConstructor ( return EFI_SUCCESS; } +/** + After memory initialization in PEI phase, the IDT table in temporary memory should + be migrated to memory, and the address of PeiServicesPointer also need to be updated + immediately preceding the new IDT table. + + @param PeiServices The address of PeiServices pointer. +**/ +VOID +MigrateIdtTable ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ +} + diff --git a/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c index 4c439ebd5f..46fe3083b9 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include VOID EFIAPI @@ -75,3 +77,34 @@ PeiServicesTablePointerLibConstructor ( AsmWriteMm7 ((UINT64)(UINTN)PeiServices); return EFI_SUCCESS; } + +/** + After memory initialization in PEI phase, the IDT table in temporary memory should + be migrated to memory, and the address of PeiServicesPointer also need to be updated + immediately preceding the new IDT table. + + @param PeiServices The address of PeiServices pointer. +**/ +VOID +MigrateIdtTable ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINTN Size; + VOID *NewBase; + EFI_STATUS Status; + IA32_DESCRIPTOR Idtr; + + AsmReadIdtr (&Idtr); + + Size = Idtr.Limit + 1; + + Status = PeiServicesAllocatePool (Size, &NewBase); + ASSERT_EFI_ERROR (Status); + + CopyMem (NewBase, (VOID*)Idtr.Base, Size); + + Idtr.Base = (UINTN)NewBase; + AsmWriteIdtr (&Idtr); +} + diff --git a/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.inf b/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.inf index 54edec520d..a0371843d1 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.inf +++ b/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.inf @@ -44,4 +44,5 @@ [LibraryClasses] DebugLib BaseLib - + BaseMemoryLib + PeiServicesLib