1 /** @file
2   Ia32 arch functions 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                     (IdtEntry[InterruptType].Bits.OffsetHigh << 16);
43   if (InterruptHandler >= sizeof (UINT32) &&  *(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE) {
44     return TRUE;
45   } else {
46     return FALSE;
47   }
48 }
49 
50 /**
51   Save IDT entry for INT1 and update it.
52 
53   @param[in]  IdtDescriptor      Pointer to IDT Descriptor.
54   @param[out] SavedIdtEntry      Original IDT entry returned.
55 
56 **/
57 VOID
SaveAndUpdateIdtEntry1(IN IA32_DESCRIPTOR * IdtDescriptor,OUT IA32_IDT_GATE_DESCRIPTOR * SavedIdtEntry)58 SaveAndUpdateIdtEntry1 (
59   IN  IA32_DESCRIPTOR            *IdtDescriptor,
60   OUT IA32_IDT_GATE_DESCRIPTOR   *SavedIdtEntry
61   )
62 {
63   IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
64   UINT16                     CodeSegment;
65   UINTN                      InterruptHandler;
66 
67   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
68   CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
69 
70     //
71   // Use current CS as the segment selector of interrupt gate in IDT
72   //
73   CodeSegment = AsmReadCs ();
74 
75   InterruptHandler = (UINTN) &AsmInterruptHandle;
76   IdtEntry[1].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;
77   IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
78   IdtEntry[1].Bits.Selector   = CodeSegment;
79   IdtEntry[1].Bits.GateType   = IA32_IDT_GATE_TYPE_INTERRUPT_32;
80 }
81 
82 /**
83   Restore IDT entry for INT1.
84 
85   @param[in]  IdtDescriptor      Pointer to IDT Descriptor.
86   @param[in]  RestoredIdtEntry   IDT entry to be restored.
87 
88 **/
89 VOID
RestoreIdtEntry1(IN IA32_DESCRIPTOR * IdtDescriptor,IN IA32_IDT_GATE_DESCRIPTOR * RestoredIdtEntry)90 RestoreIdtEntry1 (
91   IN  IA32_DESCRIPTOR            *IdtDescriptor,
92   IN  IA32_IDT_GATE_DESCRIPTOR   *RestoredIdtEntry
93   )
94 {
95   IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
96 
97   IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
98   CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
99 }
100