Jason Wessel wrote:
> I rolled up several patches along with my changes to fix HW breakpoints
> on x86_64 and i386. I also deprecated some of the #defines in favor of
> using the kgdb_ops to control the HW breakpoints for other non IA archs
> at the point that these are implemented.
>
> Until such time that there is a common interface for kernel HW
> breakpoints, if a user space application uses HW breakpoints the kernel
> breakpoints will disappear. I tested execution, data access and data
> write breakpoints and all work with gdb 6.6.
>
> If there are no objections, I am going to replace the i386.patch with
> i386_hw_breakpoints.patch and x86_64_breakpoints.patch and merge the
> core changes for arch breakpoints to core-lite.patch.
There *are* objections now -- belated as usual. :-<
> Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>
> Index: linux-2.6.21.1/arch/i386/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/arch/i386/kernel/kgdb.c
> +++ linux-2.6.21.1/arch/i386/kernel/kgdb.c
> @@ -14,12 +14,14 @@
>
> /*
> * Copyright (C) 2000-2001 VERITAS Software Corporation.
> + * Copyright (C) 2007 Wind River Systems, Inc.
> */
> /*
> * Contributor: Lake Stevens Instrument Division$
> * Written by: Glenn Engel $
> * Updated by: Amit Kale<[EMAIL PROTECTED]>
> * Updated by: Tom Rini <[EMAIL PROTECTED]>
> + * Updated by: Jason Wessel <[EMAIL PROTECTED]>
> * Modified for 386 by Jim Kingdon, Cygnus Support.
> * Origianl kgdb, compatibility with 2.1.xx kernel by
> * David Grothe <[EMAIL PROTECTED]>
> @@ -126,8 +128,53 @@ static struct hw_breakpoint {
> { .enabled = 0 },
> };
>
> -#ifdef CONFIG_KGDB_ARCH_HAS_HARDWARE_BREAKPOINTS
> -int kgdb_remove_hw_break(unsigned long addr)
> +static void kgdb_correct_hw_break(void)
> +{
> + int breakno;
> + int correctit;
> + int breakbit;
> + unsigned long dr7;
> +
> + get_debugreg(dr7, 7);
> + correctit = 0;
> + for (breakno = 0; breakno < 3; breakno++) {
Hm, why not breakno < 4 if we have 4 breakpoint regs? :-O
> + breakbit = 2 << (breakno << 1);
> + if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
> + correctit = 1;
> + dr7 |= breakbit;
> + dr7 &= ~(0xf0000 << (breakno << 2));
> + dr7 |= (((breakinfo[breakno].len << 2) |
We should shift .len by 18, otherwise the local/global enable bits are
being corrupt. :-/
> + breakinfo[breakno].type) << 16) <<
> + (breakno << 2);
> + switch (breakno) {
> + case 0:
> + set_debugreg(breakinfo[breakno].addr, 0);
> + break;
> +
> + case 1:
> + set_debugreg(breakinfo[breakno].addr, 1);
> + break;
> +
> + case 2:
> + set_debugreg(breakinfo[breakno].addr, 2);
> + break;
> +
> + case 3:
This case is never hit due to a wrong loop condition.
> + set_debugreg(breakinfo[breakno].addr, 3);
> + break;
> + }
> + } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
> + correctit = 1;
> + dr7 &= ~breakbit;
> + dr7 &= ~(0xf0000 << (breakno << 2));
> + }
> + }
> + if (correctit)
> + set_debugreg(dr7, 7);
> +}
> +
> Index: linux-2.6.21.1/arch/x86_64/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/arch/x86_64/kernel/kgdb.c
> +++ linux-2.6.21.1/arch/x86_64/kernel/kgdb.c
> @@ -17,6 +17,7 @@
> * Copyright (C) 2000-2001 VERITAS Software Corporation.
> * Copyright (C) 2002 Andi Kleen, SuSE Labs
> * Copyright (C) 2004 LinSysSoft Technologies Pvt. Ltd.
> + * Copyright (C) 2007 Jason Wessel, Wind River Systems, Inc.
> */
> /****************************************************************************
> * Contributor: Lake Stevens Instrument Division$
> @@ -136,10 +137,115 @@ enabled:0}, {
> enabled:0}, {
> enabled:0}};
>
> +static void kgdb_correct_hw_break(void)
> +{
> + int breakno;
> + int correctit;
> + int breakbit;
> + unsigned long dr7;
> +
> + get_debugreg(dr7, 7);
> + correctit = 0;
> + for (breakno = 0; breakno < 3; breakno++) {
The same wrong condition here.
> + breakbit = 2 << (breakno << 1);
> + if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
> + correctit = 1;
> + dr7 |= breakbit;
> + dr7 &= ~(0xf0000 << (breakno << 2));
> + dr7 |= (((breakinfo[breakno].len << 2) |
And the same wrong shift here.
> + breakinfo[breakno].type) << 16) <<
> + (breakno << 2);
> + switch (breakno) {
> + case 0:
> + set_debugreg(breakinfo[breakno].addr, 0);
> + break;
> +
> + case 1:
> + set_debugreg(breakinfo[breakno].addr, 1);
> + break;
> +
> + case 2:
> + set_debugreg(breakinfo[breakno].addr, 2);
> + break;
> +
> + case 3:
> + set_debugreg(breakinfo[breakno].addr, 3);
> + break;
> + }
> + } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
> + correctit = 1;
> + dr7 &= ~breakbit;
> + dr7 &= ~(0xf0000 << (breakno << 2));
> + }
> + }
> + if (correctit)
> + set_debugreg(dr7, 7);
> +}
> +
> +static int kgdb_remove_hw_break(unsigned long addr, int len,
> + enum kgdb_bptype bptype)
> +{
> + int i, idx = -1;
> + for (i = 0; i < 4; i++) {
> + if (breakinfo[i].addr == addr && breakinfo[i].enabled) {
> + idx = i;
> + break;
> + }
> + }
> + if (idx == -1)
> + return -1;
> +
> + breakinfo[idx].enabled = 0;
> + return 0;
> +}
> +
> +static void kgdb_remove_all_hw_break(void)
> +{
> + int i;
> +
> + for (i = 0; i < 4; i++) {
> + memset(&breakinfo[i], 0, sizeof(struct hw_breakpoint));
> + }
> +}
> +
> +static int kgdb_set_hw_break(unsigned long addr, int len,
> + enum kgdb_bptype bptype)
> +{
> + int i, idx = -1;
> + for (i = 0; i < 4; i++) {
> + if (!breakinfo[i].enabled) {
> + idx = i;
> + break;
> + }
> + }
> + if (idx == -1)
> + return -1;
> + if (bptype == bp_hardware_breakpoint) {
> + breakinfo[idx].type = 0;
> + breakinfo[idx].len = 0;
> + } else if (bptype == bp_write_watchpoint) {
> + breakinfo[idx].type = 1;
> + if (len == 1 || len == 2 || len == 4)
> + breakinfo[idx].len = len - 1;
> + else
> + return -1;
> + } else if (bptype == bp_access_watchpoint) {
> + breakinfo[idx].type = 3;
> + if (len == 1 || len == 2 || len == 4)
> + breakinfo[idx].len = len - 1;
> + else
> + return -1;
> + } else
> + return -1;
Well, this deserves to be handled by switch stmt. :-)
> + breakinfo[idx].enabled = 1;
> + breakinfo[idx].addr = addr;
> + return 0;
> +}
> +
Well, maybe I'll cook a patch over the weekend...
WBR, Sergei
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport