]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c
ArmPkg/ArmMmuLib AARCH64: avoid EL0 accessible mappings
[mirror_edk2.git] / ArmPkg / Library / DebugAgentSymbolsBaseLib / DebugAgentSymbolsBaseLib.c
CommitLineData
65cd89d0 1/** @file\r
2* Main file supporting the SEC Phase for Versatile Express\r
3*\r
6d0ca257 4* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
65cd89d0 5*\r
4059386c 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
65cd89d0 7*\r
8**/\r
9\r
10#include <Uefi.h>\r
11#include <Library/BaseLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/DebugAgentLib.h>\r
15#include <Library/PcdLib.h>\r
16#include <Library/PeCoffExtraActionLib.h>\r
17#include <Library/PeCoffLib.h>\r
18\r
19#include <Pi/PiFirmwareFile.h>\r
20#include <Pi/PiFirmwareVolume.h>\r
21\r
22#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
23 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
24\r
9d6b024d 25// Vector Table for Sec Phase\r
26VOID\r
27DebugAgentVectorTable (\r
28 VOID\r
29 );\r
30\r
65cd89d0 31/**\r
32 Returns the highest bit set of the State field\r
33\r
34 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY\r
35 in the Attributes field.\r
36 @param FfsHeader Pointer to FFS File Header\r
37\r
38\r
39 @retval the highest bit in the State field\r
40\r
41**/\r
42STATIC\r
43EFI_FFS_FILE_STATE\r
44GetFileState (\r
45 IN UINT8 ErasePolarity,\r
46 IN EFI_FFS_FILE_HEADER *FfsHeader\r
47 )\r
48{\r
49 EFI_FFS_FILE_STATE FileState;\r
50 EFI_FFS_FILE_STATE HighestBit;\r
51\r
52 FileState = FfsHeader->State;\r
53\r
54 if (ErasePolarity != 0) {\r
429309e0 55 FileState = (EFI_FFS_FILE_STATE) ~FileState;\r
65cd89d0 56 }\r
57\r
58 HighestBit = 0x80;\r
59 while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
60 HighestBit >>= 1;\r
61 }\r
62\r
63 return HighestBit;\r
64}\r
65\r
66/**\r
67 Calculates the checksum of the header of a file.\r
68 The header is a zero byte checksum, so zero means header is good\r
69\r
70 @param FfsHeader Pointer to FFS File Header\r
71\r
72 @retval Checksum of the header\r
73\r
74**/\r
75STATIC\r
76UINT8\r
77CalculateHeaderChecksum (\r
78 IN EFI_FFS_FILE_HEADER *FileHeader\r
79 )\r
80{\r
429309e0 81 UINT8 Sum;\r
65cd89d0 82\r
83 // Calculate the sum of the header\r
429309e0 84 Sum = CalculateSum8 ((CONST VOID *)FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
65cd89d0 85\r
86 // State field (since this indicates the different state of file).\r
87 Sum = (UINT8)(Sum - FileHeader->State);\r
88\r
89 // Checksum field of the file is not part of the header checksum.\r
90 Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);\r
91\r
92 return Sum;\r
93}\r
94\r
95EFI_STATUS\r
96GetFfsFile (\r
429309e0
MK
97 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
98 IN EFI_FV_FILETYPE FileType,\r
99 OUT EFI_FFS_FILE_HEADER **FileHeader\r
65cd89d0 100 )\r
101{\r
429309e0
MK
102 UINT64 FvLength;\r
103 UINTN FileOffset;\r
104 EFI_FFS_FILE_HEADER *FfsFileHeader;\r
105 UINT8 ErasePolarity;\r
106 UINT8 FileState;\r
107 UINT32 FileLength;\r
108 UINT32 FileOccupiedSize;\r
65cd89d0 109\r
110 ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);\r
111\r
429309e0 112 FvLength = FwVolHeader->FvLength;\r
65cd89d0 113 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
429309e0 114 FileOffset = FwVolHeader->HeaderLength;\r
65cd89d0 115\r
116 if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
117 ErasePolarity = 1;\r
118 } else {\r
119 ErasePolarity = 0;\r
120 }\r
121\r
122 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
123 // Get FileState which is the highest bit of the State\r
124 FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
125\r
126 switch (FileState) {\r
429309e0
MK
127 case EFI_FILE_HEADER_INVALID:\r
128 FileOffset += sizeof (EFI_FFS_FILE_HEADER);\r
129 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
130 break;\r
65cd89d0 131\r
429309e0
MK
132 case EFI_FILE_DATA_VALID:\r
133 case EFI_FILE_MARKED_FOR_UPDATE:\r
134 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
135 ASSERT (FALSE);\r
136 return EFI_NOT_FOUND;\r
137 }\r
65cd89d0 138\r
429309e0
MK
139 if (FfsFileHeader->Type == FileType) {\r
140 *FileHeader = FfsFileHeader;\r
141 return EFI_SUCCESS;\r
142 }\r
65cd89d0 143\r
429309e0
MK
144 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
145 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
65cd89d0 146\r
429309e0
MK
147 FileOffset += FileOccupiedSize;\r
148 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
149 break;\r
65cd89d0 150\r
429309e0
MK
151 case EFI_FILE_DELETED:\r
152 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
153 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
154 FileOffset += FileOccupiedSize;\r
155 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
156 break;\r
65cd89d0 157\r
429309e0
MK
158 default:\r
159 return EFI_NOT_FOUND;\r
65cd89d0 160 }\r
161 }\r
429309e0 162\r
65cd89d0 163 return EFI_NOT_FOUND;\r
164}\r
165\r
166EFI_STATUS\r
167GetImageContext (\r
168 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
169 OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
170 )\r
171{\r
429309e0
MK
172 EFI_STATUS Status;\r
173 UINTN ParsedLength;\r
174 UINTN SectionSize;\r
175 UINTN SectionLength;\r
176 EFI_COMMON_SECTION_HEADER *Section;\r
177 VOID *EfiImage;\r
178 UINTN ImageAddress;\r
179 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
180 VOID *CodeViewEntryPointer;\r
181\r
182 Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);\r
183 SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;\r
65cd89d0 184 SectionSize -= sizeof (EFI_FFS_FILE_HEADER);\r
185 ParsedLength = 0;\r
429309e0 186 EfiImage = NULL;\r
65cd89d0 187\r
188 while (ParsedLength < SectionSize) {\r
189 if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {\r
429309e0 190 EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Section + 1);\r
65cd89d0 191 break;\r
192 }\r
193\r
194 //\r
195 // Size is 24 bits wide so mask upper 8 bits.\r
196 // SectionLength is adjusted it is 4 byte aligned.\r
197 // Go to the next section\r
198 //\r
199 SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
200 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
201 ASSERT (SectionLength != 0);\r
202 ParsedLength += SectionLength;\r
429309e0 203 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
65cd89d0 204 }\r
205\r
206 if (EfiImage == NULL) {\r
207 return EFI_NOT_FOUND;\r
208 }\r
209\r
210 // Initialize the Image Context\r
211 ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
212 ImageContext->Handle = EfiImage;\r
213 ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;\r
214\r
215 Status = PeCoffLoaderGetImageInfo (ImageContext);\r
429309e0 216 if (!EFI_ERROR (Status) && ((VOID *)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {\r
65cd89d0 217 ImageAddress = ImageContext->ImageAddress;\r
218 if (ImageContext->IsTeImage) {\r
429309e0 219 ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER *)EfiImage)->StrippedSize;\r
65cd89d0 220 }\r
221\r
429309e0 222 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(ImageAddress + ImageContext->DebugDirectoryEntryRva);\r
65cd89d0 223 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
429309e0
MK
224 CodeViewEntryPointer = (VOID *)(ImageAddress + (UINTN)DebugEntry->RVA);\r
225 switch (*(UINT32 *)CodeViewEntryPointer) {\r
226 case CODEVIEW_SIGNATURE_NB10:\r
227 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
228 break;\r
229 case CODEVIEW_SIGNATURE_RSDS:\r
230 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
231 break;\r
232 case CODEVIEW_SIGNATURE_MTOC:\r
233 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);\r
234 break;\r
235 default:\r
236 break;\r
65cd89d0 237 }\r
238 }\r
239 }\r
240\r
241 return Status;\r
242}\r
243\r
244/**\r
245 Initialize debug agent.\r
246\r
247 This function is used to set up debug environment to support source level debugging.\r
248 If certain Debug Agent Library instance has to save some private data in the stack,\r
249 this function must work on the mode that doesn't return to the caller, then\r
250 the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one\r
251 function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is\r
252 responsible to invoke the passing-in function at the end of InitializeDebugAgent().\r
253\r
d0d8a17d 254 If the parameter Function is not NULL, Debug Agent Library instance will invoke it by\r
65cd89d0 255 passing in the Context to be its parameter.\r
256\r
257 If Function() is NULL, Debug Agent Library instance will return after setup debug\r
258 environment.\r
259\r
260 @param[in] InitFlag Init flag is used to decide the initialize process.\r
261 @param[in] Context Context needed according to InitFlag; it was optional.\r
262 @param[in] Function Continue function called by debug agent library; it was\r
263 optional.\r
264\r
265**/\r
266VOID\r
267EFIAPI\r
268InitializeDebugAgent (\r
269 IN UINT32 InitFlag,\r
1871d28e 270 IN VOID *Context OPTIONAL,\r
65cd89d0 271 IN DEBUG_AGENT_CONTINUE Function OPTIONAL\r
272 )\r
273{\r
429309e0
MK
274 EFI_STATUS Status;\r
275 EFI_FFS_FILE_HEADER *FfsHeader;\r
65cd89d0 276 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
277\r
d0d8a17d 278 // We use InitFlag to know if DebugAgent has been initialized from\r
65cd89d0 279 // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)\r
280 // modules\r
281 if (InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {\r
282 //\r
cc1e8149 283 // Get the Sec or PrePeiCore module (defined as SEC type module)\r
65cd89d0 284 //\r
429309e0
MK
285 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdSecureFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);\r
286 if (!EFI_ERROR (Status)) {\r
287 Status = GetImageContext (FfsHeader, &ImageContext);\r
288 if (!EFI_ERROR (Status)) {\r
65cd89d0 289 PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
290 }\r
291 }\r
292 } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {\r
293 //\r
294 // Get the PrePi or PrePeiCore module (defined as SEC type module)\r
295 //\r
429309e0
MK
296 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);\r
297 if (!EFI_ERROR (Status)) {\r
298 Status = GetImageContext (FfsHeader, &ImageContext);\r
299 if (!EFI_ERROR (Status)) {\r
65cd89d0 300 PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
301 }\r
302 }\r
303\r
304 //\r
305 // Get the PeiCore module (defined as PEI_CORE type module)\r
306 //\r
429309e0
MK
307 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_PEI_CORE, &FfsHeader);\r
308 if (!EFI_ERROR (Status)) {\r
309 Status = GetImageContext (FfsHeader, &ImageContext);\r
310 if (!EFI_ERROR (Status)) {\r
65cd89d0 311 PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
312 }\r
313 }\r
314 }\r
315}\r
316\r
317/**\r
318 Enable/Disable the interrupt of debug timer and return the interrupt state\r
319 prior to the operation.\r
320\r
321 If EnableStatus is TRUE, enable the interrupt of debug timer.\r
322 If EnableStatus is FALSE, disable the interrupt of debug timer.\r
323\r
324 @param[in] EnableStatus Enable/Disable.\r
325\r
326 @return FALSE always.\r
327\r
328**/\r
329BOOLEAN\r
330EFIAPI\r
331SaveAndSetDebugTimerInterrupt (\r
429309e0 332 IN BOOLEAN EnableStatus\r
65cd89d0 333 )\r
334{\r
335 return FALSE;\r
336}\r