1 | /** @file
|
---|
2 | x64-specifc functionality for DxeLoad.
|
---|
3 |
|
---|
4 | Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
|
---|
5 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
6 |
|
---|
7 | **/
|
---|
8 |
|
---|
9 | #include <PiPei.h>
|
---|
10 | #include <Library/BaseLib.h>
|
---|
11 | #include <Library/DebugLib.h>
|
---|
12 | #include <Library/BaseMemoryLib.h>
|
---|
13 | #include <Library/MemoryAllocationLib.h>
|
---|
14 | #include <Library/PcdLib.h>
|
---|
15 | #include <Library/HobLib.h>
|
---|
16 | #include "X64/VirtualMemory.h"
|
---|
17 | #include "UefiPayloadEntry.h"
|
---|
18 | #define STACK_SIZE 0x20000
|
---|
19 |
|
---|
20 | /**
|
---|
21 | Transfers control to DxeCore.
|
---|
22 |
|
---|
23 | This function performs a CPU architecture specific operations to execute
|
---|
24 | the entry point of DxeCore with the parameters of HobList.
|
---|
25 | It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
|
---|
26 |
|
---|
27 | @param DxeCoreEntryPoint The entry point of DxeCore.
|
---|
28 | @param HobList The start of HobList passed to DxeCore.
|
---|
29 |
|
---|
30 | **/
|
---|
31 | VOID
|
---|
32 | HandOffToDxeCore (
|
---|
33 | IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
|
---|
34 | IN EFI_PEI_HOB_POINTERS HobList
|
---|
35 | )
|
---|
36 | {
|
---|
37 | VOID *BaseOfStack;
|
---|
38 | VOID *TopOfStack;
|
---|
39 | UINTN PageTables;
|
---|
40 | VOID *GhcbBase;
|
---|
41 | UINTN GhcbSize;
|
---|
42 |
|
---|
43 | //
|
---|
44 | // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
|
---|
45 | //
|
---|
46 | if (IsNullDetectionEnabled ()) {
|
---|
47 | ClearFirst4KPage (HobList.Raw);
|
---|
48 | BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
|
---|
49 | }
|
---|
50 |
|
---|
51 | //
|
---|
52 | // Allocate 128KB for the Stack
|
---|
53 | //
|
---|
54 | BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
|
---|
55 | ASSERT (BaseOfStack != NULL);
|
---|
56 |
|
---|
57 | //
|
---|
58 | // Compute the top of the stack we were allocated. Pre-allocate a UINTN
|
---|
59 | // for safety.
|
---|
60 | //
|
---|
61 | TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
|
---|
62 | TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
---|
63 |
|
---|
64 | //
|
---|
65 | // Get the address and size of the GHCB pages
|
---|
66 | //
|
---|
67 | GhcbBase = 0;
|
---|
68 | GhcbSize = 0;
|
---|
69 |
|
---|
70 | PageTables = 0;
|
---|
71 | if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
|
---|
72 | //
|
---|
73 | // Create page table and save PageMapLevel4 to CR3
|
---|
74 | //
|
---|
75 | PageTables = CreateIdentityMappingPageTables (
|
---|
76 | (EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack,
|
---|
77 | STACK_SIZE,
|
---|
78 | (EFI_PHYSICAL_ADDRESS)(UINTN)GhcbBase,
|
---|
79 | GhcbSize
|
---|
80 | );
|
---|
81 | } else {
|
---|
82 | //
|
---|
83 | // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
|
---|
84 | // for the DxeIpl and the DxeCore are both X64.
|
---|
85 | //
|
---|
86 | ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
|
---|
87 | ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
|
---|
88 | }
|
---|
89 |
|
---|
90 | if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
|
---|
91 | AsmWriteCr3 (PageTables);
|
---|
92 | }
|
---|
93 |
|
---|
94 | //
|
---|
95 | // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
|
---|
96 | //
|
---|
97 | UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, STACK_SIZE);
|
---|
98 |
|
---|
99 | //
|
---|
100 | // Transfer the control to the entry point of DxeCore.
|
---|
101 | //
|
---|
102 | SwitchStack (
|
---|
103 | (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
---|
104 | HobList.Raw,
|
---|
105 | NULL,
|
---|
106 | TopOfStack
|
---|
107 | );
|
---|
108 | }
|
---|