Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e460d644
Commit
e460d644
authored
Mar 18, 2011
by
David Howells
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MN10300: Use KGDB
parent
67ddb405
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
289 additions
and
2 deletions
+289
-2
arch/mn10300/Kconfig
arch/mn10300/Kconfig
+2
-0
arch/mn10300/Kconfig.debug
arch/mn10300/Kconfig.debug
+1
-1
arch/mn10300/include/asm/kgdb.h
arch/mn10300/include/asm/kgdb.h
+81
-0
arch/mn10300/include/asm/smp.h
arch/mn10300/include/asm/smp.h
+2
-1
arch/mn10300/kernel/Makefile
arch/mn10300/kernel/Makefile
+1
-0
arch/mn10300/kernel/kgdb.c
arch/mn10300/kernel/kgdb.c
+202
-0
No files found.
arch/mn10300/Kconfig
View file @
e460d644
...
...
@@ -3,6 +3,8 @@ config MN10300
select HAVE_OPROFILE
select HAVE_GENERIC_HARDIRQS
select GENERIC_HARDIRQS_NO_DEPRECATED
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
config AM33_2
def_bool n
...
...
arch/mn10300/Kconfig.debug
View file @
e460d644
...
...
@@ -153,4 +153,4 @@ endmenu
config KERNEL_DEBUGGER
def_bool y
depends on GDBSTUB
depends on GDBSTUB
|| KGDB
arch/mn10300/include/asm/kgdb.h
0 → 100644
View file @
e460d644
/* Kernel debugger for MN10300
*
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _ASM_KGDB_H
#define _ASM_KGDB_H
/*
* BUFMAX defines the maximum number of characters in inbound/outbound
* buffers at least NUMREGBYTES*2 are needed for register packets
* Longer buffer is needed to list all threads
*/
#define BUFMAX 1024
/*
* Note that this register image is in a different order than the register
* image that Linux produces at interrupt time.
*/
enum
regnames
{
GDB_FR_D0
=
0
,
GDB_FR_D1
=
1
,
GDB_FR_D2
=
2
,
GDB_FR_D3
=
3
,
GDB_FR_A0
=
4
,
GDB_FR_A1
=
5
,
GDB_FR_A2
=
6
,
GDB_FR_A3
=
7
,
GDB_FR_SP
=
8
,
GDB_FR_PC
=
9
,
GDB_FR_MDR
=
10
,
GDB_FR_EPSW
=
11
,
GDB_FR_LIR
=
12
,
GDB_FR_LAR
=
13
,
GDB_FR_MDRQ
=
14
,
GDB_FR_E0
=
15
,
GDB_FR_E1
=
16
,
GDB_FR_E2
=
17
,
GDB_FR_E3
=
18
,
GDB_FR_E4
=
19
,
GDB_FR_E5
=
20
,
GDB_FR_E6
=
21
,
GDB_FR_E7
=
22
,
GDB_FR_SSP
=
23
,
GDB_FR_MSP
=
24
,
GDB_FR_USP
=
25
,
GDB_FR_MCRH
=
26
,
GDB_FR_MCRL
=
27
,
GDB_FR_MCVF
=
28
,
GDB_FR_FPCR
=
29
,
GDB_FR_DUMMY0
=
30
,
GDB_FR_DUMMY1
=
31
,
GDB_FR_FS0
=
32
,
GDB_FR_SIZE
=
64
,
};
#define GDB_ORIG_D0 41
#define NUMREGBYTES (GDB_FR_SIZE*4)
static
inline
void
arch_kgdb_breakpoint
(
void
)
{
asm
(
".globl __arch_kgdb_breakpoint; __arch_kgdb_breakpoint: break"
);
}
extern
u8
__arch_kgdb_breakpoint
;
#define BREAK_INSTR_SIZE 1
#define CACHE_FLUSH_IS_SAFE 1
#endif
/* _ASM_KGDB_H */
arch/mn10300/include/asm/smp.h
View file @
e460d644
...
...
@@ -62,8 +62,9 @@
* An alternate way of dealing with this could be to use the EPSW.S bits to
* cache this information for systems with up to four CPUs.
*/
#define arch_smp_processor_id() (CPUID)
#if 0
#define raw_smp_processor_id() (
CPUID
)
#define raw_smp_processor_id() (
arch_smp_processor_id()
)
#else
#define raw_smp_processor_id() (current_thread_info()->cpu)
#endif
...
...
arch/mn10300/kernel/Makefile
View file @
e460d644
...
...
@@ -25,3 +25,4 @@ obj-$(CONFIG_MN10300_RTC) += rtc.o
obj-$(CONFIG_PROFILE)
+=
profile.o profile-low.o
obj-$(CONFIG_MODULES)
+=
module.o
obj-$(CONFIG_KPROBES)
+=
kprobes.o
obj-$(CONFIG_KGDB)
+=
kgdb.o
arch/mn10300/kernel/kgdb.c
0 → 100644
View file @
e460d644
/* kgdb support for MN10300
*
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#include <linux/ptrace.h>
#include <linux/kgdb.h>
#include <linux/uaccess.h>
#include <unit/leds.h>
#include <unit/serial.h>
#include <asm/debugger.h>
#include <asm/serial-regs.h>
#include "internal.h"
/*
* Copy kernel exception frame registers to the GDB register file
*/
void
pt_regs_to_gdb_regs
(
unsigned
long
*
gdb_regs
,
struct
pt_regs
*
regs
)
{
unsigned
long
ssp
=
(
unsigned
long
)
(
regs
+
1
);
gdb_regs
[
GDB_FR_D0
]
=
regs
->
d0
;
gdb_regs
[
GDB_FR_D1
]
=
regs
->
d1
;
gdb_regs
[
GDB_FR_D2
]
=
regs
->
d2
;
gdb_regs
[
GDB_FR_D3
]
=
regs
->
d3
;
gdb_regs
[
GDB_FR_A0
]
=
regs
->
a0
;
gdb_regs
[
GDB_FR_A1
]
=
regs
->
a1
;
gdb_regs
[
GDB_FR_A2
]
=
regs
->
a2
;
gdb_regs
[
GDB_FR_A3
]
=
regs
->
a3
;
gdb_regs
[
GDB_FR_SP
]
=
(
regs
->
epsw
&
EPSW_nSL
)
?
regs
->
sp
:
ssp
;
gdb_regs
[
GDB_FR_PC
]
=
regs
->
pc
;
gdb_regs
[
GDB_FR_MDR
]
=
regs
->
mdr
;
gdb_regs
[
GDB_FR_EPSW
]
=
regs
->
epsw
;
gdb_regs
[
GDB_FR_LIR
]
=
regs
->
lir
;
gdb_regs
[
GDB_FR_LAR
]
=
regs
->
lar
;
gdb_regs
[
GDB_FR_MDRQ
]
=
regs
->
mdrq
;
gdb_regs
[
GDB_FR_E0
]
=
regs
->
e0
;
gdb_regs
[
GDB_FR_E1
]
=
regs
->
e1
;
gdb_regs
[
GDB_FR_E2
]
=
regs
->
e2
;
gdb_regs
[
GDB_FR_E3
]
=
regs
->
e3
;
gdb_regs
[
GDB_FR_E4
]
=
regs
->
e4
;
gdb_regs
[
GDB_FR_E5
]
=
regs
->
e5
;
gdb_regs
[
GDB_FR_E6
]
=
regs
->
e6
;
gdb_regs
[
GDB_FR_E7
]
=
regs
->
e7
;
gdb_regs
[
GDB_FR_SSP
]
=
ssp
;
gdb_regs
[
GDB_FR_MSP
]
=
0
;
gdb_regs
[
GDB_FR_USP
]
=
regs
->
sp
;
gdb_regs
[
GDB_FR_MCRH
]
=
regs
->
mcrh
;
gdb_regs
[
GDB_FR_MCRL
]
=
regs
->
mcrl
;
gdb_regs
[
GDB_FR_MCVF
]
=
regs
->
mcvf
;
gdb_regs
[
GDB_FR_DUMMY0
]
=
0
;
gdb_regs
[
GDB_FR_DUMMY1
]
=
0
;
gdb_regs
[
GDB_FR_FS0
]
=
0
;
}
/*
* Extracts kernel SP/PC values understandable by gdb from the values
* saved by switch_to().
*/
void
sleeping_thread_to_gdb_regs
(
unsigned
long
*
gdb_regs
,
struct
task_struct
*
p
)
{
gdb_regs
[
GDB_FR_SSP
]
=
p
->
thread
.
sp
;
gdb_regs
[
GDB_FR_PC
]
=
p
->
thread
.
pc
;
gdb_regs
[
GDB_FR_A3
]
=
p
->
thread
.
a3
;
gdb_regs
[
GDB_FR_USP
]
=
p
->
thread
.
usp
;
gdb_regs
[
GDB_FR_FPCR
]
=
p
->
thread
.
fpu_state
.
fpcr
;
}
/*
* Fill kernel exception frame registers from the GDB register file
*/
void
gdb_regs_to_pt_regs
(
unsigned
long
*
gdb_regs
,
struct
pt_regs
*
regs
)
{
regs
->
d0
=
gdb_regs
[
GDB_FR_D0
];
regs
->
d1
=
gdb_regs
[
GDB_FR_D1
];
regs
->
d2
=
gdb_regs
[
GDB_FR_D2
];
regs
->
d3
=
gdb_regs
[
GDB_FR_D3
];
regs
->
a0
=
gdb_regs
[
GDB_FR_A0
];
regs
->
a1
=
gdb_regs
[
GDB_FR_A1
];
regs
->
a2
=
gdb_regs
[
GDB_FR_A2
];
regs
->
a3
=
gdb_regs
[
GDB_FR_A3
];
regs
->
sp
=
gdb_regs
[
GDB_FR_SP
];
regs
->
pc
=
gdb_regs
[
GDB_FR_PC
];
regs
->
mdr
=
gdb_regs
[
GDB_FR_MDR
];
regs
->
epsw
=
gdb_regs
[
GDB_FR_EPSW
];
regs
->
lir
=
gdb_regs
[
GDB_FR_LIR
];
regs
->
lar
=
gdb_regs
[
GDB_FR_LAR
];
regs
->
mdrq
=
gdb_regs
[
GDB_FR_MDRQ
];
regs
->
e0
=
gdb_regs
[
GDB_FR_E0
];
regs
->
e1
=
gdb_regs
[
GDB_FR_E1
];
regs
->
e2
=
gdb_regs
[
GDB_FR_E2
];
regs
->
e3
=
gdb_regs
[
GDB_FR_E3
];
regs
->
e4
=
gdb_regs
[
GDB_FR_E4
];
regs
->
e5
=
gdb_regs
[
GDB_FR_E5
];
regs
->
e6
=
gdb_regs
[
GDB_FR_E6
];
regs
->
e7
=
gdb_regs
[
GDB_FR_E7
];
regs
->
sp
=
gdb_regs
[
GDB_FR_SSP
];
/* gdb_regs[GDB_FR_MSP]; */
// regs->usp = gdb_regs[GDB_FR_USP];
regs
->
mcrh
=
gdb_regs
[
GDB_FR_MCRH
];
regs
->
mcrl
=
gdb_regs
[
GDB_FR_MCRL
];
regs
->
mcvf
=
gdb_regs
[
GDB_FR_MCVF
];
/* gdb_regs[GDB_FR_DUMMY0]; */
/* gdb_regs[GDB_FR_DUMMY1]; */
// regs->fpcr = gdb_regs[GDB_FR_FPCR];
// regs->fs0 = gdb_regs[GDB_FR_FS0];
}
struct
kgdb_arch
arch_kgdb_ops
=
{
.
gdb_bpt_instr
=
{
0xff
},
.
flags
=
KGDB_HW_BREAKPOINT
,
};
/*
* Handle unknown packets and [Ccs] packets
*/
int
kgdb_arch_handle_exception
(
int
vector
,
int
signo
,
int
err_code
,
char
*
remcom_in_buffer
,
char
*
remcom_out_buffer
,
struct
pt_regs
*
regs
)
{
long
addr
;
char
*
ptr
;
switch
(
remcom_in_buffer
[
0
])
{
case
'c'
:
if
(
kgdb_contthread
&&
kgdb_contthread
!=
current
)
{
strcpy
(
remcom_out_buffer
,
"E00"
);
break
;
}
kgdb_contthread
=
NULL
;
/* try to read optional parameter, pc unchanged if no parm */
ptr
=
&
remcom_in_buffer
[
1
];
if
(
kgdb_hex2long
(
&
ptr
,
&
addr
))
regs
->
pc
=
addr
;
return
0
;
case
's'
:
break
;
/* we don't do hardware single stepping */
}
return
-
1
;
/* this means that we do not want to exit from the handler */
}
/*
* Handle event interception
* - returns 0 if the exception should be skipped, -ERROR otherwise.
*/
int
debugger_intercept
(
enum
exception_code
excep
,
int
signo
,
int
si_code
,
struct
pt_regs
*
regs
)
{
int
ret
;
ret
=
kgdb_handle_exception
(
excep
,
signo
,
si_code
,
regs
);
debugger_local_cache_flushinv
();
return
ret
;
}
/*
* Determine if we've hit a debugger special breakpoint
*/
int
at_debugger_breakpoint
(
struct
pt_regs
*
regs
)
{
return
regs
->
pc
==
(
unsigned
long
)
&
__arch_kgdb_breakpoint
;
}
/*
* Initialise kgdb
*/
int
kgdb_arch_init
(
void
)
{
return
0
;
}
/*
* Do something, perhaps, but don't know what.
*/
void
kgdb_arch_exit
(
void
)
{
}
#ifdef CONFIG_SMP
void
debugger_nmi_interrupt
(
struct
pt_regs
*
regs
,
enum
exception_code
code
)
{
kgdb_nmicallback
(
arch_smp_processor_id
(),
regs
);
debugger_local_cache_flushinv
();
}
void
kgdb_roundup_cpus
(
unsigned
long
flags
)
{
smp_jump_to_debugger
();
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment