]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
55da3fe55ee6b9385d43462c7c47a1fc82b49b09
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / Ia32 / ArchDebugSupport.c
1 /** @file
2 Supporting functions for IA32 architecture.
3
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "DebugAgent.h"
10
11 /**
12 Initialize IDT entries to support source level debug.
13
14 **/
15 VOID
16 InitializeDebugIdt (
17 VOID
18 )
19 {
20 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
21 UINTN InterruptHandler;
22 IA32_DESCRIPTOR IdtDescriptor;
23 UINTN Index;
24 UINT16 CodeSegment;
25 UINT32 RegEdx;
26
27 AsmReadIdtr (&IdtDescriptor);
28
29 //
30 // Use current CS as the segment selector of interrupt gate in IDT
31 //
32 CodeSegment = AsmReadCs ();
33
34 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
35
36 for (Index = 0; Index < 20; Index ++) {
37 if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) {
38 //
39 // If the exception is masked to be reserved except for INT1 and INT3, skip it
40 //
41 continue;
42 }
43 InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;
44 IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
45 IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
46 IdtEntry[Index].Bits.Selector = CodeSegment;
47 IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
48 }
49
50 InterruptHandler = (UINTN) &TimerInterruptHandle;
51 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
52 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
53 IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment;
54 IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
55
56 //
57 // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then
58 // Set DE flag in CR4 to enable IO breakpoint
59 //
60 AsmCpuid (1, NULL, NULL, NULL, &RegEdx);
61 if ((RegEdx & BIT2) != 0) {
62 AsmWriteCr4 (AsmReadCr4 () | BIT3);
63 }
64 }
65
66 /**
67 Retrieve exception handler from IDT table by ExceptionNum.
68
69 @param[in] ExceptionNum Exception number
70
71 @return Exception handler
72
73 **/
74 VOID *
75 GetExceptionHandlerInIdtEntry (
76 IN UINTN ExceptionNum
77 )
78 {
79 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
80 IA32_DESCRIPTOR IdtDescriptor;
81
82 AsmReadIdtr (&IdtDescriptor);
83 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
84
85 return (VOID *) (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetLow) |
86 (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16));
87 }
88
89 /**
90 Set exception handler in IDT table by ExceptionNum.
91
92 @param[in] ExceptionNum Exception number
93 @param[in] ExceptionHandler Exception Handler to be set
94
95 **/
96 VOID
97 SetExceptionHandlerInIdtEntry (
98 IN UINTN ExceptionNum,
99 IN VOID *ExceptionHandler
100 )
101 {
102 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
103 IA32_DESCRIPTOR IdtDescriptor;
104
105 AsmReadIdtr (&IdtDescriptor);
106 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
107
108 IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler;
109 IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16);
110 }