Subject: port-evbppc/24096: ctitcal 405GP/EP interrupts non-functional/ gdb/ss fails
To: None <gnats-bugs@gnats.netbsd.org>
From: None <djg@trpz.com>
List: netbsd-bugs
Date: 01/14/2004 15:32:40
>Number: 24096
>Category: port-evbppc
>Synopsis: ctitcal 405GP/EP interrupts non-functional/ gdb/ss fails
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: port-evbppc-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jan 14 23:33:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:
>Release: NetBSD 1.6ZD
>Organization:
>Environment:
System: NetBSD cerumen.trpz.com 1.6ZD NetBSD 1.6ZD (NATES) #1: Mon Nov 10 12:58:16 PST 2003 djg@nates.trpz.com:/home/djg/src/NetBSD/usr/src/sys/arch/i386/compile/NATES i386
Architecture: powerpc
Machine: evbppc
>Description:
The critcal interupt in arch/powerpc/ibm4xx/trap_subr.S is
non functional. Most ports only use crtitcal interrupts
for machine-check which is disabled along with comments
of the machine hanging. The debug interrupt is also
a critical interrupt on the 405GP and 405EP. This is
the interrupt from "single stepping". The current
code declares "debug" as a normal interrupt but it
isn't. The existing code
(CRITICAL_PROLOG) has several problems.
1) it uses sprg1 without reagard to NORMAL_PROLOG
2) it uses the same save area as normal interrups
3) it sets srr0 and srr1 without reagrd to other
(normal) interrupts.
For machine check, since death is imminent this problably
dosn't matter but for single steeping its really useful
to be able to return to a running system. In most cases
taking a DEBUG interrupt would incorrectly use srr0 and srr1
which by very good fortune happens to be benign except that
the PC is off by 4. It is benign bacuse gdb uses "trap" instructions
which cause a PGM exception and hence srr0 and srr1 happend to
correspend to that. Thus gdb/single step fails - everything
else works.
Of note on GP/EP when gdb starts an executable the very first
instruction is set witk msr=PSL_SE, but this will result in a TLBMISS.
The very first DEBUG interrupt therfore occurs in kernel mode
on the first instruction of the interrupt handdler for tlmiss.
(I read this in the linux code). Thus all of the conditions
obove are met. This kernel mode debug trap has to be ignored
(with PSL_SE unset) to get back to the orignal user mode PSL_SE trap .
>How-To-Repeat:
gdb and single step on the ppc405
>Fix:
I've tried several things but it looks like the only workable
solution is to separate the crital from the non-critical code.
The following code works, but if the direction of trap_subr.S
were to change to be more like the OEA code then that ought to
be considerd (or maybe the OEA code should tend towards the
IBM4XX), anyway, using spgr2 for the critcal SP, its own
stack, its own s_trap variation (for critsave) and using
rfci for the returns (preserving srr0 and srr1 throughout).
3 files: sys/arch/powerpc/ibm4xx/ibm40x_machdep.c (see comment
below)
sys/arch/powerpc/ibm4xx/trap_subr.c
sys/arch/powerpc/ibm4xx/trap.c
also included is support for critcal external interrupts, however,
that requires an "ibm4xx_install_extcin()" which dosn't fit
well into the current evbppc scheme. (behind #ifdef trpz)
There again that seems to be overly complicated and for more
flexibilty than I've seen needed. (but I'm sure it fixed somebody's
problem). The code has only been run on a 405EP which isn't supportd
in current, and still has debug code left in. (PS the wdog interrupt
on a 405/EP should end a rfci too). complete source available
on request.
*** trap_subr.S Wed Jan 14 14:53:02 2004
--- /usr/src_current/src/sys/arch/powerpc/ibm4xx/trap_subr.S Mon Aug 11 20:09:19 2003
***************
*** 76,83 ****
/*
* Data used during primary/secondary traps/interrupts
*/
- #define critsave 0x1e0 /* primary save area for trap handling */
#define tempsave 0x2e0 /* primary save area for trap handling */
#define exitsave 0x4e0 /* use this so trap return does not conflict */
/*
* XXX Interrupt and spill stacks need to be per-CPU.
--- 76,83 ----
/*
* Data used during primary/secondary traps/interrupts
*/
#define tempsave 0x2e0 /* primary save area for trap handling */
+ #define disisave 0x3e0 /* primary save area for dsi/isi traps */
#define exitsave 0x4e0 /* use this so trap return does not conflict */
/*
* XXX Interrupt and spill stacks need to be per-CPU.
***************
*** 87,100 ****
GET_CPUINFO(rX); \
lwz rX,CI_CURPCB(rX)
- /*
- * Please note a critcal interrupt can occure during this
- * code segment. (PT_STEP on exec will cause a DEBUG interrupt
- * on the tlbmiss of the first instruction in the vector!, Also
- * a tlbmiss in this segment would be very bad - but we are kenrnel
- * mode so r1 ought be usable)
- */
-
#define STANDARD_PROLOG(savearea) \
mtsprg 1,1; /* save SP */ \
stmw 28,savearea(0); /* free r28-r31 */ \
--- 87,92 ----
***************
*** 108,117 ****
1:
#define CRITICAL_PROLOG(savearea) \
! mtsprg 2,1; /* save SP in sprg2 */ \
stmw 28,savearea(0); /* free r28-r31 */ \
mflr 28; /* save LR */ \
! mfcr 29; /* save CR */
/* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */
--- 100,118 ----
1:
#define CRITICAL_PROLOG(savearea) \
! mtsprg 1,1; /* save SP */ \
stmw 28,savearea(0); /* free r28-r31 */ \
mflr 28; /* save LR */ \
! mfcr 29; /* save CR */ \
! mfsrr2 30; /* Fake a standard trap */ \
! mtsrr0 30; \
! mfsrr3 31; /* Test whether we already had PR set */ \
! mtsrr1 31; \
! mtcr 31; \
! bc 4,17,1f; /* branch if PSL_PR is clear */ \
! GET_PCB(1); \
! addi 1,1,USPACE; /* stack is top of user struct */ \
! 1:
/* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */
***************
*** 119,128 ****
.globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
_C_LABEL(name ## trap): \
STANDARD_PROLOG(tempsave); \
- mfesr 31; \
- stw 31,20+tempsave(0); \
bla s_trap ; \
- trap; \
_C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
/* Access exceptions also need DEAR and ESR saved */
--- 120,126 ----
***************
*** 134,152 ****
mfesr 31; \
stmw 30,16+tempsave(0); \
bla s_trap ; \
- trap; \
_C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
! /* Maybe this should call ddb.... save ESR too */
#define CRITICAL_EXC_HANDLER(name)\
.globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
_C_LABEL(name ## trap): \
! CRITICAL_PROLOG(critsave); \
! mfdear 30; \
! mfesr 31; \
! stw 30,16+critsave(0); \
! bla s_ctrap ; \
! trap; \
_C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
/*
--- 132,145 ----
mfesr 31; \
stmw 30,16+tempsave(0); \
bla s_trap ; \
_C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
! /* Maybe this should call ddb.... */
#define CRITICAL_EXC_HANDLER(name)\
.globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
_C_LABEL(name ## trap): \
! CRITICAL_PROLOG(tempsave); \
! bla s_trap ; \
_C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
/*
***************
*** 159,165 ****
ACCESS_EXC_HANDLER(ali)
ACCESS_EXC_HANDLER(dsi)
ACCESS_EXC_HANDLER(isi)
! CRITICAL_EXC_HANDLER(debug)
CRITICAL_EXC_HANDLER(mchk)
/*
--- 152,158 ----
ACCESS_EXC_HANDLER(ali)
ACCESS_EXC_HANDLER(dsi)
ACCESS_EXC_HANDLER(isi)
! STANDARD_EXC_HANDLER(debug)
CRITICAL_EXC_HANDLER(mchk)
/*
***************
*** 183,208 ****
ba extintr
_C_LABEL(extsize) = .-_C_LABEL(extint)
- /*
- * This one for the external critical interrupt handler.
- */
- .globl _C_LABEL(cintr),_C_LABEL(cintrsize)
- _C_LABEL(cintr):
- mtsprg 2,1 /* save SP in sprg2 */
- stmw 28,tempsave(0) /* free r28-r31 */
- mflr 28 /* save LR */
- mfcr 29 /* save CR */
- mfxer 30 /* save XER */
- GET_CPUINFO(1)
- lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */
- addic. 31,31,1
- stw 31,CI_INTRDEPTH(1)
- lwz 1,CI_INTSTK(1) /* get intstk */
- beq 1f
- mfsprg 1,2
- 1:
- ba extcintr
- _C_LABEL(cintrsize) = .-_C_LABEL(cintr)
#ifdef DDB
#define ddbsave 0xde0 /* primary save area for DDB */
--- 176,181 ----
***************
*** 218,225 ****
stmw 28,ddbsave(0) /* free r28-r31 */
mflr 28 /* save LR */
mfcr 29 /* save CR */
- mfesr 31 /* save ESR */
- stw 31,20+ddbsave(0)
lis 1,ddbstk+INTSTK@ha /* get new SP */
addi 1,1,ddbstk+INTSTK@l
bla ddbtrap
--- 191,196 ----
***************
*** 249,258 ****
#ifdef DEBUG
#define TRAP_IF_ZERO(r) tweqi r,0
- #define TRAP_IF_NZERO(r) twnei r,0
#else
#define TRAP_IF_ZERO(r)
- #define TRAP_IF_NZERO(r)
#endif
/*
--- 220,227 ----
***************
*** 329,408 ****
mtpid 30; \
lmw 29,savearea(0)
- /*
- * CFRAME_SETUP assumes:
- * SPRG2 SP (1)
- * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
- * 28 LR
- * 29 CR
- * 1 kernel critical stack
- * LR trap type
- * SRR2/3 as at start of trap
- */
- #define CFRAME_SETUP(savearea) \
- /* Have to enable translation to allow access of kernel stack: */ \
- mfsrr2 30; \
- mfsrr3 31; \
- stmw 30,savearea+24(0); \
- mfpid 30; \
- li 31,KERNEL_PID; \
- mtpid 31; \
- mfmsr 31; \
- ori 31,31,(PSL_DR|PSL_IR)@l; \
- mtmsr 31; \
- isync; \
- mfsprg2 31; \
- stwu 31,-FRAMELEN(1); \
- stw 30,FRAME_PID+8(1); \
- stw 0,FRAME_0+8(1); \
- stw 31,FRAME_1+8(1); \
- stw 28,FRAME_LR+8(1); \
- stw 29,FRAME_CR+8(1); \
- lmw 28,savearea(0); \
- stmw 2,FRAME_2+8(1); \
- lmw 28,savearea+16(0); \
- mfxer 3; \
- mfctr 4; \
- mflr 5; \
- andi. 5,5,0xff00; \
- stw 3,FRAME_XER+8(1); \
- stw 4,FRAME_CTR+8(1); \
- stw 5,FRAME_EXC+8(1); \
- stw 28,FRAME_DEAR+8(1); \
- stw 29,FRAME_ESR+8(1); \
- stw 30,FRAME_SRR0+8(1); \
- stw 31,FRAME_SRR1+8(1)
-
- #define CFRAME_LEAVE(savearea) \
- /* Now restore regs: */ \
- lwz 3,FRAME_PID+8(1); \
- lwz 4,FRAME_SRR1+8(1); \
- bl _C_LABEL(ctx_setup); \
- TRAP_IF_ZERO(3); \
- stw 3,FRAME_PID+8(1); \
- lmw 26,FRAME_LR+8(1); \
- mtlr 26; \
- mtcr 27; \
- mtxer 28; \
- mtctr 29; \
- mtsrr2 30; \
- mtsrr3 31; \
- lmw 2,FRAME_2+8(1); \
- lwz 0,FRAME_0+8(1); \
- stmw 29,savearea(0); \
- lwz 30,FRAME_PID+8(1); \
- lwz 1,FRAME_1+8(1); \
- mfmsr 31; \
- li 29,(PSL_DR|PSL_IR)@l; \
- andc 31,31,29; \
- mfcr 29; \
- mtcr 29; \
- mtmsr 31; \
- isync; \
- TRAP_IF_ZERO(30); \
- mtpid 30; \
- lmw 29,savearea(0)
-
realtrap: /* entry point after IPKDB is done with exception */
/* Test whether we already had PR set */
mfsrr1 1
--- 298,303 ----
***************
*** 444,478 ****
ba . /* Protect against prefetch */
- /* critical traps */
- /*
- * this is the stack for critical interupts. We only only
- * have one outstanding stack + machine check
- */
- .local critstk
- .comm critstk,INTSTK,8 /* critical interrupt stack */
-
- s_ctrap:
- lis 1,critstk+INTSTK@ha /* get new SP */
- addi 1,1,critstk+INTSTK@l
- mfsrr3 31 /* Test whether we already had PR set */
- mtcr 31
- bc 4,17,1f /* branch if PSL_PR is clear */
- GET_PCB(1)
- addi 1,1,USPACE; /* stack is top of user struct */
- 1:
-
- CFRAME_SETUP(critsave)
-
- /* Call C trap code: */
- addi 3,1,8
- bl _C_LABEL(trap)
- .globl _C_LABEL(ctrapexit)
- _C_LABEL(ctrapexit):
- CFRAME_LEAVE(exitsave)
- rfci
- ba . /* Protect against prefetch */
-
.globl _C_LABEL(sctrap),_C_LABEL(scsize),_C_LABEL(sctrapexit)
_C_LABEL(sctrap):
--- 339,344 ----
***************
*** 513,568 ****
/*
- * critical I/O interrupt
- */
-
- #define CINTRENTER \
- /* Save non-volatile registers: */ \
- stwu 1,-IFRAMELEN(1); /* temporarily */ \
- stw 0,IFRAME_R0(1); \
- mfsprg 0,1; /* get original SP */ \
- stw 0,IFRAME_R1(1); /* and store it */ \
- stw 3,IFRAME_R3(1); \
- stw 4,IFRAME_R4(1); \
- stw 5,IFRAME_R5(1); \
- stw 6,IFRAME_R6(1); \
- stw 7,IFRAME_R7(1); \
- stw 8,IFRAME_R8(1); \
- stw 9,IFRAME_R9(1); \
- stw 10,IFRAME_R10(1); \
- stw 11,IFRAME_R11(1); \
- stw 12,IFRAME_R12(1); \
- stw 28,IFRAME_LR(1); /* saved LR */ \
- stw 29,IFRAME_CR(1); /* saved CR */ \
- stw 30,IFRAME_XER(1); /* saved XER */ \
- lmw 28,tempsave(0); /* restore r28-r31 */ \
- mfctr 6; \
- GET_CPUINFO(5); \
- lwz 5,CI_INTRDEPTH(5); \
- mfsrr2 4; \
- mfsrr3 3; \
- stw 6,IFRAME_CTR(1); \
- stw 5,IFRAME_INTR_DEPTH(1); \
- stw 4,IFRAME_SRR0(1); \
- stw 3,IFRAME_SRR1(1); \
- mfpid 0; /* get currect PID register */ \
- stw 0,IFRAME_PID(1); \
- li 0,KERNEL_PID; \
- mtpid 0; \
- /* interrupts are recoverable here, and enable translation */ \
- mfmsr 5; \
- ori 5,5,(PSL_IR|PSL_DR); \
- mtmsr 5; \
- isync
-
- .globl _C_LABEL(extcint_call)
- extcintr:
- CINTRENTER
- _C_LABEL(extcint_call):
- bl _C_LABEL(extcint_call) /* to be filled in later */
- b intr_exit
-
- /*
* External interrupt second level handler
*/
--- 379,384 ----
***************
*** 888,911 ****
icbi 0,9 /* and instruction caches */
blr
#endif /* IPKDB */
-
-
- /*
- * trap if an external ICE is connected
- */
- .globl _C_LABEL(jtagtrap)
- _C_LABEL(jtagtrap):
- #ifndef PPC_IBM405GP
- mfdcr 3, 0xf7
- #else
- mfdcr 3, DCR_CPC0_JTAGID
- #endif
- or. 3, 3, 3
- beq 1f
- mfspr 4, SPR_DBCR0
- lis 0,0x8000
- or 4,4,0
- mtspr SPR_DBCR0,0
- twi 2,3,0
- 1:
- blr
--- 704,706 ----
Index: trap.c
===================================================================
RCS file: /sw/cvs/NetBSD/usr/src/sys/arch/powerpc/ibm4xx/trap.c,v
retrieving revision 1.1.1.6
retrieving revision 1.4
diff -c -r1.1.1.6 -r1.4
*** trap.c 21 Oct 2003 19:28:42 -0000 1.1.1.6
--- trap.c 14 Jan 2004 23:20:35 -0000 1.4
***************
*** 77,82 ****
--- 77,83 ----
#include <sys/param.h>
#include <sys/proc.h>
+ #include <sys/ras.h>
#include <sys/reboot.h>
#include <sys/syscall.h>
#include <sys/systm.h>
***************
*** 107,112 ****
--- 108,118 ----
#include <powerpc/ibm4xx/pmap.h>
#include <powerpc/ibm4xx/tlb.h>
#include <powerpc/fpu/fpu_extern.h>
+ #include <powerpc/instr.h>
+
+ #ifdef DDB
+ void db_printf(char *fmt,...);
+ #endif
/* These definitions should probably be somewhere else XXX */
#define FIRSTARG 3 /* first argument is in reg 3 */
***************
*** 123,128 ****
--- 129,135 ----
#ifdef DEBUG
#define TDB_ALL 0x1
+ #define TDB_TR 0x2
int trapdebug = /* TDB_ALL */ 0;
#define DBPRINTF(x, y) if (trapdebug & (x)) printf y
#else
***************
*** 149,163 ****
type, frame->srr0, frame, &frame));
switch (type) {
case EXC_DEBUG|EXC_USER:
{
! int srr2, srr3;
! __asm __volatile("mfspr %0,0x3f0" :
! "=r" (rv), "=r" (srr2), "=r" (srr3) :);
! printf("debug reg is %x srr2 %x srr3 %x\n", rv, srr2,
! srr3);
! /* XXX fall through or break here?! */
}
/*
* DEBUG intr -- probably single-step.
--- 156,266 ----
type, frame->srr0, frame, &frame));
switch (type) {
+ case EXC_DEBUG:
+ {
+ uint srr0, srr1;
+ uint srr2, srr3;
+ uint dbsr;
+
+ /* HID0 */
+ __asm __volatile("mfspr %0,0x3f0;"
+ "mfsrr0 %1;"
+ "mfsrr1 %2;"
+ "mfsrr2 %3;"
+ "mfsrr3 %4" :
+ "=r"(rv), "=r"(srr0), "=r"(srr1),
+ "=r"(srr2), "=r"(srr3) :);
+ dbsr = mfspr(SPR_DBSR);
+ DBPRINTF(TDB_TR, ("KDBG ssr0:0x%x/0x%x@0x%x ssr1:0x%x/0x%x srr2:0x%x srr3:0x%x dbcr0:0x%x dbcr1:0x%x dbsr:0x%x\n",
+ (uint)frame->srr0, srr0, (uint)&frame->srr0,
+ (uint)frame->srr1, srr1,
+ srr2,
+ srr3,
+ (uint)mfspr(SPR_DBCR0),
+ (uint)mfspr(SPR_DBCR1),
+ dbsr));
+
+ mtspr(SPR_DBSR, 0xffffffff);
+ }
+ if ((frame->srr0 > EXC_RSVD) && (frame->srr0 < EXC_LAST)) {
+ /*
+ * single step into, say a tlb miss.
+ * turn off single step to return back
+ * into the kernel - will go on again on
+ * return to user.
+ * Note, however, this means the pc will
+ * trap at the instruction start not completion!
+ */
+ frame->srr1 &= ~PSL_SE;
+ DBPRINTF(TDB_TR, ("KDB srr1 = 0x%x\n",
+ (uint)frame->srr1));
+ }
+ #ifdef DDB
+ /*
+ * must be kernal mode single step (currently ddb uses
+ * trap instructions on 405)
+ */
+ else {
+ if (kdb_trap(type, frame))
+ goto done;
+ }
+ #endif
+ return;
+
case EXC_DEBUG|EXC_USER:
{
! uint srr0, srr1;
! uint srr2, srr3;
! uint dbsr;
! union instr instr;
!
! /* HID0 */
! __asm __volatile("mfspr %0,0x3f0;"
! "mfsrr0 %1;"
! "mfsrr1 %2;"
! "mfsrr2 %3;"
! "mfsrr3 %4" :
! "=r"(rv), "=r"(srr0), "=r"(srr1),
! "=r"(srr2), "=r"(srr3) :);
! dbsr = mfspr(SPR_DBSR);
! DBPRINTF(TDB_TR, ("DBG ssr0:0x%x/0x%x ssr1:0x%x/0x%x srr2:0x%x srr3:0x%x dbcr0:0x%x dbcr1:0x%x dbsr:0x%x\n",
! (uint)frame->srr0, srr0,
! (uint)frame->srr1, srr1,
! srr2,
! srr3,
! (uint)mfspr(SPR_DBCR0),
! (uint)mfspr(SPR_DBCR1), dbsr));
!
! mtspr(SPR_DBSR, 0xffffffff);
!
! /*
! * if we took a DEBUG trap on a tlbmiss
! * then we havn't executed this instruction
! * at all - try again.
! */
! if (frame->srr0 == srr0) {
! /*
! frame->srr1 &= ~PSL_SE;
! */
! srr2 = 0;
! srr3 = 0;
! __asm __volatile("mfspr %0,0x3f0;"
! "mtsrr2 %0;"
! "mtsrr3 %0;" : :
! "r"(srr2), "r"(srr3));
! if (copyin((void *) (frame->srr0), &instr.i_int,
! sizeof (instr.i_int))) {
! return;
! }
! if ((instr.i_any.i_opcd != OPC_TWI) &&
! ((instr.i_any.i_opcd != OPC_integer_31) ||
! (instr.i_x.i_xo != OPC31_TW))) {
! extern void jtagtrap(void);
! jtagtrap();
! return;
! }
! }
}
/*
* DEBUG intr -- probably single-step.
***************
*** 168,173 ****
--- 271,277 ----
ksi.ksi_signo = SIGTRAP;
ksi.ksi_trap = EXC_TRC;
ksi.ksi_addr = (void *)frame->srr0;
+ ksi.ksi_code = TRAP_TRACE;
KERNEL_PROC_LOCK(l);
trapsignal(l, &ksi);
KERNEL_PROC_UNLOCK(l);
***************
*** 252,261 ****
--- 356,369 ----
KERNEL_PROC_UNLOCK(l);
break;
}
+
+ DBPRINTF(TDB_ALL, ("DSI is segv\n"));
+
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_trap = EXC_DSI;
ksi.ksi_addr = (void *)frame->dar;
+ ksi.ksi_code = SEGV_ACCERR;
if (rv == ENOMEM) {
printf("UVM: pid %d (%s) lid %d, uid %d killed: "
"out of swap\n",
***************
*** 288,297 ****
--- 396,409 ----
KERNEL_PROC_UNLOCK(l);
break;
}
+
+ DBPRINTF( TDB_ALL, ("ISI is segv\n"));
+
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_trap = EXC_ISI;
ksi.ksi_addr = (void *)frame->srr0;
+ ksi.ksi_code = SEGV_MAPERR;
trapsignal(l, &ksi);
l->l_flag &= ~L_SA_PAGEFAULT;
KERNEL_PROC_UNLOCK(l);
***************
*** 319,324 ****
--- 431,437 ----
ksi.ksi_signo = SIGBUS;
ksi.ksi_trap = EXC_ALI;
ksi.ksi_addr = (void *)frame->dar;
+ ksi.ksi_code = BUS_ADRALN;
trapsignal(l, &ksi);
} else
frame->srr0 += 4;
***************
*** 332,337 ****
--- 445,469 ----
* let's try to see if it's FPU and can be emulated.
*/
uvmexp.traps ++;
+
+ if (frame->tf_xtra[TF_ESR] & (ESR_PTR)) {
+ DBPRINTF( TDB_ALL, ("PGM+USER - 0x%x\n",
+ frame->tf_xtra[TF_ESR]));
+ if (LIST_EMPTY(&p->p_raslist) ||
+ ras_lookup(p, (caddr_t)frame->srr0) == (caddr_t) -1) {
+ KSI_INIT_TRAP(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_trap = EXC_PGM;
+ ksi.ksi_addr = (void *)frame->srr0;
+ ksi.ksi_code = TRAP_BRKPT;
+ (*p->p_emul->e_trapsignal)(l, &ksi);
+ } else {
+ /* skip the trap instruction */
+ frame->srr0 += 4;
+ }
+ break;
+ }
+
if (!(l->l_addr->u_pcb.pcb_flags & PCB_FPU)) {
memset(&l->l_addr->u_pcb.pcb_fpu, 0,
sizeof l->l_addr->u_pcb.pcb_fpu);
***************
*** 344,349 ****
--- 476,488 ----
ksi.ksi_signo = rv;
ksi.ksi_trap = EXC_PGM;
ksi.ksi_addr = (void *)frame->srr0;
+ if (rv == SIGTRAP) {
+ ksi.ksi_code = TRAP_BRKPT;
+ DBPRINTF(TDB_TR, ("Bpt 0x%x \n",
+ (uint)frame->srr0));
+ } else {
+ ksi.ksi_code = 0;
+ }
KERNEL_PROC_LOCK(l);
trapsignal(l, &ksi);
KERNEL_PROC_UNLOCK(l);
***************
*** 370,379 ****
goto brain_damage;
default:
brain_damage:
- printf("trap type 0x%x at 0x%lx\n", type, frame->srr0);
#ifdef DDB
if (kdb_trap(type, frame))
goto done;
#endif
#ifdef TRAP_PANICWAIT
printf("Press a key to panic.\n");
--- 509,521 ----
goto brain_damage;
default:
brain_damage:
#ifdef DDB
+ db_printf("trap type 0x%x", type);
+ db_printf("at 0x%lx\n", frame->srr0);
if (kdb_trap(type, frame))
goto done;
+ #else
+ printf("trap type 0x%x at 0x%lx\n", type, frame->srr0);
#endif
#ifdef TRAP_PANICWAIT
printf("Press a key to panic.\n");
***************
*** 428,433 ****
--- 570,581 ----
"or %0,%0,%1;"
"mtspr 0x3f2,%0;" :
"=&r" (dbreg) : "r" (mask));
+ } else {
+ int dbreg, mask = ~0x08000000;
+ __asm __volatile("mfspr %0,0x3f2;"
+ "and %0,%0,%1;"
+ "mtspr 0x3f2,%0;" :
+ "=&r" (dbreg) : "r" (mask));
}
}
else if (!ctx) {
Index: ibm40x_machdep.c
===================================================================
RCS file: /sw/cvs/NetBSD/usr/src/sys/arch/powerpc/ibm4xx/ibm40x_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** ibm40x_machdep.c 30 Sep 2003 16:16:55 -0000 1.1.1.1
--- ibm40x_machdep.c 13 Jan 2004 03:15:50 -0000 1.3
***************
*** 139,144 ****
--- 139,148 ----
vaddr_t msgbuf_vaddr;
+ #ifdef trpz
+ static void ibm4xx_install_extcint(void (*handler)(void));
+ #endif
+
void
ibm4xx_init_board_data(void *info_block, u_int startkernel)
{
***************
*** 170,175 ****
--- 174,183 ----
extern int tlbdmiss4xx, tlbdm4size;
extern int pitfitwdog, pitfitwdogsize;
extern int debugtrap, debugsize;
+ #ifdef trpz
+ extern int cintr, cintrsize;
+ extern void ext_cintr(void);
+ #endif
extern int errata51handler, errata51size;
#ifdef DDB
extern int ddblow, ddbsize;
***************
*** 177,182 ****
--- 185,191 ----
#ifdef IPKDB
extern int ipkdblow, ipkdbsize;
#endif
+
uintptr_t exc;
struct cpu_info * const ci = curcpu();
***************
*** 200,211 ****
--- 209,237 ----
/*
* Set up trap vectors
*/
+ #ifdef DEBUG
+ /*
+ * clear vectors set up by boot firmwares.
+ */
+ memset((void *)EXC_RSVD, 0, EXC_LAST - EXC_RSVD);
+ #endif
+
for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100)
switch (exc) {
default:
memcpy((void *)exc, &defaulttrap, (size_t)&defaultsize);
break;
+ case EXC_RSVD:
+ memset((void *)exc, 0, 0x100);
+ case EXC_RST:
+ #ifdef trpz
+ memcpy((void *)exc, &cintr, (size_t)&cintrsize);
+ #else
+ memcpy((void *)exc, &defaulttrap, (size_t)&defaultsize);
+ #endif
+ break;
case EXC_EXI:
+ memset((void *)exc, 0, 0x100);
/*
* This one is (potentially) installed during autoconf
*/
***************
*** 261,267 ****
break;
}
! __syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
mtspr(SPR_EVPR, 0); /* Set Exception vector base */
consinit();
--- 287,293 ----
break;
}
! __syncicache((void *)EXC_RSVD, EXC_LAST - EXC_RSVD + 0x100);
mtspr(SPR_EVPR, 0); /* Set Exception vector base */
consinit();
***************
*** 279,289 ****
if (handler)
ibm4xx_install_extint(handler);
/*
* Now enable translation (and machine checks/recoverable interrupts).
*/
! asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0; isync"
! : : "r"(0), "K"(PSL_IR|PSL_DR));
/* XXXX PSL_ME - With ME set kernel gets stuck... */
KASSERT(curcpu() == ci);
--- 305,319 ----
if (handler)
ibm4xx_install_extint(handler);
+ #ifdef trpz
+ ibm4xx_install_extcint(ext_cintr);
+ #endif
+
/*
* Now enable translation (and machine checks/recoverable interrupts).
*/
! asm volatile ("mfmsr %0; ori %0,%0,%1; oris %0,%0,%2@ha; mtmsr %0; isync"
! : : "r"(0), "K"(PSL_IR|PSL_DR|PSL_ME), "J"(PSL_CE));
/* XXXX PSL_ME - With ME set kernel gets stuck... */
KASSERT(curcpu() == ci);
***************
*** 309,314 ****
--- 339,366 ----
asm volatile ("mtmsr %0" :: "r"(msr));
}
+ #ifdef trpz
+ static void
+ ibm4xx_install_extcint(void (*handler)(void))
+ {
+ extern int cintr, cintrsize;
+ extern u_long extcint_call;
+ u_long offset = (u_long)handler - (u_long)&extcint_call;
+ int msr;
+
+ #ifdef DIAGNOSTIC
+ if (offset > 0x1ffffff)
+ panic("install_extint: too far away");
+ #endif
+ asm volatile ("mfmsr %0; wrteei 0" : "=r"(msr));
+ extcint_call = (extcint_call & 0xfc000003) | offset;
+ memcpy((void *)EXC_RST, &cintr, (size_t)&cintrsize);
+ __syncicache((void *)&extcint_call, sizeof extcint_call);
+ __syncicache((void *)EXC_RST, (int)&cintrsize);
+ asm volatile ("mtmsr %0" :: "r"(msr));
+ }
+ #endif
+
/*
* Machine dependent startup code.
*/
***************
*** 347,358 ****
initmsgbuf((caddr_t)msgbuf, round_page(MSGBUFSIZE));
#endif
! printf("%s", version);
if (model != NULL)
! printf("Model: %s\n", model);
format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
! printf("total memory = %s\n", pbuf);
/*
* Find out how much space we need, allocate it,
--- 399,410 ----
initmsgbuf((caddr_t)msgbuf, round_page(MSGBUFSIZE));
#endif
! aprint_normal("%s", version);
if (model != NULL)
! aprint_normal("Model: %s\n", model);
format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
! aprint_normal("total memory = %s\n", pbuf);
/*
* Find out how much space we need, allocate it,
***************
*** 423,431 ****
*/
format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
! printf("avail memory = %s\n", pbuf);
format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE);
! printf("using %u buffers containing %s of memory\n", nbuf, pbuf);
/*
* Set up the buffers.
--- 475,483 ----
*/
format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
! aprint_normal("avail memory = %s\n", pbuf);
format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE);
! aprint_normal("using %u buffers containing %s of memory\n", nbuf, pbuf);
/*
* Set up the buffers.
>Release-Note:
>Audit-Trail:
>Unformatted: