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