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;