2 IA32 specific debug support functions
4 Copyright (c) 2006 - 2008, Intel Corporation
5 All rights reserved. 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.
16 // private header files
18 #include "DebugSupport.h"
21 // This the global main table to keep track of the interrupts
23 IDT_ENTRY
*IdtEntryTable
= NULL
;
24 IA32_IDT_GATE_DESCRIPTOR NullDesc
= {0};
27 Read IDT Gate Descriptor from IDT Table.
29 @param Vector Specifies vector number.
30 @param IdtGateDecriptor Pointer to IDT Gate Descriptor read from IDT Table.
33 VOID
ReadIdtGateDecriptor (
34 IN EFI_EXCEPTION_TYPE Vector
,
35 OUT IA32_IDT_GATE_DESCRIPTOR
*IdtGateDecriptor
38 IA32_DESCRIPTOR IdtrValue
;
39 IA32_IDT_GATE_DESCRIPTOR
*IdtTable
;
41 AsmReadIdtr (&IdtrValue
);
42 IdtTable
= (IA32_IDT_GATE_DESCRIPTOR
*) IdtrValue
.Base
;
44 CopyMem ((VOID
*) IdtGateDecriptor
, (VOID
*) &(IdtTable
)[Vector
], sizeof (IA32_IDT_GATE_DESCRIPTOR
));
47 Write IDT Gate Descriptor into IDT Table.
49 @param Vector Specifies vector number.
50 @param IdtGateDecriptor Pointer to IDT Gate Descriptor written into IDT Table.
53 VOID
WriteIdtGateDecriptor (
54 EFI_EXCEPTION_TYPE Vector
,
55 IA32_IDT_GATE_DESCRIPTOR
*IdtGateDecriptor
58 IA32_DESCRIPTOR IdtrValue
;
59 IA32_IDT_GATE_DESCRIPTOR
*IdtTable
;
61 AsmReadIdtr (&IdtrValue
);
62 IdtTable
= (IA32_IDT_GATE_DESCRIPTOR
*) IdtrValue
.Base
;
64 CopyMem ((VOID
*) &(IdtTable
)[Vector
], (VOID
*) IdtGateDecriptor
, sizeof (IA32_IDT_GATE_DESCRIPTOR
));
69 Creates a nes entry stub. Then saves the current IDT entry and replaces it
70 with an interrupt gate for the new entry point. The IdtEntryTable is updated
71 with the new registered function.
73 This code executes in boot services context. The stub entry executes in interrupt
76 @param ExceptionType Specifies which vector to hook.
77 @param NewCallback A pointer to the new function to be registered.
79 @retval EFI_SUCCESS Always.
84 IN EFI_EXCEPTION_TYPE ExceptionType
,
85 IN
VOID (*NewCallback
) ()
88 BOOLEAN OldIntFlagState
;
91 Status
= CreateEntryStub (ExceptionType
, (VOID
**) &IdtEntryTable
[ExceptionType
].StubEntry
);
92 if (Status
== EFI_SUCCESS
) {
93 OldIntFlagState
= WriteInterruptFlag (0);
94 ReadIdtGateDecriptor (ExceptionType
, &(IdtEntryTable
[ExceptionType
].OrigDesc
));
96 IdtEntryTable
[ExceptionType
].OrigVector
= (DEBUG_PROC
) GetProcedureEntryPoint (&(IdtEntryTable
[ExceptionType
].OrigDesc
));
98 Vect2Desc (&IdtEntryTable
[ExceptionType
].NewDesc
, IdtEntryTable
[ExceptionType
].StubEntry
);
99 IdtEntryTable
[ExceptionType
].RegisteredCallback
= NewCallback
;
100 WriteIdtGateDecriptor (ExceptionType
, &(IdtEntryTable
[ExceptionType
].NewDesc
));
101 WriteInterruptFlag (OldIntFlagState
);
108 Undoes HookEntry. This code executes in boot services context.
110 @param ExceptionType Specifies which entry to unhook
112 @retval EFI_SUCCESS Always.
117 IN EFI_EXCEPTION_TYPE ExceptionType
120 BOOLEAN OldIntFlagState
;
122 OldIntFlagState
= WriteInterruptFlag (0);
123 WriteIdtGateDecriptor (ExceptionType
, &(IdtEntryTable
[ExceptionType
].OrigDesc
));
124 WriteInterruptFlag (OldIntFlagState
);
130 This is a DebugSupport protocol member function, hard
131 coded to support only 1 processor for now.
133 @param This The DebugSupport instance
134 @param MaxProcessorIndex The maximuim supported processor index
136 @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0.
141 GetMaximumProcessorIndex (
142 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
143 OUT UINTN
*MaxProcessorIndex
146 *MaxProcessorIndex
= 0;
147 return (EFI_SUCCESS
);
151 DebugSupport protocol member function.
153 @param This The DebugSupport instance
154 @param ProcessorIndex Which processor the callback applies to.
155 @param PeriodicCallback Callback function
157 @retval EFI_SUCCESS Indicates the callback was registered.
158 @retval others Callback was not registered.
163 RegisterPeriodicCallback (
164 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
165 IN UINTN ProcessorIndex
,
166 IN EFI_PERIODIC_CALLBACK PeriodicCallback
169 return ManageIdtEntryTable (PeriodicCallback
, SYSTEM_TIMER_VECTOR
);
173 DebugSupport protocol member function.
175 This code executes in boot services context.
177 @param This The DebugSupport instance
178 @param ProcessorIndex Which processor the callback applies to.
179 @param NewCallback Callback function
180 @param ExceptionType Which exception to hook
182 @retval EFI_SUCCESS Indicates the callback was registered.
183 @retval others Callback was not registered.
188 RegisterExceptionCallback (
189 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
190 IN UINTN ProcessorIndex
,
191 IN EFI_EXCEPTION_CALLBACK NewCallback
,
192 IN EFI_EXCEPTION_TYPE ExceptionType
195 return ManageIdtEntryTable (NewCallback
, ExceptionType
);
199 DebugSupport protocol member function. Calls assembly routine to flush cache.
201 @param This The DebugSupport instance
202 @param ProcessorIndex Which processor the callback applies to.
203 @param Start Physical base of the memory range to be invalidated
204 @param Length mininum number of bytes in instruction cache to invalidate
206 @retval EFI_SUCCESS Always returned.
211 InvalidateInstructionCache (
212 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
213 IN UINTN ProcessorIndex
,
223 Initializes driver's handler registration databas.
225 This code executes in boot services context
226 Must be public because it's referenced from DebugSupport.c
228 @retval EFI_UNSUPPORTED If IA32 processor does not support FXSTOR/FXRSTOR instructions,
229 the context save will fail, so these processor's are not supported.
230 @retval EFI_OUT_OF_RESOURCES Fails to allocate memory.
231 @retval EFI_SUCCESS Initializes successfully.
235 PlInitializeDebugSupportDriver (
239 EFI_EXCEPTION_TYPE ExceptionType
;
241 if (!FxStorSupport ()) {
242 return EFI_UNSUPPORTED
;
245 IdtEntryTable
= AllocateZeroPool (sizeof (IDT_ENTRY
) * NUM_IDT_ENTRIES
);
246 if (IdtEntryTable
== NULL
) {
247 return EFI_OUT_OF_RESOURCES
;
250 for (ExceptionType
= 0; ExceptionType
< NUM_IDT_ENTRIES
; ExceptionType
++) {
251 IdtEntryTable
[ExceptionType
].StubEntry
= (DEBUG_PROC
) (UINTN
) AllocatePool (StubSize
);
252 if (IdtEntryTable
[ExceptionType
].StubEntry
== NULL
) {
256 CopyMem ((VOID
*)(UINTN
)IdtEntryTable
[ExceptionType
].StubEntry
, InterruptEntryStub
, StubSize
);
262 for (ExceptionType
= 0; ExceptionType
< NUM_IDT_ENTRIES
; ExceptionType
++) {
263 if (IdtEntryTable
[ExceptionType
].StubEntry
!= NULL
) {
264 FreePool ((VOID
*)(UINTN
)IdtEntryTable
[ExceptionType
].StubEntry
);
267 FreePool (IdtEntryTable
);
269 return EFI_OUT_OF_RESOURCES
;
273 This is the callback that is written to the LoadedImage protocol instance
274 on the image handle. It uninstalls all registered handlers and frees all entry
277 @param ImageHandle The firmware allocated handle for the EFI image.
279 @retval EFI_SUCCESS Always.
284 PlUnloadDebugSupportDriver (
285 IN EFI_HANDLE ImageHandle
288 EFI_EXCEPTION_TYPE ExceptionType
;
290 for (ExceptionType
= 0; ExceptionType
< NUM_IDT_ENTRIES
; ExceptionType
++) {
291 ManageIdtEntryTable (NULL
, ExceptionType
);
294 FreePool (IdtEntryTable
);
299 Common piece of code that invokes the registered handlers.
301 This code executes in exception context so no efi calls are allowed.
303 @param ExceptionType Exception type
304 @param ContextRecord System context
308 InterruptDistrubutionHub (
309 EFI_EXCEPTION_TYPE ExceptionType
,
310 EFI_SYSTEM_CONTEXT_IA32
*ContextRecord
313 if (IdtEntryTable
[ExceptionType
].RegisteredCallback
!= NULL
) {
314 if (ExceptionType
!= SYSTEM_TIMER_VECTOR
) {
315 IdtEntryTable
[ExceptionType
].RegisteredCallback (ExceptionType
, ContextRecord
);
317 OrigVector
= IdtEntryTable
[ExceptionType
].OrigVector
;
318 IdtEntryTable
[ExceptionType
].RegisteredCallback (ContextRecord
);