/** @file\r
The X64 entrypoint is used to process capsule in long mode.\r
\r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
UINT64 PhyMask;\r
UINTN PageFaultBuffer;\r
UINTN PageFaultIndex;\r
+ UINT64 AddressEncMask;\r
//\r
// Store the uplink information for each page being used.\r
//\r
)\r
{\r
UINTN Address;\r
+ UINT64 AddressEncMask;\r
\r
Address = PageFaultContext->PageFaultBuffer + EFI_PAGES_TO_SIZE (PageFaultContext->PageFaultIndex);\r
ZeroMem ((VOID *) Address, EFI_PAGES_TO_SIZE (1));\r
\r
+ AddressEncMask = PageFaultContext->AddressEncMask;\r
+\r
//\r
// Cut the previous uplink if it exists and wasn't overwritten.\r
//\r
- if ((PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] != NULL) && ((*PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] & PageFaultContext->PhyMask) == Address)) {\r
+ if ((PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] != NULL) &&\r
+ ((*PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] & ~AddressEncMask & PageFaultContext->PhyMask) == Address)) {\r
*PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] = 0;\r
}\r
\r
//\r
// Link & Record the current uplink.\r
//\r
- *Uplink = Address | IA32_PG_P | IA32_PG_RW;\r
+ *Uplink = Address | AddressEncMask | IA32_PG_P | IA32_PG_RW;\r
PageFaultContext->PageFaultUplink[PageFaultContext->PageFaultIndex] = Uplink;\r
\r
PageFaultContext->PageFaultIndex = (PageFaultContext->PageFaultIndex + 1) % EXTRA_PAGE_TABLE_PAGES;\r
UINT64 *PageTable;\r
UINT64 PFAddress;\r
UINTN PTIndex;\r
+ UINT64 AddressEncMask;\r
\r
//\r
// Get the IDT Descriptor.\r
//\r
- AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr); \r
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);\r
//\r
// Then get page fault context by IDT Descriptor.\r
//\r
PageFaultContext = (PAGE_FAULT_CONTEXT *) (UINTN) (Idtr.Base - sizeof (PAGE_FAULT_CONTEXT));\r
PhyMask = PageFaultContext->PhyMask;\r
+ AddressEncMask = PageFaultContext->AddressEncMask;\r
\r
PFAddress = AsmReadCr2 ();\r
DEBUG ((EFI_D_ERROR, "CapsuleX64 - PageFaultHandler: Cr2 - %lx\n", PFAddress));\r
if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
AcquirePage (PageFaultContext, &PageTable[PTIndex]);\r
}\r
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PhyMask);\r
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~AddressEncMask & PhyMask);\r
PTIndex = BitFieldRead64 (PFAddress, 30, 38);\r
// PDPTE\r
if (PageFaultContext->Page1GSupport) {\r
- PageTable[PTIndex] = (PFAddress & ~((1ull << 30) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+ PageTable[PTIndex] = ((PFAddress | AddressEncMask) & ~((1ull << 30) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
} else {\r
if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
AcquirePage (PageFaultContext, &PageTable[PTIndex]);\r
}\r
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PhyMask);\r
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~AddressEncMask & PhyMask);\r
PTIndex = BitFieldRead64 (PFAddress, 21, 29);\r
// PD\r
- PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+ PageTable[PTIndex] = ((PFAddress | AddressEncMask) & ~((1ull << 21) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
}\r
\r
return NULL;\r
//\r
// Save the IA32 IDT Descriptor\r
//\r
- AsmReadIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr); \r
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr);\r
\r
//\r
// Setup X64 IDT table\r
ZeroMem (PageFaultIdtTable.IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * EXCEPTION_VECTOR_NUMBER);\r
X64Idtr.Base = (UINTN) PageFaultIdtTable.IdtEntryTable;\r
X64Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * EXCEPTION_VECTOR_NUMBER - 1);\r
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr); \r
+ AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);\r
\r
//\r
// Setup the default CPU exception handlers\r
// Hook page fault handler to handle >4G request.\r
//\r
PageFaultIdtTable.PageFaultContext.Page1GSupport = EntrypointContext->Page1GSupport;\r
+ PageFaultIdtTable.PageFaultContext.AddressEncMask = EntrypointContext->AddressEncMask;\r
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) (X64Idtr.Base + (14 * sizeof (IA32_IDT_GATE_DESCRIPTOR)));\r
HookPageFaultHandler (IdtEntry, &(PageFaultIdtTable.PageFaultContext));\r
\r
(VOID **) (UINTN) EntrypointContext->MemoryBase64Ptr,\r
(UINTN *) (UINTN) EntrypointContext->MemorySize64Ptr\r
);\r
- \r
+\r
ReturnContext->ReturnStatus = Status;\r
\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a() Stack Base: 0x%lx, Stack Size: 0x%lx\n",\r
+ __FUNCTION__,\r
+ EntrypointContext->StackBufferBase,\r
+ EntrypointContext->StackBufferLength\r
+ ));\r
+\r
//\r
// Disable interrupt of Debug timer, since the new IDT table cannot work in long mode\r
//\r
//\r
// Restore IA32 IDT table\r
//\r
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr); \r
- \r
+ AsmWriteIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr);\r
+\r
//\r
// Finish to coalesce capsule, and return to 32-bit mode.\r
//\r
(UINT32) (UINTN) EntrypointContext,\r
(UINT32) (UINTN) ReturnContext,\r
(UINT32) (EntrypointContext->StackBufferBase + EntrypointContext->StackBufferLength)\r
- ); \r
- \r
+ );\r
+\r
//\r
// Should never be here.\r
//\r
ASSERT (FALSE);\r
return EFI_SUCCESS;\r
-}
\ No newline at end of file
+}\r