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