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
35ef4b70
Commit
35ef4b70
authored
Mar 18, 2004
by
Richard Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ALPHA] Streamline opDEC_check and the actual fixup bits in do_entIF.
parent
afbd3007
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
36 additions
and
41 deletions
+36
-41
arch/alpha/kernel/traps.c
arch/alpha/kernel/traps.c
+36
-41
No files found.
arch/alpha/kernel/traps.c
View file @
35ef4b70
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/gentrap.h>
#include <asm/gentrap.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
...
@@ -25,35 +26,37 @@
...
@@ -25,35 +26,37 @@
#include "proto.h"
#include "proto.h"
/* data/code implementing a work-around for some SRMs which
/* Work-around for some SRMs which mishandle opDEC faults. */
mishandle opDEC faults
*/
static
int
opDEC_testing
=
0
;
static
int
opDEC_fix
=
0
;
static
int
opDEC_checked
=
0
;
static
unsigned
long
opDEC_test_pc
=
0
;
static
void
static
int
opDEC_fix
;
static
void
__init
opDEC_check
(
void
)
opDEC_check
(
void
)
{
{
unsigned
long
test_pc
;
__asm__
__volatile__
(
/* Load the address of... */
if
(
opDEC_checked
)
return
;
" br $16, 1f
\n
"
/* A stub instruction fault handler. Just add 4 to the
lock_kernel
();
pc and continue. */
opDEC_testing
=
1
;
" ldq $16, 8($sp)
\n
"
" addq $16, 4, $16
\n
"
__asm__
__volatile__
(
" stq $16, 8($sp)
\n
"
" br %0,1f
\n
"
" call_pal %[rti]
\n
"
"1: addq %0,8,%0
\n
"
/* Install the instruction fault handler. */
" stq %0,%1
\n
"
"1: lda $17, 3
\n
"
" cvttq/svm $f31,$f31
\n
"
" call_pal %[wrent]
\n
"
:
"=&r"
(
test_pc
),
"=m"
(
opDEC_test_pc
)
/* With that in place, the fault from the round-to-minf fp
:
);
insn will arrive either at the "lda 4" insn (bad) or one
past that (good). This places the correct fixup in %0. */
opDEC_testing
=
0
;
" lda %[fix], 0
\n
"
opDEC_checked
=
1
;
" cvttq/svm $f31,$f31
\n
"
unlock_kernel
();
" lda %[fix], 4"
:
[
fix
]
"=r"
(
opDEC_fix
)
:
[
rti
]
"n"
(
PAL_rti
),
[
wrent
]
"n"
(
PAL_wrent
)
:
"$0"
,
"$1"
,
"$16"
,
"$17"
,
"$22"
,
"$23"
,
"$24"
,
"$25"
);
if
(
opDEC_fix
)
printk
(
"opDEC fixup enabled.
\n
"
);
}
}
void
void
...
@@ -244,7 +247,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
...
@@ -244,7 +247,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
siginfo_t
info
;
siginfo_t
info
;
int
signo
,
code
;
int
signo
,
code
;
if
(
!
opDEC_testing
||
type
!=
4
)
{
if
(
regs
->
ps
==
0
)
{
if
(
type
==
1
)
{
if
(
type
==
1
)
{
const
unsigned
int
*
data
const
unsigned
int
*
data
=
(
const
unsigned
int
*
)
regs
->
pc
;
=
(
const
unsigned
int
*
)
regs
->
pc
;
...
@@ -359,14 +362,6 @@ do_entIF(unsigned long type, struct pt_regs *regs)
...
@@ -359,14 +362,6 @@ do_entIF(unsigned long type, struct pt_regs *regs)
fault during the boot sequence and testing if
fault during the boot sequence and testing if
we get the correct PC. If not, we set a flag
we get the correct PC. If not, we set a flag
to correct it every time through. */
to correct it every time through. */
if
(
opDEC_testing
)
{
if
(
regs
->
pc
==
opDEC_test_pc
)
{
opDEC_fix
=
4
;
regs
->
pc
+=
4
;
printk
(
"opDEC fixup enabled.
\n
"
);
}
return
;
}
regs
->
pc
+=
opDEC_fix
;
regs
->
pc
+=
opDEC_fix
;
/* EV4 does not implement anything except normal
/* EV4 does not implement anything except normal
...
@@ -1083,22 +1078,22 @@ do_entUnaUser(void * va, unsigned long opcode,
...
@@ -1083,22 +1078,22 @@ do_entUnaUser(void * va, unsigned long opcode,
return
;
return
;
}
}
void
void
__init
trap_init
(
void
)
trap_init
(
void
)
{
{
/* Tell PAL-code what global pointer we want in the kernel. */
/* Tell PAL-code what global pointer we want in the kernel. */
register
unsigned
long
gptr
__asm__
(
"$29"
);
register
unsigned
long
gptr
__asm__
(
"$29"
);
wrkgp
(
gptr
);
wrkgp
(
gptr
);
/* Hack for Multia (UDB) and JENSEN: some of their SRMs have
a bug in the handling of the opDEC fault. Fix it up if so. */
if
(
implver
()
==
IMPLVER_EV4
)
opDEC_check
();
wrent
(
entArith
,
1
);
wrent
(
entArith
,
1
);
wrent
(
entMM
,
2
);
wrent
(
entMM
,
2
);
wrent
(
entIF
,
3
);
wrent
(
entIF
,
3
);
wrent
(
entUna
,
4
);
wrent
(
entUna
,
4
);
wrent
(
entSys
,
5
);
wrent
(
entSys
,
5
);
wrent
(
entDbg
,
6
);
wrent
(
entDbg
,
6
);
/* Hack for Multia (UDB) and JENSEN: some of their SRMs have
a bug in the handling of the opDEC fault. Fix it up if so. */
if
(
implver
()
==
IMPLVER_EV4
)
opDEC_check
();
}
}
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