Commit 35ef4b70 authored by Richard Henderson's avatar Richard Henderson

[ALPHA] Streamline opDEC_check and the actual fixup bits in do_entIF.

parent afbd3007
...@@ -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();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment