svn commit: r360881 - in head/sys/powerpc: aim booke include powerpc

Justin Hibbits jhibbits at FreeBSD.org
Sun May 10 19:00:59 UTC 2020


Author: jhibbits
Date: Sun May 10 19:00:57 2020
New Revision: 360881
URL: https://svnweb.freebsd.org/changeset/base/360881

Log:
  powerpc: Add a CPU-custom machine check handler
  
  Summary:
  Some machine checks are process-recoverable, others are not.  Let a
  CPU-specific handler decide what to do.
  
  This works around a machine check error hit while building www/firefox
  and mail/thunderbird, which would otherwise cause the build to fail.
  
  More work is needed to handle all possible machine check conditions, but
  this is sufficient to unblock some ports building.
  
  Differential Revision: https://reviews.freebsd.org/D23731

Modified:
  head/sys/powerpc/aim/aim_machdep.c
  head/sys/powerpc/aim/trap_subr64.S
  head/sys/powerpc/booke/machdep_e500.c
  head/sys/powerpc/include/cpu.h
  head/sys/powerpc/include/spr.h
  head/sys/powerpc/powerpc/trap.c

Modified: head/sys/powerpc/aim/aim_machdep.c
==============================================================================
--- head/sys/powerpc/aim/aim_machdep.c	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/aim/aim_machdep.c	Sun May 10 19:00:57 2020	(r360881)
@@ -515,6 +515,32 @@ memcpy(pcpu->pc_aim.slb, PCPU_GET(aim.slb), sizeof(pcp
 #endif
 }
 
+/* Return 0 on handled success, otherwise signal number. */
+int
+cpu_machine_check(struct thread *td, struct trapframe *frame, int *ucode)
+{
+#ifdef __powerpc64__
+	/*
+	 * This block is 64-bit CPU specific currently.  Punt running in 32-bit
+	 * mode on 64-bit CPUs.
+	 */
+	/* Check if the important information is in DSISR */
+	if ((frame->srr1 & SRR1_MCHK_DATA) != 0) {
+		printf("Machine check, DSISR: %016lx\n", frame->cpu.aim.dsisr);
+		/* SLB multi-hit is recoverable. */
+		if ((frame->cpu.aim.dsisr & DSISR_MC_SLB_MULTIHIT) != 0)
+			return (0);
+		/* TODO: Add other machine check recovery procedures. */
+	} else {
+		if ((frame->srr1 & SRR1_MCHK_IFETCH_M) == SRR1_MCHK_IFETCH_SLBMH)
+			return (0);
+	}
+#endif
+	*ucode = BUS_OBJERR;
+	return (SIGBUS);
+}
+
+
 #ifndef __powerpc64__
 uint64_t
 va_to_vsid(pmap_t pm, vm_offset_t va)

Modified: head/sys/powerpc/aim/trap_subr64.S
==============================================================================
--- head/sys/powerpc/aim/trap_subr64.S	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/aim/trap_subr64.S	Sun May 10 19:00:57 2020	(r360881)
@@ -797,6 +797,8 @@ generictrap:
 	std	%r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1)
 	mfdar	%r30
 	std	%r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1)
+	mfdsisr	%r30
+	std	%r30,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1)
 	mfsprg1	%r1			/* restore SP, in case of branch */
 	mfsprg2	%r28			/* save LR */
 	mfcr	%r29			/* save CR */

Modified: head/sys/powerpc/booke/machdep_e500.c
==============================================================================
--- head/sys/powerpc/booke/machdep_e500.c	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/booke/machdep_e500.c	Sun May 10 19:00:57 2020	(r360881)
@@ -119,3 +119,15 @@ void
 booke_disable_l2_cache(void)
 {
 }
+
+/* Return 0 on handled success, otherwise signal number. */
+int
+cpu_machine_check(struct thread *td, struct trapframe *frame, int *ucode)
+{
+	register_t mcsr;
+
+	mcsr = mfspr(SPR_MCSR);
+
+	*ucode = BUS_OBJERR;
+	return (SIGBUS);
+}

Modified: head/sys/powerpc/include/cpu.h
==============================================================================
--- head/sys/powerpc/include/cpu.h	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/include/cpu.h	Sun May 10 19:00:57 2020	(r360881)
@@ -134,6 +134,8 @@ get_cyclecount(void)
 extern char btext[];
 extern char etext[];
 
+struct thread;
+
 #ifdef __powerpc64__
 extern void enter_idle_powerx(void);
 extern uint64_t can_wakeup;
@@ -146,5 +148,6 @@ void	cpu_sleep(void);
 void	flush_disable_caches(void);
 void	fork_trampoline(void);
 void	swi_vm(void *);
+int	cpu_machine_check(struct thread *, struct trapframe *, int *);
 
 #endif	/* _MACHINE_CPU_H_ */

Modified: head/sys/powerpc/include/spr.h
==============================================================================
--- head/sys/powerpc/include/spr.h	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/include/spr.h	Sun May 10 19:00:57 2020	(r360881)
@@ -108,6 +108,15 @@
 #define	  DSISR_DABR		  0x00400000 /* DABR match */
 #define	  DSISR_SEGMENT		  0x00200000 /* XXX; not in 6xx PEM */
 #define	  DSISR_EAR		  0x00100000 /* eciwx/ecowx && EAR[E] == 0 */
+#define	  DSISR_MC_UE_DEFERRED	  0x00008000 /* UE deferred error */
+#define	  DSISR_MC_UE_TABLEWALK	  0x00004000 /* UE deferred error during tablewalk */
+#define	  DSISR_MC_DERAT_MULTIHIT	  0x00000800 /* D-ERAT multi-hit */
+#define	  DSISR_MC_TLB_MULTIHIT	  0x00000400 /* TLB multi-hit */
+#define	  DSISR_MC_TLBIE_ERR	  0x00000200 /* TLBIE or TLBIEL programming error */
+#define	  DSISR_MC_SLB_PARITY	  0x00000100 /* SLB parity error */
+#define	  DSISR_MC_SLB_MULTIHIT	  0x00000080 /* SLB Multi-hit detected (D-side) */
+#define	  DSISR_MC_BAD_REAL_LD	  0x00000040 /* Bad real address for load. */
+#define	  DSISR_MC_BAD_ADDR	  0x00000020 /* Bad address for load or store tablewalk */
 #define	SPR_DAR			0x013	/* .68 Data Address Register */
 #define	SPR_RTCU_W		0x014	/* .6. 601 RTC Upper - Write */
 #define	SPR_RTCL_W		0x015	/* .6. 601 RTC Lower - Write */
@@ -115,9 +124,12 @@
 #define	SPR_SDR1		0x019	/* .68 Page table base address register */
 #define	SPR_SRR0		0x01a	/* 468 Save/Restore Register 0 */
 #define	SPR_SRR1		0x01b	/* 468 Save/Restore Register 1 */
-#define	  SRR1_ISI_PFAULT	0x40000000 /* ISI page not found */
-#define	  SRR1_ISI_NOEXECUTE	0x10000000 /* Memory marked no-execute */
-#define	  SRR1_ISI_PP		0x08000000 /* PP bits forbid access */
+#define	  SRR1_ISI_PFAULT	  0x40000000 /* ISI page not found */
+#define	  SRR1_ISI_NOEXECUTE	  0x10000000 /* Memory marked no-execute */
+#define	  SRR1_ISI_PP		  0x08000000 /* PP bits forbid access */
+#define	  SRR1_MCHK_DATA	  0x00200000 /* Machine check data in DSISR */
+#define	  SRR1_MCHK_IFETCH_M	  0x081c0000 /* Machine check instr fetch mask */
+#define	  SRR1_MCHK_IFETCH_SLBMH  0x000c0000 /* SLB multihit */
 #define	SPR_DECAR		0x036	/* ..8 Decrementer auto reload */
 #define	SPR_EIE			0x050	/* ..8 Exception Interrupt ??? */
 #define	SPR_EID			0x051	/* ..8 Exception Interrupt ??? */
@@ -725,6 +737,16 @@
 
 #define	SPR_MCARU		0x239	/* ..8 Machine Check Address register upper bits */
 #define	SPR_MCSR		0x23c	/* ..8 Machine Check Syndrome register */
+#define	  MCSR_MCP		  0x80000000 /* Machine check input signal to core */
+#define	  MCSR_L2MMU_MHIT	  0x08000000 /* L2 MMU simultaneous hit */
+#define	  MCSR_NMI		  0x00100000 /* Non-maskable interrupt */
+#define	  MCSR_MAV		  0x00080000 /* MCAR address valid */
+#define	  MCSR_MEA		  0x00040000 /* MCAR effective address */
+#define	  MCSR_IF		  0x00010000 /* Instruction fetch error report */
+#define	  MCSR_LD		  0x00008000 /* Load instruction error report */
+#define	  MCSR_ST		  0x00004000 /* Store instruction error report */
+#define	  MCSR_LDG		  0x00002000 /* Guarded load instruction error report */
+#define	  MCSR_TLBSYNC		  0x00000002 /* Simultaneous TLBSYNC detected */
 #define	SPR_MCAR		0x23d	/* ..8 Machine Check Address register */
 
 #define	SPR_ESR			0x003e	/* ..8 Exception Syndrome Register */

Modified: head/sys/powerpc/powerpc/trap.c
==============================================================================
--- head/sys/powerpc/powerpc/trap.c	Sun May 10 18:17:25 2020	(r360880)
+++ head/sys/powerpc/powerpc/trap.c	Sun May 10 19:00:57 2020	(r360881)
@@ -402,13 +402,8 @@ trap(struct trapframe *frame)
 			break;
 
 		case EXC_MCHK:
-			/*
-			 * Note that this may not be recoverable for the user
-			 * process, depending on the type of machine check,
-			 * but it at least prevents the kernel from dying.
-			 */
-			sig = SIGBUS;
-			ucode = BUS_OBJERR;
+			sig = cpu_machine_check(td, frame, &ucode);
+			printtrap(frame->exc, frame, 0, (frame->srr1 & PSL_PR));
 			break;
 
 #if defined(__powerpc64__) && defined(AIM)
@@ -513,18 +508,17 @@ cpu_printtrap(u_int vector, struct trapframe *frame, i
 	uint16_t ver;
 
 	switch (vector) {
+	case EXC_MCHK:
+		ver = mfpvr() >> 16;
+		if (MPC745X_P(ver))
+			printf("    msssr0         = 0x%b\n",
+			    (int)mfspr(SPR_MSSSR0), MSSSR_BITMASK);
 	case EXC_DSE:
 	case EXC_DSI:
 	case EXC_DTMISS:
 		printf("   dsisr           = 0x%lx\n",
 		    (u_long)frame->cpu.aim.dsisr);
 		break;
-	case EXC_MCHK:
-		ver = mfpvr() >> 16;
-		if (MPC745X_P(ver))
-			printf("    msssr0         = 0x%b\n",
-			    (int)mfspr(SPR_MSSSR0), MSSSR_BITMASK);
-		break;
 	}
 #elif defined(BOOKE)
 	vm_paddr_t pa;
@@ -556,14 +550,13 @@ printtrap(u_int vector, struct trapframe *frame, int i
 	case EXC_DSI:
 	case EXC_DTMISS:
 	case EXC_ALI:
+	case EXC_MCHK:
 		printf("   virtual address = 0x%" PRIxPTR "\n", frame->dar);
 		break;
 	case EXC_ISE:
 	case EXC_ISI:
 	case EXC_ITMISS:
 		printf("   virtual address = 0x%" PRIxPTR "\n", frame->srr0);
-		break;
-	case EXC_MCHK:
 		break;
 	}
 	cpu_printtrap(vector, frame, isfatal, user);


More information about the svn-src-all mailing list