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