Date: Thu, 9 Sep 2010 22:52:39 -0700 From: Neel Natu <neelnatu@gmail.com> To: "Jayachandran C." <c.jayachandran@gmail.com> Cc: gonzo@freebsd.org, freebsd-mips@freebsd.org Subject: Re: busdma_machdep.c with more than 512M memory Message-ID: <AANLkTikOKU8KOaw6aFd1dMqpcZW%2BcMkU72mrDBcUncVq@mail.gmail.com> In-Reply-To: <AANLkTim7zDxy9bYYvPT31t-mRB37NPpONsBHhouBPpG_@mail.gmail.com> References: <AANLkTimjmpOBOAncY9K9AhCodvp27t=XTQ9qZp4q8%2Bvv@mail.gmail.com> <AANLkTim2gqj=cbgM35rD5oyMD43rWFY1cjyY4A4CoR99@mail.gmail.com> <AANLkTim7zDxy9bYYvPT31t-mRB37NPpONsBHhouBPpG_@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi JC, On Mon, Sep 6, 2010 at 12:38 AM, Jayachandran C. <c.jayachandran@gmail.com> wrote: > On Mon, Sep 6, 2010 at 1:04 PM, Jayachandran C. > <c.jayachandran@gmail.com> wrote: >> On Wed, Sep 1, 2010 at 12:37 PM, Jayachandran C. >> <c.jayachandran@gmail.com> wrote: >>> I was looking at a few crashes I see with PCI drivers, and I think it >>> is caused by an issue in busdma_machdep.c where physical address is >>> directly converted using MIPS_PHYS_TO_KSEG1. I have not looked at it >>> in detail, but it looks obviously wrong. >>> >>> Any suggestions on how to fix thiis is welcome, it probably needs an >>> uncached TLB entry. On 64bit we could use XKPHYS uncached. >>> >>> >>> --- >>> =A0632 =A0 =A0 =A0 =A0 if (newmap->flags & DMAMAP_UNCACHEABLE) { >>> =A0633 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *tmpaddr =3D (void *)*vaddr= ; >>> =A0634 >>> =A0635 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (tmpaddr) { >>> =A0636 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tmpaddr =3D (voi= d >>> *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr)); >>> =A0637 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 newmap->origbuff= er =3D *vaddr; >>> =A0638 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 newmap->allocbuf= fer =3D tmpaddr; >>> =A0639 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mips_dcache_wbin= v_range((vm_offset_t)*vaddr, >>> =A0640 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dmat->ma= xsize); >>> =A0641 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *vaddr =3D tmpad= dr; >>> =A0642 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >>> --- >>> 1361 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bpage->busaddr =3D pmap_kextract(b= page->vaddr); >>> 1362 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bpage->vaddr_nocache =3D >>> 1363 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (vm_offset_t)MIPS_PHYS_TO_= KSEG1(bpage->busaddr); >>> 1364 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mtx_lock(&bounce_lock); >> >> Based on Juli's suggestion, I have a patch (attached) to switch the >> calls to pmap_mapdev/pmap_unmapdev. >> >> Seems to work for me now, please review. > > That was an older version of the patch, here is the correct version. > This assumes that pmap_mapdev() always returns an uncached mapping which is true for n64 kernels but not for o32 kernels with memory beyond 512MB. Any objections if I commit the following patch that makes pmap_mapdev() always return an uncached mapping. Index: sys/mips/mips/pmap.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/mips/mips/pmap.c (revision 212404) +++ sys/mips/mips/pmap.c (working copy) @@ -828,8 +828,8 @@ /* * add a wired page to the kva */ - /* PMAP_INLINE */ void -pmap_kenter(vm_offset_t va, vm_paddr_t pa) +static void +pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int attr) { pt_entry_t *pte; pt_entry_t opte, npte; @@ -837,13 +837,8 @@ #ifdef PMAP_DEBUG printf("pmap_kenter: va: %p -> pa: %p\n", (void *)va, (void *)pa); #endif - npte =3D TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | PTE_W; + npte =3D TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | PTE_W | attr; - if (is_cacheable_mem(pa)) - npte |=3D PTE_C_CACHE; - else - npte |=3D PTE_C_UNCACHED; - pte =3D pmap_pte(kernel_pmap, va); opte =3D *pte; *pte =3D npte; @@ -851,6 +846,19 @@ pmap_update_page(kernel_pmap, va, npte); } +void +pmap_kenter(vm_offset_t va, vm_paddr_t pa) +{ + int attr; + + if (is_cacheable_mem(pa)) + attr =3D PTE_C_CACHE; + else + attr =3D PTE_C_UNCACHED; + + pmap_kenter_attr(va, pa, attr); +} + /* * remove a page from the kernel pagetables */ @@ -2863,7 +2871,7 @@ panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); pa =3D trunc_page(pa); for (tmpva =3D va; size > 0;) { - pmap_kenter(tmpva, pa); + pmap_kenter_attr(tmpva, pa, PTE_C_UNCACHED); size -=3D PAGE_SIZE; tmpva +=3D PAGE_SIZE; pa +=3D PAGE_SIZE; best Neel > Thanks, > JC. >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTikOKU8KOaw6aFd1dMqpcZW%2BcMkU72mrDBcUncVq>