2 Debug Agent library implementition for Dxe Core and Dxr modules.
4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "DxeDebugAgentLib.h"
17 DEBUG_AGENT_MAILBOX mMailbox
;
18 DEBUG_AGENT_MAILBOX
*mMailboxPointer
;
19 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable
[33];
20 BOOLEAN mDxeCoreFlag
= FALSE
;
21 CONST BOOLEAN MultiProcessorDebugSupport
= TRUE
;
24 Constructor allocates the NVS memory to store Mailbox and install configuration table
25 in system table to store its pointer.
27 @param[in] ImageHandle The firmware allocated handle for the EFI image.
28 @param[in] SystemTable A pointer to the EFI System Table.
30 @retval RETURN_SUCCESS Allocate the global memory space to store guid and function tables.
35 DxeDebugAgentLibConstructor (
36 IN EFI_HANDLE ImageHandle
,
37 IN EFI_SYSTEM_TABLE
*SystemTable
41 EFI_PHYSICAL_ADDRESS Address
;
43 VOID
*EventRegistration
;
46 return RETURN_SUCCESS
;
49 Status
= gBS
->CreateEvent (
52 InstallSerialIoNotification
,
56 ASSERT_EFI_ERROR (Status
);
59 // Register for protocol notifications on this event
62 Status
= gBS
->RegisterProtocolNotify (
68 ASSERT_EFI_ERROR (Status
);
71 Status
= gBS
->AllocatePages (
74 EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX
)),
77 ASSERT_EFI_ERROR (Status
);
80 (UINT8
*) (UINTN
) Address
,
81 (UINT8
*) (UINTN
) mMailboxPointer
,
82 sizeof (DEBUG_AGENT_MAILBOX
)
85 mMailboxPointer
= (DEBUG_AGENT_MAILBOX
*) (UINTN
) Address
;
87 Status
= gBS
->InstallConfigurationTable (&gEfiDebugAgentGuid
, (VOID
*) mMailboxPointer
);
88 ASSERT_EFI_ERROR (Status
);
94 Get the pointer to Mailbox from the GUIDed HOB.
96 @param[in] HobStart The starting HOB pointer to search from.
98 @return Pointer to Mailbox.
101 DEBUG_AGENT_MAILBOX
*
106 EFI_HOB_GUID_TYPE
*GuidHob
;
108 GuidHob
= GetNextGuidHob (&gEfiDebugAgentGuid
, HobStart
);
109 if (GuidHob
== NULL
) {
113 return (DEBUG_AGENT_MAILBOX
*) (GET_GUID_HOB_DATA(GuidHob
));
117 Get Debug Agent Mailbox pointer.
119 @return Mailbox pointer.
122 DEBUG_AGENT_MAILBOX
*
127 return mMailboxPointer
;
131 Get debug port handle.
133 @return Debug port handle.
141 return (DEBUG_PORT_HANDLE
) (UINTN
)(mMailboxPointer
->DebugPortHandle
);
146 Initialize debug agent.
148 This function is used to set up debug enviroment for DXE phase.
150 If this function is called by DXE Core, Context must be the pointer
151 to HOB list which will be used to get GUIDed HOB. It will enable
152 interrupt to support break-in feature.
153 If this function is called by DXE module, Context must be NULL. It
154 will enable interrupt to support break-in feature.
156 @param[in] InitFlag Init flag is used to decide initialize process.
157 @param[in] Context Context needed according to InitFlag.
158 @param[in] Function Continue function called by debug agent library; it was
164 InitializeDebugAgent (
166 IN VOID
*Context
, OPTIONAL
167 IN DEBUG_AGENT_CONTINUE Function OPTIONAL
170 DEBUG_AGENT_MAILBOX
*Mailbox
;
171 IA32_DESCRIPTOR Idtr
;
172 UINT16 IdtEntryCount
;
173 BOOLEAN InterruptStatus
;
175 if (InitFlag
!= DEBUG_AGENT_INIT_DXE_CORE
&&
176 InitFlag
!= DEBUG_AGENT_INIT_S3
&&
177 InitFlag
!= DEBUG_AGENT_INIT_DXE_AP
) {
182 // Save and disable original interrupt status
184 InterruptStatus
= SaveAndDisableInterrupts ();
186 if (InitFlag
== DEBUG_AGENT_INIT_DXE_CORE
) {
188 // Try to get Mailbox from GUIDed HOB.
191 Mailbox
= GetMailboxFromHob (Context
);
194 // Clear Break CPU index value
196 mDebugMpContext
.BreakAtCpuIndex
= (UINT32
) -1;
198 } else if (InitFlag
== DEBUG_AGENT_INIT_DXE_AP
) {
206 // If it is in S3 path, needn't to install configuration table.
211 if (Mailbox
!= NULL
) {
213 // If Mailbox exists, copy it into one global variable.
215 CopyMem (&mMailbox
, Mailbox
, sizeof (DEBUG_AGENT_MAILBOX
));
218 // If Mailbox not exists, used the local Mailbox.
220 ZeroMem (&mMailbox
, sizeof (DEBUG_AGENT_MAILBOX
));
223 mMailboxPointer
= &mMailbox
;
226 // Get original IDT address and size.
228 AsmReadIdtr ((IA32_DESCRIPTOR
*) &Idtr
);
229 IdtEntryCount
= (UINT16
) ((Idtr
.Limit
+ 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR
));
230 if (IdtEntryCount
< 33) {
231 Idtr
.Limit
= (UINT16
) (sizeof (IA32_IDT_GATE_DESCRIPTOR
) * 33 - 1);
232 Idtr
.Base
= (UINTN
) &mIdtEntryTable
;
233 ZeroMem (&mIdtEntryTable
, Idtr
.Limit
+ 1);
234 AsmWriteIdtr ((IA32_DESCRIPTOR
*) &Idtr
);
238 // Initialize the IDT table entries to support source level debug.
240 InitializeDebugIdt ();
243 // Initialize debug communication port
245 mMailboxPointer
->DebugPortHandle
= (UINT64
) (UINTN
)DebugPortInitialize ((VOID
*)(UINTN
)mMailbox
.DebugPortHandle
, NULL
);
247 InitializeSpinLock (&mDebugMpContext
.MpContextSpinLock
);
248 InitializeSpinLock (&mDebugMpContext
.DebugPortSpinLock
);
250 if (InitFlag
== DEBUG_AGENT_INIT_DXE_CORE
) {
252 // Initialize Debug Timer hardware and enable interrupt.
254 InitializeDebugTimer ();
260 // Disable Debug Timer interrupt in S3 path.
262 SaveAndSetDebugTimerInterrupt (FALSE
);
265 // Restore interrupt state.
267 SetInterruptState (InterruptStatus
);