]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
This revision can only work with Intel(c) UDK Debugger Tool version 1.2 or greater...
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DxeDebugAgent / DxeDebugAgentLib.c
1 /** @file
2 Debug Agent library implementition for Dxe Core and Dxr modules.
3
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.
9
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.
12
13 **/
14
15 #include "DxeDebugAgentLib.h"
16
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;
22
23 /**
24 Constructor allocates the NVS memory to store Mailbox and install configuration table
25 in system table to store its pointer.
26
27 @param[in] ImageHandle The firmware allocated handle for the EFI image.
28 @param[in] SystemTable A pointer to the EFI System Table.
29
30 @retval RETURN_SUCCESS Allocate the global memory space to store guid and function tables.
31
32 **/
33 RETURN_STATUS
34 EFIAPI
35 DxeDebugAgentLibConstructor (
36 IN EFI_HANDLE ImageHandle,
37 IN EFI_SYSTEM_TABLE *SystemTable
38 )
39 {
40 EFI_STATUS Status;
41 EFI_PHYSICAL_ADDRESS Address;
42 EFI_EVENT Event;
43 VOID *EventRegistration;
44
45 if (!mDxeCoreFlag) {
46 return RETURN_SUCCESS;
47 }
48
49 Status = gBS->CreateEvent (
50 EVT_NOTIFY_SIGNAL,
51 TPL_CALLBACK,
52 InstallSerialIoNotification,
53 NULL,
54 &Event
55 );
56 ASSERT_EFI_ERROR (Status);
57
58 //
59 // Register for protocol notifications on this event
60 //
61
62 Status = gBS->RegisterProtocolNotify (
63 &gEfiPcdProtocolGuid,
64 Event,
65 &EventRegistration
66 );
67
68 ASSERT_EFI_ERROR (Status);
69
70 Address = 0;
71 Status = gBS->AllocatePages (
72 AllocateAnyPages,
73 EfiACPIMemoryNVS,
74 EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),
75 &Address
76 );
77 ASSERT_EFI_ERROR (Status);
78
79 CopyMem (
80 (UINT8 *) (UINTN) Address,
81 (UINT8 *) (UINTN) mMailboxPointer,
82 sizeof (DEBUG_AGENT_MAILBOX)
83 );
84
85 mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
86
87 Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
88 ASSERT_EFI_ERROR (Status);
89
90 return Status;
91 }
92
93 /**
94 Get the pointer to Mailbox from the GUIDed HOB.
95
96 @param[in] HobStart The starting HOB pointer to search from.
97
98 @return Pointer to Mailbox.
99
100 **/
101 DEBUG_AGENT_MAILBOX *
102 GetMailboxFromHob (
103 IN VOID *HobStart
104 )
105 {
106 EFI_HOB_GUID_TYPE *GuidHob;
107
108 GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
109 if (GuidHob == NULL) {
110 return NULL;
111 }
112
113 return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));
114 }
115
116 /**
117 Get Debug Agent Mailbox pointer.
118
119 @return Mailbox pointer.
120
121 **/
122 DEBUG_AGENT_MAILBOX *
123 GetMailboxPointer (
124 VOID
125 )
126 {
127 return mMailboxPointer;
128 }
129
130 /**
131 Get debug port handle.
132
133 @return Debug port handle.
134
135 **/
136 DEBUG_PORT_HANDLE
137 GetDebugPortHandle (
138 VOID
139 )
140 {
141 return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
142 }
143
144
145 /**
146 Initialize debug agent.
147
148 This function is used to set up debug enviroment for DXE phase.
149
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.
155
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
159 optional.
160
161 **/
162 VOID
163 EFIAPI
164 InitializeDebugAgent (
165 IN UINT32 InitFlag,
166 IN VOID *Context, OPTIONAL
167 IN DEBUG_AGENT_CONTINUE Function OPTIONAL
168 )
169 {
170 DEBUG_AGENT_MAILBOX *Mailbox;
171 IA32_DESCRIPTOR Idtr;
172 UINT16 IdtEntryCount;
173 BOOLEAN InterruptStatus;
174
175 if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&
176 InitFlag != DEBUG_AGENT_INIT_S3 &&
177 InitFlag != DEBUG_AGENT_INIT_DXE_AP) {
178 return;
179 }
180
181 //
182 // Save and disable original interrupt status
183 //
184 InterruptStatus = SaveAndDisableInterrupts ();
185
186 if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
187 //
188 // Try to get Mailbox from GUIDed HOB.
189 //
190 mDxeCoreFlag = TRUE;
191 Mailbox = GetMailboxFromHob (Context);
192
193 //
194 // Clear Break CPU index value
195 //
196 mDebugMpContext.BreakAtCpuIndex = (UINT32) -1;
197
198 } else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {
199
200 EnableInterrupts ();
201
202 return;
203
204 } else {
205 //
206 // If it is in S3 path, needn't to install configuration table.
207 //
208 Mailbox = NULL;
209 }
210
211 if (Mailbox != NULL) {
212 //
213 // If Mailbox exists, copy it into one global variable.
214 //
215 CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
216 } else {
217 //
218 // If Mailbox not exists, used the local Mailbox.
219 //
220 ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
221 }
222
223 mMailboxPointer = &mMailbox;
224
225 //
226 // Get original IDT address and size.
227 //
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);
235 }
236
237 //
238 // Initialize the IDT table entries to support source level debug.
239 //
240 InitializeDebugIdt ();
241
242 //
243 // Initialize debug communication port
244 //
245 mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)mMailbox.DebugPortHandle, NULL);
246
247 InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
248 InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
249
250 if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
251 //
252 // Initialize Debug Timer hardware and enable interrupt.
253 //
254 InitializeDebugTimer ();
255 EnableInterrupts ();
256
257 return;
258 } else {
259 //
260 // Disable Debug Timer interrupt in S3 path.
261 //
262 SaveAndSetDebugTimerInterrupt (FALSE);
263
264 //
265 // Restore interrupt state.
266 //
267 SetInterruptState (InterruptStatus);
268 }
269
270 }
271