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**/
27BOOLEAN
28CheckDebugAgentHandler (
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**/
57VOID
58SaveAndUpdateIdtEntry1 (
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**/
89VOID
90RestoreIdtEntry1 (
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