]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c
1. Merger generic functions into one file.
[mirror_edk2.git] / MdeModulePkg / Universal / DebugSupportDxe / Ia32 / PlDebugSupportIa32.c
CommitLineData
6e8a984e 1/** @file\r
2 IA32 specific debug support functions\r
3\r
4Copyright (c) 2006 - 2008, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "DebugSupport.h"\r
16\r
17/**\r
18 Get Procedure Entry Point from IDT Gate Descriptor.\r
19\r
20 @param IdtGateDecriptor IDT Gate Descriptor.\r
21\r
22 @return Procedure Entry Point located in IDT Gate Descriptor.\r
23\r
24**/\r
25UINTN GetProcedureEntryPoint (\r
26 IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor\r
27 )\r
28{\r
29 UINTN ProcedureEntryPoint;\r
30 \r
31 ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow;\r
32 ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh;\r
33\r
34 return ProcedureEntryPoint;\r
35}\r
36\r
37/**\r
38 Allocate pool for a new IDT entry stub.\r
39\r
40 Copy the generic stub into the new buffer and fixup the vector number\r
41 and jump target address.\r
42\r
43 @param ExceptionType This is the exception type that the new stub will be created\r
44 for.\r
45 @param Stub On successful exit, *Stub contains the newly allocated entry stub.\r
46\r
47 @retval EFI_SUCCESS Always.\r
48\r
49**/\r
50EFI_STATUS\r
51CreateEntryStub (\r
52 IN EFI_EXCEPTION_TYPE ExceptionType,\r
53 OUT VOID **Stub\r
54 )\r
55{\r
56 UINT8 *StubCopy;\r
57\r
58 StubCopy = *Stub;\r
59\r
60 //\r
61 // Fixup the stub code for this vector\r
62 //\r
63\r
64 // The stub code looks like this:\r
65 //\r
66 // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top\r
67 // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack\r
68 // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed\r
69 // 0000000D E9 db 0e9h ; jump rel32\r
70 // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry\r
71 //\r
72\r
73 //\r
74 // poke in the exception type so the second push pushes the exception type\r
75 //\r
76 StubCopy[0x0c] = (UINT8) ExceptionType;\r
77\r
78 //\r
79 // fixup the jump target to point to the common entry\r
80 //\r
81 *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];\r
82\r
83 return EFI_SUCCESS;\r
84}\r
85\r
86/**\r
87 This is the main worker function that manages the state of the interrupt\r
88 handlers. It both installs and uninstalls interrupt handlers based on the\r
89 value of NewCallback. If NewCallback is NULL, then uninstall is indicated.\r
90 If NewCallback is non-NULL, then install is indicated.\r
91\r
92 @param NewCallback If non-NULL, NewCallback specifies the new handler to register.\r
93 If NULL, specifies that the previously registered handler should\r
94 be uninstalled.\r
95 @param ExceptionType Indicates which entry to manage.\r
96\r
97 @retval EFI_SUCCESS Process is ok.\r
98 @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has\r
99 no handler registered for it\r
100 @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered.\r
101 @retval others Possible return values are passed through from UnHookEntry and HookEntry.\r
102\r
103**/\r
104EFI_STATUS\r
105ManageIdtEntryTable (\r
106 VOID (*NewCallback)(),\r
107 EFI_EXCEPTION_TYPE ExceptionType\r
108 )\r
109{\r
110 EFI_STATUS Status;\r
111\r
112 Status = EFI_SUCCESS;\r
113\r
114 if (!FeaturePcdGet (PcdNtEmulatorEnable)) {\r
115 if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) {\r
116 //\r
117 // we've already installed to this vector\r
118 //\r
119 if (NewCallback != NULL) {\r
120 //\r
121 // if the input handler is non-null, error\r
122 //\r
123 Status = EFI_ALREADY_STARTED;\r
124 } else {\r
125 Status = UnhookEntry (ExceptionType);\r
126 }\r
127 } else {\r
128 //\r
129 // no user handler installed on this vector\r
130 //\r
131 if (NewCallback == NULL) {\r
132 //\r
133 // if the input handler is null, error\r
134 //\r
135 Status = EFI_INVALID_PARAMETER;\r
136 } else {\r
137 Status = HookEntry (ExceptionType, NewCallback);\r
138 }\r
139 }\r
140 }\r
141\r
142 return Status;\r
143}\r