VOID\r
);\r
\r
+/**\r
+ Read CpuSaveStates from PI for Framework use.\r
+\r
+ The function reads PI style CpuSaveStates of CpuIndex-th CPU for Framework driver use. If\r
+ ToRead is specified, the CpuSaveStates will be copied to ToRead, otherwise copied to\r
+ mFrameworkSmst->CpuSaveState[CpuIndex].\r
+\r
+ @param[in] CpuIndex The zero-based CPU index.\r
+ @param[in, out] ToRead If not NULL, CpuSaveStates will be copied to it.\r
+\r
+**/\r
VOID\r
ReadCpuSaveState (\r
- UINTN CpuIndex,\r
- EFI_SMM_CPU_SAVE_STATE *ToRead\r
+ IN UINTN CpuIndex,\r
+ IN OUT EFI_SMM_CPU_SAVE_STATE *ToRead\r
)\r
{\r
EFI_STATUS Status;\r
}\r
}\r
\r
+/**\r
+ Write CpuSaveStates from Framework into PI.\r
+\r
+ The function writes back CpuSaveStates of CpuIndex-th CPU from PI to Framework. If\r
+ ToWrite is specified, it contains the CpuSaveStates to write from, otherwise CpuSaveStates\r
+ to write from mFrameworkSmst->CpuSaveState[CpuIndex].\r
+\r
+ @param[in] CpuIndex The zero-based CPU index.\r
+ @param[in] ToWrite If not NULL, CpuSaveStates to write from.\r
+\r
+**/\r
VOID\r
WriteCpuSaveState (\r
- UINTN CpuIndex,\r
- EFI_SMM_CPU_SAVE_STATE *ToWrite\r
+ IN UINTN CpuIndex,\r
+ IN EFI_SMM_CPU_SAVE_STATE *ToWrite\r
)\r
{\r
EFI_STATUS Status;\r
}\r
}\r
\r
+/**\r
+ Read or write a page that contains CpuSaveStates. Read is from PI to Framework.\r
+ Write is from Framework to PI.\r
+\r
+ This function reads or writes a page that contains CpuSaveStates. The page contains Framework\r
+ CpuSaveStates. On read, it reads PI style CpuSaveStates and fill the page up. On write, it\r
+ writes back from the page content to PI CpuSaveStates struct.\r
+ The first Framework CpuSaveStates (for CPU 0) is from mFrameworkSmst->CpuSaveState which is\r
+ page aligned. Because Framework CpuSaveStates are continuous, we can know which CPUs' SaveStates\r
+ are in the page start from PageAddress.\r
+\r
+ @param[in] PageAddress The base address for a page.\r
+ @param[in] IsRead TRUE for Read, FALSE for Write.\r
+\r
+**/\r
VOID\r
ReadWriteCpuStatePage (\r
- UINT64 PageAddress,\r
- BOOLEAN IsRead\r
+ IN UINT64 PageAddress,\r
+ IN BOOLEAN IsRead\r
)\r
{\r
UINTN FirstSSIndex; // Index of first CpuSaveState in the page\r
}\r
}\r
\r
+/**\r
+ The page fault handler that on-demand read PI CpuSaveStates for framework use. If the fault\r
+ is not targeted to mFrameworkSmst->CpuSaveState range, the function will return FALSE to let\r
+ PageFaultHandlerHook know it needs to pass the fault over to original page fault handler.\r
+ \r
+ @retval TRUE The page fault is correctly handled.\r
+ @retval FALSE The page fault is not handled and is passed through to original handler.\r
+\r
+**/\r
BOOLEAN\r
PageFaultHandler (\r
VOID\r
return IsHandled;\r
}\r
\r
+/**\r
+ Write back the dirty Framework CpuSaveStates to PI.\r
+ \r
+ The function scans the page table for dirty pages in mFrameworkSmst->CpuSaveState\r
+ to write back to PI CpuSaveStates. It is meant to be called on each SmmBaseHelper SMI\r
+ callback after Framework handler is called.\r
+\r
+**/\r
VOID\r
WriteBackDirtyPages (\r
VOID\r
}\r
}\r
\r
+/**\r
+ Hook IDT with our page fault handler so that the on-demand paging works on page fault.\r
+ \r
+ The function hooks the IDT with PageFaultHandlerHook to get on-demand paging work for\r
+ PI<->Framework CpuSaveStates marshalling. It also saves original handler for pass-through\r
+ purpose.\r
+\r
+**/\r
VOID\r
HookPageFaultHandler (\r
VOID\r
IdtGateDesc[14].Bits.OffsetHigh = (UINT32)(((UINTN)PageFaultHandlerHook >> 16) & ((1 << 16) - 1));\r
}\r
\r
+/**\r
+ Initialize page table for pages contain HookData.\r
+ \r
+ The function initialize PDE for 2MB range that contains HookData. If the related PDE points\r
+ to a 2MB page, a page table will be allocated and initialized for 4KB pages. Otherwise we juse\r
+ use the original page table.\r
+\r
+ @param[in] HookData Based on which to initialize page table.\r
+\r
+ @return The pointer to a Page Table that points to 4KB pages which contain HookData.\r
+**/\r
UINT64 *\r
InitCpuStatePageTable (\r
- VOID *HookData\r
+ IN VOID *HookData\r
)\r
{\r
UINTN Index;\r
return PageTable;\r
}\r
\r
+/**\r
+ Mark all the CpuSaveStates as not present.\r
+ \r
+ The function marks all CpuSaveStates memory range as not present so that page fault can be triggered\r
+ on CpuSaveStates access. It is meant to be called on each SmmBaseHelper SMI callback before Framework\r
+ handler is called.\r
+\r
+ @param[in] CpuSaveState The base of CpuSaveStates.\r
+\r
+**/\r
VOID\r
HookCpuStateMemory (\r
- EFI_SMM_CPU_SAVE_STATE *CpuSaveState\r
+ IN EFI_SMM_CPU_SAVE_STATE *CpuSaveState\r
)\r
{\r
UINT64 Index;\r
return Status; \r
}\r
\r
+/**\r
+ Initialize all the stuff needed for on-demand paging hooks for PI<->Framework\r
+ CpuSaveStates marshalling.\r
+\r
+ @param[in] FrameworkSmst Framework SMM system table pointer.\r
+\r
+**/\r
VOID\r
InitHook (\r
- EFI_SMM_SYSTEM_TABLE *FrameworkSmst\r
+ IN EFI_SMM_SYSTEM_TABLE *FrameworkSmst\r
)\r
{\r
UINTN NumCpuStatePages;\r