]>
Commit | Line | Data |
---|---|---|
68312710 | 1 | /** @file\r |
47bd85e9 AC |
2 | * High memory node enumeration DXE driver for ARM and RISC-V\r |
3 | * Virtual Machines\r | |
68312710 | 4 | *\r |
490acf89 | 5 | * Copyright (c) 2015-2016, Linaro Ltd. All rights reserved.\r |
68312710 | 6 | *\r |
9792fb0e | 7 | * SPDX-License-Identifier: BSD-2-Clause-Patent\r |
68312710 SZ |
8 | *\r |
9 | **/\r | |
10 | \r | |
11 | #include <Library/BaseLib.h>\r | |
68312710 | 12 | #include <Library/DebugLib.h>\r |
68312710 | 13 | #include <Library/DxeServicesTableLib.h>\r |
490acf89 AB |
14 | #include <Library/PcdLib.h>\r |
15 | #include <Library/UefiBootServicesTableLib.h>\r | |
16 | \r | |
60bd1e12 | 17 | #include <Protocol/Cpu.h>\r |
490acf89 | 18 | #include <Protocol/FdtClient.h>\r |
68312710 SZ |
19 | \r |
20 | EFI_STATUS\r | |
21 | EFIAPI\r | |
22 | InitializeHighMemDxe (\r | |
ac0a286f MK |
23 | IN EFI_HANDLE ImageHandle,\r |
24 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
68312710 SZ |
25 | )\r |
26 | {\r | |
ac0a286f MK |
27 | FDT_CLIENT_PROTOCOL *FdtClient;\r |
28 | EFI_CPU_ARCH_PROTOCOL *Cpu;\r | |
29 | EFI_STATUS Status, FindNodeStatus;\r | |
30 | INT32 Node;\r | |
31 | CONST UINT32 *Reg;\r | |
32 | UINT32 RegSize;\r | |
33 | UINTN AddressCells, SizeCells;\r | |
34 | UINT64 CurBase;\r | |
35 | UINT64 CurSize;\r | |
36 | UINT64 Attributes;\r | |
37 | EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r | |
38 | \r | |
39 | Status = gBS->LocateProtocol (\r | |
40 | &gFdtClientProtocolGuid,\r | |
41 | NULL,\r | |
42 | (VOID **)&FdtClient\r | |
43 | );\r | |
490acf89 | 44 | ASSERT_EFI_ERROR (Status);\r |
68312710 | 45 | \r |
ac0a286f MK |
46 | Status = gBS->LocateProtocol (\r |
47 | &gEfiCpuArchProtocolGuid,\r | |
48 | NULL,\r | |
49 | (VOID **)&Cpu\r | |
50 | );\r | |
60bd1e12 AB |
51 | ASSERT_EFI_ERROR (Status);\r |
52 | \r | |
68312710 | 53 | //\r |
490acf89 | 54 | // Check for memory node and add the memory spaces except the lowest one\r |
68312710 | 55 | //\r |
ac0a286f MK |
56 | for (FindNodeStatus = FdtClient->FindMemoryNodeReg (\r |
57 | FdtClient,\r | |
58 | &Node,\r | |
59 | (CONST VOID **)&Reg,\r | |
60 | &AddressCells,\r | |
61 | &SizeCells,\r | |
62 | &RegSize\r | |
63 | );\r | |
490acf89 | 64 | !EFI_ERROR (FindNodeStatus);\r |
ac0a286f MK |
65 | FindNodeStatus = FdtClient->FindNextMemoryNodeReg (\r |
66 | FdtClient,\r | |
67 | Node,\r | |
68 | &Node,\r | |
69 | (CONST VOID **)&Reg,\r | |
70 | &AddressCells,\r | |
71 | &SizeCells,\r | |
72 | &RegSize\r | |
73 | ))\r | |
74 | {\r | |
490acf89 AB |
75 | ASSERT (AddressCells <= 2);\r |
76 | ASSERT (SizeCells <= 2);\r | |
68312710 | 77 | \r |
490acf89 AB |
78 | while (RegSize > 0) {\r |
79 | CurBase = SwapBytes32 (*Reg++);\r | |
80 | if (AddressCells > 1) {\r | |
81 | CurBase = (CurBase << 32) | SwapBytes32 (*Reg++);\r | |
82 | }\r | |
ac0a286f | 83 | \r |
490acf89 AB |
84 | CurSize = SwapBytes32 (*Reg++);\r |
85 | if (SizeCells > 1) {\r | |
86 | CurSize = (CurSize << 32) | SwapBytes32 (*Reg++);\r | |
87 | }\r | |
ac0a286f | 88 | \r |
490acf89 | 89 | RegSize -= (AddressCells + SizeCells) * sizeof (UINT32);\r |
68312710 | 90 | \r |
5d5a1902 AB |
91 | Status = gDS->GetMemorySpaceDescriptor (CurBase, &GcdDescriptor);\r |
92 | if (EFI_ERROR (Status)) {\r | |
ac0a286f MK |
93 | DEBUG ((\r |
94 | DEBUG_WARN,\r | |
5d5a1902 | 95 | "%a: Region 0x%lx - 0x%lx not found in the GCD memory space map\n",\r |
ac0a286f MK |
96 | __FUNCTION__,\r |
97 | CurBase,\r | |
98 | CurBase + CurSize - 1\r | |
99 | ));\r | |
100 | continue;\r | |
5d5a1902 | 101 | }\r |
ac0a286f | 102 | \r |
5d5a1902 | 103 | if (GcdDescriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r |
ac0a286f MK |
104 | Status = gDS->AddMemorySpace (\r |
105 | EfiGcdMemoryTypeSystemMemory,\r | |
106 | CurBase,\r | |
107 | CurSize,\r | |
108 | EFI_MEMORY_WB\r | |
109 | );\r | |
68312710 | 110 | \r |
490acf89 | 111 | if (EFI_ERROR (Status)) {\r |
ac0a286f MK |
112 | DEBUG ((\r |
113 | DEBUG_ERROR,\r | |
490acf89 | 114 | "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",\r |
ac0a286f MK |
115 | __FUNCTION__,\r |
116 | CurBase,\r | |
117 | CurBase + CurSize - 1,\r | |
118 | Status\r | |
119 | ));\r | |
490acf89 AB |
120 | continue;\r |
121 | }\r | |
68312710 | 122 | \r |
ac0a286f MK |
123 | Status = gDS->SetMemorySpaceAttributes (\r |
124 | CurBase,\r | |
125 | CurSize,\r | |
126 | EFI_MEMORY_WB\r | |
127 | );\r | |
60bd1e12 | 128 | if (EFI_ERROR (Status)) {\r |
ac0a286f MK |
129 | DEBUG ((\r |
130 | DEBUG_WARN,\r | |
60bd1e12 | 131 | "%a: gDS->SetMemorySpaceAttributes() failed on region 0x%lx - 0x%lx (%r)\n",\r |
ac0a286f MK |
132 | __FUNCTION__,\r |
133 | CurBase,\r | |
134 | CurBase + CurSize - 1,\r | |
135 | Status\r | |
136 | ));\r | |
60bd1e12 AB |
137 | }\r |
138 | \r | |
139 | //\r | |
140 | // Due to the ambiguous nature of the RO/XP GCD memory space attributes,\r | |
141 | // it is impossible to add a memory space with the XP attribute in a way\r | |
142 | // that does not result in the XP attribute being set on *all* UEFI\r | |
143 | // memory map entries that are carved from it, including code regions\r | |
144 | // that require executable permissions.\r | |
413edd47 | 145 | //\r |
60bd1e12 AB |
146 | // So instead, we never set the RO/XP attributes in the GCD memory space\r |
147 | // capabilities or attribute fields, and apply any protections directly\r | |
148 | // on the page table mappings by going through the cpu arch protocol.\r | |
413edd47 AB |
149 | //\r |
150 | Attributes = EFI_MEMORY_WB;\r | |
151 | if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) &\r | |
ac0a286f MK |
152 | (1U << (UINT32)EfiConventionalMemory)) != 0)\r |
153 | {\r | |
413edd47 AB |
154 | Attributes |= EFI_MEMORY_XP;\r |
155 | }\r | |
156 | \r | |
60bd1e12 | 157 | Status = Cpu->SetMemoryAttributes (Cpu, CurBase, CurSize, Attributes);\r |
68312710 | 158 | \r |
490acf89 | 159 | if (EFI_ERROR (Status)) {\r |
ac0a286f MK |
160 | DEBUG ((\r |
161 | DEBUG_ERROR,\r | |
490acf89 | 162 | "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",\r |
ac0a286f MK |
163 | __FUNCTION__,\r |
164 | CurBase,\r | |
165 | CurBase + CurSize - 1,\r | |
166 | Status\r | |
167 | ));\r | |
490acf89 | 168 | } else {\r |
ac0a286f MK |
169 | DEBUG ((\r |
170 | DEBUG_INFO,\r | |
171 | "%a: Add System RAM @ 0x%lx - 0x%lx\n",\r | |
172 | __FUNCTION__,\r | |
173 | CurBase,\r | |
174 | CurBase + CurSize - 1\r | |
175 | ));\r | |
68312710 SZ |
176 | }\r |
177 | }\r | |
178 | }\r | |
179 | }\r | |
180 | \r | |
181 | return EFI_SUCCESS;\r | |
182 | }\r |