During the finalization of Mp initialization before booting into the OS, depending on whether Mwait is supported or not, AsmRelocateApLoop places Aps in MWAIT-loop or HLT-loop. Since paging is necessary for long mode, the original implementation of moving APs to 32-bit was to disable paging to ensure that the booting does not crash. The current modification creates a page table in reserved memory, avoiding switching modes and reclaiming memory by OS. This modification is only for 64 bit mode. More specifically, we keep the AMD logic as the original code flow, extract and update the Intel-related code, where the APs would stay in 64-bit, and run in a Mwait or Hlt loop until the OS wake them up. Signed-off-by: Ray Ni <ray.ni@intel.com> Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
76 lines
2.0 KiB
C
76 lines
2.0 KiB
C
/** @file
|
|
Function to create page talbe.
|
|
Only create page table for x64, and leave the CreatePageTable empty for Ia32.
|
|
|
|
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
#include <Library/CpuPageTableLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Base.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
/**
|
|
Create 1:1 mapping page table in reserved memory to map the specified address range.
|
|
|
|
@param[in] LinearAddress The start of the linear address range.
|
|
@param[in] Length The length of the linear address range.
|
|
|
|
@return The page table to be created.
|
|
**/
|
|
UINTN
|
|
CreatePageTable (
|
|
IN UINTN Address,
|
|
IN UINTN Length
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *PageTableBuffer;
|
|
UINTN PageTableBufferSize;
|
|
UINTN PageTable;
|
|
|
|
IA32_MAP_ATTRIBUTE MapAttribute;
|
|
IA32_MAP_ATTRIBUTE MapMask;
|
|
|
|
MapAttribute.Uint64 = Address;
|
|
MapAttribute.Bits.Present = 1;
|
|
MapAttribute.Bits.ReadWrite = 1;
|
|
|
|
MapMask.Bits.PageTableBaseAddress = 1;
|
|
MapMask.Bits.Present = 1;
|
|
MapMask.Bits.ReadWrite = 1;
|
|
|
|
PageTable = 0;
|
|
PageTableBufferSize = 0;
|
|
|
|
Status = PageTableMap (
|
|
&PageTable,
|
|
Paging4Level,
|
|
NULL,
|
|
&PageTableBufferSize,
|
|
Address,
|
|
Length,
|
|
&MapAttribute,
|
|
&MapMask
|
|
);
|
|
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
|
DEBUG ((DEBUG_INFO, "AP Page Table Buffer Size = %x\n", PageTableBufferSize));
|
|
|
|
PageTableBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
|
|
ASSERT (PageTableBuffer != NULL);
|
|
Status = PageTableMap (
|
|
&PageTable,
|
|
Paging4Level,
|
|
PageTableBuffer,
|
|
&PageTableBufferSize,
|
|
Address,
|
|
Length,
|
|
&MapAttribute,
|
|
&MapMask
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
return PageTable;
|
|
}
|