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