]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
Allocate ACPImemoryNVS type memory to save mailbox and debug port handle buffer since...
[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
177 // Check if mailbox was setup in PEI firstly, cannot used GetDebugFlag() to \r
178 // get CheckMailboxInHob flag to avoid GetMailboxPointer() nesting.\r
179 //\r
180 if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1) {\r
181 //\r
182 // If mailbox in IDT entry has already been the final one\r
183 //\r
184 return Mailbox;\r
185 }\r
186\r
187 MailboxLocationInHob = GetMailboxLocationFromHob ();\r
188 //\r
189 // Compare mailbox in IDT enry with mailbox in HOB\r
190 //\r
191 if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) {\r
192 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob);\r
193 //\r
194 // Fix up Debug Port handler and save new mailbox in IDT entry\r
195 //\r
196 Mailbox = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));\r
197 DebugPortHandle = (UINT64)((UINTN)Mailbox->DebugPortHandle + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));\r
198 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
199 *MailboxLocationInHob = (UINT64)(UINTN)Mailbox;\r
200 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);\r
201 //\r
202 // Clean CheckMailboxInHob flag\r
203 //\r
204 Mailbox->DebugFlag.Bits.CheckMailboxInHob = 0;\r
205 UpdateMailboxChecksum (Mailbox);\r
206 }\r
207\r
208 return Mailbox;\r
18b144ea 209}\r
210\r
211/**\r
212 Get debug port handle.\r
213\r
214 @return Debug port handle.\r
215\r
216**/\r
217DEBUG_PORT_HANDLE\r
218GetDebugPortHandle (\r
219 VOID\r
220 )\r
221{\r
222 DEBUG_AGENT_MAILBOX *DebugAgentMailbox;\r
223 \r
b422b62c 224 DebugAgentMailbox = GetMailboxPointer ();\r
18b144ea 225\r
226 return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle);\r
227}\r
228\r
229/**\r
b422b62c 230 Debug Agent provided notify callback function on Memory Discovered PPI.\r
231\r
232 @param[in] PeiServices Indirect reference to the PEI Services Table.\r
233 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
234 @param[in] Ppi Address of the PPI that was installed.\r
18b144ea 235\r
b422b62c 236 @retval EFI_SUCCESS If the function completed successfully.\r
18b144ea 237\r
238**/\r
b422b62c 239EFI_STATUS\r
240EFIAPI\r
241DebugAgentCallbackMemoryDiscoveredPpi (\r
242 IN EFI_PEI_SERVICES **PeiServices,\r
243 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
244 IN VOID *Ppi\r
18b144ea 245 )\r
246{\r
dca18202 247 EFI_STATUS Status;\r
b422b62c 248 DEBUG_AGENT_MAILBOX *Mailbox;\r
249 BOOLEAN InterruptStatus;\r
dca18202 250 EFI_PHYSICAL_ADDRESS Memory; \r
251 DEBUG_AGENT_MAILBOX *NewMailbox;\r
252 UINT64 *MailboxLocationInHob;\r
253\r
18b144ea 254 //\r
b422b62c 255 // Save and disable original interrupt status\r
18b144ea 256 //\r
b422b62c 257 InterruptStatus = SaveAndDisableInterrupts ();\r
dca18202 258\r
18b144ea 259 //\r
dca18202 260 // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer\r
261 //\r
262 Status = PeiServicesAllocatePages (\r
263 EfiACPIMemoryNVS,\r
264 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),\r
265 &Memory\r
266 );\r
267 ASSERT_EFI_ERROR (Status);\r
268 NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Memory;\r
269 //\r
270 // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox\r
271 // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core\r
272 // reallocates the HOB.\r
18b144ea 273 //\r
b422b62c 274 Mailbox = GetMailboxPointer ();\r
dca18202 275 CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
276 CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));\r
18b144ea 277 //\r
dca18202 278 // Update Mailbox Location pointer in GUIDed HOB and IDT entry with new one\r
18b144ea 279 //\r
dca18202 280 MailboxLocationInHob = GetMailboxLocationFromHob ();\r
281 *MailboxLocationInHob = (UINT64)(UINTN)NewMailbox;\r
282 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);\r
283 //\r
284 // Update Debug Port Handle in new Mailbox\r
285 //\r
286 UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));\r
287 //\r
288 // Set physical memory ready flag\r
289 //\r
290 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
291\r
b422b62c 292 if (IsHostAttached ()) {\r
293 //\r
294 // Trigger one software interrupt to inform HOST\r
295 //\r
296 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
297 }\r
18b144ea 298\r
299 //\r
b422b62c 300 // Restore interrupt state.\r
18b144ea 301 //\r
b422b62c 302 SetInterruptState (InterruptStatus);\r
303 \r
304 return EFI_SUCCESS;\r
18b144ea 305}\r
306\r
307/**\r
308 Initialize debug agent.\r
309\r
310 This function is used to set up debug environment for SEC and PEI phase.\r
311\r
312 If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries\r
313 and initialize debug port. It will enable interrupt to support break-in feature.\r
314 It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before\r
315 physical memory is ready.\r
316 If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed\r
317 HOB to copy debug agent Mailbox. It will be called after physical memory is ready.\r
318\r
319 This function is used to set up debug environment to support source level debugging.\r
320 If certain Debug Agent Library instance has to save some private data in the stack,\r
321 this function must work on the mode that doesn't return to the caller, then\r
322 the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one\r
323 function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is\r
324 responsible to invoke the passing-in function at the end of InitializeDebugAgent().\r
325\r
326 If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by\r
327 passing in the Context to be its parameter.\r
328\r
329 If Function() is NULL, Debug Agent Library instance will return after setup debug\r
330 environment.\r
331\r
332 @param[in] InitFlag Init flag is used to decide the initialize process.\r
333 @param[in] Context Context needed according to InitFlag; it was optional.\r
334 @param[in] Function Continue function called by debug agent library; it was\r
335 optional.\r
336\r
337**/\r
338VOID\r
339EFIAPI\r
340InitializeDebugAgent (\r
341 IN UINT32 InitFlag,\r
342 IN VOID *Context, OPTIONAL\r
343 IN DEBUG_AGENT_CONTINUE Function OPTIONAL\r
344 )\r
345{\r
346 DEBUG_AGENT_MAILBOX *Mailbox;\r
347 DEBUG_AGENT_MAILBOX MailboxInStack;\r
348 DEBUG_AGENT_PHASE2_CONTEXT Phase2Context;\r
349 DEBUG_AGENT_CONTEXT_POSTMEM_SEC *DebugAgentContext;\r
b422b62c 350 EFI_STATUS Status;\r
351 IA32_DESCRIPTOR *Ia32Idtr;\r
352 IA32_IDT_ENTRY *Ia32IdtEntry;\r
353 UINT64 DebugPortHandle;\r
354 UINT64 MailboxLocation;\r
355 UINT64 *MailboxLocationPointer;\r
356 \r
18b144ea 357 DisableInterrupts ();\r
358\r
e2104834 359 switch (InitFlag) {\r
360\r
361 case DEBUG_AGENT_INIT_PREMEM_SEC:\r
362\r
363 InitializeDebugIdt ();\r
364\r
b422b62c 365 MailboxLocation = (UINT64)(UINTN)&MailboxInStack;\r
e2104834 366 Mailbox = &MailboxInStack;\r
367 ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
e2104834 368 //\r
369 // Get and save debug port handle and set the length of memory block.\r
370 //\r
b422b62c 371 SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);\r
372 SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);\r
e2104834 373\r
374 InitializeDebugTimer ();\r
375\r
376 Phase2Context.Context = Context;\r
377 Phase2Context.Function = Function;\r
378 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);\r
e2104834 379 //\r
380 // If reaches here, it means Debug Port initialization failed.\r
381 //\r
382 DEBUG ((EFI_D_ERROR, "Debug Agent: Debug port initialization failed.\n"));\r
383\r
384 break;\r
385\r
386 case DEBUG_AGENT_INIT_POSTMEM_SEC:\r
b422b62c 387 Mailbox = GetMailboxPointer ();\r
18b144ea 388 //\r
389 // Memory has been ready\r
390 //\r
b422b62c 391 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
392 if (IsHostAttached ()) {\r
18b144ea 393 //\r
394 // Trigger one software interrupt to inform HOST\r
395 //\r
396 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
397 }\r
398\r
b422b62c 399 //\r
400 // Fix up Debug Port handle address and mailbox address\r
401 //\r
18b144ea 402 DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;\r
b422b62c 403 DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);\r
404 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
405 Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);\r
406 MailboxLocation = (UINT64)(UINTN)Mailbox;\r
407 //\r
408 // Build mailbox location in HOB and fix-up its address\r
409 //\r
410 MailboxLocationPointer = BuildGuidDataHob (\r
411 &gEfiDebugAgentGuid,\r
412 &MailboxLocation,\r
413 sizeof (UINT64)\r
414 );\r
415 MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);\r
416 //\r
417 // Update IDT entry to save the location saved mailbox pointer\r
418 //\r
419 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
420 //\r
421 // Enable CPU interrupts so debug timer interrupts can be delivered\r
422 //\r
423 EnableInterrupts ();\r
424\r
425 break;\r
426\r
427 case DEBUG_AGENT_INIT_PEI:\r
428 //\r
429 // Check if Debug Agent has initialized before\r
430 //\r
431 if (IsDebugAgentInitialzed()) {\r
432 DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));\r
433 break;\r
434 }\r
435 //\r
436 // Set up IDT entries\r
437 //\r
438 InitializeDebugIdt ();\r
439 //\r
440 // Build mailbox in HOB and setup Mailbox Set In Pei flag\r
441 //\r
442 Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));\r
443 MailboxLocation = (UINT64)(UINTN)Mailbox;\r
444 MailboxLocationPointer = BuildGuidDataHob (\r
445 &gEfiDebugAgentGuid,\r
446 &MailboxLocation,\r
447 sizeof (UINT64)\r
448 );\r
18b144ea 449\r
b422b62c 450 InitializeDebugTimer ();\r
451 //\r
452 // Update IDT entry to save the location pointer saved mailbox pointer\r
453 //\r
454 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
455 //\r
456 // Register for a callback once memory has been initialized.\r
457 // If memery has been ready, the callback funtion will be invoked immediately\r
458 //\r
459 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);\r
460 ASSERT_EFI_ERROR (Status);\r
461 //\r
462 // Set HOB check flag if memory has not been ready yet\r
463 //\r
464 if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {\r
465 SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);\r
466 }\r
18b144ea 467\r
b422b62c 468 Phase2Context.Context = Context;\r
469 Phase2Context.Function = Function;\r
470 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);\r
18b144ea 471\r
b422b62c 472 FindAndReportModuleImageInfo (4);\r
18b144ea 473\r
b422b62c 474 break;\r
18b144ea 475\r
b422b62c 476 case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:\r
477 if (Context == NULL) {\r
478 DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));\r
479 CpuDeadLoop ();\r
480 } else {\r
481 Ia32Idtr = (IA32_DESCRIPTOR *) Context;\r
482 Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);\r
483 MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +\r
484 (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));\r
485 Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);\r
486 VerifyMailboxChecksum (Mailbox);\r
487\r
488 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);\r
489 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);\r
490 //\r
491 // Set up IDT entries\r
492 //\r
493 InitializeDebugIdt ();\r
494 //\r
495 // Update IDT entry to save location pointer saved the mailbox pointer\r
496 //\r
497 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
498\r
499 FindAndReportModuleImageInfo (4);\r
500 }\r
e2104834 501 break;\r
18b144ea 502\r
e2104834 503 default:\r
18b144ea 504 //\r
e2104834 505 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this \r
506 // Debug Agent library instance.\r
18b144ea 507 //\r
e2104834 508 DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));\r
509 CpuDeadLoop ();\r
510 break;\r
18b144ea 511\r
e2104834 512 }\r
18b144ea 513\r
b422b62c 514 EnableInterrupts ();\r
515\r
e2104834 516 //\r
517 // If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.\r
518 //\r
519 if (Function != NULL) {\r
520 Function (Context);\r
18b144ea 521 }\r
522}\r
523\r
524/**\r
525 Caller provided function to be invoked at the end of DebugPortInitialize().\r
526\r
527 Refer to the descrption for DebugPortInitialize() for more details.\r
528\r
529 @param[in] Context The first input argument of DebugPortInitialize().\r
530 @param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.\r
531\r
532**/\r
533VOID\r
534EFIAPI\r
535InitializeDebugAgentPhase2 (\r
536 IN VOID *Context,\r
537 IN DEBUG_PORT_HANDLE DebugPortHandle\r
538 )\r
539{\r
540 DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context;\r
b422b62c 541 UINT64 *MailboxLocation;\r
18b144ea 542 DEBUG_AGENT_MAILBOX *Mailbox;\r
543 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
b422b62c 544 UINT16 BufferSize;\r
545 UINT64 NewDebugPortHandle;\r
18b144ea 546\r
b422b62c 547 Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context;\r
548 MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry ();\r
549 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);\r
550 BufferSize = PcdGet16(PcdDebugPortHandleBufferSize);\r
551 if (Phase2Context->Function == NULL && DebugPortHandle != NULL && BufferSize != 0) {\r
552 NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle);\r
553 } else {\r
554 NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle;\r
555 }\r
556 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle);\r
18b144ea 557\r
558 //\r
559 // Trigger one software interrupt to inform HOST\r
560 //\r
561 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);\r
562\r
563 //\r
564 // If Temporary RAM region is below 128 MB, then send message to \r
565 // host to disable low memory filtering.\r
566 //\r
18b144ea 567 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context;\r
93c0bdec 568 if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostAttached ()) {\r
b422b62c 569 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);\r
18b144ea 570 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
571 }\r
572\r
573 //\r
574 // Enable CPU interrupts so debug timer interrupts can be delivered\r
575 //\r
576 EnableInterrupts ();\r
577\r
578 //\r
e2104834 579 // Call continuation function if it is not NULL.\r
18b144ea 580 //\r
581 if (Phase2Context->Function != NULL) {\r
582 Phase2Context->Function (Phase2Context->Context);\r
583 }\r
584}\r