From 5f72e68c9067ae5b8cfa7c935db81002cb22e00f Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Mon, 27 Apr 2015 19:53:36 +0000 Subject: [PATCH] SourceLevelDebugPkg/DebugAgent: Support IA32 processors without DE or FXSAVE/FXRESTOR Use CPUID Leaf 01 to detect support for debug extensions and FXSAVE/FXRESTOR instructions. Do not enable those features in CR4 if they are not supported. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17220 6f19259b-4bc3-4df7-8a09-765794883524 --- .../DebugAgentCommon/Ia32/ArchDebugSupport.c | 9 ++++-- .../DebugAgentCommon/Ia32/AsmFuncs.S | 31 +++++++++++++++++-- .../DebugAgentCommon/Ia32/AsmFuncs.asm | 26 ++++++++++++++-- .../DebugAgentCommon/X64/ArchDebugSupport.c | 9 ++++-- .../Library/DebugAgent/DxeDebugAgentLib.inf | 4 +-- .../DebugAgent/SecPeiDebugAgentLib.inf | 4 +-- .../Library/DebugAgent/SmmDebugAgentLib.inf | 2 +- 7 files changed, 71 insertions(+), 14 deletions(-) diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c index 9bd8fca6b6..1aef63f206 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c @@ -1,7 +1,7 @@ /** @file Supporting functions for IA32 architecture. - Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -28,6 +28,7 @@ InitializeDebugIdt ( IA32_DESCRIPTOR IdtDescriptor; UINTN Index; UINT16 CodeSegment; + UINT32 RegEdx; AsmReadIdtr (&IdtDescriptor); @@ -59,9 +60,13 @@ InitializeDebugIdt ( IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; // + // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then // Set DE flag in CR4 to enable IO breakpoint // - AsmWriteCr4 (AsmReadCr4 () | BIT3); + AsmCpuid (1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT2) != 0) { + AsmWriteCr4 (AsmReadCr4 () | BIT3); + } } /** diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S index efeaebc2c8..a6a3da6a6b 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ # -# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -232,10 +232,25 @@ NoExtrPush: pushl %edi ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; +## insure FXSAVE/FXRSTOR is enabled in CR4... +## ... while we're at it, make sure DE is also enabled... + mov $1, %eax + pushl %ebx # temporarily save value of ebx on stack + cpuid # use CPUID to determine if FXSAVE/FXRESTOR + # and DE are supported + popl %ebx # retore value of ebx that was overwritten + # by CPUID movl %cr4, %eax - orl $0x208,%eax + pushl %eax # push cr4 firstly + testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support + jz L1 + orl $BIT9, %eax # Set CR4.OSFXSR +L1: + testl $BIT2, %edx # Test for Debugging Extensions support + jz L2 + orl $BIT3, %eax # Set CR4.DE +L2: movl %eax, %cr4 - pushl %eax movl %cr3, %eax pushl %eax movl %cr2, %eax @@ -303,7 +318,11 @@ NoExtrPush: ## FX_SAVE_STATE_IA32 FxSaveState; subl $512,%esp movl %esp,%edi + testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support. + # edx still contains result from CPUID above + jz L3 .byte 0x0f, 0xae, 0x07 # fxsave [edi] +L3: ## save the exception data pushl 8(%esp) @@ -322,7 +341,13 @@ NoExtrPush: ## FX_SAVE_STATE_IA32 FxSaveState; movl %esp,%esi + movl $1, %eax + cpuid # use CPUID to determine if FXSAVE/FXRESTOR + # are supported + testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support + jz L4 .byte 0x0f, 0xae, 0x0e # fxrstor [esi] +L4: addl $512,%esp ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm index 377ade7c3b..44ed6f7710 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm @@ -230,9 +230,21 @@ NoExtrPush: ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; ;; insure FXSAVE/FXRSTOR is enabled in CR4... ;; ... while we're at it, make sure DE is also enabled... + mov eax, 1 + push ebx ; temporarily save value of ebx on stack + cpuid ; use CPUID to determine if FXSAVE/FXRESTOR and + ; DE are supported + pop ebx ; retore value of ebx that was overwritten by CPUID mov eax, cr4 - push eax ; push cr4 firstly - or eax, 208h + push eax ; push cr4 firstly + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz @F + or eax, BIT9 ; Set CR4.OSFXSR +@@: + test edx, BIT2 ; Test for Debugging Extensions support + jz @F + or eax, BIT3 ; Set CR4.DE +@@: mov cr4, eax mov eax, cr3 push eax @@ -313,7 +325,12 @@ NoExtrPush: mov ecx, 128 ;= 512 / 4 rep stosd mov edi, esp + + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support. + ; edx still contains result from CPUID above + jz @F db 0fh, 0aeh, 00000111y ;fxsave [edi] +@@: ;; save the exception data push dword ptr [ebp + 8] @@ -329,7 +346,12 @@ NoExtrPush: ;; FX_SAVE_STATE_IA32 FxSaveState; mov esi, esp + mov eax, 1 + cpuid ; use CPUID to determine if FXSAVE/FXRESTOR are supported + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz @F db 0fh, 0aeh, 00001110y ; fxrstor [esi] +@@: add esp, 512 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c index 60d3eb8bb3..08cef0154f 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c @@ -1,7 +1,7 @@ /** @file Supporting functions for X64 architecture. - Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -28,6 +28,7 @@ InitializeDebugIdt ( IA32_DESCRIPTOR IdtDescriptor; UINTN Index; UINT16 CodeSegment; + UINT32 RegEdx; AsmReadIdtr (&IdtDescriptor); @@ -61,9 +62,13 @@ InitializeDebugIdt ( IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; // + // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then // Set DE flag in CR4 to enable IO breakpoint // - AsmWriteCr4 (AsmReadCr4 () | BIT3); + AsmCpuid (1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT2) != 0) { + AsmWriteCr4 (AsmReadCr4 () | BIT3); + } } /** diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf index 2a67a6b707..7ed5f5514c 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf @@ -1,7 +1,7 @@ ## @file # Debug Agent library instance for Dxe Core and Dxe modules. # -# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -19,7 +19,7 @@ MODULE_UNI_FILE = DxeDebugAgentLib.uni FILE_GUID = BA6BAD25-B814-4747-B0B0-0FBB61D40B90 MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 0.7 + VERSION_STRING = 0.8 LIBRARY_CLASS = DebugAgentLib|DXE_CORE DXE_DRIVER CONSTRUCTOR = DxeDebugAgentLibConstructor diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf index 793962d507..f2569dfaa4 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf @@ -1,7 +1,7 @@ ## @file # Debug Agent library instance for SEC Core and PEI modules. # -# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -19,7 +19,7 @@ MODULE_UNI_FILE = SecPeiDebugAgentLib.uni FILE_GUID = 508B7D59-CD4E-4a6b-A45B-6D3B2D90111E MODULE_TYPE = PEIM - VERSION_STRING = 0.7 + VERSION_STRING = 0.8 LIBRARY_CLASS = DebugAgentLib|SEC PEIM # diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf index b0581a3145..ca99933f3b 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf @@ -19,7 +19,7 @@ MODULE_UNI_FILE = SmmDebugAgentLib.uni FILE_GUID = CB07D74C-598F-4268-A5D1-644FB4A481E8 MODULE_TYPE = DXE_SMM_DRIVER - VERSION_STRING = 0.7 + VERSION_STRING = 0.8 LIBRARY_CLASS = DebugAgentLib|DXE_SMM_DRIVER # -- 2.39.2