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
Kirill Smelkov
linux
Commits
fc8ab213
Commit
fc8ab213
authored
Sep 08, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/scratch/anton/export
into samba.org:/scratch/anton/linux-2.5_ppc64
parents
979bd8fe
4f6b41e5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
174 additions
and
300 deletions
+174
-300
arch/ppc64/Makefile
arch/ppc64/Makefile
+1
-1
arch/ppc64/kernel/irq.c
arch/ppc64/kernel/irq.c
+89
-28
arch/ppc64/kernel/process.c
arch/ppc64/kernel/process.c
+3
-64
arch/ppc64/xmon/xmon.c
arch/ppc64/xmon/xmon.c
+81
-207
No files found.
arch/ppc64/Makefile
View file @
fc8ab213
...
...
@@ -18,7 +18,7 @@ KERNELLOAD := 0xc000000000000000
LDFLAGS
:=
-m
elf64ppc
LDFLAGS_vmlinux
:=
-Bstatic
-e
$(KERNELLOAD)
-Ttext
$(KERNELLOAD)
CFLAGS
+=
-msoft-float
-pipe
-Wno-uninitialized
-mminimal-toc
\
-m
traceback
=
full
-m
cpu
=
power4
-mcpu
=
power4
have_zero_bss
:=
$(
shell
if
$(CC)
-fno-zero-initialized-in-bss
-S
-o
/dev/null
-xc
/dev/null
>
/dev/null 2>&1
;
then
echo
y
;
else
echo
n
;
fi
)
...
...
arch/ppc64/kernel/irq.c
View file @
fc8ab213
...
...
@@ -39,6 +39,7 @@
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
...
...
@@ -350,14 +351,11 @@ int show_interrupts(struct seq_file *p, void *v)
return
0
;
}
extern
char
*
ppc_find_proc_name
(
unsigned
*
p
,
char
*
buf
,
unsigned
buflen
);
static
inline
void
handle_irq_event
(
int
irq
,
struct
pt_regs
*
regs
,
struct
irqaction
*
action
)
static
inline
int
handle_irq_event
(
int
irq
,
struct
pt_regs
*
regs
,
struct
irqaction
*
action
)
{
int
status
=
0
;
int
retval
=
0
;
struct
irqaction
*
first_action
=
action
;
if
(
!
(
action
->
flags
&
SA_INTERRUPT
))
local_irq_enable
();
...
...
@@ -370,30 +368,90 @@ static inline void handle_irq_event(int irq, struct pt_regs *regs,
if
(
status
&
SA_SAMPLE_RANDOM
)
add_interrupt_randomness
(
irq
);
local_irq_disable
();
if
(
retval
!=
1
)
{
static
int
count
=
100
;
char
name_buf
[
256
];
if
(
count
)
{
count
--
;
if
(
retval
)
{
printk
(
"irq event %d: bogus retval mask %x
\n
"
,
irq
,
retval
);
}
else
{
printk
(
"irq %d: nobody cared!
\n
"
,
irq
);
}
dump_stack
();
printk
(
"handlers:
\n
"
);
action
=
first_action
;
do
{
printk
(
"[<%p>]"
,
action
->
handler
);
printk
(
" (%s)
\n
"
,
ppc_find_proc_name
((
unsigned
*
)
action
->
handler
,
name_buf
,
256
));
action
=
action
->
next
;
}
while
(
action
);
}
return
retval
;
}
static
void
__report_bad_irq
(
int
irq
,
irq_desc_t
*
desc
,
irqreturn_t
action_ret
)
{
struct
irqaction
*
action
;
if
(
action_ret
!=
IRQ_HANDLED
&&
action_ret
!=
IRQ_NONE
)
{
printk
(
KERN_ERR
"irq event %d: bogus return value %x
\n
"
,
irq
,
action_ret
);
}
else
{
printk
(
KERN_ERR
"irq %d: nobody cared!
\n
"
,
irq
);
}
dump_stack
();
printk
(
KERN_ERR
"handlers:
\n
"
);
action
=
desc
->
action
;
do
{
printk
(
KERN_ERR
"[<%p>]"
,
action
->
handler
);
print_symbol
(
" (%s)"
,
(
unsigned
long
)
action
->
handler
);
printk
(
"
\n
"
);
action
=
action
->
next
;
}
while
(
action
);
}
static
void
report_bad_irq
(
int
irq
,
irq_desc_t
*
desc
,
irqreturn_t
action_ret
)
{
static
int
count
=
100
;
if
(
count
)
{
count
--
;
__report_bad_irq
(
irq
,
desc
,
action_ret
);
}
}
static
int
noirqdebug
;
static
int
__init
noirqdebug_setup
(
char
*
str
)
{
noirqdebug
=
1
;
printk
(
"IRQ lockup detection disabled
\n
"
);
return
1
;
}
__setup
(
"noirqdebug"
,
noirqdebug_setup
);
/*
* If 99,900 of the previous 100,000 interrupts have not been handled then
* assume that the IRQ is stuck in some manner. Drop a diagnostic and try to
* turn the IRQ off.
*
* (The other 100-of-100,000 interrupts may have been a correctly-functioning
* device sharing an IRQ with the failing one)
*
* Called under desc->lock
*/
static
void
note_interrupt
(
int
irq
,
irq_desc_t
*
desc
,
irqreturn_t
action_ret
)
{
if
(
action_ret
!=
IRQ_HANDLED
)
{
desc
->
irqs_unhandled
++
;
if
(
action_ret
!=
IRQ_NONE
)
report_bad_irq
(
irq
,
desc
,
action_ret
);
}
desc
->
irq_count
++
;
if
(
desc
->
irq_count
<
100000
)
return
;
desc
->
irq_count
=
0
;
if
(
desc
->
irqs_unhandled
>
99900
)
{
/*
* The interrupt is stuck
*/
__report_bad_irq
(
irq
,
desc
,
action_ret
);
/*
* Now kill the IRQ
*/
printk
(
KERN_EMERG
"Disabling IRQ #%d
\n
"
,
irq
);
desc
->
status
|=
IRQ_DISABLED
;
desc
->
handler
->
disable
(
irq
);
}
desc
->
irqs_unhandled
=
0
;
}
/*
* Eventually, this should take an array of interrupts and an array size
* so it can dispatch multiple interrupts.
...
...
@@ -462,10 +520,13 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
* SMP environment.
*/
for
(;;)
{
irqreturn_t
action_ret
;
spin_unlock
(
&
desc
->
lock
);
handle_irq_event
(
irq
,
regs
,
action
);
action_ret
=
handle_irq_event
(
irq
,
regs
,
action
);
spin_lock
(
&
desc
->
lock
);
if
(
!
noirqdebug
)
note_interrupt
(
irq
,
desc
,
action_ret
);
if
(
likely
(
!
(
desc
->
status
&
IRQ_PENDING
)))
break
;
desc
->
status
&=
~
IRQ_PENDING
;
...
...
arch/ppc64/kernel/process.c
View file @
fc8ab213
...
...
@@ -32,6 +32,7 @@
#include <linux/init_task.h>
#include <linux/prctl.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
...
...
@@ -130,12 +131,9 @@ struct task_struct *__switch_to(struct task_struct *prev,
return
last
;
}
char
*
ppc_find_proc_name
(
unsigned
*
p
,
char
*
buf
,
unsigned
buflen
);
void
show_regs
(
struct
pt_regs
*
regs
)
{
int
i
;
char
name_buf
[
256
];
printk
(
"NIP: %016lX XER: %016lX LR: %016lX
\n
"
,
regs
->
nip
,
regs
->
xer
,
regs
->
link
);
...
...
@@ -170,8 +168,7 @@ void show_regs(struct pt_regs * regs)
* above info out without failing
*/
printk
(
"NIP [%016lx] "
,
regs
->
nip
);
printk
(
"%s
\n
"
,
ppc_find_proc_name
((
unsigned
*
)
regs
->
nip
,
name_buf
,
256
));
print_symbol
(
"%s
\n
"
,
regs
->
nip
);
show_stack
(
current
,
(
unsigned
long
*
)
regs
->
gpr
[
1
]);
}
...
...
@@ -385,62 +382,6 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
return
error
;
}
char
*
ppc_find_proc_name
(
unsigned
*
p
,
char
*
buf
,
unsigned
buflen
)
{
unsigned
long
tb_flags
;
unsigned
short
name_len
;
unsigned
long
tb_start
,
code_start
,
code_ptr
,
code_offset
;
unsigned
int
code_len
;
unsigned
long
end
;
strcpy
(
buf
,
"Unknown"
);
code_ptr
=
(
unsigned
long
)
p
;
code_offset
=
0
;
/* handle functions in text and init sections */
if
(((
unsigned
long
)
p
>=
(
unsigned
long
)
_stext
)
&&
((
unsigned
long
)
p
<
(
unsigned
long
)
_etext
))
end
=
(
unsigned
long
)
_etext
;
else
if
(((
unsigned
long
)
p
>=
(
unsigned
long
)
__init_begin
)
&&
((
unsigned
long
)
p
<
(
unsigned
long
)
__init_end
))
end
=
(
unsigned
long
)
__init_end
;
else
return
buf
;
while
((
unsigned
long
)
p
<
end
)
{
if
(
*
p
==
0
)
{
tb_start
=
(
unsigned
long
)
p
;
++
p
;
/* Point to traceback flags */
tb_flags
=
*
((
unsigned
long
*
)
p
);
p
+=
2
;
/* Skip over traceback flags */
if
(
tb_flags
&
TB_NAME_PRESENT
)
{
if
(
tb_flags
&
TB_PARMINFO
)
++
p
;
/* skip over parminfo data */
if
(
tb_flags
&
TB_HAS_TBOFF
)
{
code_len
=
*
p
;
/* get code length */
code_start
=
tb_start
-
code_len
;
code_offset
=
code_ptr
-
code_start
+
1
;
if
(
code_offset
>
0x100000
)
break
;
++
p
;
/* skip over code size */
}
name_len
=
*
((
unsigned
short
*
)
p
);
if
(
name_len
>
(
buflen
-
20
))
name_len
=
buflen
-
20
;
memcpy
(
buf
,
((
char
*
)
p
)
+
2
,
name_len
);
buf
[
name_len
]
=
0
;
if
(
code_offset
)
sprintf
(
buf
+
name_len
,
"+0x%lx"
,
code_offset
-
1
);
}
break
;
}
++
p
;
}
return
buf
;
}
/*
* These bracket the sleeping functions..
*/
...
...
@@ -480,7 +421,6 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
unsigned
long
ip
;
unsigned
long
stack_page
=
(
unsigned
long
)
p
->
thread_info
;
int
count
=
0
;
char
name_buf
[
256
];
unsigned
long
sp
=
(
unsigned
long
)
_sp
;
if
(
!
p
)
...
...
@@ -499,8 +439,7 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
if
(
__get_user
(
ip
,
(
unsigned
long
*
)(
sp
+
16
)))
break
;
printk
(
"[%016lx] "
,
ip
);
printk
(
"%s
\n
"
,
ppc_find_proc_name
((
unsigned
*
)
ip
,
name_buf
,
256
));
print_symbol
(
"%s
\n
"
,
ip
);
}
while
(
count
++
<
32
);
}
...
...
arch/ppc64/xmon/xmon.c
View file @
fc8ab213
...
...
@@ -15,6 +15,8 @@
#include <linux/mm.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/kallsyms.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
...
...
@@ -27,6 +29,7 @@
#include <asm/paca.h>
#include <asm/ppcdebug.h>
#include <asm/cputable.h>
#include "nonstdio.h"
#include "privinst.h"
...
...
@@ -59,7 +62,6 @@ struct bpt {
unsigned
instr
;
unsigned
long
count
;
unsigned
char
enabled
;
char
funcname
[
64
];
/* function name for humans */
};
#define NBPTS 16
...
...
@@ -79,10 +81,6 @@ static void memex(void);
static
int
bsesc
(
void
);
static
void
dump
(
void
);
static
void
prdump
(
unsigned
long
,
long
);
#ifdef __MWERKS__
static
void
prndump
(
unsigned
,
int
);
static
int
nvreadb
(
unsigned
);
#endif
static
int
ppc_inst_dump
(
unsigned
long
,
long
);
void
print_address
(
unsigned
long
);
static
int
getsp
(
void
);
...
...
@@ -105,7 +103,6 @@ static void take_input(char *);
static
unsigned
long
read_spr
(
int
);
static
void
write_spr
(
int
,
unsigned
long
);
static
void
super_regs
(
void
);
static
void
print_sysmap
(
void
);
static
void
remove_bpts
(
void
);
static
void
insert_bpts
(
void
);
static
struct
bpt
*
at_breakpoint
(
unsigned
long
pc
);
...
...
@@ -181,6 +178,13 @@ static int xmon_trace[NR_CPUS];
static
struct
pt_regs
*
xmon_regs
[
NR_CPUS
];
void
__xmon_print_symbol
(
const
char
*
fmt
,
unsigned
long
address
);
#define xmon_print_symbol(fmt, addr) \
do { \
__check_printsym_format(fmt, ""); \
__xmon_print_symbol(fmt, addr); \
} while(0)
/*
* Stuff for reading and writing memory safely
*/
...
...
@@ -209,42 +213,6 @@ extern inline void sync(void)
no functions have been called from the current function.
*/
/*
A traceback table typically follows each function.
The find_tb_table() func will fill in this struct. Note that the struct
is not an exact match with the encoded table defined by the ABI. It is
defined here more for programming convenience.
*/
struct
tbtable
{
unsigned
long
flags
;
/* flags: */
#define TBTAB_FLAGSGLOBALLINK (1L<<47)
#define TBTAB_FLAGSISEPROL (1L<<46)
#define TBTAB_FLAGSHASTBOFF (1L<<45)
#define TBTAB_FLAGSINTPROC (1L<<44)
#define TBTAB_FLAGSHASCTL (1L<<43)
#define TBTAB_FLAGSTOCLESS (1L<<42)
#define TBTAB_FLAGSFPPRESENT (1L<<41)
#define TBTAB_FLAGSNAMEPRESENT (1L<<38)
#define TBTAB_FLAGSUSESALLOCA (1L<<37)
#define TBTAB_FLAGSSAVESCR (1L<<33)
#define TBTAB_FLAGSSAVESLR (1L<<32)
#define TBTAB_FLAGSSTORESBC (1L<<31)
#define TBTAB_FLAGSFIXUP (1L<<30)
#define TBTAB_FLAGSPARMSONSTK (1L<<0)
unsigned
char
fp_saved
;
/* num fp regs saved f(32-n)..f31 */
unsigned
char
gpr_saved
;
/* num gpr's saved */
unsigned
char
fixedparms
;
/* num fixed point parms */
unsigned
char
floatparms
;
/* num float parms */
unsigned
char
parminfo
[
32
];
/* types of args. null terminated */
#define TBTAB_PARMFIXED 1
#define TBTAB_PARMSFLOAT 2
#define TBTAB_PARMDFLOAT 3
unsigned
int
tb_offset
;
/* offset from start of func */
unsigned
long
funcstart
;
/* addr of start of function */
char
name
[
64
];
/* name of function (null terminated)*/
};
static
int
find_tb_table
(
unsigned
long
codeaddr
,
struct
tbtable
*
tab
);
#define SURVEILLANCE_TOKEN 9000
static
inline
void
disable_surveillance
(
void
)
...
...
@@ -302,8 +270,7 @@ xmon(struct pt_regs *excp)
std 29,232(%0)
\n
\
std 30,240(%0)
\n
\
std 31,248(%0)"
:
:
"b"
(
&
regs
));
/* Fetch the link reg for this stack frame.
NOTE: the prev printf fills in the lr. */
regs
.
nip
=
regs
.
link
=
((
unsigned
long
*
)(
regs
.
gpr
[
1
]))[
2
];
regs
.
msr
=
get_msr
();
regs
.
ctr
=
get_ctr
();
...
...
@@ -378,7 +345,9 @@ xmon_bpt(struct pt_regs *regs)
xmon_trace
[
smp_processor_id
()]
=
BRSTEP
;
regs
->
msr
|=
MSR_SE
;
}
else
{
printf
(
"Stopped at breakpoint %x (%lx %s)
\n
"
,
(
bp
-
bpts
)
+
1
,
bp
->
address
,
bp
->
funcname
);
printf
(
"Stopped at breakpoint %x (%lx "
,
(
bp
-
bpts
)
+
1
,
bp
->
address
);
xmon_print_symbol
(
"%s)
\n
"
,
bp
->
address
);
xmon
(
regs
);
}
return
1
;
...
...
@@ -576,9 +545,6 @@ cmds(struct pt_regs *excp)
else
excprint
(
excp
);
break
;
case
'M'
:
print_sysmap
();
break
;
case
'S'
:
super_regs
();
break
;
...
...
@@ -768,7 +734,6 @@ bpt_cmds(void)
unsigned
long
a
;
int
mode
,
i
;
struct
bpt
*
bp
;
struct
tbtable
tab
;
cmd
=
inchar
();
switch
(
cmd
)
{
...
...
@@ -824,7 +789,9 @@ bpt_cmds(void)
if
(
bp
==
0
)
{
printf
(
"No breakpoint at %x
\n
"
,
a
);
}
else
{
printf
(
"Cleared breakpoint %x (%lx %s)
\n
"
,
(
bp
-
bpts
)
+
1
,
bp
->
address
,
bp
->
funcname
);
printf
(
"Cleared breakpoint %x (%lx "
,
(
bp
-
bpts
)
+
1
,
bp
->
address
);
xmon_print_symbol
(
"%s)
\n
"
,
bp
->
address
);
bp
->
enabled
=
0
;
}
}
...
...
@@ -858,8 +825,11 @@ bpt_cmds(void)
printf
(
" inst %.16lx %8x
\n
"
,
iabr
.
address
&
~
3
,
iabr
.
count
);
for
(
bp
=
bpts
,
bpnum
=
1
;
bp
<
&
bpts
[
NBPTS
];
++
bp
,
++
bpnum
)
if
(
bp
->
enabled
)
printf
(
"%2x trap %.16lx %8x %s
\n
"
,
bpnum
,
bp
->
address
,
bp
->
count
,
bp
->
funcname
);
if
(
bp
->
enabled
)
{
printf
(
"%2x trap %.16lx %8x "
,
bpnum
,
bp
->
address
,
bp
->
count
);
xmon_print_symbol
(
"%s
\n
"
,
bp
->
address
);
}
break
;
}
bp
=
at_breakpoint
(
a
);
...
...
@@ -876,14 +846,9 @@ bpt_cmds(void)
bp
->
address
=
a
;
bp
->
count
=
0
;
scanhex
(
&
bp
->
count
);
/* Find the function name just once. */
bp
->
funcname
[
0
]
=
'\0'
;
if
(
find_tb_table
(
bp
->
address
,
&
tab
)
&&
tab
.
name
[
0
])
{
/* Got a nice name for it. */
int
delta
=
bp
->
address
-
tab
.
funcstart
;
sprintf
(
bp
->
funcname
,
"%s+0x%x"
,
tab
.
name
,
delta
);
}
printf
(
"Set breakpoint %2x trap %.16lx %8x %s
\n
"
,
(
bp
-
bpts
)
+
1
,
bp
->
address
,
bp
->
count
,
bp
->
funcname
);
printf
(
"Set breakpoint %2x trap %.16lx %8x "
,
(
bp
-
bpts
)
+
1
,
bp
->
address
,
bp
->
count
);
xmon_print_symbol
(
"%s
\n
"
,
bp
->
address
);
break
;
}
}
...
...
@@ -920,7 +885,6 @@ backtrace(struct pt_regs *excp)
unsigned
long
lr
;
unsigned
long
stack
[
3
];
struct
pt_regs
regs
;
struct
tbtable
tab
;
int
framecount
;
char
*
funcname
;
/* declare these as raw ptrs so we don't get func descriptors */
...
...
@@ -966,14 +930,8 @@ backtrace(struct pt_regs *excp)
break
;
printf
(
"exception: %lx %s regs %lx
\n
"
,
regs
.
trap
,
getvecname
(
regs
.
trap
),
sp
+
112
);
printf
(
" %.16lx"
,
regs
.
nip
);
if
((
regs
.
nip
&
0xffffffff00000000UL
)
&&
find_tb_table
(
regs
.
nip
,
&
tab
))
{
int
delta
=
regs
.
nip
-
tab
.
funcstart
;
if
(
delta
<
0
)
printf
(
" <unknown code>"
);
else
printf
(
" %s+0x%x"
,
tab
.
name
,
delta
);
}
if
(
regs
.
nip
&
0xffffffff00000000UL
)
xmon_print_symbol
(
" %s"
,
regs
.
nip
);
printf
(
"
\n
"
);
if
(
regs
.
gpr
[
1
]
<
sp
)
{
printf
(
"<Stack drops into userspace %.16lx>
\n
"
,
regs
.
gpr
[
1
]);
...
...
@@ -984,13 +942,8 @@ backtrace(struct pt_regs *excp)
if
(
mread
(
sp
,
stack
,
sizeof
(
stack
))
!=
sizeof
(
stack
))
break
;
}
else
{
if
(
stack
[
2
]
&&
find_tb_table
(
stack
[
2
],
&
tab
))
{
int
delta
=
stack
[
2
]
-
tab
.
funcstart
;
if
(
delta
<
0
)
printf
(
" <unknown code>"
);
else
printf
(
" %s+0x%x"
,
tab
.
name
,
delta
);
}
if
(
stack
[
2
])
xmon_print_symbol
(
" %s"
,
stack
[
2
]);
printf
(
"
\n
"
);
}
if
(
stack
[
0
]
&&
stack
[
0
]
<=
sp
)
{
...
...
@@ -1019,8 +972,6 @@ spinlock_t exception_print_lock = SPIN_LOCK_UNLOCKED;
void
excprint
(
struct
pt_regs
*
fp
)
{
struct
task_struct
*
c
;
struct
tbtable
tab
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
exception_print_lock
,
flags
);
...
...
@@ -1029,21 +980,13 @@ excprint(struct pt_regs *fp)
printf
(
"cpu %d: "
,
smp_processor_id
());
#endif
/* CONFIG_SMP */
printf
(
"Vector: %lx %s at
[%lx]
\n
"
,
fp
->
trap
,
getvecname
(
fp
->
trap
),
fp
);
printf
(
"Vector: %lx %s at [%lx]
\n
"
,
fp
->
trap
,
getvecname
(
fp
->
trap
),
fp
);
printf
(
" pc: %lx"
,
fp
->
nip
);
if
(
find_tb_table
(
fp
->
nip
,
&
tab
)
&&
tab
.
name
[
0
])
{
/* Got a nice name for it */
int
delta
=
fp
->
nip
-
tab
.
funcstart
;
printf
(
" (%s+0x%x)"
,
tab
.
name
,
delta
);
}
printf
(
"
\n
"
);
xmon_print_symbol
(
" (%s)
\n
"
,
fp
->
nip
);
printf
(
" lr: %lx"
,
fp
->
link
);
if
(
find_tb_table
(
fp
->
link
,
&
tab
)
&&
tab
.
name
[
0
])
{
/* Got a nice name for it */
int
delta
=
fp
->
link
-
tab
.
funcstart
;
printf
(
" (%s+0x%x)"
,
tab
.
name
,
delta
);
}
printf
(
"
\n
"
);
xmon_print_symbol
(
" (%s)
\n
"
,
fp
->
link
);
printf
(
" sp: %lx
\n
"
,
fp
->
gpr
[
1
]);
printf
(
" msr: %lx
\n
"
,
fp
->
msr
);
...
...
@@ -1052,13 +995,11 @@ excprint(struct pt_regs *fp)
printf
(
" dsisr: %lx
\n
"
,
fp
->
dsisr
);
}
/* XXX: need to copy current or we die. Why? */
c
=
current
;
printf
(
" current = 0x%lx
\n
"
,
c
);
printf
(
" current = 0x%lx
\n
"
,
current
);
printf
(
" paca = 0x%lx
\n
"
,
get_paca
());
if
(
c
)
{
printf
(
"
current = %lx, pid
= %ld, comm = %s
\n
"
,
c
,
c
->
pid
,
c
->
comm
);
if
(
c
urrent
)
{
printf
(
"
pid
= %ld, comm = %s
\n
"
,
c
urrent
->
pid
,
current
->
comm
);
}
spin_unlock_irqrestore
(
&
exception_print_lock
,
flags
);
...
...
@@ -1147,14 +1088,6 @@ static unsigned long regno;
extern
char
exc_prolog
;
extern
char
dec_exc
;
void
print_sysmap
(
void
)
{
extern
char
*
sysmap
;
if
(
sysmap
)
printf
(
"System.map:
\n
%s"
,
sysmap
);
}
void
super_regs
()
{
...
...
@@ -1922,111 +1855,52 @@ char *str;
lineptr
=
str
;
}
/* Starting at codeaddr scan forward for a tbtable and fill in the
given table. Return non-zero if successful at doing something.
*/
static
int
find_tb_table
(
unsigned
long
codeaddr
,
struct
tbtable
*
tab
)
/* xmon version of __print_symbol */
void
__xmon_print_symbol
(
const
char
*
fmt
,
unsigned
long
address
)
{
unsigned
long
codeaddr_max
;
unsigned
long
tbtab_start
;
int
nr
;
int
instr
;
int
num_parms
;
/* don't look for traceback table in userspace */
if
(
codeaddr
<
PAGE_OFFSET
)
return
0
;
char
*
modname
;
const
char
*
name
;
unsigned
long
offset
,
size
;
char
namebuf
[
128
];
if
(
tab
==
NULL
)
return
0
;
memset
(
tab
,
0
,
sizeof
(
tab
));
/* Scan instructions starting at codeaddr for 128k max */
for
(
codeaddr_max
=
codeaddr
+
128
*
1024
*
4
;
codeaddr
<
codeaddr_max
;
codeaddr
+=
4
)
{
nr
=
mread
(
codeaddr
,
&
instr
,
4
);
if
(
nr
!=
4
)
return
0
;
/* Bad read. Give up promptly. */
if
(
instr
==
0
)
{
/* table should follow. */
int
version
;
unsigned
long
flags
;
tbtab_start
=
codeaddr
;
/* save it to compute func start addr */
codeaddr
+=
4
;
nr
=
mread
(
codeaddr
,
&
flags
,
8
);
if
(
nr
!=
8
)
return
0
;
/* Bad read or no tb table. */
tab
->
flags
=
flags
;
version
=
(
flags
>>
56
)
&
0xff
;
if
(
version
!=
0
)
continue
;
/* No tb table here. */
/* Now, like the version, some of the flags are values
that are more conveniently extracted... */
tab
->
fp_saved
=
(
flags
>>
24
)
&
0x3f
;
tab
->
gpr_saved
=
(
flags
>>
16
)
&
0x3f
;
tab
->
fixedparms
=
(
flags
>>
8
)
&
0xff
;
tab
->
floatparms
=
(
flags
>>
1
)
&
0x7f
;
codeaddr
+=
8
;
num_parms
=
tab
->
fixedparms
+
tab
->
floatparms
;
if
(
num_parms
)
{
unsigned
int
parminfo
;
int
parm
;
if
(
num_parms
>
32
)
return
1
;
/* incomplete */
nr
=
mread
(
codeaddr
,
&
parminfo
,
4
);
if
(
nr
!=
4
)
return
1
;
/* incomplete */
/* decode parminfo...32 bits.
A zero means fixed. A one means float and the
following bit determines single (0) or double (1).
*/
for
(
parm
=
0
;
parm
<
num_parms
;
parm
++
)
{
if
(
parminfo
&
0x80000000
)
{
parminfo
<<=
1
;
if
(
parminfo
&
0x80000000
)
tab
->
parminfo
[
parm
]
=
TBTAB_PARMDFLOAT
;
else
tab
->
parminfo
[
parm
]
=
TBTAB_PARMSFLOAT
;
}
else
{
tab
->
parminfo
[
parm
]
=
TBTAB_PARMFIXED
;
}
parminfo
<<=
1
;
}
codeaddr
+=
4
;
}
if
(
flags
&
TBTAB_FLAGSHASTBOFF
)
{
nr
=
mread
(
codeaddr
,
&
tab
->
tb_offset
,
4
);
if
(
nr
!=
4
)
return
1
;
/* incomplete */
if
(
tab
->
tb_offset
>
0
)
{
tab
->
funcstart
=
tbtab_start
-
tab
->
tb_offset
;
}
codeaddr
+=
4
;
}
/* hand_mask appears to be always be omitted. */
if
(
flags
&
TBTAB_FLAGSHASCTL
)
{
/* Assume this will never happen for C or asm */
return
1
;
/* incomplete */
}
if
(
flags
&
TBTAB_FLAGSNAMEPRESENT
)
{
short
namlen
;
nr
=
mread
(
codeaddr
,
&
namlen
,
2
);
if
(
nr
!=
2
)
return
1
;
/* incomplete */
if
(
namlen
>=
sizeof
(
tab
->
name
))
namlen
=
sizeof
(
tab
->
name
)
-
1
;
codeaddr
+=
2
;
nr
=
mread
(
codeaddr
,
tab
->
name
,
namlen
);
tab
->
name
[
namlen
]
=
'\0'
;
codeaddr
+=
namlen
;
}
return
1
;
}
if
(
setjmp
(
bus_error_jmp
)
==
0
)
{
debugger_fault_handler
=
handle_fault
;
sync
();
name
=
kallsyms_lookup
(
address
,
&
size
,
&
offset
,
&
modname
,
namebuf
);
sync
();
/* wait a little while to see if we get a machine check */
__delay
(
200
);
}
else
{
name
=
"symbol lookup failed"
;
}
debugger_fault_handler
=
0
;
if
(
!
name
)
{
char
addrstr
[
sizeof
(
"0x%lx"
)
+
(
BITS_PER_LONG
*
3
/
10
)];
sprintf
(
addrstr
,
"0x%lx"
,
address
);
printf
(
fmt
,
addrstr
);
return
;
}
if
(
modname
)
{
/* This is pretty small. */
char
buffer
[
sizeof
(
"%s+%#lx/%#lx [%s]"
)
+
strlen
(
name
)
+
2
*
(
BITS_PER_LONG
*
3
/
10
)
+
strlen
(
modname
)];
sprintf
(
buffer
,
"%s+%#lx/%#lx [%s]"
,
name
,
offset
,
size
,
modname
);
printf
(
fmt
,
buffer
);
}
else
{
char
buffer
[
sizeof
(
"%s+%#lx/%#lx"
)
+
strlen
(
name
)
+
2
*
(
BITS_PER_LONG
*
3
/
10
)];
sprintf
(
buffer
,
"%s+%#lx/%#lx"
,
name
,
offset
,
size
);
printf
(
fmt
,
buffer
);
}
return
0
;
/* hit max...sorry. */
}
void
...
...
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