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