1 /** @file 2 Supporting functions for IA32 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.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.Selector = CodeSegment; 60 IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 61 62 // 63 // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then 64 // Set DE flag in CR4 to enable IO breakpoint 65 // 66 AsmCpuid (1, NULL, NULL, NULL, &RegEdx); 67 if ((RegEdx & BIT2) != 0) { 68 AsmWriteCr4 (AsmReadCr4 () | BIT3); 69 } 70 } 71 72 /** 73 Retrieve exception handler from IDT table by ExceptionNum. 74 75 @param[in] ExceptionNum Exception number 76 77 @return Exception handler 78 79 **/ 80 VOID * 81 GetExceptionHandlerInIdtEntry ( 82 IN UINTN ExceptionNum 83 ) 84 { 85 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 86 IA32_DESCRIPTOR IdtDescriptor; 87 88 AsmReadIdtr (&IdtDescriptor); 89 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 90 91 return (VOID *) (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetLow) | 92 (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16)); 93 } 94 95 /** 96 Set exception handler in IDT table by ExceptionNum. 97 98 @param[in] ExceptionNum Exception number 99 @param[in] ExceptionHandler Exception Handler to be set 100 101 **/ 102 VOID 103 SetExceptionHandlerInIdtEntry ( 104 IN UINTN ExceptionNum, 105 IN VOID *ExceptionHandler 106 ) 107 { 108 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 109 IA32_DESCRIPTOR IdtDescriptor; 110 111 AsmReadIdtr (&IdtDescriptor); 112 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 113 114 IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler; 115 IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16); 116 } 117