Subject: Re: Toolchain build error
To: None <port-dreamcast@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-dreamcast
Date: 02/22/2003 04:13:14
In article <200302211259.09138.mlist@beholder.homeunix.net>
mlist@beholder.homeunix.net wrote:

> The reboots are random, but only seem to occur under heavy load.  But the load
> I'm putting it under uses NFS heavily, so it could still be network related.  

According to the SH4 manual, if TLB multiple-hit exception occurs
CPU jumps the reset vector. i.e. the machine reboots without messages
and we can never catch it even with the kernel debugger.

I'm still wondering whether we should disable interrupt
while TLB update/invalidate operations.
Could you try the following patch?

Index: mmu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/mmu.c,v
retrieving revision 1.8
diff -u -r1.8 mmu.c
--- mmu.c	2002/05/09 12:27:04	1.8
+++ mmu.c	2003/02/21 19:01:03
@@ -109,6 +109,9 @@
 void
 sh_tlb_set_asid(int asid)
 {
+	int s;
 
+	s = _cpu_exception_suspend();
 	_reg_write_4(SH_(PTEH), asid);
+	_cpu_exception_resume(s);
 }
Index: mmu_sh4.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/mmu_sh4.c,v
retrieving revision 1.6
diff -u -r1.6 mmu_sh4.c
--- mmu_sh4.c	2002/11/04 01:31:43	1.6
+++ mmu_sh4.c	2003/02/21 19:01:03
@@ -82,7 +82,10 @@
 sh4_tlb_invalidate_addr(int asid, vaddr_t va)
 {
 	u_int32_t pteh;
+	int s;
+
 	va &= SH4_PTEH_VPN_MASK;
+	s = _cpu_exception_suspend();
 
 	/* Save current ASID */
 	pteh = _reg_read_4(SH4_PTEH);
@@ -95,14 +98,17 @@
 	RUN_P1;
 	/* Restore ASID */
 	_reg_write_4(SH4_PTEH, pteh);
+
+	_cpu_exception_resume(s);
 }
 
 void
 sh4_tlb_invalidate_asid(int asid)
 {
 	u_int32_t a;
-	int e;
+	int e, s;
 
+	s = _cpu_exception_suspend();
 	/* Invalidate entry attribute to ASID */
 	RUN_P2;
 	for (e = 0; e < SH4_UTLB_ENTRY; e++) {
@@ -113,14 +119,16 @@
 
 	__sh4_itlb_invalidate_all();
 	RUN_P1;
+	_cpu_exception_resume(s);
 }
 
 void
 sh4_tlb_invalidate_all()
 {
 	u_int32_t a;
-	int e, eend;
+	int e, eend, s;
 
+	s = _cpu_exception_suspend();
 	/* If non-wired entry limit is zero, clear all entry. */
 	a = _reg_read_4(SH4_MMUCR) & SH4_MMUCR_URB_MASK;
 	eend = a ? (a >> SH4_MMUCR_URB_SHIFT) : SH4_UTLB_ENTRY;
@@ -138,6 +146,7 @@
 	_reg_write_4(SH4_ITLB_DA1 | (2 << SH4_ITLB_E_SHIFT), 0);
 	_reg_write_4(SH4_ITLB_DA1 | (3 << SH4_ITLB_E_SHIFT), 0);
 	RUN_P1;
+	_cpu_exception_resume(s);
 }
 
 void
@@ -145,9 +154,11 @@
 {
 	u_int32_t oasid;
 	u_int32_t ptel;
+	int s;
 
 	KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
 
+	s = _cpu_exception_suspend();
 	/* Save old ASID */
 	oasid = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
 
@@ -170,4 +181,5 @@
 	/* Restore old ASID */
 	if (asid != oasid)
 		_reg_write_4(SH4_PTEH, oasid);
+	_cpu_exception_resume(s);
 }

---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp