Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sparc
kernel
kgdb_32.c
Go to the documentation of this file.
1
/* kgdb.c: KGDB support for 32-bit sparc.
2
*
3
* Copyright (C) 2008 David S. Miller <
[email protected]
>
4
*/
5
6
#include <
linux/kgdb.h
>
7
#include <
linux/kdebug.h
>
8
9
#include <asm/kdebug.h>
10
#include <asm/ptrace.h>
11
#include <asm/irq.h>
12
#include <asm/cacheflush.h>
13
14
extern
unsigned
long
trapbase
;
15
16
void
pt_regs_to_gdb_regs
(
unsigned
long
*
gdb_regs
,
struct
pt_regs
*
regs
)
17
{
18
struct
reg_window32
*
win
;
19
int
i
;
20
21
gdb_regs[
GDB_G0
] = 0;
22
for
(i = 0; i < 15; i++)
23
gdb_regs[
GDB_G1
+ i] = regs->
u_regs
[
UREG_G1
+ i];
24
25
win = (
struct
reg_window32
*) regs->
u_regs
[
UREG_FP
];
26
for
(i = 0; i < 8; i++)
27
gdb_regs[
GDB_L0
+ i] = win->
locals
[i];
28
for
(i = 0; i < 8; i++)
29
gdb_regs[
GDB_I0
+ i] = win->
ins
[i];
30
31
for
(i =
GDB_F0
; i <=
GDB_F31
; i++)
32
gdb_regs[i] = 0;
33
34
gdb_regs[
GDB_Y
] = regs->
y
;
35
gdb_regs[GDB_PSR] = regs->
psr
;
36
gdb_regs[GDB_WIM] = 0;
37
gdb_regs[GDB_TBR] = (
unsigned
long
) &
trapbase
;
38
gdb_regs[
GDB_PC
] = regs->
pc
;
39
gdb_regs[
GDB_NPC
] = regs->
npc
;
40
gdb_regs[
GDB_FSR
] = 0;
41
gdb_regs[GDB_CSR] = 0;
42
}
43
44
void
sleeping_thread_to_gdb_regs
(
unsigned
long
*
gdb_regs
,
struct
task_struct
*
p
)
45
{
46
struct
thread_info
*
t
=
task_thread_info
(p);
47
struct
reg_window32
*
win
;
48
int
i
;
49
50
for
(i =
GDB_G0
; i <
GDB_G6
; i++)
51
gdb_regs[i] = 0;
52
gdb_regs[
GDB_G6
] = (
unsigned
long
) t;
53
gdb_regs[
GDB_G7
] = 0;
54
for
(i =
GDB_O0
; i <
GDB_SP
; i++)
55
gdb_regs[i] = 0;
56
gdb_regs[
GDB_SP
] = t->ksp;
57
gdb_regs[
GDB_O7
] = 0;
58
59
win = (
struct
reg_window32
*) t->ksp;
60
for
(i = 0; i < 8; i++)
61
gdb_regs[
GDB_L0
+ i] = win->
locals
[i];
62
for
(i = 0; i < 8; i++)
63
gdb_regs[
GDB_I0
+ i] = win->
ins
[i];
64
65
for
(i =
GDB_F0
; i <=
GDB_F31
; i++)
66
gdb_regs[i] = 0;
67
68
gdb_regs[
GDB_Y
] = 0;
69
70
gdb_regs[GDB_PSR] = t->kpsr;
71
gdb_regs[GDB_WIM] = t->kwim;
72
gdb_regs[GDB_TBR] = (
unsigned
long
) &
trapbase
;
73
gdb_regs[
GDB_PC
] = t->kpc;
74
gdb_regs[
GDB_NPC
] = t->kpc + 4;
75
gdb_regs[
GDB_FSR
] = 0;
76
gdb_regs[GDB_CSR] = 0;
77
}
78
79
void
gdb_regs_to_pt_regs
(
unsigned
long
*
gdb_regs
,
struct
pt_regs
*
regs
)
80
{
81
struct
reg_window32
*
win
;
82
int
i
;
83
84
for
(i = 0; i < 15; i++)
85
regs->
u_regs
[
UREG_G1
+ i] = gdb_regs[
GDB_G1
+ i];
86
87
/* If the PSR register is changing, we have to preserve
88
* the CWP field, otherwise window save/restore explodes.
89
*/
90
if
(regs->
psr
!= gdb_regs[GDB_PSR]) {
91
unsigned
long
cwp = regs->
psr
&
PSR_CWP
;
92
93
regs->
psr
= (gdb_regs[GDB_PSR] & ~
PSR_CWP
) | cwp;
94
}
95
96
regs->
pc
= gdb_regs[
GDB_PC
];
97
regs->
npc
= gdb_regs[
GDB_NPC
];
98
regs->
y
= gdb_regs[
GDB_Y
];
99
100
win = (
struct
reg_window32
*) regs->
u_regs
[
UREG_FP
];
101
for
(i = 0; i < 8; i++)
102
win->
locals
[i] = gdb_regs[
GDB_L0
+ i];
103
for
(i = 0; i < 8; i++)
104
win->
ins
[i] = gdb_regs[
GDB_I0
+ i];
105
}
106
107
int
kgdb_arch_handle_exception
(
int
e_vector
,
int
signo,
int
err_code
,
108
char
*remcomInBuffer,
char
*remcomOutBuffer,
109
struct
pt_regs
*linux_regs)
110
{
111
unsigned
long
addr
;
112
char
*
ptr
;
113
114
switch
(remcomInBuffer[0]) {
115
case
'c'
:
116
/* try to read optional parameter, pc unchanged if no parm */
117
ptr = &remcomInBuffer[1];
118
if
(
kgdb_hex2long
(&ptr, &addr)) {
119
linux_regs->
pc
=
addr
;
120
linux_regs->
npc
= addr + 4;
121
}
122
/* fallthru */
123
124
case
'D'
:
125
case
'k'
:
126
if
(linux_regs->
pc
== (
unsigned
long
)
arch_kgdb_breakpoint
) {
127
linux_regs->
pc
= linux_regs->
npc
;
128
linux_regs->
npc
+= 4;
129
}
130
return
0;
131
}
132
return
-1;
133
}
134
135
extern
void
do_hw_interrupt
(
struct
pt_regs
*
regs
,
unsigned
long
type
);
136
137
asmlinkage
void
kgdb_trap
(
struct
pt_regs
*
regs
)
138
{
139
unsigned
long
flags
;
140
141
if
(
user_mode
(regs)) {
142
do_hw_interrupt
(regs, 0xfd);
143
return
;
144
}
145
146
flushw_all
();
147
148
local_irq_save
(flags);
149
kgdb_handle_exception
(0x172,
SIGTRAP
, 0, regs);
150
local_irq_restore
(flags);
151
}
152
153
int
kgdb_arch_init
(
void
)
154
{
155
return
0;
156
}
157
158
void
kgdb_arch_exit
(
void
)
159
{
160
}
161
162
void
kgdb_arch_set_pc
(
struct
pt_regs
*
regs
,
unsigned
long
ip
)
163
{
164
regs->
pc
=
ip
;
165
regs->
npc
= regs->
pc
+ 4;
166
}
167
168
struct
kgdb_arch
arch_kgdb_ops
= {
169
/* Breakpoint instruction: ta 0x7d */
170
.gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d },
171
};
Generated on Thu Jan 10 2013 13:18:22 for Linux Kernel by
1.8.2