2 SEC Core Debug Agent Library instance implementition.
4 Copyright (c) 2010 - 2011, 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 "SecPeiDebugAgentLib.h"
17 CONST BOOLEAN MultiProcessorDebugSupport
= FALSE
;
20 Get pointer to Mailbox from IDT entry before memory is ready.
24 GetMailboxPointerInIdtEntry (
28 IA32_IDT_GATE_DESCRIPTOR
*IdtEntry
;
29 IA32_DESCRIPTOR IdtDescriptor
;
32 AsmReadIdtr (&IdtDescriptor
);
33 IdtEntry
= (IA32_IDT_GATE_DESCRIPTOR
*) IdtDescriptor
.Base
;
35 Mailbox
= IdtEntry
[DEBUG_MAILBOX_VECTOR
].Bits
.OffsetLow
+ (IdtEntry
[DEBUG_MAILBOX_VECTOR
].Bits
.OffsetHigh
<< 16);
36 return (VOID
*) Mailbox
;
40 Set the pointer of Mailbox into IDT entry before memory is ready.
42 @param[in] Mailbox The pointer of Mailbox.
46 SetMailboxPointerInIdtEntry (
50 IA32_IDT_GATE_DESCRIPTOR
*IdtEntry
;
51 IA32_DESCRIPTOR IdtDescriptor
;
53 AsmReadIdtr (&IdtDescriptor
);
54 IdtEntry
= (IA32_IDT_GATE_DESCRIPTOR
*) IdtDescriptor
.Base
;
56 IdtEntry
[DEBUG_MAILBOX_VECTOR
].Bits
.OffsetLow
= (UINT16
)(UINTN
)Mailbox
;
57 IdtEntry
[DEBUG_MAILBOX_VECTOR
].Bits
.OffsetHigh
= (UINT16
)((UINTN
)Mailbox
>> 16);
61 Get the pointer to Mailbox from IDT entry and build the Mailbox into GUIDed Hob
62 after memory is ready.
64 @return Pointer to Mailbox.
72 DEBUG_AGENT_MAILBOX
*Mailbox
;
74 Mailbox
= (DEBUG_AGENT_MAILBOX
*) GetMailboxPointerInIdtEntry ();
76 return BuildGuidDataHob (
79 sizeof (DEBUG_AGENT_MAILBOX
)
84 Get Debug Agent Mailbox pointer.
86 @return Mailbox pointer.
94 return (DEBUG_AGENT_MAILBOX
*) GetMailboxPointerInIdtEntry ();
98 Get debug port handle.
100 @return Debug port handle.
108 DEBUG_AGENT_MAILBOX
*DebugAgentMailbox
;
110 DebugAgentMailbox
= (DEBUG_AGENT_MAILBOX
*)GetMailboxPointerInIdtEntry ();
112 return (DEBUG_PORT_HANDLE
) (UINTN
)(DebugAgentMailbox
->DebugPortHandle
);
116 Trigger one software interrupt to debug agent to handle it.
118 @param Signature Software interrupt signature.
122 TriggerSoftInterrupt (
130 // Save Debug Register State
138 AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE
);
139 AsmWriteDr1 (Signature
);
142 // Do INT3 to communicate with HOST side
147 // Restore Debug Register State only when Host didn't change it inside exception handler.
148 // Dr registers can only be changed by setting the HW breakpoint.
156 Initialize debug agent.
158 This function is used to set up debug environment for SEC and PEI phase.
160 If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries
161 and initialize debug port. It will enable interrupt to support break-in feature.
162 It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before
163 physical memory is ready.
164 If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed
165 HOB to copy debug agent Mailbox. It will be called after physical memory is ready.
167 This function is used to set up debug environment to support source level debugging.
168 If certain Debug Agent Library instance has to save some private data in the stack,
169 this function must work on the mode that doesn't return to the caller, then
170 the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
171 function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
172 responsible to invoke the passing-in function at the end of InitializeDebugAgent().
174 If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by
175 passing in the Context to be its parameter.
177 If Function() is NULL, Debug Agent Library instance will return after setup debug
180 @param[in] InitFlag Init flag is used to decide the initialize process.
181 @param[in] Context Context needed according to InitFlag; it was optional.
182 @param[in] Function Continue function called by debug agent library; it was
188 InitializeDebugAgent (
190 IN VOID
*Context
, OPTIONAL
191 IN DEBUG_AGENT_CONTINUE Function OPTIONAL
194 DEBUG_AGENT_MAILBOX
*Mailbox
;
195 DEBUG_AGENT_MAILBOX MailboxInStack
;
196 DEBUG_AGENT_PHASE2_CONTEXT Phase2Context
;
197 DEBUG_AGENT_CONTEXT_POSTMEM_SEC
*DebugAgentContext
;
199 DisableInterrupts ();
203 case DEBUG_AGENT_INIT_PREMEM_SEC
:
205 InitializeDebugIdt ();
207 Mailbox
= &MailboxInStack
;
208 ZeroMem ((VOID
*) Mailbox
, sizeof (DEBUG_AGENT_MAILBOX
));
211 // Get and save debug port handle and set the length of memory block.
213 SetMailboxPointerInIdtEntry ((VOID
*) Mailbox
);
215 InitializeDebugTimer ();
217 Phase2Context
.Context
= Context
;
218 Phase2Context
.Function
= Function
;
219 DebugPortInitialize ((VOID
*) &Phase2Context
, InitializeDebugAgentPhase2
);
222 // If reaches here, it means Debug Port initialization failed.
224 DEBUG ((EFI_D_ERROR
, "Debug Agent: Debug port initialization failed.\n"));
228 case DEBUG_AGENT_INIT_POSTMEM_SEC
:
231 // Memory has been ready
233 if (IsHostConnected()) {
235 // Trigger one software interrupt to inform HOST
237 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE
);
240 DebugAgentContext
= (DEBUG_AGENT_CONTEXT_POSTMEM_SEC
*) Context
;
242 Mailbox
= (DEBUG_AGENT_MAILBOX
*) GetMailboxPointerInIdtEntry ();
243 Mailbox
->DebugPortHandle
= Mailbox
->DebugPortHandle
+ DebugAgentContext
->StackMigrateOffset
;
245 Mailbox
= BuildMailboxHob ();
246 Mailbox
= (DEBUG_AGENT_MAILBOX
*) ((UINTN
) Mailbox
+ DebugAgentContext
->HeapMigrateOffset
);
248 SetMailboxPointerInIdtEntry ((VOID
*) Mailbox
);
257 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
258 // Debug Agent library instance.
260 DEBUG ((EFI_D_ERROR
, "Debug Agent: The InitFlag value is not allowed!\n"));
267 // If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.
269 if (Function
!= NULL
) {
275 Caller provided function to be invoked at the end of DebugPortInitialize().
277 Refer to the descrption for DebugPortInitialize() for more details.
279 @param[in] Context The first input argument of DebugPortInitialize().
280 @param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.
285 InitializeDebugAgentPhase2 (
287 IN DEBUG_PORT_HANDLE DebugPortHandle
290 DEBUG_AGENT_PHASE2_CONTEXT
*Phase2Context
;
291 DEBUG_AGENT_MAILBOX
*Mailbox
;
292 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
294 Mailbox
= GetMailboxPointerInIdtEntry ();
295 Mailbox
->DebugPortHandle
= (UINT64
) (UINTN
)DebugPortHandle
;
298 // Trigger one software interrupt to inform HOST
300 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE
);
303 // If Temporary RAM region is below 128 MB, then send message to
304 // host to disable low memory filtering.
306 Phase2Context
= (DEBUG_AGENT_PHASE2_CONTEXT
*) Context
;
307 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*)Phase2Context
->Context
;
308 if ((UINTN
)SecCoreData
->TemporaryRamBase
< BASE_128MB
&& IsHostConnected ()) {
309 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE
);
313 // Enable CPU interrupts so debug timer interrupts can be delivered
318 // Call continuation function if it is not NULL.
320 if (Phase2Context
->Function
!= NULL
) {
321 Phase2Context
->Function (Phase2Context
->Context
);