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
frv
kernel
debug-stub.c
Go to the documentation of this file.
1
/* debug-stub.c: debug-mode stub
2
*
3
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (
[email protected]
)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/string.h>
13
#include <linux/kernel.h>
14
#include <linux/signal.h>
15
#include <linux/sched.h>
16
#include <
linux/init.h
>
17
#include <
linux/serial_reg.h
>
18
#include <
linux/start_kernel.h
>
19
20
#include <asm/serial-regs.h>
21
#include <asm/timer-regs.h>
22
#include <
asm/irc-regs.h
>
23
#include <asm/gdb-stub.h>
24
#include "
gdb-io.h
"
25
26
/* CPU board CON5 */
27
#define __UART0(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
28
29
#define LSR_WAIT_FOR0(STATE) \
30
do { \
31
} while (!(__UART0(LSR) & UART_LSR_##STATE))
32
33
#define FLOWCTL_QUERY0(LINE) ({ __UART0(MSR) & UART_MSR_##LINE; })
34
#define FLOWCTL_CLEAR0(LINE) do { __UART0(MCR) &= ~UART_MCR_##LINE; } while (0)
35
#define FLOWCTL_SET0(LINE) do { __UART0(MCR) |= UART_MCR_##LINE; } while (0)
36
37
#define FLOWCTL_WAIT_FOR0(LINE) \
38
do { \
39
gdbstub_do_rx(); \
40
} while(!FLOWCTL_QUERY(LINE))
41
42
struct
frv_debug_status
__debug_status
;
43
44
static
void
__init
debug_stub_init(
void
);
45
46
/*****************************************************************************/
47
/*
48
* debug mode handler stub
49
* - we come here with the CPU in debug mode and with exceptions disabled
50
* - handle debugging services for userspace
51
*/
52
asmlinkage
void
debug_stub
(
void
)
53
{
54
unsigned
long
hsr0;
55
int
type
= 0;
56
57
static
u8
inited = 0;
58
if
(!inited) {
59
debug_stub_init();
60
type = -1;
61
inited = 1;
62
}
63
64
hsr0 =
__get_HSR
(0);
65
if
(hsr0 &
HSR0_ETMD
)
66
__set_HSR
(0, hsr0 & ~HSR0_ETMD);
67
68
/* disable single stepping */
69
__debug_status
.dcr &= ~
DCR_SE
;
70
71
/* kernel mode can propose an exception be handled in debug mode by jumping to a special
72
* location */
73
if
(
__debug_frame
->pc == (
unsigned
long
)
__break_hijack_kernel_event_breaks_here
) {
74
/* replace the debug frame with the kernel frame and discard
75
* the top kernel context */
76
*
__debug_frame
= *__frame;
77
__frame =
__debug_frame
->next_frame;
78
__debug_status
.brr = (
__debug_frame
->tbr &
TBR_TT
) << 12;
79
__debug_status
.brr |=
BRR_EB
;
80
}
81
82
if
(
__debug_frame
->pc == (
unsigned
long
) __debug_bug_trap + 4) {
83
__debug_frame
->pc =
__debug_frame
->lr;
84
type =
__debug_frame
->gr8;
85
}
86
87
#ifdef CONFIG_GDBSTUB
88
gdbstub
(type);
89
#endif
90
91
if
(hsr0 & HSR0_ETMD)
92
__set_HSR
(0,
__get_HSR
(0) | HSR0_ETMD);
93
94
}
/* end debug_stub() */
95
96
/*****************************************************************************/
97
/*
98
* debug stub initialisation
99
*/
100
static
void
__init
debug_stub_init(
void
)
101
{
102
__set_IRR
(6, 0xff000000);
/* map ERRs to NMI */
103
__set_IITMR
(1, 0x20000000);
/* ERR0/1, UART0/1 IRQ detect levels */
104
105
asm
volatile
(
" movgs gr0,ibar0 \n"
106
" movgs gr0,ibar1 \n"
107
" movgs gr0,ibar2 \n"
108
" movgs gr0,ibar3 \n"
109
" movgs gr0,dbar0 \n"
110
" movgs gr0,dbmr00 \n"
111
" movgs gr0,dbmr01 \n"
112
" movgs gr0,dbdr00 \n"
113
" movgs gr0,dbdr01 \n"
114
" movgs gr0,dbar1 \n"
115
" movgs gr0,dbmr10 \n"
116
" movgs gr0,dbmr11 \n"
117
" movgs gr0,dbdr10 \n"
118
" movgs gr0,dbdr11 \n"
119
);
120
121
/* deal with debugging stub initialisation and initial pause */
122
if
(
__debug_frame
->pc == (
unsigned
long
)
__debug_stub_init_break
)
123
__debug_frame
->pc = (
unsigned
long
)
start_kernel
;
124
125
/* enable the debug events we want to trap */
126
__debug_status
.dcr =
DCR_EBE
;
127
128
#ifdef CONFIG_GDBSTUB
129
gdbstub_init
();
130
#endif
131
132
__clr_MASK_all
();
133
__clr_MASK
(15);
134
__clr_RC
(15);
135
136
}
/* end debug_stub_init() */
137
138
/*****************************************************************************/
139
/*
140
* kernel "exit" trap for gdb stub
141
*/
142
void
debug_stub_exit
(
int
status
)
143
{
144
145
#ifdef CONFIG_GDBSTUB
146
gdbstub_exit
(status);
147
#endif
148
149
}
/* end debug_stub_exit() */
150
151
/*****************************************************************************/
152
/*
153
* send string to serial port
154
*/
155
void
debug_to_serial
(
const
char
*
p
,
int
n
)
156
{
157
char
ch;
158
159
for
(; n > 0; n--) {
160
ch = *p++;
161
FLOWCTL_SET0
(
DTR
);
162
LSR_WAIT_FOR0
(
THRE
);
163
// FLOWCTL_WAIT_FOR(CTS);
164
165
if
(ch == 0x0a) {
166
__UART0
(
TX
) = 0x0d;
167
mb
();
168
LSR_WAIT_FOR0
(
THRE
);
169
// FLOWCTL_WAIT_FOR(CTS);
170
}
171
__UART0
(
TX
) = ch;
172
mb
();
173
174
FLOWCTL_CLEAR0
(
DTR
);
175
}
176
177
}
/* end debug_to_serial() */
178
179
/*****************************************************************************/
180
/*
181
* send string to serial port
182
*/
183
void
debug_to_serial2
(
const
char
*
fmt
, ...)
184
{
185
va_list
va
;
186
char
buf
[64];
187
int
n
;
188
189
va_start
(va, fmt);
190
n =
vsprintf
(buf, fmt, va);
191
va_end
(va);
192
193
debug_to_serial
(buf, n);
194
195
}
/* end debug_to_serial2() */
196
197
/*****************************************************************************/
198
/*
199
* set up the ttyS0 serial port baud rate timers
200
*/
201
void
__init
console_set_baud
(
unsigned
baud
)
202
{
203
unsigned
value
,
high
,
low
;
204
u8
lcr
;
205
206
/* work out the divisor to give us the nearest higher baud rate */
207
value =
__serial_clock_speed_HZ
/ 16 /
baud
;
208
209
/* determine the baud rate range */
210
high =
__serial_clock_speed_HZ
/ 16 /
value
;
211
low =
__serial_clock_speed_HZ
/ 16 / (value + 1);
212
213
/* pick the nearest bound */
214
if
(low + (high - low) / 2 >
baud
)
215
value++;
216
217
lcr =
__UART0
(
LCR
);
218
__UART0
(
LCR
) |=
UART_LCR_DLAB
;
219
mb
();
220
__UART0
(
DLL
) = value & 0xff;
221
__UART0
(
DLM
) = (value >> 8) & 0xff;
222
mb
();
223
__UART0
(
LCR
) =
lcr
;
224
mb
();
225
226
}
/* end console_set_baud() */
227
228
/*****************************************************************************/
229
/*
230
*
231
*/
232
int
__init
console_get_baud
(
void
)
233
{
234
unsigned
value
;
235
u8
lcr
;
236
237
lcr =
__UART0
(
LCR
);
238
__UART0
(
LCR
) |=
UART_LCR_DLAB
;
239
mb
();
240
value =
__UART0
(
DLM
) << 8;
241
value |=
__UART0
(
DLL
);
242
__UART0
(
LCR
) =
lcr
;
243
mb
();
244
245
return
value
;
246
}
/* end console_get_baud() */
247
248
/*****************************************************************************/
249
/*
250
* display BUG() info
251
*/
252
#ifndef CONFIG_NO_KERNEL_MSG
253
void
__debug_bug_printk
(
const
char
*
file
,
unsigned
line
)
254
{
255
printk
(
"kernel BUG at %s:%d!\n"
, file, line);
256
257
}
/* end __debug_bug_printk() */
258
#endif
Generated on Thu Jan 10 2013 13:05:38 for Linux Kernel by
1.8.2