Subject: Re: Stability of 2.0_RCx?
To: None <port-dreamcast@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-dreamcast
Date: 12/27/2004 00:27:11
In article <EA39C57A99D5484F815AD68F37CCA8687570DA@exmuc101.eAladdin.org>
cpg@aladdin.de wrote:

> Now I want to update to an up-to-date 2.0RC version, but I get strange
> reboots or hangs.

I'm using the attached diff for long years on my DC,
but I don't know if these changes are really necessary or not...
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp


Index: arch/sh3/sh3/mmu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/mmu.c,v
retrieving revision 1.9
diff -u -r1.9 mmu.c
--- arch/sh3/sh3/mmu.c	15 Jul 2003 03:35:57 -0000	1.9
+++ arch/sh3/sh3/mmu.c	26 Dec 2004 15:09:05 -0000
@@ -112,6 +112,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: arch/sh3/sh3/mmu_sh3.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/mmu_sh3.c,v
retrieving revision 1.6
diff -u -r1.6 mmu_sh3.c
--- arch/sh3/sh3/mmu_sh3.c	15 Jul 2003 03:35:57 -0000	1.6
+++ arch/sh3/sh3/mmu_sh3.c	26 Dec 2004 15:09:05 -0000
@@ -63,10 +63,11 @@
 sh3_tlb_invalidate_addr(int asid, vaddr_t va)
 {
 	u_int32_t a, d;
-	int w;
+	int s, w;
 
 	d = (va & SH3_MMUAA_D_VPN_MASK_4K) | asid;  /* 4K page */
 	va = va & SH3_MMU_VPN_MASK;   /* [16:12] entry index */
+	s = _cpu_exception_suspend();
 
 	/* Probe entry and invalidate it. */
 	for (w = 0; w < SH3_MMU_WAY; w++) {
@@ -77,14 +78,17 @@
 			break;
 		}
 	}
+
+	_cpu_exception_resume(s);
 }
 
 void
 sh3_tlb_invalidate_asid(int asid)
 {
 	u_int32_t aw, a;
-	int e, w;
+	int s, e, w;
 
+	s = _cpu_exception_suspend();
 	/* Invalidate entry attribute to ASID */
 	for (w = 0; w < SH3_MMU_WAY; w++) {
 		aw = (w << SH3_MMU_WAY_SHIFT);
@@ -96,14 +100,16 @@
 			}
 		}
 	}
+	_cpu_exception_resume(s);
 }
 
 void
 sh3_tlb_invalidate_all()
 {
 	u_int32_t aw, a;
-	int e, w;
+	int s, e, w;
 
+	s = _cpu_exception_suspend();
 	/* Zero clear all TLB entry to avoid unexpected VPN match. */
 	for (w = 0; w < SH3_MMU_WAY; w++) {
 		aw = (w << SH3_MMU_WAY_SHIFT);
@@ -113,15 +119,18 @@
 			_reg_write_4(SH3_MMUDA | a, 0);
 		}
 	}
+	_cpu_exception_resume(s);
 }
 
 void
 sh3_tlb_update(int asid, vaddr_t va, u_int32_t pte)
 {
 	u_int32_t oasid;
+	int s;
 
 	KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
 
+	s = _cpu_exception_suspend();
 	/* Save old ASID */
 	oasid = _reg_read_4(SH3_PTEH) & SH3_PTEH_ASID_MASK;
 
@@ -136,4 +145,5 @@
 	/* Restore old ASID */
 	if (asid != oasid)
 		_reg_write_4(SH3_PTEH, oasid);
+	_cpu_exception_resume(s);
 }
Index: arch/sh3/sh3/mmu_sh4.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/mmu_sh4.c,v
retrieving revision 1.7
diff -u -r1.7 mmu_sh4.c
--- arch/sh3/sh3/mmu_sh4.c	15 Jul 2003 03:35:57 -0000	1.7
+++ arch/sh3/sh3/mmu_sh4.c	26 Dec 2004 15:09:05 -0000
@@ -85,7 +85,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);
@@ -98,14 +101,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++) {
@@ -116,14 +122,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;
@@ -141,6 +149,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
@@ -148,9 +157,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;
 
@@ -173,4 +184,5 @@
 	/* Restore old ASID */
 	if (asid != oasid)
 		_reg_write_4(SH4_PTEH, oasid);
+	_cpu_exception_resume(s);
 }
Index: arch/sh3/sh3/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/pmap.c,v
retrieving revision 1.50
diff -u -r1.50 pmap.c
--- arch/sh3/sh3/pmap.c	30 Dec 2003 12:33:19 -0000	1.50
+++ arch/sh3/sh3/pmap.c	26 Dec 2004 15:09:05 -0000
@@ -311,6 +311,7 @@
 	struct vm_page_md *pvh;
 	pt_entry_t entry;
 	boolean_t kva = (pmap == pmap_kernel());
+	int s;
 
 	/* "flags" never exceed "prot" */
 	KDASSERT(prot != 0 && ((flags & VM_PROT_ALL) & ~prot) == 0);
@@ -320,6 +321,7 @@
 	if (flags & PMAP_WIRED)
 		entry |= _PG_WIRED;
 
+	s = splvm();
 	if (pg != NULL) {	/* memory-space */
 		pvh = &pg->mdpage;
 		entry |= PG_C;	/* always cached */
@@ -348,8 +350,10 @@
 		}
 
 		/* Check for existing mapping */
-		if (__pmap_map_change(pmap, va, pa, prot, entry))
+		if (__pmap_map_change(pmap, va, pa, prot, entry)) {
+			splx(s);
 			return (0);
+		}
 
 		/* Add to physical-virtual map list of this page */
 		__pmap_pv_enter(pmap, pg, va);
@@ -376,10 +380,12 @@
 	    (prot == (VM_PROT_READ | VM_PROT_EXECUTE)))
 		sh_icache_sync_range_index(va, PAGE_SIZE);
 
-	if (entry & _PG_WIRED)
+	if (entry & _PG_WIRED) {
 		pmap->pm_stats.wired_count++;
+	}
 	pmap->pm_stats.resident_count++;
 
+	splx(s);
 	return (0);
 }
 
@@ -401,7 +407,7 @@
 	    ((oentry = *pte) == 0))
 		return (FALSE);		/* no mapping exists. */
 
-	if (pa != (oentry & PG_PPN)) {
+	if ((pa & PG_PPN) != (oentry & PG_PPN)) {
 		/* Enter a mapping at a mapping to another physical page. */
 		pmap_remove(pmap, va, eva);
 		return (FALSE);
@@ -468,9 +474,11 @@
 	struct vm_page *pg;
 	pt_entry_t *pte, entry;
 	vaddr_t va;
+	int s;
 
 	KDASSERT((sva & PGOFSET) == 0);
 
+	s = splvm();
 	for (va = sva; va < eva; va += PAGE_SIZE) {
 		if ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
 		    (entry = *pte) == 0)
@@ -491,6 +499,7 @@
 		if (pmap->pm_asid != -1)
 			sh_tlb_invalidate_addr(pmap->pm_asid, va);
 	}
+	splx(s);
 }
 
 /*
@@ -536,6 +545,7 @@
 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
 {
 	pt_entry_t *pte, entry;
+	int s;
 
 	KDASSERT((va & PGOFSET) == 0);
 	KDASSERT(va >= VM_MIN_KERNEL_ADDRESS && va < VM_MAX_KERNEL_ADDRESS);
@@ -549,12 +559,14 @@
 	if (PHYS_TO_VM_PAGE(pa))
 		entry |= PG_C;
 
+	s = splvm();
 	pte = __pmap_kpte_lookup(va);
 
 	KDASSERT(*pte == 0);
 	*pte = entry;
 
 	sh_tlb_update(0, va, entry);
+	splx(s);
 }
 
 void
@@ -562,11 +574,13 @@
 {
 	pt_entry_t *pte;
 	vaddr_t eva = va + len;
+	int s;
 
 	KDASSERT((va & PGOFSET) == 0);
 	KDASSERT((len & PGOFSET) == 0);
 	KDASSERT(va >= VM_MIN_KERNEL_ADDRESS && eva <= VM_MAX_KERNEL_ADDRESS);
 
+	s = splvm();
 	for (; va < eva; va += PAGE_SIZE) {
 		pte = __pmap_kpte_lookup(va);
 		KDASSERT(pte != NULL);
@@ -579,6 +593,7 @@
 
 		sh_tlb_invalidate_addr(0, va);
 	}
+	splx(s);
 }
 
 boolean_t
@@ -601,6 +616,7 @@
 	boolean_t kernel = pmap == pmap_kernel();
 	pt_entry_t *pte, entry;
 	vaddr_t va;
+	int s;
 
 	sva = trunc_page(sva);
 
@@ -609,6 +625,7 @@
 		return;
 	}
 
+	s = splvm();
 	for (va = sva; va < eva; va += PAGE_SIZE) {
 
 		if (((pte = __pmap_pte_lookup(pmap, va)) == NULL) ||
@@ -642,6 +659,7 @@
 		if (pmap->pm_asid != -1)
 			sh_tlb_update(pmap->pm_asid, va, entry);
 	}
+	splx(s);
 }
 
 void
@@ -688,14 +706,19 @@
 pmap_unwire(pmap_t pmap, vaddr_t va)
 {
 	pt_entry_t *pte, entry;
+	int s;
 
+	s = splvm();
 	if ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
 	    (entry = *pte) == 0 ||
-	    (entry & _PG_WIRED) == 0)
+	    (entry & _PG_WIRED) == 0) {
+		splx(s);
 		return;
+	}
 
 	*pte = entry & ~_PG_WIRED;
 	pmap->pm_stats.wired_count--;
+	splx(s);
 }
 
 void
Index: arch/sh3/sh3/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/vm_machdep.c,v
retrieving revision 1.45
diff -u -r1.45 vm_machdep.c
--- arch/sh3/sh3/vm_machdep.c	17 Sep 2004 14:11:22 -0000	1.45
+++ arch/sh3/sh3/vm_machdep.c	26 Dec 2004 15:09:05 -0000
@@ -379,6 +379,7 @@
 {
 	vaddr_t faddr, taddr, off;
 	paddr_t fpa;
+	pmap_t kpmap, upmap;
 
 	if ((bp->b_flags & B_PHYS) == 0)
 		panic("vmapbuf");
@@ -399,16 +400,18 @@
 	 * where we we just allocated (TLB will be flushed when our
 	 * mapping is removed).
 	 */
+	upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
+	kpmap = vm_map_pmap(phys_map);
 	while (len) {
-		pmap_extract(vm_map_pmap(&bp->b_proc->p_vmspace->vm_map),
-			     faddr, &fpa);
-		pmap_enter(vm_map_pmap(phys_map), taddr, fpa,
-		    VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
+		pmap_extract(upmap, faddr, &fpa);
+		pmap_enter(kpmap, taddr, fpa,
+		    VM_PROT_READ | VM_PROT_WRITE,
+		    VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
 		faddr += PAGE_SIZE;
 		taddr += PAGE_SIZE;
 		len -= PAGE_SIZE;
 	}
-	pmap_update(vm_map_pmap(phys_map));
+	pmap_update(kpmap);
 }
 
 /*
@@ -419,14 +422,16 @@
 vunmapbuf(struct buf *bp, vsize_t len)
 {
 	vaddr_t addr, off;
+	pmap_t kpmap;
 
 	if ((bp->b_flags & B_PHYS) == 0)
 		panic("vunmapbuf");
 	addr = trunc_page((vaddr_t)bp->b_data);
 	off = (vaddr_t)bp->b_data - addr;
 	len = round_page(off + len);
-	pmap_remove(vm_map_pmap(phys_map), addr, addr + len);
-	pmap_update(vm_map_pmap(phys_map));
+	kpmap = vm_map_pmap(phys_map);
+	pmap_remove(kpmap, addr, addr + len);
+	pmap_update(kpmap);
 	uvm_km_free_wakeup(phys_map, addr, len);
 	bp->b_data = bp->b_saveaddr;
 	bp->b_saveaddr = 0;