]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
Check-in missing part at r14302.
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / SecPeiDebugAgent / SecPeiDebugAgentLib.c
CommitLineData
18b144ea 1/** @file\r
2 SEC Core Debug Agent Library instance implementition.\r
3\r
b422b62c 4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
18b144ea 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "SecPeiDebugAgentLib.h"\r
16\r
b422b62c 17BOOLEAN mSkipBreakpoint = FALSE;\r
18\r
19EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {\r
20 {\r
21 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
22 &gEfiPeiMemoryDiscoveredPpiGuid,\r
23 DebugAgentCallbackMemoryDiscoveredPpi\r
24 }\r
25};\r
26\r
27/**\r
28 Check if debug agent support multi-processor.\r
29\r
30 @retval TRUE Multi-processor is supported.\r
31 @retval FALSE Multi-processor is not supported.\r
32\r
33**/\r
34BOOLEAN\r
35MultiProcessorDebugSupport (\r
36 VOID\r
37 )\r
38{\r
39 return FALSE;\r
40}\r
18b144ea 41\r
93c0bdec 42/**\r
43 Read the Attach/Break-in symbols from the debug port.\r
44\r
45 @param[in] Handle Pointer to Debug Port handle.\r
46 @param[out] BreakSymbol Returned break symbol.\r
47\r
48 @retval EFI_SUCCESS Read the symbol in BreakSymbol.\r
49 @retval EFI_NOT_FOUND No read the break symbol.\r
50\r
51**/\r
52EFI_STATUS\r
53DebugReadBreakSymbol (\r
54 IN DEBUG_PORT_HANDLE Handle,\r
55 OUT UINT8 *BreakSymbol\r
56 )\r
57{\r
b422b62c 58 EFI_STATUS Status;\r
59 DEBUG_PACKET_HEADER DebugHeader;\r
60 UINT8 *Data8;\r
61\r
93c0bdec 62 *BreakSymbol = 0;\r
63 //\r
b422b62c 64 // If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty.\r
93c0bdec 65 //\r
b422b62c 66 Data8 = (UINT8 *) &DebugHeader;\r
67 while (TRUE) {\r
68 //\r
69 // If start symbol is not received\r
70 //\r
71 if (!DebugPortPollBuffer (Handle)) {\r
72 //\r
73 // If no data in Debug Port, exit\r
74 //\r
75 break;\r
76 }\r
77 //\r
78 // Try to read the start symbol\r
79 //\r
80 DebugPortReadBuffer (Handle, Data8, 1, 0);\r
81 if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {\r
82 *BreakSymbol = *Data8;\r
83 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *BreakSymbol);\r
93c0bdec 84 return EFI_SUCCESS;\r
b422b62c 85 } \r
86 if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {\r
87 Status = ReadRemainingBreakPacket (Handle, &DebugHeader);\r
88 if (Status == EFI_SUCCESS) {\r
89 *BreakSymbol = DebugHeader.Command;\r
90 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", *BreakSymbol);\r
91 return EFI_SUCCESS;\r
92 }\r
93 if (Status == EFI_TIMEOUT) {\r
94 break;\r
95 }\r
93c0bdec 96 }\r
97 }\r
98 \r
99 return EFI_NOT_FOUND;\r
100}\r
101\r
18b144ea 102/**\r
b422b62c 103 Get the pointer to location saved Mailbox pointer from IDT entry.\r
18b144ea 104\r
105**/\r
106VOID *\r
b422b62c 107GetLocationSavedMailboxPointerInIdtEntry (\r
18b144ea 108 VOID\r
109 )\r
110{\r
b422b62c 111 UINTN *MailboxLocation;\r
18b144ea 112\r
b422b62c 113 MailboxLocation = (UINTN *) GetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR);\r
114 //\r
115 // *MailboxLocation is the pointer to Mailbox\r
116 //\r
117 VerifyMailboxChecksum ((DEBUG_AGENT_MAILBOX *) (*MailboxLocation));\r
118 return MailboxLocation;\r
18b144ea 119}\r
120\r
121/**\r
122 Set the pointer of Mailbox into IDT entry before memory is ready.\r
123\r
b422b62c 124 @param[in] MailboxLocation Pointer to location saved Mailbox pointer.\r
18b144ea 125\r
126**/\r
127VOID\r
b422b62c 128SetLocationSavedMailboxPointerInIdtEntry (\r
129 IN VOID *MailboxLocation\r
18b144ea 130 )\r
131{\r
b422b62c 132 SetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR, MailboxLocation);\r
18b144ea 133}\r
134\r
135/**\r
b422b62c 136 Get the location of Mailbox pointer from the GUIDed HOB.\r
18b144ea 137\r
b422b62c 138 @return Pointer to the location saved Mailbox pointer.\r
18b144ea 139\r
140**/\r
b422b62c 141UINT64 *\r
142GetMailboxLocationFromHob (\r
18b144ea 143 VOID\r
144 )\r
145{\r
b422b62c 146 EFI_HOB_GUID_TYPE *GuidHob;\r
18b144ea 147\r
b422b62c 148 GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);\r
149 if (GuidHob == NULL) {\r
150 return NULL;\r
151 }\r
152 return (UINT64 *) (GET_GUID_HOB_DATA(GuidHob));\r
18b144ea 153}\r
154\r
155/**\r
156 Get Debug Agent Mailbox pointer.\r
157\r
158 @return Mailbox pointer.\r
159\r
160**/\r
161DEBUG_AGENT_MAILBOX *\r
162GetMailboxPointer (\r
163 VOID\r
164 )\r
165{\r
b422b62c 166 UINT64 DebugPortHandle;\r
167 UINT64 *MailboxLocationInIdt;\r
168 UINT64 *MailboxLocationInHob;\r
169 DEBUG_AGENT_MAILBOX *Mailbox;\r
170 \r
171 //\r
172 // Get mailbox from IDT entry firstly\r
173 //\r
174 MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry ();\r
175 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt);\r
176 //\r
0a488765 177 // Cannot used GetDebugFlag() to get Debug Flag to avoid GetMailboxPointer() nested\r
b422b62c 178 //\r
0a488765 179 if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1 ||\r
180 Mailbox->DebugFlag.Bits.InitArch != DEBUG_ARCH_SYMBOL) {\r
b422b62c 181 //\r
0a488765 182 // If mailbox was setup in SEC or the current CPU arch is different from the init arch\r
183 // Debug Agent initialized, return the mailbox from IDT entry directly.\r
184 // Otherwise, we need to check the mailbox location saved in GUIDed HOB further.\r
185 // \r
b422b62c 186 return Mailbox;\r
187 }\r
188\r
189 MailboxLocationInHob = GetMailboxLocationFromHob ();\r
190 //\r
0a488765 191 // Compare mailbox in IDT enry with mailbox in HOB,\r
192 // need to fix mailbox location if HOB moved by PEI CORE\r
b422b62c 193 //\r
194 if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) {\r
195 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob);\r
196 //\r
197 // Fix up Debug Port handler and save new mailbox in IDT entry\r
198 //\r
199 Mailbox = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));\r
200 DebugPortHandle = (UINT64)((UINTN)Mailbox->DebugPortHandle + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));\r
201 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
202 *MailboxLocationInHob = (UINT64)(UINTN)Mailbox;\r
203 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);\r
204 //\r
205 // Clean CheckMailboxInHob flag\r
206 //\r
207 Mailbox->DebugFlag.Bits.CheckMailboxInHob = 0;\r
208 UpdateMailboxChecksum (Mailbox);\r
209 }\r
210\r
211 return Mailbox;\r
18b144ea 212}\r
213\r
214/**\r
215 Get debug port handle.\r
216\r
217 @return Debug port handle.\r
218\r
219**/\r
220DEBUG_PORT_HANDLE\r
221GetDebugPortHandle (\r
222 VOID\r
223 )\r
224{\r
225 DEBUG_AGENT_MAILBOX *DebugAgentMailbox;\r
226 \r
b422b62c 227 DebugAgentMailbox = GetMailboxPointer ();\r
18b144ea 228\r
229 return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle);\r
230}\r
231\r
232/**\r
b422b62c 233 Debug Agent provided notify callback function on Memory Discovered PPI.\r
234\r
235 @param[in] PeiServices Indirect reference to the PEI Services Table.\r
236 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
237 @param[in] Ppi Address of the PPI that was installed.\r
18b144ea 238\r
b422b62c 239 @retval EFI_SUCCESS If the function completed successfully.\r
18b144ea 240\r
241**/\r
b422b62c 242EFI_STATUS\r
243EFIAPI\r
244DebugAgentCallbackMemoryDiscoveredPpi (\r
245 IN EFI_PEI_SERVICES **PeiServices,\r
246 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
247 IN VOID *Ppi\r
18b144ea 248 )\r
249{\r
dca18202 250 EFI_STATUS Status;\r
b422b62c 251 DEBUG_AGENT_MAILBOX *Mailbox;\r
252 BOOLEAN InterruptStatus;\r
0a488765 253 EFI_PHYSICAL_ADDRESS Address; \r
dca18202 254 DEBUG_AGENT_MAILBOX *NewMailbox;\r
255 UINT64 *MailboxLocationInHob;\r
256\r
18b144ea 257 //\r
b422b62c 258 // Save and disable original interrupt status\r
18b144ea 259 //\r
b422b62c 260 InterruptStatus = SaveAndDisableInterrupts ();\r
dca18202 261\r
18b144ea 262 //\r
dca18202 263 // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer\r
264 //\r
265 Status = PeiServicesAllocatePages (\r
266 EfiACPIMemoryNVS,\r
267 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),\r
0a488765 268 &Address\r
dca18202 269 );\r
270 ASSERT_EFI_ERROR (Status);\r
0a488765 271 NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;\r
dca18202 272 //\r
273 // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox\r
274 // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core\r
275 // reallocates the HOB.\r
18b144ea 276 //\r
b422b62c 277 Mailbox = GetMailboxPointer ();\r
dca18202 278 CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
279 CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));\r
18b144ea 280 //\r
dca18202 281 // Update Mailbox Location pointer in GUIDed HOB and IDT entry with new one\r
18b144ea 282 //\r
dca18202 283 MailboxLocationInHob = GetMailboxLocationFromHob ();\r
284 *MailboxLocationInHob = (UINT64)(UINTN)NewMailbox;\r
285 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);\r
286 //\r
287 // Update Debug Port Handle in new Mailbox\r
288 //\r
289 UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));\r
290 //\r
291 // Set physical memory ready flag\r
292 //\r
293 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
294\r
b422b62c 295 if (IsHostAttached ()) {\r
296 //\r
297 // Trigger one software interrupt to inform HOST\r
298 //\r
299 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
300 }\r
18b144ea 301\r
302 //\r
b422b62c 303 // Restore interrupt state.\r
18b144ea 304 //\r
b422b62c 305 SetInterruptState (InterruptStatus);\r
306 \r
307 return EFI_SUCCESS;\r
18b144ea 308}\r
309\r
310/**\r
311 Initialize debug agent.\r
312\r
313 This function is used to set up debug environment for SEC and PEI phase.\r
314\r
315 If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries\r
316 and initialize debug port. It will enable interrupt to support break-in feature.\r
317 It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before\r
318 physical memory is ready.\r
319 If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed\r
320 HOB to copy debug agent Mailbox. It will be called after physical memory is ready.\r
321\r
322 This function is used to set up debug environment to support source level debugging.\r
323 If certain Debug Agent Library instance has to save some private data in the stack,\r
324 this function must work on the mode that doesn't return to the caller, then\r
325 the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one\r
326 function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is\r
327 responsible to invoke the passing-in function at the end of InitializeDebugAgent().\r
328\r
329 If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by\r
330 passing in the Context to be its parameter.\r
331\r
332 If Function() is NULL, Debug Agent Library instance will return after setup debug\r
333 environment.\r
334\r
335 @param[in] InitFlag Init flag is used to decide the initialize process.\r
336 @param[in] Context Context needed according to InitFlag; it was optional.\r
337 @param[in] Function Continue function called by debug agent library; it was\r
338 optional.\r
339\r
340**/\r
341VOID\r
342EFIAPI\r
343InitializeDebugAgent (\r
344 IN UINT32 InitFlag,\r
345 IN VOID *Context, OPTIONAL\r
346 IN DEBUG_AGENT_CONTINUE Function OPTIONAL\r
347 )\r
348{\r
349 DEBUG_AGENT_MAILBOX *Mailbox;\r
350 DEBUG_AGENT_MAILBOX MailboxInStack;\r
351 DEBUG_AGENT_PHASE2_CONTEXT Phase2Context;\r
352 DEBUG_AGENT_CONTEXT_POSTMEM_SEC *DebugAgentContext;\r
b422b62c 353 EFI_STATUS Status;\r
354 IA32_DESCRIPTOR *Ia32Idtr;\r
355 IA32_IDT_ENTRY *Ia32IdtEntry;\r
356 UINT64 DebugPortHandle;\r
357 UINT64 MailboxLocation;\r
358 UINT64 *MailboxLocationPointer;\r
359 \r
18b144ea 360 DisableInterrupts ();\r
361\r
e2104834 362 switch (InitFlag) {\r
363\r
364 case DEBUG_AGENT_INIT_PREMEM_SEC:\r
365\r
366 InitializeDebugIdt ();\r
367\r
b422b62c 368 MailboxLocation = (UINT64)(UINTN)&MailboxInStack;\r
e2104834 369 Mailbox = &MailboxInStack;\r
370 ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
e2104834 371 //\r
372 // Get and save debug port handle and set the length of memory block.\r
373 //\r
b422b62c 374 SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);\r
0a488765 375 //\r
376 // Force error message could be printed during the first shakehand between Target/HOST.\r
377 //\r
b422b62c 378 SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);\r
0a488765 379 //\r
380 // Save init arch type when debug agent initialized\r
381 //\r
b6d1508f 382 SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);\r
e2104834 383\r
384 InitializeDebugTimer ();\r
385\r
386 Phase2Context.Context = Context;\r
387 Phase2Context.Function = Function;\r
388 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);\r
e2104834 389 //\r
390 // If reaches here, it means Debug Port initialization failed.\r
391 //\r
392 DEBUG ((EFI_D_ERROR, "Debug Agent: Debug port initialization failed.\n"));\r
393\r
394 break;\r
395\r
396 case DEBUG_AGENT_INIT_POSTMEM_SEC:\r
b422b62c 397 Mailbox = GetMailboxPointer ();\r
18b144ea 398 //\r
399 // Memory has been ready\r
400 //\r
b422b62c 401 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
402 if (IsHostAttached ()) {\r
18b144ea 403 //\r
404 // Trigger one software interrupt to inform HOST\r
405 //\r
406 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
407 }\r
408\r
b422b62c 409 //\r
410 // Fix up Debug Port handle address and mailbox address\r
411 //\r
18b144ea 412 DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;\r
b422b62c 413 DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);\r
414 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
415 Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);\r
416 MailboxLocation = (UINT64)(UINTN)Mailbox;\r
417 //\r
418 // Build mailbox location in HOB and fix-up its address\r
419 //\r
420 MailboxLocationPointer = BuildGuidDataHob (\r
421 &gEfiDebugAgentGuid,\r
422 &MailboxLocation,\r
423 sizeof (UINT64)\r
424 );\r
425 MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);\r
426 //\r
427 // Update IDT entry to save the location saved mailbox pointer\r
428 //\r
429 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
430 //\r
431 // Enable CPU interrupts so debug timer interrupts can be delivered\r
432 //\r
433 EnableInterrupts ();\r
434\r
435 break;\r
436\r
437 case DEBUG_AGENT_INIT_PEI:\r
438 //\r
439 // Check if Debug Agent has initialized before\r
440 //\r
441 if (IsDebugAgentInitialzed()) {\r
442 DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));\r
443 break;\r
444 }\r
445 //\r
446 // Set up IDT entries\r
447 //\r
448 InitializeDebugIdt ();\r
449 //\r
450 // Build mailbox in HOB and setup Mailbox Set In Pei flag\r
451 //\r
452 Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));\r
453 MailboxLocation = (UINT64)(UINTN)Mailbox;\r
454 MailboxLocationPointer = BuildGuidDataHob (\r
455 &gEfiDebugAgentGuid,\r
456 &MailboxLocation,\r
457 sizeof (UINT64)\r
458 );\r
18b144ea 459\r
b422b62c 460 InitializeDebugTimer ();\r
461 //\r
462 // Update IDT entry to save the location pointer saved mailbox pointer\r
463 //\r
464 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
465 //\r
0a488765 466 // Save init arch type when debug agent initialized\r
467 //\r
468 SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);\r
469 //\r
b422b62c 470 // Register for a callback once memory has been initialized.\r
471 // If memery has been ready, the callback funtion will be invoked immediately\r
472 //\r
473 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);\r
474 ASSERT_EFI_ERROR (Status);\r
475 //\r
476 // Set HOB check flag if memory has not been ready yet\r
477 //\r
478 if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {\r
479 SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);\r
480 }\r
18b144ea 481\r
b422b62c 482 Phase2Context.Context = Context;\r
483 Phase2Context.Function = Function;\r
484 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);\r
18b144ea 485\r
b422b62c 486 FindAndReportModuleImageInfo (4);\r
18b144ea 487\r
b422b62c 488 break;\r
18b144ea 489\r
b422b62c 490 case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:\r
491 if (Context == NULL) {\r
492 DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));\r
493 CpuDeadLoop ();\r
494 } else {\r
495 Ia32Idtr = (IA32_DESCRIPTOR *) Context;\r
496 Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);\r
497 MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +\r
498 (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));\r
499 Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);\r
0a488765 500 //\r
501 // Mailbox should valid and setup before executing thunk code\r
502 //\r
b422b62c 503 VerifyMailboxChecksum (Mailbox);\r
504\r
505 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);\r
506 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
507 //\r
508 // Set up IDT entries\r
509 //\r
510 InitializeDebugIdt ();\r
511 //\r
512 // Update IDT entry to save location pointer saved the mailbox pointer\r
513 //\r
514 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
515\r
516 FindAndReportModuleImageInfo (4);\r
517 }\r
e2104834 518 break;\r
18b144ea 519\r
e2104834 520 default:\r
18b144ea 521 //\r
e2104834 522 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this \r
523 // Debug Agent library instance.\r
18b144ea 524 //\r
e2104834 525 DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));\r
526 CpuDeadLoop ();\r
527 break;\r
e2104834 528 }\r
18b144ea 529\r
b422b62c 530 EnableInterrupts ();\r
531\r
e2104834 532 //\r
533 // If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.\r
534 //\r
535 if (Function != NULL) {\r
536 Function (Context);\r
18b144ea 537 }\r
538}\r
539\r
540/**\r
541 Caller provided function to be invoked at the end of DebugPortInitialize().\r
542\r
543 Refer to the descrption for DebugPortInitialize() for more details.\r
544\r
545 @param[in] Context The first input argument of DebugPortInitialize().\r
546 @param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.\r
547\r
548**/\r
549VOID\r
550EFIAPI\r
551InitializeDebugAgentPhase2 (\r
552 IN VOID *Context,\r
553 IN DEBUG_PORT_HANDLE DebugPortHandle\r
554 )\r
555{\r
556 DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context;\r
b422b62c 557 UINT64 *MailboxLocation;\r
18b144ea 558 DEBUG_AGENT_MAILBOX *Mailbox;\r
559 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
b422b62c 560 UINT16 BufferSize;\r
561 UINT64 NewDebugPortHandle;\r
18b144ea 562\r
b422b62c 563 Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context;\r
564 MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry ();\r
565 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);\r
566 BufferSize = PcdGet16(PcdDebugPortHandleBufferSize);\r
567 if (Phase2Context->Function == NULL && DebugPortHandle != NULL && BufferSize != 0) {\r
568 NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle);\r
569 } else {\r
570 NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle;\r
571 }\r
572 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle);\r
18b144ea 573\r
574 //\r
575 // Trigger one software interrupt to inform HOST\r
576 //\r
577 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);\r
578\r
579 //\r
580 // If Temporary RAM region is below 128 MB, then send message to \r
581 // host to disable low memory filtering.\r
582 //\r
18b144ea 583 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context;\r
93c0bdec 584 if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostAttached ()) {\r
b422b62c 585 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
18b144ea 586 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
587 }\r
588\r
589 //\r
590 // Enable CPU interrupts so debug timer interrupts can be delivered\r
591 //\r
592 EnableInterrupts ();\r
593\r
594 //\r
e2104834 595 // Call continuation function if it is not NULL.\r
18b144ea 596 //\r
597 if (Phase2Context->Function != NULL) {\r
598 Phase2Context->Function (Phase2Context->Context);\r
599 }\r
600}\r