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