]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
1. Merger generic functions into one file.
[mirror_edk2.git] / MdeModulePkg / Universal / DebugSupportDxe / X64 / PlDebugSupportX64.c
1 /** @file
2 X64 specific debug support functions
3
4 Copyright (c) 2006 - 2007, 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
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 //
16 // private header files
17 //
18 #include "DebugSupport.h"
19
20 /**
21 Get Procedure Entry Point from IDT Gate Descriptor.
22
23 @param IdtGateDecriptor IDT Gate Descriptor.
24
25 @return Procedure Entry Point located in IDT Gate Descriptor.
26
27 **/
28 UINTN GetProcedureEntryPoint (
29 IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
30 )
31 {
32 UINTN ProcedureEntryPoint;
33
34 ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow;
35 ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh;
36 ((UINT32 *) &ProcedureEntryPoint)[1] = (UINT32) IdtGateDecriptor->Bits.OffsetUpper;
37
38 return ProcedureEntryPoint;
39 }
40
41 /**
42 Allocate pool for a new IDT entry stub.
43
44 Copy the generic stub into the new buffer and fixup the vector number
45 and jump target address.
46
47 @param ExceptionType This is the exception type that the new stub will be created
48 for.
49 @param Stub On successful exit, *Stub contains the newly allocated entry stub.
50
51 @retval EFI_SUCCESS Always.
52
53 **/
54 EFI_STATUS
55 CreateEntryStub (
56 IN EFI_EXCEPTION_TYPE ExceptionType,
57 OUT VOID **Stub
58 )
59 {
60 UINT8 *StubCopy;
61
62 StubCopy = *Stub;
63
64 //
65 // Fixup the stub code for this vector
66 //
67
68 // The stub code looks like this:
69 //
70 // 00000000 6A 00 push 0 ; push vector number - will be modified before installed
71 // 00000002 E9 db 0e9h ; jump rel32
72 // 00000003 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
73 //
74
75 //
76 // poke in the exception type so the second push pushes the exception type
77 //
78 StubCopy[0x1] = (UINT8) ExceptionType;
79
80 //
81 // fixup the jump target to point to the common entry
82 //
83 *(UINT32 *) &StubCopy[0x3] = (UINT32)((UINTN) CommonIdtEntry - (UINTN) &StubCopy[StubSize]);
84
85 return EFI_SUCCESS;
86 }
87
88 /**
89 This is the main worker function that manages the state of the interrupt
90 handlers. It both installs and uninstalls interrupt handlers based on the
91 value of NewCallback. If NewCallback is NULL, then uninstall is indicated.
92 If NewCallback is non-NULL, then install is indicated.
93
94 @param NewCallback If non-NULL, NewCallback specifies the new handler to register.
95 If NULL, specifies that the previously registered handler should
96 be uninstalled.
97 @param ExceptionType Indicates which entry to manage.
98
99 @retval EFI_SUCCESS Process is ok.
100 @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has
101 no handler registered for it
102 @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered.
103 @retval others Possible return values are passed through from UnHookEntry and HookEntry.
104
105 **/
106 EFI_STATUS
107 ManageIdtEntryTable (
108 VOID (*NewCallback)(),
109 EFI_EXCEPTION_TYPE ExceptionType
110 )
111 {
112 EFI_STATUS Status;
113
114 Status = EFI_SUCCESS;
115
116 if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) {
117 //
118 // we've already installed to this vector
119 //
120 if (NewCallback != NULL) {
121 //
122 // if the input handler is non-null, error
123 //
124 Status = EFI_ALREADY_STARTED;
125 } else {
126 Status = UnhookEntry (ExceptionType);
127 }
128 } else {
129 //
130 // no user handler installed on this vector
131 //
132 if (NewCallback == NULL) {
133 //
134 // if the input handler is null, error
135 //
136 Status = EFI_INVALID_PARAMETER;
137 } else {
138 Status = HookEntry (ExceptionType, NewCallback);
139 }
140 }
141
142 return Status;
143 }