1 /** @file
2   X64 arch function to access IDT vector.
3 
4   Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <PeCoffExtraActionLib.h>
10 
11 /**
12   Read IDT entry to check if IDT entries are setup by Debug Agent.
13 
14   @param[in]  IdtDescriptor      Pointer to IDT Descriptor.
15   @param[in]  InterruptType      Interrupt type.
16 
17   @retval  TRUE     IDT entries were setup by Debug Agent.
18   @retval  FALSE    IDT entries were not setuo by Debug Agent.
19 
20 **/
21 BOOLEAN
CheckDebugAgentHandler(IN IA32_DESCRIPTOR * IdtDescriptor,IN UINTN InterruptType)22 CheckDebugAgentHandler (
23   IN  IA32_DESCRIPTOR            *IdtDescriptor,
24   IN  UINTN                      InterruptType
25   )
26 {
27   IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
28   UINTN                      InterruptHandler;
29 
30   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
31   if (IdtEntry == NULL) {
32     return FALSE;
33   }
34 
35   InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow +
36                     (((UINTN)IdtEntry[InterruptType].Bits.OffsetHigh) << 16) +
37                     (((UINTN)IdtEntry[InterruptType].Bits.OffsetUpper) << 32);
38   if (InterruptHandler >= sizeof (UINT32) &&  *(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE) {
39     return TRUE;
40   } else {
41     return FALSE;
42   }
43 }
44 
45 /**
46   Save IDT entry for INT1 and update it.
47 
48   @param[in]  IdtDescriptor      Pointer to IDT Descriptor.
49   @param[out] SavedIdtEntry      Original IDT entry returned.
50 
51 **/
52 VOID
SaveAndUpdateIdtEntry1(IN IA32_DESCRIPTOR * IdtDescriptor,OUT IA32_IDT_GATE_DESCRIPTOR * SavedIdtEntry)53 SaveAndUpdateIdtEntry1 (
54   IN  IA32_DESCRIPTOR            *IdtDescriptor,
55   OUT IA32_IDT_GATE_DESCRIPTOR   *SavedIdtEntry
56   )
57 {
58   IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
59   UINT16                     CodeSegment;
60   UINTN                      InterruptHandler;
61 
62   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
63   CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
64 
65     //
66   // Use current CS as the segment selector of interrupt gate in IDT
67   //
68   CodeSegment = AsmReadCs ();
69 
70   InterruptHandler = (UINTN) &AsmInterruptHandle;
71   IdtEntry[1].Bits.OffsetLow       = (UINT16)(UINTN)InterruptHandler;
72   IdtEntry[1].Bits.OffsetHigh      = (UINT16)((UINTN)InterruptHandler >> 16);
73   IdtEntry[1].Bits.OffsetUpper     = (UINT32)((UINTN)InterruptHandler >> 32);
74   IdtEntry[1].Bits.Selector        = CodeSegment;
75   IdtEntry[1].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;
76 }
77 
78 /**
79   Restore IDT entry for INT1.
80 
81   @param[in]  IdtDescriptor      Pointer to IDT Descriptor.
82   @param[in]  RestoredIdtEntry   IDT entry to be restored.
83 
84 **/
85 VOID
RestoreIdtEntry1(IN IA32_DESCRIPTOR * IdtDescriptor,IN IA32_IDT_GATE_DESCRIPTOR * RestoredIdtEntry)86 RestoreIdtEntry1 (
87   IN  IA32_DESCRIPTOR            *IdtDescriptor,
88   IN  IA32_IDT_GATE_DESCRIPTOR   *RestoredIdtEntry
89   )
90 {
91   IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
92 
93   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
94   CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
95 }
96