From: Richard Henderson <rth@redhat.com>
To: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Jay.Estabrook@compaq.com, linux-kernel@vger.kernel.org
Subject: Re: [alpha] cleanup opDEC workaround
Date: Wed, 21 Nov 2001 14:27:53 -0800 [thread overview]
Message-ID: <20011121142753.A876@redhat.com> (raw)
In-Reply-To: <20011119232355.C16091@redhat.com> <20011120133150.A9033@jurassic.park.msu.ru> <20011120090818.A16366@redhat.com> <20011120205105.A15395@jurassic.park.msu.ru> <20011120104748.B16422@redhat.com> <20011121151555.A20128@jurassic.park.msu.ru>
In-Reply-To: <20011121151555.A20128@jurassic.park.msu.ru>; from ink@jurassic.park.msu.ru on Wed, Nov 21, 2001 at 03:15:55PM +0300
On Wed, Nov 21, 2001 at 03:15:55PM +0300, Ivan Kokshaysky wrote:
> > I suppose the other alternative to get the testing code out of
> > the normal entIF is to create a custom entIF that is installed
> > only during opDEC testing. Seems too much work...
>
> Agreed. Alternatively, it's possible to hack dummy_emul(), which
> doesn't affect the normal case.
Actually, the custom entIF isn't that much work. What about this?
r~
--- traps.c.orig Wed Nov 21 14:13:31 2001
+++ traps.c Wed Nov 21 14:25:22 2001
@@ -24,31 +24,35 @@
#include "proto.h"
-/* data/code implementing a work-around for some SRMs which
- mishandle opDEC faults
-*/
-static int opDEC_testing = 0;
-static int opDEC_fix = 0;
-static unsigned long opDEC_test_pc = 0;
+/* Work-around for some SRMs which mishandle opDEC faults. */
+static int opDEC_fix;
-static void
+extern void opDEC_check_entIF(void);
+asm(".section .text.init,\"ax\" \n\
+ .ent opDEC_check_entIF \n\
+opDEC_check_entIF: \n\
+ ldq $16,8($sp) \n\
+ call_pal 63 /* PAL_rti */ \n\
+ .end opDEC_check_entIF \n\
+ .previous");
+
+static void __init
opDEC_check(void)
{
- unsigned long test_pc;
+ long diff;
- lock_kernel();
- opDEC_testing = 1;
+ wrent(opDEC_check_entIF, 3);
__asm__ __volatile__(
- " br %0,1f\n"
- "1: addq %0,8,%0\n"
- " stq %0,%1\n"
- " cvttq/svm $f31,$f31\n"
- : "=&r"(test_pc), "=m"(opDEC_test_pc)
- : );
-
- opDEC_testing = 0;
- unlock_kernel();
+ "br %0,1f\n"
+ "1:\n\t"
+ "cvttq/svm $f31, $f31\n\t"
+ "subq $16, %0, %0"
+ : "=r"(diff) : : "$16");
+
+ opDEC_fix = 4 - diff;
+ if (opDEC_fix)
+ printk("opDEC fixup enabled.\n");
}
void
@@ -231,24 +235,22 @@
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{
- if (!opDEC_testing || type != 4) {
- die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
- ®s, type, 0);
- }
-
switch (type) {
- case 0: /* breakpoint */
+ case 0: /* breakpoint */
+ die_if_kernel("Breakpoint fault", ®s, type, 0);
if (ptrace_cancel_bpt(current)) {
regs.pc -= 4; /* make pc point to former bpt */
}
send_sig(SIGTRAP, current, 1);
return;
- case 1: /* bugcheck */
+ case 1: /* bugcheck */
+ die_if_kernel("Kernel Bug", ®s, type, 0);
send_sig(SIGTRAP, current, 1);
return;
- case 2: /* gentrap */
+ case 2: /* gentrap */
+ die_if_kernel("Divide by zero fault", ®s, type, 0);
/*
* The exception code should be passed on to the signal
* handler as the second argument. Linux doesn't do that
@@ -285,27 +287,14 @@
}
break;
- case 4: /* opDEC */
+ case 4: /* opDEC */
if (implver() == IMPLVER_EV4) {
- /* The some versions of SRM do not handle
- the opDEC properly - they return the PC of the
- opDEC fault, not the instruction after as the
- Alpha architecture requires. Here we fix it up.
- We do this by intentionally causing an opDEC
- fault during the boot sequence and testing if
- we get the correct PC. If not, we set a flag
- 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;
- }
+ /* Some versions of SRM do not handle opDEC properly.
+ They return the PC of the opDEC fault, not the
+ instruction after the fault as the architecture
+ requires. Here we fix it up. */
regs.pc += opDEC_fix;
-
+
/* EV4 does not implement anything except normal
rounding. Everything else will come here as
an illegal instruction. Emulate them. */
@@ -314,7 +303,7 @@
}
break;
- case 3: /* FEN fault */
+ case 3: /* FEN fault */
/* Irritating users can call PAL_clrfen to disable the
FPU for the process. The kernel will then trap in
do_switch_stack and undo_switch_stack when we try
@@ -328,10 +317,12 @@
__reload_thread(¤t->thread);
return;
- case 5: /* illoc */
- default: /* unexpected instruction-fault type */
- ;
+ case 5: /* illoc */
+ default: /* unexpected instruction-fault type */
+ break;
}
+
+ die_if_kernel("Instruction fault", ®s, type, 0);
send_sig(SIGILL, current, 1);
}
@@ -999,24 +990,22 @@
return -ENOSYS;
}
-void
+void __init
trap_init(void)
{
/* Tell PAL-code what global pointer we want in the kernel. */
register unsigned long gptr __asm__("$29");
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(entMM, 2);
wrent(entIF, 3);
wrent(entUna, 4);
wrent(entSys, 5);
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();
- }
}
next prev parent reply other threads:[~2001-11-21 22:28 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-11-20 7:23 [alpha] cleanup opDEC workaround Richard Henderson
2001-11-20 10:31 ` Ivan Kokshaysky
2001-11-20 17:08 ` Richard Henderson
2001-11-20 17:51 ` Ivan Kokshaysky
2001-11-20 18:47 ` Richard Henderson
2001-11-21 12:15 ` Ivan Kokshaysky
2001-11-21 22:27 ` Richard Henderson [this message]
2001-11-22 10:55 ` Ivan Kokshaysky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20011121142753.A876@redhat.com \
--to=rth@redhat.com \
--cc=Jay.Estabrook@compaq.com \
--cc=ink@jurassic.park.msu.ru \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox