Revamp interrupts again:

Fix a bug causing interrmittent panics in interrupt dispatch.
	Use interrupt vectors for softints.
	Add a new send_softint interface.
	Improved D$ flushing.
	Improve traptrace and other debugging enhancements.
This commit is contained in:
eeh 2000-03-16 02:36:56 +00:00
parent 6190c3253f
commit 3b51289caa
12 changed files with 429 additions and 270 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.11 2000/02/07 20:16:53 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.12 2000/03/16 02:36:56 eeh Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles M. Hannum.
@ -78,6 +78,9 @@
/* XXX misuse a flag to identify format operation */
#define B_FORMAT B_XXX
/* These machines are fast enough that doing this in assembly is silly. */
#define FDC_C_HANDLER
#define FD_DEBUG
#ifdef FD_DEBUG
int fdc_debug = 0;
@ -257,24 +260,7 @@ void fd_do_eject __P((struct fd_softc *));
void fd_mountroot_hook __P((struct device *));
static void fdconf __P((struct fdc_softc *));
#if PIL_FDSOFT == 4
#define IE_FDSOFT IE_L4
#else
#error 4
#endif
#ifdef FDC_C_HANDLER
#if defined(SUN4M)
#define FD_SET_SWINTR do { \
if (CPU_ISSUN4M) \
raise(0, PIL_FDSOFT); \
else \
ienab_bis(IE_L4); \
} while(0)
#else
#define AUDIO_SET_SWINTR ienab_bis(IE_FDSOFT)
#endif /* defined(SUN4M) */
#endif /* FDC_C_HANDLER */
#define FD_SET_SWINTR send_softint(-1, PIL_FDSOFT, fdc->sc_sih)
#define OBP_FDNAME (CPU_ISSUN4M ? "SUNW,fdtwo" : "fd")
@ -1075,7 +1061,7 @@ fdchwintr(fdc)
if ((msr & NE7_NDM) == 0) {
fdcresult(fdc);
fdc->sc_istate = ISTATE_IDLE;
ienab_bis(IE_FDSOFT);
FD_SET_SWINTR;
printf("fdc: overrun: tc = %d\n", fdc->sc_tc);
break;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.14 2000/03/06 21:36:12 thorpej Exp $ */
/* $NetBSD: zs.c,v 1.15 2000/03/16 02:36:57 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -96,19 +96,6 @@ int zs_major = 12;
*/
#define PCLK (9600 * 512) /* PCLK pin input clock rate */
/*
* Select software interrupt bit based on TTY ipl.
*/
#if PIL_TTY == 1
# define IE_ZSSOFT IE_L1
#elif PIL_TTY == 4
# define IE_ZSSOFT IE_L4
#elif PIL_TTY == 6
# define IE_ZSSOFT IE_L6
#else
# error "no suitable software interrupt bit"
#endif
#define ZS_DELAY()
/* The layout of this is hardware-dependent (padding, order). */
@ -590,13 +577,8 @@ zshard(arg)
/* We are at splzs here, so no need to lock. */
if (softreq && (zssoftpending == 0)) {
zssoftpending = IE_ZSSOFT;
#if defined(SUN4M)
if (CPU_ISSUN4M)
raise(0, PIL_TTY);
else
#endif
ienab_bis(IE_ZSSOFT);
zssoftpending = PIL_TTY;
send_softint(-1, PIL_TTY, &levelsoft);
}
return (rval);
}
@ -614,14 +596,6 @@ zssoft(arg)
/* This is not the only ISR on this IPL. */
if (zssoftpending == 0)
return (0);
/*
* The soft intr. bit will be set by zshard only if
* the variable zssoftpending is zero. The order of
* these next two statements prevents our clearing
* the soft intr bit just after zshard has set it.
*/
/* ienab_bic(IE_ZSSOFT); */
zssoftpending = 0;
/* Make sure we call the tty layer at spltty. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.15 1999/12/30 16:26:18 eeh Exp $ */
/* $NetBSD: cpu.h,v 1.16 2000/03/16 02:36:58 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -107,9 +107,17 @@ union sir {
#define SIR_NET 0
#define SIR_CLOCK 1
#define setsoftint() ienab_bis(IE_L1)
#define setsoftnet() (sir.sir_which[SIR_NET] = 1, setsoftint())
#define setsoftclock() (sir.sir_which[SIR_CLOCK] = 1, setsoftint())
extern struct intrhand soft01intr, soft01net, soft01clock;
#if 0
#define setsoftint() send_softint(-1, IPL_SOFTINT, &soft01intr)
#define setsoftnet() send_softint(-1, IPL_SOFTNET, &soft01net)
#define setsoftclock() send_softint(-1, IPL_SOFTCLOCK, &soft01clock)
#else
void setsoftint __P((void));
void setsoftnet __P((void));
void setsoftclock __P((void));
#endif
int want_ast;

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_machdep.h,v 1.9 2000/01/10 03:53:20 eeh Exp $ */
/* $NetBSD: db_machdep.h,v 1.10 2000/03/16 02:36:58 eeh Exp $ */
/*
* Mach Operating System
@ -45,18 +45,20 @@
typedef vaddr_t db_addr_t; /* address - unsigned */
typedef long db_expr_t; /* expression - signed */
#if 1
typedef struct {
struct trapframe64 ddb_tf;
struct frame64 ddb_fr;
} db_regs_t;
#else
struct trapregs {
int64_t tt;
struct trapstate {
int64_t tstate;
int64_t tpc;
int64_t tnpc;
int64_t tt;
};
#if 1
typedef struct {
struct trapframe64 ddb_tf;
struct frame64 ddb_fr;
struct trapstate ddb_ts[5];
int ddb_tl;
} db_regs_t;
#else
typedef struct db_regs {
struct trapregs dbr_traps[4];
int dbr_y;

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.1 1999/05/30 02:37:10 mrg Exp $ */
/* $NetBSD: intr.h,v 1.2 2000/03/16 02:36:58 eeh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -38,6 +38,7 @@
/* XXX - arbitrary numbers; no interpretation is defined yet */
#define IPL_NONE 0 /* nothing */
#define IPL_SOFTINT 1 /* softint */
#define IPL_SOFTCLOCK 1 /* timeouts */
#define IPL_SOFTNET 1 /* protocol stack */
#define IPL_BIO 2 /* block I/O */

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.26 2000/01/16 03:10:58 eeh Exp $ */
/* $NetBSD: autoconf.c,v 1.27 2000/03/16 02:37:00 eeh Exp $ */
/*
* Copyright (c) 1996
@ -240,7 +240,7 @@ bootstrap(nctx)
* Eventually we should drop all of this in favor of traversing
* process address spaces during MMU faults.
*/
pmap_bootstrap(KERNBASE, (u_int)&end, nctx);
pmap_bootstrap(KERNBASE, (u_long)&end, nctx);
}
/*
@ -342,6 +342,15 @@ bootpath_build()
case 's':
boothowto |= RB_SINGLE;
break;
case 't':
{
/* turn on traptrace w/o breaking into kdb */
extern int trap_trace_dis;
trap_trace_dis = 0;
break;
}
}
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_interface.c,v 1.27 2000/01/21 23:29:09 thorpej Exp $ */
/* $NetBSD: db_interface.c,v 1.28 2000/03/16 02:36:58 eeh Exp $ */
/*
* Mach Operating System
@ -60,6 +60,17 @@
extern void OF_enter __P((void));
extern struct traptrace {
unsigned short tl:3, /* Trap level */
ns:4, /* PCB nsaved */
tt:9; /* Trap type */
unsigned short pid; /* PID */
u_int tstate; /* tstate */
u_int tsp; /* sp */
u_int tpc; /* pc */
u_int tfault; /* MMU tag access */
} trap_trace[], trap_trace_end[];
static int nil;
struct db_variable db_regs[] = {
@ -116,6 +127,7 @@ void db_ctx_cmd __P((db_expr_t, int, db_expr_t, char *));
void db_dump_window __P((db_expr_t, int, db_expr_t, char *));
void db_dump_stack __P((db_expr_t, int, db_expr_t, char *));
void db_dump_trap __P((db_expr_t, int, db_expr_t, char *));
void db_dump_ts __P((db_expr_t, int, db_expr_t, char *));
void db_dump_pcb __P((db_expr_t, int, db_expr_t, char *));
void db_dump_pv __P((db_expr_t, int, db_expr_t, char *));
void db_setpcb __P((db_expr_t, int, db_expr_t, char *));
@ -131,6 +143,8 @@ void db_dump_espcmd __P((db_expr_t, int, db_expr_t, char *));
void db_watch __P((db_expr_t, int, db_expr_t, char *));
static void db_dump_pmap __P((struct pmap*));
static void db_print_trace_entry __P((struct traptrace *, int));
/*
* Received keyboard interrupt sequence.
@ -145,9 +159,6 @@ kdb_kbd_trap(tf)
}
}
/* Flip this to turn on traptrace */
int traptrace_enabled = 0;
/*
* kdb_trap - field a TRACE or BPT trap
*/
@ -156,18 +167,13 @@ kdb_trap(type, tf)
int type;
register struct trapframe64 *tf;
{
int i, s, tl;
struct trapstate {
int64_t tstate;
int64_t tpc;
int64_t tnpc;
int64_t tt;
} ts[5];
extern int savetstate(struct trapstate ts[]);
extern void restoretstate(int tl, struct trapstate ts[]);
int s, tl;
struct trapstate *ts = &ddb_regs.ddb_ts;
extern int savetstate(struct trapstate *ts);
extern void restoretstate(int tl, struct trapstate *ts);
extern int trap_trace_dis;
trap_trace_dis = 1;
trap_trace_dis++;
fb_unblank();
switch (type) {
@ -222,12 +228,8 @@ kdb_trap(type, tf)
db_active++;
cnpollc(TRUE);
/* Need to do spl stuff till cnpollc works */
tl = savetstate(ts);
for (i=0; i<tl; i++) {
printf("%d tt=%lx tstate=%lx tpc=%p tnpc=%p\n",
i+1, (long)ts[i].tt, (u_long)ts[i].tstate,
(void*)(u_long)ts[i].tpc, (void*)(u_long)ts[i].tnpc);
}
tl = ddb_regs.ddb_tl = savetstate(ts);
db_dump_ts(0, 0, 0, 0);
db_trap(type, 0/*code*/);
restoretstate(tl,ts);
cnpollc(FALSE);
@ -239,7 +241,7 @@ kdb_trap(type, tf)
*(struct frame *)tf->tf_out[6] = ddb_regs.ddb_fr;
#endif
*tf = ddb_regs.ddb_tf;
trap_trace_dis = traptrace_enabled;
trap_trace_dis--;
return (1);
}
@ -380,16 +382,16 @@ struct pmap* pm;
n = 0;
for (i=0; i<STSZ; i++) {
if((pdir = (paddr_t *)(u_long)ldxa(&pm->pm_segs[i], ASI_PHYS_CACHED))) {
if((pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED))) {
db_printf("pdir %ld at %lx:\n", i, (long)pdir);
for (k=0; k<PDSZ; k++) {
if ((ptbl = (paddr_t *)(u_long)ldxa(&pdir[k], ASI_PHYS_CACHED))) {
if ((ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED))) {
db_printf("\tptable %ld:%ld at %lx:\n", i, k, (long)ptbl);
for (j=0; j<PTSZ; j++) {
int64_t data0, data1;
data0 = ldxa(&ptbl[j], ASI_PHYS_CACHED);
data0 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
j++;
data1 = ldxa(&ptbl[j], ASI_PHYS_CACHED);
data1 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
if (data0 || data1) {
db_printf("%p: %lx\t",
(i<<STSHIFT)|(k<<PDSHIFT)|((j-1)<<PTSHIFT),
@ -442,7 +444,7 @@ db_pmap_kernel(addr, have_addr, count, modif)
db_dump_pmap(&kernel_pmap_);
} else {
for (j=i=0; i<STSZ; i++) {
long seg = (long)ldxa(&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
if (seg)
db_printf("seg %ld => %p%c", i, seg, (j++%4)?'\t':'\n');
}
@ -480,7 +482,7 @@ db_pmap_cmd(addr, have_addr, count, modif)
db_dump_pmap(pm);
} else {
for (i=0; i<STSZ; i++) {
long seg = (long)ldxa(&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
if (seg)
db_printf("seg %ld => %p%c", i, seg, (j++%4)?'\t':'\n');
}
@ -679,6 +681,25 @@ db_setpcb(addr, have_addr, count, modif)
db_printf("PID %d not found.\n", addr);
}
static void
db_print_trace_entry(te, i)
struct traptrace *te;
int i;
{
db_printf("%d:%d p:%d tt:%x:%lx:%p %p:%p ", i,
(int)te->tl, (int)te->pid,
(int)te->tt, (u_long)te->tstate,
(u_long)te->tfault, (u_long)te->tsp,
(u_long)te->tpc);
db_printsym((u_long)te->tpc, DB_STGY_PROC);
db_printf(": ");
if ((te->tpc && !(te->tpc&0x3)) &&
curproc &&
(curproc->p_pid == te->pid)) {
db_disasm((u_long)te->tpc, 0);
} else db_printf("\n");
}
void
db_traptrace(addr, have_addr, count, modif)
db_expr_t addr;
@ -686,17 +707,7 @@ db_traptrace(addr, have_addr, count, modif)
db_expr_t count;
char *modif;
{
extern struct traptrace {
unsigned short tl:3, /* Trap level */
ns:4, /* PCB nsaved */
tt:9; /* Trap type */
unsigned short pid; /* PID */
u_int tstate; /* tstate */
u_int tsp; /* sp */
u_int tpc; /* pc */
u_int tfault; /* MMU tag access */
} trap_trace[], trap_trace_end[];
int i, start, full = 0;
int i, start = 0, full = 0, reverse = 0;
struct traptrace *end;
start = 0;
@ -705,31 +716,42 @@ db_traptrace(addr, have_addr, count, modif)
{
register char c, *cp = modif;
if (modif)
while ((c = *cp++) != 0)
while ((c = *cp++) != 0) {
if (c == 'f')
full = 1;
if (c == 'r')
reverse = 1;
}
}
if (have_addr) {
start=addr;
start = addr / (sizeof (struct traptrace));
if (&trap_trace[start] > &trap_trace_end[0]) {
db_printf("Address out of range.\n");
return;
}
if (!full) end = &trap_trace[start+1];
}
for (i=start; &trap_trace[i] < end ; i++) {
db_printf("%d:%d p:%d tt:%x:%lx:%p %p:%p", i,
(int)trap_trace[i].tl, (int)trap_trace[i].pid,
(int)trap_trace[i].tt, (u_long)trap_trace[i].tstate,
(u_long)trap_trace[i].tfault, (u_long)trap_trace[i].tsp,
(u_long)trap_trace[i].tpc);
db_printsym((u_long)trap_trace[i].tpc, DB_STGY_PROC);
db_printf(": ");
if ((trap_trace[i].tpc && !(trap_trace[i].tpc&0x3)) &&
curproc &&
(curproc->p_pid == trap_trace[i].pid)) {
db_disasm((u_long)trap_trace[i].tpc, 0);
} else db_printf("\n");
db_printf("#:tl p:pid tt:tt:tstate:tfault sp:pc\n");
if (reverse) {
if (full && start)
for (i=start; --i;) {
db_print_trace_entry(&trap_trace[i], i);
}
i = (end - &trap_trace[0]);
while(--i > start) {
db_print_trace_entry(&trap_trace[i], i);
}
} else {
for (i=start; &trap_trace[i] < end ; i++) {
db_print_trace_entry(&trap_trace[i], i);
}
if (full && start)
for (i=0; i < start ; i++) {
db_print_trace_entry(&trap_trace[i], i);
}
}
}
/*
@ -848,6 +870,7 @@ struct db_command sparc_db_command_table[] = {
{ "pv", db_dump_pv, 0, 0 },
{ "stack", db_dump_stack, 0, 0 },
{ "tf", db_dump_trap, 0, 0 },
{ "ts", db_dump_ts, 0, 0 },
{ "traptrace", db_traptrace, 0, 0 },
{ "uvmdump", db_uvmhistdump, 0, 0 },
{ "watch", db_watch, 0, 0 },

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_trace.c,v 1.10 1999/11/06 20:18:50 eeh Exp $ */
/* $NetBSD: db_trace.c,v 1.11 2000/03/16 02:36:58 eeh Exp $ */
/*
* Mach Operating System
@ -39,6 +39,7 @@
void db_dump_window __P((db_expr_t, int, db_expr_t, char *));
void db_dump_stack __P((db_expr_t, int, db_expr_t, char *));
void db_dump_trap __P((db_expr_t, int, db_expr_t, char *));
void db_dump_ts __P((db_expr_t, int, db_expr_t, char *));
void db_print_window __P((u_int64_t));
#define INKERNEL(va) (((vaddr_t)(va)) >= USRSTACK) /* Not really true, y'know */
@ -351,3 +352,25 @@ db_dump_trap(addr, have_addr, count, modif)
}
void
db_dump_ts(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char *modif;
{
struct trapstate *ts;
int i, tl;
/* Use our last trapframe? */
ts = &ddb_regs.ddb_ts;
tl = ddb_regs.ddb_tl;
for (i=0; i<tl; i++) {
printf("%d tt=%lx tstate=%lx tpc=%p tnpc=%p\n",
i+1, (long)ts[i].tt, (u_long)ts[i].tstate,
(void*)(u_long)ts[i].tpc, (void*)(u_long)ts[i].tnpc);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.20 2000/02/21 20:38:51 erh Exp $ */
/* $NetBSD: intr.c,v 1.21 2000/03/16 02:36:58 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -106,7 +106,9 @@
struct intrhand *intrlev[MAXINTNUM];
void strayintr __P((const struct trapframe64 *, int));
int soft01intr __P((void *));
int softintr __P((void *));
int softnet __P((void *));
int send_softclock __P((void *));
/*
* Stray interrupt handler. Clear it if possible.
@ -158,47 +160,64 @@ strayintr(fp, vectored)
* Soft clock interrupt
*/
int
soft01intr(fp)
softintr(fp)
void *fp;
{
extern int rom_console_input;
if (rom_console_input && cnrom())
cnrint();
if (sir.sir_any) {
/*
* XXX this is bogus: should just have a list of
* routines to call, a la timeouts. Mods to
* netisr are not atomic and must be protected (gah).
*/
if (sir.sir_which[SIR_NET]) {
int n, s;
s = splhigh();
n = netisr;
netisr = 0;
splx(s);
sir.sir_which[SIR_NET] = 0;
return (1);
}
int
softnet(fp)
void *fp;
{
int n, s;
s = splhigh();
n = netisr;
netisr = 0;
splx(s);
#define DONETISR(bit, fn) do { \
if (n & (1 << bit)) \
fn(); \
} while (0)
#include <net/netisr_dispatch.h>
#undef DONETISR
}
if (sir.sir_which[SIR_CLOCK]) {
sir.sir_which[SIR_CLOCK] = 0;
softclock();
}
}
return (1);
}
struct intrhand level01 = { soft01intr, NULL, 1 };
/*
* Damn softclock doesn't return a value.
*/
int
send_softclock(fp)
void *fp;
{
softclock();
return 1;
}
struct intrhand soft01intr = { softintr, NULL, 1 };
struct intrhand soft01net = { softnet, NULL, 1 };
struct intrhand soft01clock = { send_softclock, NULL, 1 };
#if 1
void
setsoftint() {
send_softint(-1, IPL_SOFTINT, &soft01intr);
}
void
setsoftnet() {
send_softint(-1, IPL_SOFTNET, &soft01net);
}
void
setsoftclock() {
send_softint(-1, IPL_SOFTCLOCK, &soft01clock);
}
#endif
/*
* Level 15 interrupts are special, and not vectored here.
@ -207,7 +226,7 @@ struct intrhand level01 = { soft01intr, NULL, 1 };
*/
struct intrhand *intrhand[15] = {
NULL, /* 0 = error */
&level01, /* 1 = software level 1 + Sbus */
&soft01intr, /* 1 = software level 1 + Sbus */
NULL, /* 2 = Sbus level 2 (4m: Sbus L1) */
NULL, /* 3 = SCSI + DMA + Sbus level 3 (4m: L2,lpt)*/
NULL, /* 4 = software level 4 (tty softint) (scsi) */

View File

@ -1,4 +1,4 @@
/* $NetBSD: intreg.h,v 1.1.1.1 1998/06/20 04:58:52 eeh Exp $ */
/* $NetBSD: intreg.h,v 1.2 2000/03/16 02:36:59 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -71,9 +71,13 @@
#define IE_L1 (1<<1) /* request software level 1 interrupt */
#ifndef _LOCORE
struct intrhand; /* This is in cpu.h if you need it. */
void send_softint __P((int cpu, int level, struct intrhand *ih));
#if 0
void ienab_bis __P((int bis)); /* set given bits */
void ienab_bic __P((int bic)); /* clear given bits */
#endif
#endif
#if 0
#if defined(SUN4M)

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.50 2000/01/16 03:13:24 eeh Exp $ */
/* $NetBSD: locore.s,v 1.51 2000/03/16 02:36:59 eeh Exp $ */
/*
* Copyright (c) 1996-1999 Eduardo Horvath
* Copyright (c) 1996 Paul Kranenburg
@ -51,7 +51,7 @@
*/
#undef NO_VCACHE /* Map w/D$ disabled */
#undef TRAPTRACE /* Keep history of all traps (may watchdog) */
#define TRAPTRACE /* Keep history of all traps (may watchdog) */
#undef FLTRACE /* Keep history of all page faults only */
#define TRAPSTATS /* Count traps */
#undef TRAPS_USE_IG /* Use Interrupt Globals for trap handling */
@ -182,6 +182,7 @@
andn a, 0x1f, t; \
stxa %g0, [ t ] ASI_DCACHE_TAG; \
membar #Sync
/* The following can be used if the pointer is 16-byte aligned */
#define DLFLUSH2(t) \
stxa %g0, [ t ] ASI_DCACHE_TAG; \
membar #Sync
@ -449,6 +450,7 @@ _C_LABEL(msgbuf) = KERNBASE
#ifdef TRAPTRACE
#define TRACEME sethi %hi(1f), %g1; ba,pt %icc,traceit; or %g1, %lo(1f), %g1; 1:
#if 0
/* Can't use this macro 'cause we have no clean registers during a spill */
#define TRACEWIN sethi %hi(9f), %l6; ba,pt %icc,traceitwin; or %l6, %lo(9f), %l6; 9:
#endif
#ifdef TRAPS_USE_IG
@ -1405,17 +1407,28 @@ traceit:
brnz,pn %g4, 1f
lduw [%g2+TRACEPTR], %g3
rdpr %tl, %g4
rdpr %tt, %g5
set _C_LABEL(curproc), %g6
rdpr %tt, %g5
cmp %g4, 1
sllx %g4, 13, %g4
cmp %g6, 0x68
bnz,a,pt %icc, 3f
clr %g6
cmp %g5, 0x68
bnz,a,pt %icc, 3f
clr %g6
cmp %g5, 0x64
bnz,a,pt %icc, 3f
clr %g6
cmp %g5, 0x6c
bnz,a,pt %icc, 3f
clr %g6
LDPTR [%g6], %g6
movz %icc, %g0, %g6 ! DISABLE PID
3:
or %g4, %g5, %g4
mov %g0, %g5
brz,pn %g6, 2f
andncc %g3, (TRACESIZ-1), %g0
! LDPTR [%g6+P_PID], %g5 ! Load PID
andncc %g3, (TRACESIZ-1), %g0 ! At end of buffer? wrap
LDPTR [%g6+P_PID], %g5 ! Load PID
set _C_LABEL(cpcb), %g6 ! Load up nsaved
LDPTR [%g6], %g6
@ -1425,7 +1438,7 @@ traceit:
2:
rdpr %tstate, %g6
movnz %icc, %g0, %g3
movnz %icc, %g0, %g3 ! Wrap buffer if needed
rdpr %tpc, %g7
sth %g4, [%g2+%g3]
inc 2, %g3
@ -1456,7 +1469,7 @@ traceitwin:
or %l4, %l5, %l4
clr %l5 ! Don't load PID
andncc %l3, (TRACESIZ-1), %g0
movnz %icc, %g0, %l3
movnz %icc, %g0, %l3 ! Wrap?
clr %l0 ! Don't load nsaved
sllx %l0, 9, %l1
@ -2024,6 +2037,7 @@ dmmu_write_fault:
ldxa [%g0] ASI_DMMU_8KPTR, %g2 ! Load DMMU 8K TSB pointer
ldxa [%g0] ASI_DMMU, %g1 ! Hard coded for unified 8K TSB Load DMMU tag target register
stxa %g4, [%g6] ASI_PHYS_CACHED ! and write it out
DLFLUSH(%g6, %g6)
stx %g1, [%g2] ! Update TSB entry tag
stx %g4, [%g2+8] ! Update TSB entry data
@ -2148,6 +2162,7 @@ Ludata_miss:
brgez,pn %g4, winfix ! Entry invalid? Punt
bset TTE_ACCESS, %g4 ! Update the modified bit
stxa %g4, [%g6] ASI_PHYS_CACHED ! and write it out
DLFLUSH(%g6, %g6)
stx %g1, [%g2] ! Update TSB entry tag
stx %g4, [%g2+8] ! Update TSB entry data
#ifdef DEBUG
@ -2336,7 +2351,7 @@ winfixspill:
mov 2, %g5
set _C_LABEL(curproc), %g6
sllx %g4, 13, %g4
LDPTR [%g6], %g6
! LDPTR [%g6], %g6 ! Never touch PID
clr %g6 ! DISABLE PID
or %g4, %g5, %g4
mov %g0, %g5
@ -2344,14 +2359,15 @@ winfixspill:
andncc %g3, (TRACESIZ-1), %g0
! ldsw [%g6+P_PID], %g5 ! Load PID
2:
movnz %icc, %g0, %g3
movnz %icc, %g0, %g3 ! Wrap if needed
ba,a,pt %xcc, 4f
set _C_LABEL(cpcb), %g6 ! Load up nsaved
LDPTR [%g6], %g6
ldub [%g6 + PCB_NSAVED], %g6
sllx %g6, 9, %g6
or %g6, %g4, %g4
4:
rdpr %tstate, %g6
rdpr %tpc, %g7
sth %g4, [%g2+%g3]
@ -2467,7 +2483,7 @@ winfixspill:
mov %g7, %g1
CHKPT(%g5,%g7,0x13)
add %g6, PCB_NSAVED, %g7
DLFLUSH(%g6,%g7)
DLFLUSH(%g7,%g5)
lduba [%g6 + PCB_NSAVED] %asi, %g7 ! Start incrementing pcb_nsaved
#ifdef DEBUG
@ -2688,7 +2704,7 @@ winfixsave:
mov 3, %g5
set _C_LABEL(curproc), %g6
sllx %g4, 13, %g4
LDPTR [%g6], %g6
! LDPTR [%g6], %g6 ! Never do faultable loads
clr %g6 ! DISABLE PID
or %g4, %g5, %g4
mov %g0, %g5
@ -2696,7 +2712,7 @@ winfixsave:
andncc %g3, (TRACESIZ-1), %g0
! ldsw [%g6+P_PID], %g5 ! Load PID
2:
movnz %icc, %g0, %g3
movnz %icc, %g0, %g3 ! Wrap if needed
set _C_LABEL(cpcb), %g6 ! Load up nsaved
LDPTR [%g6], %g6
@ -2901,11 +2917,6 @@ data_error:
data_recover:
CHKPT(%o1,%o2,1)
wrpr %g0, PSTATE_KERN, %pstate ! disable interrupts
#if 1
rdpr %tl, %g1 ! DEBUG Make sure we have one trap level avail
inc %g1 ! DEBUG
wrpr %g0, %g1, %tl ! DEBUG
#endif
#ifdef TRAPSTATS
set _C_LABEL(uintrcnt), %g1
stw %g0, [%g1]
@ -3014,6 +3025,7 @@ Lutext_miss:
brgez,pn %g4, textfault
bset TTE_ACCESS, %g4 ! Update accessed bit
stxa %g4, [%g6] ASI_PHYS_CACHED ! and store it
DLFLUSH(%g6,%g6)
stx %g1, [%g2] ! Update TSB entry tag
stx %g4, [%g2+8] ! Update TSB entry data
#ifdef DEBUG
@ -3108,13 +3120,11 @@ textfault:
stb %g5, [%sp + CC64FSZ + STKB + TF_PIL]
stb %g5, [%sp + CC64FSZ + STKB + TF_OLDPIL]
#if 1
rdpr %tl, %g7
dec %g7
movrlz %g7, %g0, %g7
CHKPT(%g1,%g3,0x22)
wrpr %g0, %g7, %tl ! Revert to kernel mode
#endif
/* Now we need to blast away the D$ to make sure we're in sync */
set (2*NBPG)-8, %g7
1:
@ -3134,7 +3144,7 @@ textfault:
wrpr %g0, PSTATE_INTR, %pstate ! reenable interrupts
call _C_LABEL(text_access_fault) ! mem_access_fault(type, pc, &tf);
add %sp, CC64FSZ + STKB, %o2 ! (argument: &tf)
add %sp, CC64FSZ + STKB, %o2 ! (argument: &tf)
ba text_recover
nop
@ -3143,16 +3153,11 @@ text_error:
wrpr %g0, PSTATE_INTR, %pstate ! reenable interrupts
call _C_LABEL(text_access_error) ! mem_access_fault(type, sfva [pc], sfsr,
! afva, afsr, &tf);
add %sp, CC64FSZ + STKB, %o5 ! (argument: &tf)
add %sp, CC64FSZ + STKB, %o5 ! (argument: &tf)
text_recover:
CHKPT(%o1,%o2,2)
wrpr %g0, PSTATE_KERN, %pstate ! disable interrupts
#if 1
rdpr %tl, %g1 ! DEBUG Make sure we have one trap level avail
inc %g1 ! DEBUG
wrpr %g0, %g1, %tl ! DEBUG
#endif
wrpr %g0, PSTATE_KERN, %pstate ! disable interrupts
b return_from_trap ! go return
ldx [%sp + CC64FSZ + STKB + TF_TSTATE], %g1 ! Load this for return_from_trap
NOTREACHED
@ -3233,13 +3238,11 @@ Lslowtrap_reenter:
/*
* Phew, ready to enable traps and call C code.
*/
#if 1
rdpr %tl, %g1
dec %g1
movrlz %g1, %g0, %g1
CHKPT(%g2,%g3,0x24)
wrpr %g0, %g1, %tl ! Revert to kernel mode
#endif
!! In the medium anywhere model %g4 points to the start of the data segment.
!! In our case we need to clear it before calling any C-code
clr %g4
@ -3249,13 +3252,6 @@ Lslowtrap_reenter:
wrpr %g0, PSTATE_INTR, %pstate ! traps on again
! wrpr %g0, PSTATE_KERN, %pstate ! traps off again
#if 1
rdpr %tl, %g1 ! DEBUG Make sure we have one trap level avail
inc %g1 ! DEBUG
CHKPT(%g2,%g3,0x25)
wrpr %g0, %g1, %tl ! DEBUG
#endif
CLRTT ! Clear out old handled trap
CHKPT(%o1,%o2,3)
b return_from_trap
nop
@ -3640,8 +3636,7 @@ syscall_setup:
return_from_syscall:
wrpr %g0, PSTATE_KERN, %pstate ! Disable intterrupts
CHKPT(%o1,%o2,0x32)
wrpr %g0, 1, %tl ! Return to tl==1
CLRTT
wrpr %g0, 0, %tl ! Return to tl==0
CHKPT(%o1,%o2,4)
b return_from_trap
nop
@ -3686,7 +3681,8 @@ return_from_syscall:
* shift instead of multiply for address calculation). It hunts for
* any available slot at that level. Available slots are NULL.
*
* NOTE: If no slots are available, the interrupt is lost.
* NOTE: If no slots are available, we issue an un-vectored interrupt,
* but it will probably be lost anyway.
*
* Then interrupt_vector uses the interrupt level in the intrhand
* to issue a softint of the appropriate level. The softint handler
@ -3733,14 +3729,18 @@ interrupt_vector:
#endif
bgeu 3f
sllx %g2, PTRSHFT, %g5 ! Calculate entry number
LDPTR [%g3+%g5], %g5 ! We have a pointer to the handler
add %g3, %g5, %g5
DLFLUSH(%g5, %g6)
LDPTR [%g5], %g5 ! We have a pointer to the handler
#ifdef DEBUG
tst %g5
tz 56
#endif
brz,pn %g5, 3f ! NULL means it isn't registered yet. Skip it.
nop
setup_sparcintr:
setup_sparcintr:
add %g5, IH_PIL, %g6
DLFLUSH(%g6, %g6)
lduh [%g5+IH_PIL], %g6 ! Read interrupt mask
#ifdef DEBUG
set _C_LABEL(intrdebug), %g7
@ -3772,10 +3772,12 @@ setup_sparcintr:
add %g1, %g2, %g1
2:
#if 1
DLFLUSH(%g1, %g2)
mov %g5, %g2
CASPTR [%g1] ASI_N, %g0, %g2 ! Try a slot -- MPU safe
brz,pt %g2, 4f ! Available?
#else
DLFLUSH(%g1, %g2)
LDPTR [%g1], %g2 ! Try a slog
brz,a %g2, 4f ! Available?
STPTR %g5, [%g1] ! Grab it
@ -3788,6 +3790,7 @@ setup_sparcintr:
!! There were no available slots and the interrupt was lost.
!! We'll resort to polling in this case.
4:
DLFLUSH(%g1, %g1) ! Prevent D$ pollution
#endif
set 1, %g7
stxa %g0, [%g0] ASI_IRSR ! Ack IRQ
@ -3853,6 +3856,25 @@ iv_halt:
* are set, handle those interrupts, then clear them by setting the
* appropriate bits in ASR_CLEAR_SOFTINT(0x15).
*
* We have an array of 8 interrupt vector slots for each of 15 interrupt
* levels. If a vectored interrupt can be dispatched, the dispatch
* routine will place a pointer to an intrhand structure in one of
* the slots. The interrupt handler will go through the list to look
* for an interrupt to dispatch. If it finds one it will pull it off
* the list, free the entry, and call the handler. The code is like
* this:
*
* for (i=0; i<8; i++)
* if (ih = intrpending[intlev][i]) {
* intrpending[intlev][i] = NULL;
* if ((*ih->ih_fun)(ih->ih_arg ? ih->ih_arg : &frame))
* return;
* strayintr(&frame);
* return;
* }
*
* Otherwise we go back to the old style of polled interrupts.
*
* After preliminary setup work, the interrupt is passed to each
* registered handler in turn. These are expected to return nonzero if
* they took care of the interrupt. If a handler claims the interrupt,
@ -3902,6 +3924,7 @@ _C_LABEL(sparc_interrupt):
bz,pt %icc, 0f
set _C_LABEL(intrlev), %g3
wr %g0, 1, CLEAR_SOFTINT
DLFLUSH(%g3, %g2)
ba,pt %icc, setup_sparcintr
LDPTR [%g3 + PTRSZ], %g5
0:
@ -3960,10 +3983,14 @@ _C_LABEL(sparc_interrupt):
sth %l5, [%sp + CC64FSZ + STKB + TF_TT]! debug
stx %l0, [%sp + CC64FSZ + STKB + TF_TSTATE] ! set up intrframe/clockframe
stx %l1, [%sp + CC64FSZ + STKB + TF_PC]
btst TSTATE_PRIV, %l0 ! User mode?
stx %l2, [%sp + CC64FSZ + STKB + TF_NPC]
stx %fp, [%sp + CC64FSZ + STKB + TF_KSTACK] ! old frame pointer
! bnz,pt %xcc, 1f ! No.
stx %fp, [%sp + CC64FSZ + STKB + TF_KSTACK] ! old frame pointer
sub %l5, 0x40, %l5 ! Convert to interrupt level
! call _C_LABEL(blast_vcache) ! Clear out our D$ if from user mode
1:
sub %l5, 0x40, %l5 ! Convert to interrupt level
mov 1, %l3 ! Ack softint
sll %l3, %l5, %l3 ! Generate IRQ mask
wr %l3, 0, CLEAR_SOFTINT ! (don't clear possible %tick IRQ)
@ -3983,16 +4010,19 @@ _C_LABEL(sparc_interrupt):
sll %l5, PTRSHFT+3, %l2
add %l2, %l4, %l4
mov 8, %l7
1:
clr %l5 ! Handled?
3:
! DLFLUSH(%l4, %l2)
LDPTR [%l4], %l2 ! Check a slot
dec %l7
brnz,a,pt %l2, 1f ! Pending?
STPTR %g0, [%l4] ! Clear the slot
brgz,pt %l7, 1b
brnz,pt %l2, 1f ! Pending?
nop
brgz,pt %l7, 3b
inc PTRSZ, %l4 ! Next slot
ba,a,pt %icc, 2f ! Not found -- use the old scheme
nop ! XXX Spitfire bug
1:
! DLFLUSH(%l2, %o3)
LDPTR [%l2 + IH_CLR], %o3
add %sp, CC64FSZ+STKB, %o2 ! tf = %sp + CC64FSZ + STKB
LDPTR [%l2 + IH_FUN], %o1 ! ih->ih_fun
@ -4002,12 +4032,16 @@ _C_LABEL(sparc_interrupt):
0:
jmpl %o1, %o7 ! handled = (*ih->ih_fun)(...)
movrz %o0, %o2, %o0 ! arg = (arg == 0) ? arg : tf
brnz,pt %o0, intrcmplt ! Done?
mov 1, %o1
inc %l5
brnz,pt %o0, 3b ! Handle any others
STPTR %g0, [%l4] ! Clear the slot
mov 1, %o1
call _C_LABEL(strayintr) ! strayintr(&intrframe, 1)
add %sp, CC64FSZ + STKB, %o0
ba,a,pt %icc, intrcmplt ! done
2:
ba,a,pt %icc, 3b ! Try another
2:
brnz,pt %l5, intrcmplt ! Finish up
nop
#endif
#ifdef TRAPSTATS
set _C_LABEL(intrpoll), %l4
@ -4016,7 +4050,9 @@ _C_LABEL(sparc_interrupt):
st %o0, [%l4]
#endif
set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev];
LDPTR [%l4 + %l3], %l4
add %l4, %l3, %l4
! DLFLUSH(%l4, %o6) ! Not really needed
LDPTR [%l4], %l4
wrpr %g0, PSTATE_INTR, %pstate ! Reenable interrupts
clr %l3
#ifdef DEBUG
@ -4054,7 +4090,9 @@ _C_LABEL(sparc_interrupt):
_ALIGN
#endif
1: LDPTR [%l4 + IH_FUN], %o1 ! do {
1:
! DLFLUSH(%l4, %o1) ! Should not be needed
LDPTR [%l4 + IH_FUN], %o1 ! do {
LDPTR [%l4 + IH_ARG], %o0
#ifdef DEBUG
set _C_LABEL(intrdebug), %o2
@ -4114,12 +4152,6 @@ intrcmplt:
stw %l6, [%sp + CC64FSZ + STKB + TF_Y] ! Silly, but we need to save this for rft
wrpr %l3, 0, %pil
rdpr %tl, %l3 ! Restore old trap frame
inc %l3
CHKPT(%l1,%l2,0x27)
wrpr %g0, %l3, %tl
CLRTT
CHKPT(%o1,%o2,5)
b return_from_trap
nop
@ -4255,15 +4287,27 @@ return_from_trap:
!! We'll make sure we flush our pcb here, rather than later.
!!
ldx [%sp + CC64FSZ + STKB + TF_TSTATE], %g1
#if 0
btst TSTATE_PRIV, %g1 ! returning to userland?
#if 0
bnz,pt %icc, 0f
sethi %hi(_C_LABEL(curproc)), %o1
call _C_LABEL(rwindow_save) ! Flush out our pcb
LDPTR [%o1 + %lo(_C_LABEL(curproc))], %o0
0:
#endif
!!
!! Let all pending interrupts drain before returning to userland
!!
wrpr %g0, PSTATE_INTR, %pstate
bnz,pn %icc, 1f ! Returning to userland?
nop
wrpr %g0, %g0, %pil ! Lower IPL
1:
wrpr %g0, PSTATE_KERN, %pstate ! Make sure we have normal globals & no IRQs
rdpr %tl, %g1 ! Grab a set of trap registers
inc %g1
wrpr %g1, %g0, %tl
/* First restore normal globals */
ldx [%sp + CC64FSZ + STKB + TF_G + (1*8)], %g1 ! restore g1
ldx [%sp + CC64FSZ + STKB + TF_G + (2*8)], %g2 ! restore g2
@ -4277,24 +4321,30 @@ return_from_trap:
#ifdef TRAPS_USE_IG
wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate ! DEBUG
#endif
mov %sp, %g6
ldx [%g6 + CC64FSZ + STKB + TF_O + (0*8)], %i0 ! tf.tf_out[0], etc
ldx [%g6 + CC64FSZ + STKB + TF_O + (1*8)], %i1
ldx [%g6 + CC64FSZ + STKB + TF_O + (2*8)], %i2
ldx [%g6 + CC64FSZ + STKB + TF_O + (3*8)], %i3
ldx [%g6 + CC64FSZ + STKB + TF_O + (4*8)], %i4
ldx [%g6 + CC64FSZ + STKB + TF_O + (5*8)], %i5
ldx [%g6 + CC64FSZ + STKB + TF_O + (6*8)], %i6
ldx [%g6 + CC64FSZ + STKB + TF_O + (7*8)], %i7
ldx [%sp + CC64FSZ + STKB + TF_O + (0*8)], %i0 ! tf.tf_out[0], etc
ldx [%sp + CC64FSZ + STKB + TF_O + (1*8)], %i1
ldx [%sp + CC64FSZ + STKB + TF_O + (2*8)], %i2
ldx [%sp + CC64FSZ + STKB + TF_O + (3*8)], %i3
ldx [%sp + CC64FSZ + STKB + TF_O + (4*8)], %i4
ldx [%sp + CC64FSZ + STKB + TF_O + (5*8)], %i5
ldx [%sp + CC64FSZ + STKB + TF_O + (6*8)], %i6
ldx [%sp + CC64FSZ + STKB + TF_O + (7*8)], %i7
/* Now load trap registers into alternate globals */
ld [%g6 + CC64FSZ + STKB + TF_Y], %g4
ldx [%g6 + CC64FSZ + STKB + TF_TSTATE], %g1 ! load new values
ld [%sp + CC64FSZ + STKB + TF_Y], %g4
ldx [%sp + CC64FSZ + STKB + TF_TSTATE], %g1 ! load new values
wr %g4, 0, %y
ldx [%g6 + CC64FSZ + STKB + TF_PC], %g2
ldx [%g6 + CC64FSZ + STKB + TF_NPC], %g3
ldx [%sp + CC64FSZ + STKB + TF_PC], %g2
ldx [%sp + CC64FSZ + STKB + TF_NPC], %g3
#ifdef DEBUG
tst %g2
tz 1 ! tpc NULL? Panic
tst %i6
tz 1 ! %fp NULL? Panic
#endif
#ifdef NOTDEF_DEBUG
ldub [%g6 + CC64FSZ + STKB + TF_PIL], %g5 ! restore %pil
ldub [%sp + CC64FSZ + STKB + TF_PIL], %g5 ! restore %pil
wrpr %g5, %pil ! DEBUG
#endif
@ -4348,7 +4398,7 @@ rft_kernel:
or %g6, %g4, %g4
rdpr %tstate, %g6
movnz %icc, %g0, %g3
movnz %icc, %g0, %g3 ! Wrap if needed
rdpr %tpc, %g7
sth %g4, [%g2+%g3]
inc 2, %g3
@ -4375,8 +4425,10 @@ rft_kernel:
lduw [%g1], %g2
inc %g2
stw %g2, [%g1]
#endif
! wrpr %g0, 0, %cleanwin ! DEBUG
#endif
#if 0
wrpr %g0, 0, %cleanwin ! DEBUG
#endif
retry ! We should allow some way to distinguish retry/done
NOTREACHED
/*
@ -4644,7 +4696,7 @@ badregs:
membar #Sync ! Should not be needed due to retry
flush %g7 ! Should not be needed due to retry
CLRTT
CHKPT(%g4,%g7,0xc)
CHKPT(%g4,%g7,0xd)
#ifdef TRAPTRACE
set trap_trace, %g2
lduw [%g2+TRACEDIS], %g4
@ -4656,7 +4708,7 @@ badregs:
set _C_LABEL(curproc), %g6
sllx %g4, 13, %g4
LDPTR [%g6], %g6
clr %g6 ! DISABLE PID
! clr %g6 ! DISABLE PID
or %g4, %g5, %g4
mov %g0, %g5
brz,pn %g6, 2f
@ -4671,7 +4723,7 @@ badregs:
or %g6, %g4, %g4
rdpr %tstate, %g6
movnz %icc, %g0, %g3
movnz %icc, %g0, %g3 ! Wrap if needed
rdpr %tpc, %g7
sth %g4, [%g2+%g3]
inc 2, %g3
@ -5293,10 +5345,10 @@ _C_LABEL(openfirmware):
mov %g7, %l7
rdpr %pstate, %l0
jmpl %i4, %o7
#ifndef _LP64
wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate
#else
#if defined(_LP64) || defined(TRAPTRACE)
wrpr %g0, PSTATE_PROM, %pstate
#else
wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate
#endif
wrpr %l0, %g0, %pstate
mov %l1, %g1
@ -5348,7 +5400,7 @@ _C_LABEL(openfirmware):
mov %g6, %l6
mov %g7, %l7
jmpl %o1, %o7
#ifdef _LP64
#if defined(_LP64) || defined(TRAPTRACE)
wrpr %g0, PSTATE_PROM, %pstate ! Enable 64-bit addresses for the prom
#else
wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate ! Enable 64-bit addresses for the prom
@ -5528,22 +5580,23 @@ _C_LABEL(blast_vcache):
.proc 1
FTYPE(dcache_flush_page)
_C_LABEL(dcache_flush_page):
mov -1, %g1
srlx %o0, 13-2, %g2
srl %g1, 3, %g1 ! Generate mask for tag: bits [29..2]
sllx %g1, 1, %g1
mov -1, %g1 ! Generate mask for tag: bits [29..2]
srlx %o0, 13-2, %g2 ! Tag is VA bits <40:13> in bits <29:2>
srl %g1, 2, %g1 ! Now we have bits <29:0> set
andn %g1, 3, %g1 ! Now we have bits <29:2> set
set (2*NBPG)-8, %o3
set (2*NBPG), %o3
clr %o1
1:
ldxa [%o3] ASI_DCACHE_TAG, %g3
ldxa [%o1] ASI_DCACHE_TAG, %g3
xor %g3, %g2, %g3
andcc %g3, %g1, %g0
bne,pt %xcc, 2f
nop
stxa %g0, [%o3] ASI_DCACHE_TAG
dec 16, %o3
stxa %g0, [%o1] ASI_DCACHE_TAG
2:
brnz,pt %o3, 1b
dec 8, %o3
inc 16, %o1
sethi %hi(KERNBASE), %o5
flush %o5
retl
@ -7356,7 +7409,7 @@ Lsw_havectx:
andncc %o3, (TRACESIZ-1), %g0
! ldsw [%o0+P_PID], %o5 ! Load PID
2:
movnz %icc, %g0, %o3
movnz %icc, %g0, %o3 ! Wrap if needed
set _C_LABEL(cpcb), %o0 ! Load up nsaved
LDPTR [%o0], %o0
@ -8053,17 +8106,17 @@ ENTRY(pmap_zero_page)
#endif
pmap_zero_phys:
#endif
#if 0
set NBPG, %o2 ! Start of upper D$
sub %o2, 8, %o1 ! End of lower D$ and bytes to clear
#if 1
set NBPG, %o2 ! Loop count
clr %o1
1:
dec 8, %o2
stxa %g0, [%o0] ASI_PHYS_CACHED
inc 8, %o0
stxa %g0, [%o1] ASI_DCACHE_TAG
dec 8, %o1
stxa %g0, [%o2] ASI_DCACHE_TAG
brnz %o1, 1b
inc 8, %o2
brgz %o2, 1b
inc 16, %o1
sethi %hi(KERNBASE), %o3
flush %o3
retl
@ -8479,7 +8532,7 @@ pmap_copy_phys:
/* This is the short, slow, safe version that uses %g1 */
set NBPG, %o3
sub %o3, 8, %o2
clr %o2
mov %g1, %o4 ! Save g1
1:
DLFLUSH(%o0,%g1)
@ -8488,11 +8541,10 @@ pmap_copy_phys:
stxa %g1, [%o1] ASI_PHYS_CACHED
inc 8, %o1
dec 8, %o3
stxa %g0, [%o2] ASI_DCACHE_TAG! Blast away at the D$
dec 8, %o2
stxa %g0, [%o3] ASI_DCACHE_TAG
brnz,pt %o2, 1b
inc 8, %o3
brnz,pt %o3, 1b
inc 16, %o2
mov %o4, %g1
sethi %hi(KERNBASE), %o5
flush %o5
@ -8509,10 +8561,13 @@ pmap_copy_phys:
inc 8, %o0
cmp %o0, %o3
stxa %g1, [%o1] ASI_PHYS_CACHED
DLFLUSH(%o1,%g1)
bl,pt %icc, 1b ! We don't care about pages >4GB
inc 8, %o1
#if 0
ba _C_LABEL(blast_vcache) ! Clear out D$ and return
mov %o4, %g1 ! Restore g1
#endif
retl
mov %o4, %g1 ! Restore g1
#endif
@ -8647,7 +8702,9 @@ ENTRY(pseg_set)
brnz,a,pt %o5, 0f ! Null pointer?
mov %o5, %o4
brz,pn %o3, 1f ! Have a spare?
stxa %o3, [%o4] ASI_PHYS_CACHED
nop
stxa %o3, [%o4] ASI_PHYS_CACHED
DLFLUSH(%o4, %o4)
mov %o3, %o4
clr %o3 ! Mark spare as used
0:
@ -8661,7 +8718,9 @@ ENTRY(pseg_set)
brnz,a,pt %o5, 0f ! Null pointer?
mov %o5, %o4
brz,pn %o3, 1f ! Have a spare?
stxa %o3, [%o4] ASI_PHYS_CACHED
nop
stxa %o3, [%o4] ASI_PHYS_CACHED
DLFLUSH(%o4, %o4)
mov %o3, %o4
clr %o3 ! Mark spare as used
0:
@ -8670,6 +8729,7 @@ ENTRY(pseg_set)
sll %o5, 3, %o5
add %o5, %o4, %o4
stxa %o2, [%o4] ASI_PHYS_CACHED ! Easier than shift+or
DLFLUSH(%o4, %o4)
#ifdef DEBUG
!! Try pseg_get to verify we did this right
mov %o7, %o4
@ -9896,6 +9956,56 @@ ENTRY(ienab_bic)
retl
wr %o0, 0, CLEAR_SOFTINT ! CLEAR_SOFTINT
/*
* send_softint(cpu, level, intrhand)
*
* Send a softint with an intrhand pointer so we can cause a vectored
* interrupt instead of a polled interrupt. This does pretty much the
* same as interrupt_vector. If intrhand is NULL then it just sends
* a polled interrupt. If cpu is -1 then send it to this CPU, if it's
* -2 send it to any CPU, otherwise send it to a particular CPU.
*
* XXXX Dispatching to different CPUs is not implemented yet.
*
* XXXX We do not block interrupts here so it's possible that another
* interrupt of the same level is dispatched before we get to
* enable the softint, causing a spurious interrupt.
*/
ENTRY(send_softint)
#ifdef VECTORED_INTERRUPTS
brz,pn %o2, 1f
set intrpending, %o3
mov 8, %o4 ! Number of slots to search
sll %o1, PTRSHFT+3, %o5 ! Find start of table for this IPL
add %o3, %o5, %o3
2:
#if 1
DLFLUSH(%o3, %o5)
mov %o2, %o5
CASPTR [%o3] ASI_N, %g0, %o5 ! Try a slot -- MPU safe
brz,pt %o5, 4f ! Available?
#else
DLFLUSH(%o3, %o5)
LDPTR [%o3], %o5 ! Try a slog
brz,a %o5, 4f ! Available?
STPTR %o2, [%o3] ! Grab it
#endif
dec %o4
brgz,pt %o4, 2b
inc PTRSZ, %o3 ! Next slot
!! If we get here we have a problem.
!! There were no available slots and the interrupt was lost.
!! We'll resort to polling in this case.
4:
DLFLUSH(%o3, %o3) ! Prevent D$ pollution
1:
#endif
mov 1, %o3 ! Change from level to bitmask
sllx %o3, %o1, %o3
retl
wr %o3, 0, SET_SOFTINT ! CLEAR_SOFTINT
/*
* Here is a very good random number generator. This implementation is
* based on _Two Fast Implementations of the `Minimal Standard' Random

View File

@ -1,8 +1,8 @@
/* $NetBSD: pmap.c,v 1.47 1999/12/30 16:31:18 eeh Exp $ */
/* #define NO_VCACHE */ /* Don't forget the locked TLB in dostart */
/* $NetBSD: pmap.c,v 1.48 2000/03/16 02:37:00 eeh Exp $ */
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF 1
/* #define BOOT_DEBUG */
/* #define BOOT1_DEBUG */
#undef BOOT_DEBUG
#undef BOOT1_DEBUG
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@ -434,7 +434,7 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
phys_msgbuf);
#endif
if (prom_map_phys(phys_msgbuf, msgbufsiz, (vaddr_t)msgbufp,
-1/* sunos does this */) != -1)
-1/* sunos does this */) == -1)
prom_printf("Failed to map msgbuf\r\n");
#ifdef BOOT_DEBUG
else
@ -491,7 +491,7 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
* in, copy the kernel over, swap mappings, then finally, free the
* old kernel. Then we can continue with this.
*/
ksize = round_page(mp1->start - kernelstart);
ksize = round_page(kernelend - kernelstart);
if (ksegp & (4*MEG-1)) {
#ifdef BOOT1_DEBUG
@ -1472,7 +1472,7 @@ pmap_kenter_pa(va, pa, prot)
tsb_enter(pm->pm_ctx, va, tte.data.data);
ASSERT((tsb[i].data.data & TLB_NFO) == 0);
#if 1
#if 0
#if 1
/* this is correct */
dcache_flush_page(va);
#else
@ -1851,7 +1851,7 @@ pmap_enter(pm, va, pa, prot, flags)
}
/* Force reload -- protections may be changed */
tlb_flush_pte((npv->pv_va&PV_VAMASK), pm->pm_ctx);
#if 0
#if 1
/* XXXXXX We should now flush the DCACHE to make sure */
dcache_flush_page((npv->pv_va&PV_VAMASK));
#else
@ -1904,7 +1904,7 @@ pmap_enter(pm, va, pa, prot, flags)
ASSERT((tsb[i].data.data & TLB_NFO) == 0);
}
#if 1
#if 0
#if 1
/* this is correct */
dcache_flush_page(va);
#else