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: