diff --git a/sys/arch/sparc64/dev/fd.c b/sys/arch/sparc64/dev/fd.c index 673134bbe335..75c382e87be0 100644 --- a/sys/arch/sparc64/dev/fd.c +++ b/sys/arch/sparc64/dev/fd.c @@ -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; } diff --git a/sys/arch/sparc64/dev/zs.c b/sys/arch/sparc64/dev/zs.c index 46f47e798dd9..18b250ccbef5 100644 --- a/sys/arch/sparc64/dev/zs.c +++ b/sys/arch/sparc64/dev/zs.c @@ -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. */ diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h index a41735ac2527..9e77e3a58d7c 100644 --- a/sys/arch/sparc64/include/cpu.h +++ b/sys/arch/sparc64/include/cpu.h @@ -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; diff --git a/sys/arch/sparc64/include/db_machdep.h b/sys/arch/sparc64/include/db_machdep.h index ce1612e56201..3b31e235dd29 100644 --- a/sys/arch/sparc64/include/db_machdep.h +++ b/sys/arch/sparc64/include/db_machdep.h @@ -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; diff --git a/sys/arch/sparc64/include/intr.h b/sys/arch/sparc64/include/intr.h index dbae5ae49521..1f57be0cba88 100644 --- a/sys/arch/sparc64/include/intr.h +++ b/sys/arch/sparc64/include/intr.h @@ -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 */ diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c index 9754d3af7c4f..1dd639df5dcf 100644 --- a/sys/arch/sparc64/sparc64/autoconf.c +++ b/sys/arch/sparc64/sparc64/autoconf.c @@ -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; + } } } } diff --git a/sys/arch/sparc64/sparc64/db_interface.c b/sys/arch/sparc64/sparc64/db_interface.c index c58a428543bd..71b1b5e5b553 100644 --- a/sys/arch/sparc64/sparc64/db_interface.c +++ b/sys/arch/sparc64/sparc64/db_interface.c @@ -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; itf_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; ipm_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 %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 %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 }, diff --git a/sys/arch/sparc64/sparc64/db_trace.c b/sys/arch/sparc64/sparc64/db_trace.c index cde0a6802ce2..e0cc7d945d94 100644 --- a/sys/arch/sparc64/sparc64/db_trace.c +++ b/sys/arch/sparc64/sparc64/db_trace.c @@ -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 - #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) */ diff --git a/sys/arch/sparc64/sparc64/intreg.h b/sys/arch/sparc64/sparc64/intreg.h index 38b5be3403f7..d49939470b34 100644 --- a/sys/arch/sparc64/sparc64/intreg.h +++ b/sys/arch/sparc64/sparc64/intreg.h @@ -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) diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index 128fe5a6690f..560a7bddfefe 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -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 diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c index a9de65db2a74..f9697b11c5d1 100644 --- a/sys/arch/sparc64/sparc64/pmap.c +++ b/sys/arch/sparc64/sparc64/pmap.c @@ -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