]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / DebugSupportDxe / Ia32 / PlDebugSupportIa32.c
1 /** @file
2 IA32 specific functions to support Debug Support protocol.
3
4 Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "PlDebugSupport.h"
10
11 IA32_IDT_GATE_DESCRIPTOR NullDesc = {{0}};
12
13 /**
14 Get Interrupt Handle from IDT Gate Descriptor.
15
16 @param IdtGateDescriptor IDT Gate Descriptor.
17
18 @return Interrupt Handle stored in IDT Gate Descriptor.
19
20 **/
21 UINTN
22 GetInterruptHandleFromIdt (
23 IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor
24 )
25 {
26 UINTN InterruptHandle;
27
28 //
29 // InterruptHandle 0-15 : OffsetLow
30 // InterruptHandle 16-31 : OffsetHigh
31 //
32 ((UINT16 *) &InterruptHandle)[0] = (UINT16) IdtGateDescriptor->Bits.OffsetLow;
33 ((UINT16 *) &InterruptHandle)[1] = (UINT16) IdtGateDescriptor->Bits.OffsetHigh;
34
35 return InterruptHandle;
36 }
37
38 /**
39 Allocate pool for a new IDT entry stub.
40
41 Copy the generic stub into the new buffer and fixup the vector number
42 and jump target address.
43
44 @param ExceptionType This is the exception type that the new stub will be created
45 for.
46 @param Stub On successful exit, *Stub contains the newly allocated entry stub.
47
48 **/
49 VOID
50 CreateEntryStub (
51 IN EFI_EXCEPTION_TYPE ExceptionType,
52 OUT VOID **Stub
53 )
54 {
55 UINT8 *StubCopy;
56
57 StubCopy = *Stub;
58
59 //
60 // Fixup the stub code for this vector
61 //
62
63 // The stub code looks like this:
64 //
65 // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top
66 // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack
67 // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed
68 // 0000000D E9 db 0e9h ; jump rel32
69 // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
70 //
71
72 //
73 // poke in the exception type so the second push pushes the exception type
74 //
75 StubCopy[0x0c] = (UINT8) ExceptionType;
76
77 //
78 // fixup the jump target to point to the common entry
79 //
80 *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];
81
82 return ;
83 }
84
85 /**
86 This is the main worker function that manages the state of the interrupt
87 handlers. It both installs and uninstalls interrupt handlers based on the
88 value of NewCallback. If NewCallback is NULL, then uninstall is indicated.
89 If NewCallback is non-NULL, then install is indicated.
90
91 @param NewCallback If non-NULL, NewCallback specifies the new handler to register.
92 If NULL, specifies that the previously registered handler should
93 be uninstalled.
94 @param ExceptionType Indicates which entry to manage.
95
96 @retval EFI_SUCCESS Installing or Uninstalling operation is ok.
97 @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has
98 no handler registered for it
99 @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered.
100
101 **/
102 EFI_STATUS
103 ManageIdtEntryTable (
104 CALLBACK_FUNC NewCallback,
105 EFI_EXCEPTION_TYPE ExceptionType
106 )
107 {
108 EFI_STATUS Status;
109
110 Status = EFI_SUCCESS;
111
112 if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) {
113 //
114 // we've already installed to this vector
115 //
116 if (NewCallback != NULL) {
117 //
118 // if the input handler is non-null, error
119 //
120 Status = EFI_ALREADY_STARTED;
121 } else {
122 UnhookEntry (ExceptionType);
123 }
124 } else {
125 //
126 // no user handler installed on this vector
127 //
128 if (NewCallback == NULL) {
129 //
130 // if the input handler is null, error
131 //
132 Status = EFI_INVALID_PARAMETER;
133 } else {
134 HookEntry (ExceptionType, NewCallback);
135 }
136 }
137
138 return Status;
139 }