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
d33a40e5
Commit
d33a40e5
authored
Sep 08, 2003
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/home/paulus/kernel/linux-2.5
into samba.org:/home/paulus/kernel/for-linus-ppc
parents
79b8787e
2550d7f1
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
531 additions
and
344 deletions
+531
-344
arch/ppc/kernel/align.c
arch/ppc/kernel/align.c
+17
-15
arch/ppc/kernel/asm-offsets.c
arch/ppc/kernel/asm-offsets.c
+2
-1
arch/ppc/kernel/head.S
arch/ppc/kernel/head.S
+2
-0
arch/ppc/kernel/misc.S
arch/ppc/kernel/misc.S
+1
-1
arch/ppc/kernel/process.c
arch/ppc/kernel/process.c
+1
-0
arch/ppc/kernel/signal.c
arch/ppc/kernel/signal.c
+352
-255
arch/ppc/kernel/traps.c
arch/ppc/kernel/traps.c
+128
-60
include/asm-ppc/bitops.h
include/asm-ppc/bitops.h
+4
-4
include/asm-ppc/highmem.h
include/asm-ppc/highmem.h
+3
-2
include/asm-ppc/processor.h
include/asm-ppc/processor.h
+1
-0
include/asm-ppc/ucontext.h
include/asm-ppc/ucontext.h
+20
-6
No files found.
arch/ppc/kernel/align.c
View file @
d33a40e5
...
@@ -21,11 +21,11 @@ struct aligninfo {
...
@@ -21,11 +21,11 @@ struct aligninfo {
unsigned
char
flags
;
unsigned
char
flags
;
};
};
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx)
|| defined(CONFIG_POWER4)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RA(inst) (((inst) & 0x001F0000) >> 16)
#define RA(inst) (((inst) & 0x001F0000) >> 16)
#define IS_
DFORM(code) ((code) >= 32 && (code) <= 55
)
#define IS_
XFORM(code) ((code) == 31
)
#endif
#endif
#define INVALID { 0, 0 }
#define INVALID { 0, 0 }
...
@@ -61,9 +61,9 @@ static struct aligninfo aligninfo[128] = {
...
@@ -61,9 +61,9 @@ static struct aligninfo aligninfo[128] = {
{
4
,
ST
+
F
+
S
},
/* 00 0 1010: stfs */
{
4
,
ST
+
F
+
S
},
/* 00 0 1010: stfs */
{
8
,
ST
+
F
},
/* 00 0 1011: stfd */
{
8
,
ST
+
F
},
/* 00 0 1011: stfd */
INVALID
,
/* 00 0 1100 */
INVALID
,
/* 00 0 1100 */
INVALID
,
/* 00 0 1101 */
INVALID
,
/* 00 0 1101
: ld/ldu/lwa
*/
INVALID
,
/* 00 0 1110 */
INVALID
,
/* 00 0 1110 */
INVALID
,
/* 00 0 1111 */
INVALID
,
/* 00 0 1111
: std/stdu
*/
{
4
,
LD
+
U
},
/* 00 1 0000: lwzu */
{
4
,
LD
+
U
},
/* 00 1 0000: lwzu */
INVALID
,
/* 00 1 0001 */
INVALID
,
/* 00 1 0001 */
{
4
,
ST
+
U
},
/* 00 1 0010: stwu */
{
4
,
ST
+
U
},
/* 00 1 0010: stwu */
...
@@ -80,12 +80,12 @@ static struct aligninfo aligninfo[128] = {
...
@@ -80,12 +80,12 @@ static struct aligninfo aligninfo[128] = {
INVALID
,
/* 00 1 1101 */
INVALID
,
/* 00 1 1101 */
INVALID
,
/* 00 1 1110 */
INVALID
,
/* 00 1 1110 */
INVALID
,
/* 00 1 1111 */
INVALID
,
/* 00 1 1111 */
INVALID
,
/* 01 0 0000 */
INVALID
,
/* 01 0 0000
: ldx
*/
INVALID
,
/* 01 0 0001 */
INVALID
,
/* 01 0 0001 */
INVALID
,
/* 01 0 0010 */
INVALID
,
/* 01 0 0010
: stdx
*/
INVALID
,
/* 01 0 0011 */
INVALID
,
/* 01 0 0011 */
INVALID
,
/* 01 0 0100 */
INVALID
,
/* 01 0 0100 */
INVALID
,
/* 01 0 0101: lwax
??
*/
INVALID
,
/* 01 0 0101: lwax */
INVALID
,
/* 01 0 0110 */
INVALID
,
/* 01 0 0110 */
INVALID
,
/* 01 0 0111 */
INVALID
,
/* 01 0 0111 */
{
0
,
LD
+
HARD
},
/* 01 0 1000: lswx */
{
0
,
LD
+
HARD
},
/* 01 0 1000: lswx */
...
@@ -96,12 +96,12 @@ static struct aligninfo aligninfo[128] = {
...
@@ -96,12 +96,12 @@ static struct aligninfo aligninfo[128] = {
INVALID
,
/* 01 0 1101 */
INVALID
,
/* 01 0 1101 */
INVALID
,
/* 01 0 1110 */
INVALID
,
/* 01 0 1110 */
INVALID
,
/* 01 0 1111 */
INVALID
,
/* 01 0 1111 */
INVALID
,
/* 01 1 0000 */
INVALID
,
/* 01 1 0000
: ldux
*/
INVALID
,
/* 01 1 0001 */
INVALID
,
/* 01 1 0001 */
INVALID
,
/* 01 1 0010 */
INVALID
,
/* 01 1 0010
: stdux
*/
INVALID
,
/* 01 1 0011 */
INVALID
,
/* 01 1 0011 */
INVALID
,
/* 01 1 0100 */
INVALID
,
/* 01 1 0100 */
INVALID
,
/* 01 1 0101: lwaux
??
*/
INVALID
,
/* 01 1 0101: lwaux */
INVALID
,
/* 01 1 0110 */
INVALID
,
/* 01 1 0110 */
INVALID
,
/* 01 1 0111 */
INVALID
,
/* 01 1 0111 */
INVALID
,
/* 01 1 1000 */
INVALID
,
/* 01 1 1000 */
...
@@ -157,9 +157,9 @@ static struct aligninfo aligninfo[128] = {
...
@@ -157,9 +157,9 @@ static struct aligninfo aligninfo[128] = {
{
4
,
ST
+
F
+
S
},
/* 11 0 1010: stfsx */
{
4
,
ST
+
F
+
S
},
/* 11 0 1010: stfsx */
{
8
,
ST
+
F
},
/* 11 0 1011: stfdx */
{
8
,
ST
+
F
},
/* 11 0 1011: stfdx */
INVALID
,
/* 11 0 1100 */
INVALID
,
/* 11 0 1100 */
INVALID
,
/* 11 0 1101 */
INVALID
,
/* 11 0 1101
: lmd
*/
INVALID
,
/* 11 0 1110 */
INVALID
,
/* 11 0 1110 */
INVALID
,
/* 11 0 1111 */
INVALID
,
/* 11 0 1111
: stmd
*/
{
4
,
LD
+
U
},
/* 11 1 0000: lwzux */
{
4
,
LD
+
U
},
/* 11 1 0000: lwzux */
INVALID
,
/* 11 1 0001 */
INVALID
,
/* 11 1 0001 */
{
4
,
ST
+
U
},
/* 11 1 0010: stwux */
{
4
,
ST
+
U
},
/* 11 1 0010: stwux */
...
@@ -184,7 +184,7 @@ int
...
@@ -184,7 +184,7 @@ int
fix_alignment
(
struct
pt_regs
*
regs
)
fix_alignment
(
struct
pt_regs
*
regs
)
{
{
int
instr
,
nb
,
flags
;
int
instr
,
nb
,
flags
;
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx)
|| defined(CONFIG_POWER4)
int
opcode
,
f1
,
f2
,
f3
;
int
opcode
,
f1
,
f2
,
f3
;
#endif
#endif
int
i
,
t
;
int
i
,
t
;
...
@@ -199,9 +199,11 @@ fix_alignment(struct pt_regs *regs)
...
@@ -199,9 +199,11 @@ fix_alignment(struct pt_regs *regs)
CHECK_FULL_REGS
(
regs
);
CHECK_FULL_REGS
(
regs
);
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx)
|| defined(CONFIG_POWER4)
/* The 4xx-family processors have no DSISR register,
/* The 4xx-family processors have no DSISR register,
* so we emulate it.
* so we emulate it.
* The POWER4 has a DSISR register but doesn't set it on
* an alignment fault. -- paulus
*/
*/
instr
=
*
((
unsigned
int
*
)
regs
->
nip
);
instr
=
*
((
unsigned
int
*
)
regs
->
nip
);
...
@@ -209,7 +211,7 @@ fix_alignment(struct pt_regs *regs)
...
@@ -209,7 +211,7 @@ fix_alignment(struct pt_regs *regs)
reg
=
RS
(
instr
);
reg
=
RS
(
instr
);
areg
=
RA
(
instr
);
areg
=
RA
(
instr
);
if
(
IS_D
FORM
(
opcode
))
{
if
(
!
IS_X
FORM
(
opcode
))
{
f1
=
0
;
f1
=
0
;
f2
=
(
instr
&
0x04000000
)
>>
26
;
f2
=
(
instr
&
0x04000000
)
>>
26
;
f3
=
(
instr
&
0x78000000
)
>>
27
;
f3
=
(
instr
&
0x78000000
)
>>
27
;
...
...
arch/ppc/kernel/asm-offsets.c
View file @
d33a40e5
...
@@ -52,6 +52,7 @@ main(void)
...
@@ -52,6 +52,7 @@ main(void)
DEFINE
(
THREAD_VR0
,
offsetof
(
struct
thread_struct
,
vr
[
0
]));
DEFINE
(
THREAD_VR0
,
offsetof
(
struct
thread_struct
,
vr
[
0
]));
DEFINE
(
THREAD_VRSAVE
,
offsetof
(
struct
thread_struct
,
vrsave
));
DEFINE
(
THREAD_VRSAVE
,
offsetof
(
struct
thread_struct
,
vrsave
));
DEFINE
(
THREAD_VSCR
,
offsetof
(
struct
thread_struct
,
vscr
));
DEFINE
(
THREAD_VSCR
,
offsetof
(
struct
thread_struct
,
vscr
));
DEFINE
(
THREAD_USED_VR
,
offsetof
(
struct
thread_struct
,
used_vr
));
#endif
/* CONFIG_ALTIVEC */
#endif
/* CONFIG_ALTIVEC */
/* Interrupt register frame */
/* Interrupt register frame */
DEFINE
(
STACK_FRAME_OVERHEAD
,
STACK_FRAME_OVERHEAD
);
DEFINE
(
STACK_FRAME_OVERHEAD
,
STACK_FRAME_OVERHEAD
);
...
@@ -101,7 +102,7 @@ main(void)
...
@@ -101,7 +102,7 @@ main(void)
DEFINE
(
_XER
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
xer
));
DEFINE
(
_XER
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
xer
));
DEFINE
(
_DAR
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
dar
));
DEFINE
(
_DAR
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
dar
));
DEFINE
(
_DSISR
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
dsisr
));
DEFINE
(
_DSISR
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
dsisr
));
/* The PowerPC 400-class processors have neither the DAR nor the DSISR
/* The PowerPC 400-class
& Book-E
processors have neither the DAR nor the DSISR
* SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
* SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
* for such processors. For critical interrupts we use them to
* for such processors. For critical interrupts we use them to
* hold SRR0 and SRR1.
* hold SRR0 and SRR1.
...
...
arch/ppc/kernel/head.S
View file @
d33a40e5
...
@@ -915,7 +915,9 @@ load_up_altivec:
...
@@ -915,7 +915,9 @@ load_up_altivec:
/
*
enable
use
of
AltiVec
after
return
*/
/
*
enable
use
of
AltiVec
after
return
*/
oris
r9
,
r9
,
MSR_VEC
@
h
oris
r9
,
r9
,
MSR_VEC
@
h
mfspr
r5
,
SPRG3
/*
current
task
's THREAD (phys) */
mfspr
r5
,
SPRG3
/*
current
task
's THREAD (phys) */
li
r4
,
1
li
r10
,
THREAD_VSCR
li
r10
,
THREAD_VSCR
stw
r4
,
THREAD_USED_VR
(
r5
)
lvx
vr0
,
r10
,
r5
lvx
vr0
,
r10
,
r5
mtvscr
vr0
mtvscr
vr0
REST_32VR
(0,
r10
,
r5
)
REST_32VR
(0,
r10
,
r5
)
...
...
arch/ppc/kernel/misc.S
View file @
d33a40e5
...
@@ -1379,7 +1379,7 @@ _GLOBAL(sys_call_table)
...
@@ -1379,7 +1379,7 @@ _GLOBAL(sys_call_table)
.
long
sys_clock_gettime
.
long
sys_clock_gettime
.
long
sys_clock_getres
.
long
sys_clock_getres
.
long
sys_clock_nanosleep
.
long
sys_clock_nanosleep
.
long
sys_
ni_syscall
/*
reserved
for
swapcontext
*/
.
long
sys_
swapcontext
.
long
sys_tgkill
/*
250
*/
.
long
sys_tgkill
/*
250
*/
.
long
sys_utimes
.
long
sys_utimes
.
long
sys_statfs64
.
long
sys_statfs64
...
...
arch/ppc/kernel/process.c
View file @
d33a40e5
...
@@ -415,6 +415,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
...
@@ -415,6 +415,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
memset
(
current
->
thread
.
vr
,
0
,
sizeof
(
current
->
thread
.
vr
));
memset
(
current
->
thread
.
vr
,
0
,
sizeof
(
current
->
thread
.
vr
));
memset
(
&
current
->
thread
.
vscr
,
0
,
sizeof
(
current
->
thread
.
vscr
));
memset
(
&
current
->
thread
.
vscr
,
0
,
sizeof
(
current
->
thread
.
vscr
));
current
->
thread
.
vrsave
=
0
;
current
->
thread
.
vrsave
=
0
;
current
->
thread
.
used_vr
=
0
;
#endif
/* CONFIG_ALTIVEC */
#endif
/* CONFIG_ALTIVEC */
}
}
...
...
arch/ppc/kernel/signal.c
View file @
d33a40e5
This diff is collapsed.
Click to expand it.
arch/ppc/kernel/traps.c
View file @
d33a40e5
...
@@ -95,14 +95,19 @@ void die(const char * str, struct pt_regs * fp, long err)
...
@@ -95,14 +95,19 @@ void die(const char * str, struct pt_regs * fp, long err)
}
}
void
void
_exception
(
int
signr
,
struct
pt_regs
*
regs
)
_exception
(
int
signr
,
struct
pt_regs
*
regs
,
int
code
,
unsigned
long
addr
)
{
{
if
(
!
user_mode
(
regs
))
siginfo_t
info
;
{
if
(
!
user_mode
(
regs
))
{
debugger
(
regs
);
debugger
(
regs
);
die
(
"Exception in kernel mode"
,
regs
,
signr
);
die
(
"Exception in kernel mode"
,
regs
,
signr
);
}
}
force_sig
(
signr
,
current
);
info
.
si_signo
=
signr
;
info
.
si_errno
=
0
;
info
.
si_code
=
code
;
info
.
si_addr
=
(
void
*
)
addr
;
force_sig_info
(
signr
,
&
info
,
current
);
}
}
/*
/*
...
@@ -154,12 +159,40 @@ static inline int check_io_access(struct pt_regs *regs)
...
@@ -154,12 +159,40 @@ static inline int check_io_access(struct pt_regs *regs)
return
0
;
return
0
;
}
}
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
/* On 4xx, the reason for the machine check or program exception
is in the ESR. */
#define get_reason(regs) ((regs)->dsisr)
#define REASON_FP 0
#define REASON_ILLEGAL ESR_PIL
#define REASON_PRIVILEGED ESR_PPR
#define REASON_TRAP ESR_PTR
/* single-step stuff */
#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC)
#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC)
#else
/* On non-4xx, the reason for the machine check or program
exception is in the MSR. */
#define get_reason(regs) ((regs)->msr)
#define REASON_FP 0x100000
#define REASON_ILLEGAL 0x80000
#define REASON_PRIVILEGED 0x40000
#define REASON_TRAP 0x20000
#define single_stepping(regs) ((regs)->msr & MSR_SE)
#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
#endif
void
void
MachineCheckException
(
struct
pt_regs
*
regs
)
MachineCheckException
(
struct
pt_regs
*
regs
)
{
{
unsigned
long
reason
=
get_reason
(
regs
);
if
(
user_mode
(
regs
))
{
if
(
user_mode
(
regs
))
{
regs
->
msr
|=
MSR_RI
;
regs
->
msr
|=
MSR_RI
;
_exception
(
SIG
SEGV
,
regs
);
_exception
(
SIG
BUS
,
regs
,
BUS_ADRERR
,
regs
->
nip
);
return
;
return
;
}
}
...
@@ -178,10 +211,18 @@ MachineCheckException(struct pt_regs *regs)
...
@@ -178,10 +211,18 @@ MachineCheckException(struct pt_regs *regs)
if
(
check_io_access
(
regs
))
if
(
check_io_access
(
regs
))
return
;
return
;
#ifndef CONFIG_4xx
#ifdef CONFIG_4xx
printk
(
KERN_CRIT
"Machine check in kernel mode.
\n
"
);
if
(
reason
&
ESR_IMCP
)
{
printk
(
KERN_CRIT
"Caused by (from SRR1=%lx): "
,
regs
->
msr
);
printk
(
"Instruction"
);
switch
(
regs
->
msr
&
0x601F0000
)
{
mtspr
(
SPRN_ESR
,
reason
&
~
ESR_IMCP
);
}
else
printk
(
"Data"
);
printk
(
" machine check in kernel mode.
\n
"
);
#else
/* !CONFIG_4xx */
printk
(
"Machine check in kernel mode.
\n
"
);
printk
(
"Caused by (from SRR1=%lx): "
,
reason
);
switch
(
reason
&
0x601F0000
)
{
case
0x80000
:
case
0x80000
:
printk
(
"Machine check signal
\n
"
);
printk
(
"Machine check signal
\n
"
);
break
;
break
;
...
@@ -208,15 +249,6 @@ MachineCheckException(struct pt_regs *regs)
...
@@ -208,15 +249,6 @@ MachineCheckException(struct pt_regs *regs)
default:
default:
printk
(
"Unknown values in msr
\n
"
);
printk
(
"Unknown values in msr
\n
"
);
}
}
#else
/* CONFIG_4xx */
/* Note that the ESR gets stored in regs->dsisr on 4xx. */
if
(
regs
->
dsisr
&
ESR_MCI
)
{
printk
(
KERN_CRIT
"Instruction"
);
mtspr
(
SPRN_ESR
,
regs
->
dsisr
&
~
ESR_MCI
);
}
else
printk
(
KERN_CRIT
"Data"
);
printk
(
" machine check in kernel mode.
\n
"
);
#endif
/* CONFIG_4xx */
#endif
/* CONFIG_4xx */
debugger
(
regs
);
debugger
(
regs
);
...
@@ -238,7 +270,7 @@ UnknownException(struct pt_regs *regs)
...
@@ -238,7 +270,7 @@ UnknownException(struct pt_regs *regs)
{
{
printk
(
"Bad trap at PC: %lx, MSR: %lx, vector=%lx %s
\n
"
,
printk
(
"Bad trap at PC: %lx, MSR: %lx, vector=%lx %s
\n
"
,
regs
->
nip
,
regs
->
msr
,
regs
->
trap
,
print_tainted
());
regs
->
nip
,
regs
->
msr
,
regs
->
trap
,
print_tainted
());
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
0
,
0
);
}
}
void
void
...
@@ -246,13 +278,13 @@ InstructionBreakpoint(struct pt_regs *regs)
...
@@ -246,13 +278,13 @@ InstructionBreakpoint(struct pt_regs *regs)
{
{
if
(
debugger_iabr_match
(
regs
))
if
(
debugger_iabr_match
(
regs
))
return
;
return
;
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
TRAP_BRKPT
,
0
);
}
}
void
void
RunModeException
(
struct
pt_regs
*
regs
)
RunModeException
(
struct
pt_regs
*
regs
)
{
{
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
0
,
0
);
}
}
/* Illegal instruction emulation support. Originally written to
/* Illegal instruction emulation support. Originally written to
...
@@ -271,17 +303,17 @@ RunModeException(struct pt_regs *regs)
...
@@ -271,17 +303,17 @@ RunModeException(struct pt_regs *regs)
static
int
static
int
emulate_instruction
(
struct
pt_regs
*
regs
)
emulate_instruction
(
struct
pt_regs
*
regs
)
{
{
u
int
instword
;
u
32
instword
;
u
int
rd
;
u
32
rd
;
uint
retval
;
int
retval
;
retval
=
EINVAL
;
retval
=
-
EINVAL
;
if
(
!
user_mode
(
regs
))
if
(
!
user_mode
(
regs
))
return
retval
;
return
retval
;
CHECK_FULL_REGS
(
regs
);
CHECK_FULL_REGS
(
regs
);
if
(
get_user
(
instword
,
(
u
int
__user
*
)(
regs
->
nip
)))
if
(
get_user
(
instword
,
(
u
32
__user
*
)(
regs
->
nip
)))
return
-
EFAULT
;
return
-
EFAULT
;
/* Emulate the mfspr rD, PVR.
/* Emulate the mfspr rD, PVR.
...
@@ -290,10 +322,23 @@ emulate_instruction(struct pt_regs *regs)
...
@@ -290,10 +322,23 @@ emulate_instruction(struct pt_regs *regs)
rd
=
(
instword
>>
21
)
&
0x1f
;
rd
=
(
instword
>>
21
)
&
0x1f
;
regs
->
gpr
[
rd
]
=
mfspr
(
PVR
);
regs
->
gpr
[
rd
]
=
mfspr
(
PVR
);
retval
=
0
;
retval
=
0
;
}
if
(
retval
==
0
)
regs
->
nip
+=
4
;
regs
->
nip
+=
4
;
return
(
retval
);
}
return
retval
;
}
/*
* After we have successfully emulated an instruction, we have to
* check if the instruction was being single-stepped, and if so,
* pretend we got a single-step exception. This was pointed out
* by Kumar Gala. -- paulus
*/
static
void
emulate_single_step
(
struct
pt_regs
*
regs
)
{
if
(
single_stepping
(
regs
))
{
clear_single_step
(
regs
);
_exception
(
SIGTRAP
,
regs
,
TRAP_TRACE
,
0
);
}
}
}
/*
/*
...
@@ -349,29 +394,47 @@ check_bug_trap(struct pt_regs *regs)
...
@@ -349,29 +394,47 @@ check_bug_trap(struct pt_regs *regs)
void
void
ProgramCheckException
(
struct
pt_regs
*
regs
)
ProgramCheckException
(
struct
pt_regs
*
regs
)
{
{
int
errcode
;
unsigned
int
reason
=
get_reason
(
regs
);
#if defined(CONFIG_4xx)
unsigned
int
esr
=
regs
->
dsisr
;
int
isbpt
=
esr
&
ESR_PTR
;
extern
int
do_mathemu
(
struct
pt_regs
*
regs
);
extern
int
do_mathemu
(
struct
pt_regs
*
regs
);
#ifdef CONFIG_MATH_EMULATION
#ifdef CONFIG_MATH_EMULATION
if
(
!
isbpt
&&
do_mathemu
(
regs
)
==
0
)
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
* but there seems to be a hardware bug on the 405GP (RevD)
* that means ESR is sometimes set incorrectly - either to
* ESR_DST (!?) or 0. In the process of chasing this with the
* hardware people - not sure if it can happen on any illegal
* instruction or only on FP instructions, whether there is a
* pattern to occurences etc. -dgibson 31/Mar/2003 */
if
(
!
(
reason
&
REASON_TRAP
)
&&
do_mathemu
(
regs
)
==
0
)
{
emulate_single_step
(
regs
);
return
;
return
;
}
#endif
/* CONFIG_MATH_EMULATION */
#endif
/* CONFIG_MATH_EMULATION */
#else
/* ! CONFIG_4xx */
if
(
reason
&
REASON_FP
)
{
int
isbpt
=
regs
->
msr
&
0x20000
;
if
(
regs
->
msr
&
0x100000
)
{
/* IEEE FP exception */
/* IEEE FP exception */
_exception
(
SIGFPE
,
regs
);
int
code
=
0
;
u32
fpscr
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
fpscr
=
current
->
thread
.
fpscr
;
fpscr
&=
fpscr
<<
22
;
/* mask summary bits with enables */
if
(
fpscr
&
FPSCR_VX
)
code
=
FPE_FLTINV
;
else
if
(
fpscr
&
FPSCR_OX
)
code
=
FPE_FLTOVF
;
else
if
(
fpscr
&
FPSCR_UX
)
code
=
FPE_FLTUND
;
else
if
(
fpscr
&
FPSCR_ZX
)
code
=
FPE_FLTDIV
;
else
if
(
fpscr
&
FPSCR_XX
)
code
=
FPE_FLTRES
;
_exception
(
SIGFPE
,
regs
,
code
,
regs
->
nip
);
return
;
return
;
}
}
#endif
/* ! CONFIG_4xx */
if
(
isbpt
)
{
if
(
reason
&
REASON_TRAP
)
{
/* trap exception */
/* trap exception */
if
(
debugger_bpt
(
regs
))
if
(
debugger_bpt
(
regs
))
return
;
return
;
...
@@ -379,17 +442,21 @@ ProgramCheckException(struct pt_regs *regs)
...
@@ -379,17 +442,21 @@ ProgramCheckException(struct pt_regs *regs)
regs
->
nip
+=
4
;
regs
->
nip
+=
4
;
return
;
return
;
}
}
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
TRAP_BRKPT
,
0
);
return
;
return
;
}
}
/* Try to emulate it if we should. */
if
(
reason
&
REASON_PRIVILEGED
)
{
if
((
errcode
=
emulate_instruction
(
regs
)))
{
/* Try to emulate it if we should. */
if
(
errcode
==
-
EFAULT
)
if
(
emulate_instruction
(
regs
)
==
0
)
{
_exception
(
SIGBUS
,
regs
);
emulate_single_step
(
regs
);
else
return
;
_exception
(
SIGILL
,
regs
);
}
_exception
(
SIGILL
,
regs
,
ILL_PRVOPC
,
regs
->
nip
);
return
;
}
}
_exception
(
SIGILL
,
regs
,
ILL_ILLOPC
,
regs
->
nip
);
}
}
void
void
...
@@ -398,7 +465,7 @@ SingleStepException(struct pt_regs *regs)
...
@@ -398,7 +465,7 @@ SingleStepException(struct pt_regs *regs)
regs
->
msr
&=
~
MSR_SE
;
/* Turn off 'trace' bit */
regs
->
msr
&=
~
MSR_SE
;
/* Turn off 'trace' bit */
if
(
debugger_sstep
(
regs
))
if
(
debugger_sstep
(
regs
))
return
;
return
;
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
TRAP_TRACE
,
0
);
}
}
void
void
...
@@ -414,12 +481,12 @@ AlignmentException(struct pt_regs *regs)
...
@@ -414,12 +481,12 @@ AlignmentException(struct pt_regs *regs)
if
(
fixed
==
-
EFAULT
)
{
if
(
fixed
==
-
EFAULT
)
{
/* fixed == -EFAULT means the operand address was bad */
/* fixed == -EFAULT means the operand address was bad */
if
(
user_mode
(
regs
))
if
(
user_mode
(
regs
))
force_sig
(
SIGSEGV
,
current
);
_exception
(
SIGSEGV
,
regs
,
SEGV_ACCERR
,
regs
->
dar
);
else
else
bad_page_fault
(
regs
,
regs
->
dar
,
SIGSEGV
);
bad_page_fault
(
regs
,
regs
->
dar
,
SIGSEGV
);
return
;
return
;
}
}
_exception
(
SIGBUS
,
regs
);
_exception
(
SIGBUS
,
regs
,
BUS_ADRALN
,
regs
->
dar
);
}
}
void
void
...
@@ -470,16 +537,17 @@ SoftwareEmulation(struct pt_regs *regs)
...
@@ -470,16 +537,17 @@ SoftwareEmulation(struct pt_regs *regs)
#endif
#endif
if
(
errcode
)
{
if
(
errcode
)
{
if
(
errcode
>
0
)
if
(
errcode
>
0
)
_exception
(
SIGFPE
,
regs
);
_exception
(
SIGFPE
,
regs
,
0
,
0
);
else
if
(
errcode
==
-
EFAULT
)
else
if
(
errcode
==
-
EFAULT
)
_exception
(
SIGSEGV
,
regs
);
_exception
(
SIGSEGV
,
regs
,
0
,
0
);
else
else
_exception
(
SIGILL
,
regs
);
_exception
(
SIGILL
,
regs
,
ILL_ILLOPC
,
regs
->
nip
);
}
}
else
emulate_single_step
(
regs
);
}
}
#endif
/* CONFIG_8xx */
#endif
/* CONFIG_8xx */
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx)
|| defined(CONFIG_BOOKE)
void
DebugException
(
struct
pt_regs
*
regs
,
unsigned
long
debug_status
)
void
DebugException
(
struct
pt_regs
*
regs
,
unsigned
long
debug_status
)
{
{
...
@@ -487,7 +555,7 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status)
...
@@ -487,7 +555,7 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status)
if (debug_status & DBSR_TIE) { /* trap instruction*/
if (debug_status & DBSR_TIE) { /* trap instruction*/
if (!user_mode(regs) && debugger_bpt(regs))
if (!user_mode(regs) && debugger_bpt(regs))
return;
return;
_exception(SIGTRAP, regs);
_exception(SIGTRAP, regs
, 0, 0
);
}
}
#endif
#endif
...
@@ -495,10 +563,10 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status)
...
@@ -495,10 +563,10 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status)
if
(
!
user_mode
(
regs
)
&&
debugger_sstep
(
regs
))
if
(
!
user_mode
(
regs
)
&&
debugger_sstep
(
regs
))
return
;
return
;
current
->
thread
.
dbcr0
&=
~
DBCR0_IC
;
current
->
thread
.
dbcr0
&=
~
DBCR0_IC
;
_exception
(
SIGTRAP
,
regs
);
_exception
(
SIGTRAP
,
regs
,
TRAP_TRACE
,
0
);
}
}
}
}
#endif
/* CONFIG_4xx */
#endif
/* CONFIG_4xx
|| CONFIG_BOOKE
*/
#if !defined(CONFIG_TAU_INT)
#if !defined(CONFIG_TAU_INT)
void
void
...
...
include/asm-ppc/bitops.h
View file @
d33a40e5
...
@@ -276,7 +276,7 @@ static __inline__ int fls(unsigned int x)
...
@@ -276,7 +276,7 @@ static __inline__ int fls(unsigned int x)
* Find the first bit set in a 140-bit bitmap.
* Find the first bit set in a 140-bit bitmap.
* The first 100 bits are unlikely to be set.
* The first 100 bits are unlikely to be set.
*/
*/
static
inline
int
sched_find_first_bit
(
unsigned
long
*
b
)
static
inline
int
sched_find_first_bit
(
const
unsigned
long
*
b
)
{
{
if
(
unlikely
(
b
[
0
]))
if
(
unlikely
(
b
[
0
]))
return
__ffs
(
b
[
0
]);
return
__ffs
(
b
[
0
]);
...
@@ -295,7 +295,7 @@ static inline int sched_find_first_bit(unsigned long *b)
...
@@ -295,7 +295,7 @@ static inline int sched_find_first_bit(unsigned long *b)
* @offset: The bitnumber to start searching at
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
* @size: The maximum size to search
*/
*/
static
__inline__
unsigned
long
find_next_bit
(
unsigned
long
*
addr
,
static
__inline__
unsigned
long
find_next_bit
(
const
unsigned
long
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
unsigned
long
size
,
unsigned
long
offset
)
{
{
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
...
@@ -352,7 +352,7 @@ static __inline__ unsigned long find_next_bit(unsigned long *addr,
...
@@ -352,7 +352,7 @@ static __inline__ unsigned long find_next_bit(unsigned long *addr,
#define find_first_zero_bit(addr, size) \
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
find_next_zero_bit((addr), (size), 0)
static
__inline__
unsigned
long
find_next_zero_bit
(
unsigned
long
*
addr
,
static
__inline__
unsigned
long
find_next_zero_bit
(
const
unsigned
long
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
unsigned
long
size
,
unsigned
long
offset
)
{
{
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
...
@@ -411,7 +411,7 @@ static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
...
@@ -411,7 +411,7 @@ static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
#define ext2_find_first_zero_bit(addr, size) \
#define ext2_find_first_zero_bit(addr, size) \
ext2_find_next_zero_bit((addr), (size), 0)
ext2_find_next_zero_bit((addr), (size), 0)
static
__inline__
unsigned
long
ext2_find_next_zero_bit
(
void
*
addr
,
static
__inline__
unsigned
long
ext2_find_next_zero_bit
(
const
void
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
unsigned
long
size
,
unsigned
long
offset
)
{
{
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
unsigned
int
*
p
=
((
unsigned
int
*
)
addr
)
+
(
offset
>>
5
);
...
...
include/asm-ppc/highmem.h
View file @
d33a40e5
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <asm/kmap_types.h>
#include <asm/kmap_types.h>
#include <asm/tlbflush.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
/* undef for production */
/* undef for production */
#define HIGHMEM_DEBUG 1
#define HIGHMEM_DEBUG 1
...
@@ -41,8 +42,8 @@ extern void kmap_init(void) __init;
...
@@ -41,8 +42,8 @@ extern void kmap_init(void) __init;
* easily, subsequent pte tables have to be allocated in one physical
* easily, subsequent pte tables have to be allocated in one physical
* chunk of RAM.
* chunk of RAM.
*/
*/
#define PKMAP_BASE CONFIG_HIGHMEM_START
#define PKMAP_BASE
CONFIG_HIGHMEM_START
#define LAST_PKMAP
1024
#define LAST_PKMAP
(1 << PTE_SHIFT)
#define LAST_PKMAP_MASK (LAST_PKMAP-1)
#define LAST_PKMAP_MASK (LAST_PKMAP-1)
#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
...
...
include/asm-ppc/processor.h
View file @
d33a40e5
...
@@ -848,6 +848,7 @@ struct thread_struct {
...
@@ -848,6 +848,7 @@ struct thread_struct {
/* AltiVec status */
/* AltiVec status */
vector128
vscr
__attribute
((
aligned
(
16
)));
vector128
vscr
__attribute
((
aligned
(
16
)));
unsigned
long
vrsave
;
unsigned
long
vrsave
;
int
used_vr
;
/* set if process has used altivec */
#endif
/* CONFIG_ALTIVEC */
#endif
/* CONFIG_ALTIVEC */
};
};
...
...
include/asm-ppc/ucontext.h
View file @
d33a40e5
#ifndef _ASMPPC_UCONTEXT_H
#ifndef _ASMPPC_UCONTEXT_H
#define _ASMPPC_UCONTEXT_H
#define _ASMPPC_UCONTEXT_H
/* Copied from i386. */
#include <asm/elf.h>
#include <asm/signal.h>
struct
mcontext
{
elf_gregset_t
mc_gregs
;
elf_fpregset_t
mc_fregs
;
unsigned
long
mc_pad
[
2
];
elf_vrregset_t
mc_vregs
__attribute__
((
__aligned__
(
16
)));
};
struct
ucontext
{
struct
ucontext
{
unsigned
long
uc_flags
;
unsigned
long
uc_flags
;
struct
ucontext
*
uc_link
;
struct
ucontext
*
uc_link
;
stack_t
uc_stack
;
stack_t
uc_stack
;
struct
sigcontext
uc_mcontext
;
int
uc_pad
[
7
];
sigset_t
uc_sigmask
;
/* mask last for extensibility */
struct
mcontext
*
uc_regs
;
/* backward compat */
sigset_t
uc_oldsigmask
;
/* backward compat */
int
uc_pad2
;
sigset_t
uc_sigmask
;
/* glibc has 1024-bit signal masks, ours are 64-bit */
int
uc_maskext
[
30
];
struct
mcontext
uc_mcontext
;
};
};
#endif
/* !_ASMPPC_UCONTEXT_H */
#endif
/* !_ASMPPC_UCONTEXT_H */
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