Hi Benjamin,
Based on what you've described, I'll try to provide my best guess as to
what is happening without actually debugging it. Ultimately, I will need
to submit a patch to update PeiSerialPortLibSpiFlash.
Are you're aware, gPchSpiPpiGuid is installed in
Silicon/Intel/KabylakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.c:
PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof
(PEI_SPI_INSTANCE));
if (NULL == PeiSpiInstance) {
return EFI_OUT_OF_RESOURCES;
}
SpiInstance = &(PeiSpiInstance->SpiInstance);
SpiProtocolConstructor (SpiInstance);
PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
PeiSpiInstance->PpiDescriptor.Guid = &gPchSpiPpiGuid;
PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol);
Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor);
Note that this PPI descriptor and the PPI interface structure are
allocated via a pool allocation on the T-RAM heap. The allocation
contains the descriptor followed by the interface structure. There's
several pointers set within these structures.
In the descriptor, the GUID pointer is set to the GUID value within the
image (not the heap) and the PPI interface pointer is set to the
interface structure in the same pool allocation in the heap. This
interface structure contains function pointers for SPI flash operations
as defined in the PCH_SPI_PROTOCOL structure.
The function pointers are set in SpiProtocolConstructor() .
Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
Those function addresses are to image addresses at their XIP address in
T-RAM.
Starting from the heap, I suspect:
1. After PeiInstallPeiMemory () is called, PeiCheckAndSwitchStack() will
eventually get called by the dispatcher and see the stack switch signal
is now TRUE.
2. The heap and stack migration will occur. New heap offsets will be
calculated. Note that pointers to structures in the heap will be updated
after PeiCore() reentry.
3. PeiCore() will be reentered using the new permanent memory stack.
4. In this entry, ShadowedPeiCore is NULL. So the T-RAM heap and stack
are still around, the permanent memory heap and stack are known and
setup, but the PeiCore image is still executing at its T-RAM address.
5. The private pointer to the HOB list in the permanent memory heap (in
addition to other lists in the heap like PPI lists) are updated.
6. Eventually, ConvertPpiPointers() will convert pointers in the PPI
list to their permanent memory locations.
- This includes the PPI descriptor, PPI GUID, and PPI interface
pointers.
- These should include pointers into T-RAM memory allocations, heap,
and stack.
- Note: PPI structures initialized as global variables are not
handled. That is what PcdMigrateTemporaryRamFirmwareVolumes helps
address. Not particularly relevant in this specific scenario.
- Further note: For most platforms that execute from flash
mapped as MMIO, these address should still resolve as code fetches over
the SPI bus.
- Anyway, for gPchSpiPpiGuid, I suspect:
1. The PPI list pointer now points to the PPI descriptor in
permanent memory (updated)
2. The PPI descriptor pointer now points to the descriptor in
permanent memory (migrated/updated)
3. The PPI GUID pointer still points to the GUID at the XIP
address (not migrated/update attempted)
4. The PPI interface pointer now points to the interface structure
in the permanent memory heap (migrated/updated)
- The function pointers within the struct still point to the
functions at their XIP addresses (not migrated/not updated)
5. The HOB gSpiFlashDebugHobGuid, has been copied to the permanent
memory heap (with other heap contents) and the HOB heap pointer was updated.
- [other actions will obviously happen but I don't think will
significantly affect the outcome for this situation]
Although, a PPI notify was registered in PeiSerialPortLibSpiFlash on
gPchSpiPpiGuid. The PPI was not actually explicitly reinstalled (that I
can find in the code) so the HOB retains the T-RAM pointers which work
until NEM is disabled (because the PPI descriptor was in the T-RAM heap
not backed by MMIO so it can't be fetched again).
Even if the PPI was explicitly reinstalled, with this code printing
debug messages, the gap is too far between when a message will be
printed and the dispatcher would invoke notifications.
For something in the debug stack especially, it was a poor
implementation choice on my part to cache the PPI pointer in the HOB.
Additionally, this is a library so multiple HOB instances could be
produced which is undesirable. In conclusion, I will send a patch to
update PeiSerialPortLibSpiFlash.
Regarding, the test point checks, are you sure the HOB is actually
created? Were you able to successfully get the HOB at any point after it
should have been created? For example, it looks like there's several
preliminary checks in TestPointLibSetTable() that could prevent
publishing of the HOB.
Regards,
Michael
On 7/7/2021 1:55 AM, Benjamin Doron wrote:
Hi all,
I'm working on root-causing an issue where I'm unable to retrieve any
debug logs after cache-as-RAM teardown on my MinPlatform board port for
GSoC 2021. I'm using KabylakeOpenBoardPkg/PeiSerialPortLibSpiFlash.
My best guess at the moment is that it's related to HOBs, which this
SerialPortLib uses. If I reinitialise the library stack, it largely
works, but a HOB/context structure entry "CurrentWriteOffset" also looks
like it's zeroed.
Also, GetFeatureImplemented() in
MinPlatformPkg/Test/TestPointCheckLib/PeiTestPointCheckLib.c asserts
with "Status = Not Found". Internally, the test point architecture uses
HOBs. I don't think this should happen, so, if not for this, I would
think that perhaps a pointer in the serial port library needed to be
updated.
I can see that the heap is copied over to permanent memory by the PEI
core dispatcher
(https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c#L881
<https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c#L881>).
However, I can't see that the HOB list pointer is updated, so it looks
like it
(https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/Hob/Hob.c#L44
<https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/Hob/Hob.c#L44>)
still has the value that's copied over from the old PEI core's data
(https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c#L348
<https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c#L348>).
Does this look like a bug, or might there be something else that I'm
missing?
Best regards,
Benjamin
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#77618): https://edk2.groups.io/g/devel/message/77618
Mute This Topic: https://groups.io/mt/84038809/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-