TianoCore EDK2 master
Loading...
Searching...
No Matches
HighMemDxe.c
Go to the documentation of this file.
1
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
14#include <Library/PcdLib.h>
16
17#include <Protocol/Cpu.h>
18#include <Protocol/FdtClient.h>
19
21EFIAPI
22InitializeHighMemDxe (
23 IN EFI_HANDLE ImageHandle,
24 IN EFI_SYSTEM_TABLE *SystemTable
25 )
26{
27 FDT_CLIENT_PROTOCOL *FdtClient;
29 EFI_STATUS Status, FindNodeStatus;
30 INT32 Node;
31 CONST UINT32 *Reg;
32 UINT32 RegSize;
33 UINTN AddressCells, SizeCells;
34 UINT64 CurBase;
35 UINT64 CurSize;
36 UINT64 Attributes;
38
39 Status = gBS->LocateProtocol (
40 &gFdtClientProtocolGuid,
41 NULL,
42 (VOID **)&FdtClient
43 );
44 ASSERT_EFI_ERROR (Status);
45
46 Status = gBS->LocateProtocol (
47 &gEfiCpuArchProtocolGuid,
48 NULL,
49 (VOID **)&Cpu
50 );
51 ASSERT_EFI_ERROR (Status);
52
53 //
54 // Check for memory node and add the memory spaces except the lowest one
55 //
56 for (FindNodeStatus = FdtClient->FindMemoryNodeReg (
57 FdtClient,
58 &Node,
59 (CONST VOID **)&Reg,
60 &AddressCells,
61 &SizeCells,
62 &RegSize
63 );
64 !EFI_ERROR (FindNodeStatus);
65 FindNodeStatus = FdtClient->FindNextMemoryNodeReg (
66 FdtClient,
67 Node,
68 &Node,
69 (CONST VOID **)&Reg,
70 &AddressCells,
71 &SizeCells,
72 &RegSize
73 ))
74 {
75 ASSERT (AddressCells <= 2);
76 ASSERT (SizeCells <= 2);
77
78 while (RegSize > 0) {
79 CurBase = SwapBytes32 (*Reg++);
80 if (AddressCells > 1) {
81 CurBase = (CurBase << 32) | SwapBytes32 (*Reg++);
82 }
83
84 CurSize = SwapBytes32 (*Reg++);
85 if (SizeCells > 1) {
86 CurSize = (CurSize << 32) | SwapBytes32 (*Reg++);
87 }
88
89 RegSize -= (AddressCells + SizeCells) * sizeof (UINT32);
90
91 Status = gDS->GetMemorySpaceDescriptor (CurBase, &GcdDescriptor);
92 if (EFI_ERROR (Status)) {
93 DEBUG ((
94 DEBUG_WARN,
95 "%a: Region 0x%lx - 0x%lx not found in the GCD memory space map\n",
96 __func__,
97 CurBase,
98 CurBase + CurSize - 1
99 ));
100 continue;
101 }
102
103 if (GcdDescriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
104 Status = gDS->AddMemorySpace (
106 CurBase,
107 CurSize,
108 EFI_MEMORY_WB
109 );
110
111 if (EFI_ERROR (Status)) {
112 DEBUG ((
113 DEBUG_ERROR,
114 "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",
115 __func__,
116 CurBase,
117 CurBase + CurSize - 1,
118 Status
119 ));
120 continue;
121 }
122
123 Status = gDS->SetMemorySpaceAttributes (
124 CurBase,
125 CurSize,
126 EFI_MEMORY_WB
127 );
128 if (EFI_ERROR (Status)) {
129 DEBUG ((
130 DEBUG_WARN,
131 "%a: gDS->SetMemorySpaceAttributes() failed on region 0x%lx - 0x%lx (%r)\n",
132 __func__,
133 CurBase,
134 CurBase + CurSize - 1,
135 Status
136 ));
137 }
138
139 //
140 // Due to the ambiguous nature of the RO/XP GCD memory space attributes,
141 // it is impossible to add a memory space with the XP attribute in a way
142 // that does not result in the XP attribute being set on *all* UEFI
143 // memory map entries that are carved from it, including code regions
144 // that require executable permissions.
145 //
146 // So instead, we never set the RO/XP attributes in the GCD memory space
147 // capabilities or attribute fields, and apply any protections directly
148 // on the page table mappings by going through the cpu arch protocol.
149 //
150 Attributes = EFI_MEMORY_WB;
151 if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) &
152 (1U << (UINT32)EfiConventionalMemory)) != 0)
153 {
154 Attributes |= EFI_MEMORY_XP;
155 }
156
157 Status = Cpu->SetMemoryAttributes (Cpu, CurBase, CurSize, Attributes);
158
159 if (EFI_ERROR (Status)) {
160 DEBUG ((
161 DEBUG_ERROR,
162 "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",
163 __func__,
164 CurBase,
165 CurBase + CurSize - 1,
166 Status
167 ));
168 } else {
169 DEBUG ((
170 DEBUG_INFO,
171 "%a: Add System RAM @ 0x%lx - 0x%lx\n",
172 __func__,
173 CurBase,
174 CurBase + CurSize - 1
175 ));
176 }
177 }
178 }
179 }
180
181 return EFI_SUCCESS;
182}
UINT64 UINTN
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
EFI_DXE_SERVICES * gDS
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
@ EfiGcdMemoryTypeNonExistent
Definition: PiDxeCis.h:26
@ EfiGcdMemoryTypeSystemMemory
Definition: PiDxeCis.h:38
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiConventionalMemory
EFI_GCD_MEMORY_TYPE GcdMemoryType
Definition: PiDxeCis.h:152