Skip site navigation (1)Skip section navigation (2)
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>