(1) Restructure and improve machine check and correctable error

handling based on information in the 2nd Ed. of the Alpha Architecture
Reference Manual.
(2)     Clean up interrupt handling slightly.
(3)     Clean up badaddr().
This commit is contained in:
cgd 1996-07-14 04:20:40 +00:00
parent 43588a48d5
commit 775cca7853
1 changed files with 74 additions and 36 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: interrupt.c,v 1.8 1996/07/11 05:31:18 cgd Exp $ */
/* $NetBSD: interrupt.c,v 1.9 1996/07/14 04:20:40 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -49,47 +49,52 @@ struct logout {
/* Unspecified. */
};
void machine_check __P((struct trapframe *, struct logout *,
u_int64_t));
static void nullintr __P((void *, int));
void machine_check __P((struct trapframe *, unsigned long,
unsigned long));
static void nullintr __P((void *, unsigned long));
static void (*iointr) __P((void *, int)) = nullintr;
static void (*clockintr) __P((void *, int)) = nullintr;
static int mc_expected, mc_received;
static void (*iointr) __P((void *, unsigned long)) = nullintr;
static void (*clockintr) __P((void *, unsigned long)) = nullintr;
static volatile int mc_expected, mc_received;
#ifdef EVCNT_COUNTERS
struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
#endif
void
interrupt(framep, type, vec, logoutp)
interrupt(a0, a1, a2, framep)
unsigned long a0, a1, a2;
struct trapframe *framep;
u_int64_t type, vec;
struct logout *logoutp;
{
if (type == 1) /* clock interrupt */
(*clockintr)(framep, vec);
else if (type == 3) /* I/O device interrupt */
(*iointr)(framep, vec);
else if (type == 2)
machine_check(framep, logoutp, vec);
else
panic("unexpected interrupt: type %ld, vec %ld\n",
(long)type, (long)vec);
if (a0 == 1) /* clock interrupt */
(*clockintr)(framep, a1);
else if (a0 == 3) /* I/O device interrupt */
(*iointr)(framep, a1);
else if (a0 == 2) /* machine check or correctable error */
machine_check(framep, a1, a2);
else {
/*
* Not expected or handled:
* 0 Interprocessor interrupt
* 4 Performance counter
*/
panic("unexpected interrupt: type 0x%lx, vec 0x%lx\n",
a0, a1);
}
}
static void
nullintr(framep, vec)
void *framep;
int vec;
unsigned long vec;
{
}
static void
real_clockintr(framep, vec)
void *framep;
int vec;
unsigned long vec;
{
#ifdef EVCNT_COUNTERS
@ -112,7 +117,7 @@ set_clockintr()
void
set_iointr(niointr)
void (*niointr) __P((void *, int));
void (*niointr) __P((void *, unsigned long));
{
if (iointr != nullintr)
@ -122,30 +127,61 @@ set_iointr(niointr)
}
void
machine_check(framep, logoutp, vec)
machine_check(framep, vector, param)
struct trapframe *framep;
struct logout *logoutp;
u_int64_t vec;
unsigned long vector, param;
{
unsigned long mces;
const char *type;
if (!mc_expected)
panic("machine check: vec 0x%lx, pc = 0x%lx, ra = 0x%lx",
vec, framep->tf_regs[FRAME_PC], framep->tf_regs[FRAME_RA]);
mces = alpha_pal_rdmces();
/* If not a machine check, we have no clue ho we got here. */
if ((mces & ALPHA_MCES_MIP) == 0) {
type = "fatal machine check or error (unknown type)";
goto fatal;
}
/* If we weren't expecting it, then we punt. */
if (!mc_expected) {
type = "unexpected machine check";
goto fatal;
}
mc_expected = 0;
mc_received = 1;
logoutp->q1 &= ~LOGOUT_RETRY; /* XXX: Necessary? */
alpha_pal_wrmces(0x19); /* XXX */
/* Clear pending machine checks and correctable errors */
alpha_pal_wrmces(mces);
return;
fatal:
printf("\n");
printf("%s:\n", type);
printf("\n");
printf(" mces = 0x%lx\n", mces);
printf(" vector = 0x%lx\n", vector);
printf(" param = 0x%lx\n", param);
printf(" pc = 0x%lx\n", framep->tf_regs[FRAME_PC]);
printf(" ra = 0x%lx\n", framep->tf_regs[FRAME_RA]);
printf(" curproc = %p\n", curproc);
if (curproc != NULL)
printf(" pid = %d, comm = %s\n", curproc->p_pid,
curproc->p_comm);
printf("\n");
panic("machine check");
}
int
badaddr(addr, size)
void *addr;
u_int64_t size;
size_t size;
{
int rv;
volatile long rcpt;
long rcpt;
/* Get rid of any stale machine checks that have been waiting. */
alpha_pal_draina();
/* Tell the trap code to expect a machine check. */
mc_received = 0;
@ -155,25 +191,27 @@ badaddr(addr, size)
alpha_mb();
switch (size) {
case sizeof (u_int8_t):
rcpt = *(u_int8_t *)addr;
rcpt = *(volatile u_int8_t *)addr;
break;
case sizeof (u_int16_t):
rcpt = *(u_int16_t *)addr;
rcpt = *(volatile u_int16_t *)addr;
break;
case sizeof (u_int32_t):
rcpt = *(u_int32_t *)addr;
rcpt = *(volatile u_int32_t *)addr;
break;
case sizeof (u_int64_t):
rcpt = *(u_int64_t *)addr;
rcpt = *(volatile u_int64_t *)addr;
break;
default:
panic("badaddr: invalid size (%ld)\n", size);
}
alpha_mb();
/* Make sure we took the machine check, if we caused one. */
alpha_pal_draina();
/* disallow further machine checks */