Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Sep 2010 13:08:15 +0530
From:      "Jayachandran C." <c.jayachandran@gmail.com>
To:        freebsd-mips@freebsd.org
Cc:        gonzo@freebsd.org
Subject:   Re: busdma_machdep.c with more than 512M memory
Message-ID:  <AANLkTim7zDxy9bYYvPT31t-mRB37NPpONsBHhouBPpG_@mail.gmail.com>
In-Reply-To: <AANLkTim2gqj=cbgM35rD5oyMD43rWFY1cjyY4A4CoR99@mail.gmail.com>
References:  <AANLkTimjmpOBOAncY9K9AhCodvp27t=XTQ9qZp4q8%2Bvv@mail.gmail.com> <AANLkTim2gqj=cbgM35rD5oyMD43rWFY1cjyY4A4CoR99@mail.gmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
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.
>>
>>
>> ---
>>  632         if (newmap->flags & DMAMAP_UNCACHEABLE) {
>>  633                 void *tmpaddr = (void *)*vaddr;
>>  634
>>  635                 if (tmpaddr) {
>>  636                         tmpaddr = (void
>> *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr));
>>  637                         newmap->origbuffer = *vaddr;
>>  638                         newmap->allocbuffer = tmpaddr;
>>  639                         mips_dcache_wbinv_range((vm_offset_t)*vaddr,
>>  640                             dmat->maxsize);
>>  641                         *vaddr = tmpaddr;
>>  642                 }
>> ---
>> 1361                 bpage->busaddr = pmap_kextract(bpage->vaddr);
>> 1362                 bpage->vaddr_nocache =
>> 1363                     (vm_offset_t)MIPS_PHYS_TO_KSEG1(bpage->busaddr);
>> 1364                 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.

Thanks,
JC.

[-- Attachment #2 --]
Index: sys/mips/mips/busdma_machdep.c
===================================================================
--- sys/mips/mips/busdma_machdep.c	(revision 212247)
+++ sys/mips/mips/busdma_machdep.c	(working copy)
@@ -425,7 +425,6 @@
 #endif
 
 	if (dmat != NULL) {
-		
                 if (dmat->map_count != 0)
                         return (EBUSY);
 		
@@ -602,20 +601,6 @@
                  *     and handles multi-seg allocations.  Nobody is doing
                  *     multi-seg allocations yet though.
                  */
-	         vm_paddr_t maxphys;
-	         if((uint32_t)dmat->lowaddr >= MIPS_KSEG0_LARGEST_PHYS) {
-		   /* Note in the else case I just put in what was already
-		    * being passed in dmat->lowaddr. I am not sure
-		    * how this would have worked. Since lowaddr is in the
-		    * max address postion. I would have thought that the
-		    * caller would have wanted dmat->highaddr. That is
-		    * presuming they are asking for physical addresses
-		    * which is what contigmalloc takes. - RRS
-		    */
-		   maxphys = MIPS_KSEG0_LARGEST_PHYS - 1;
-		 } else {
-		   maxphys = dmat->lowaddr;
-		 }
                 *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
                     0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
                     dmat->boundary);
@@ -633,7 +618,8 @@
 		void *tmpaddr = (void *)*vaddr;
 
 		if (tmpaddr) {
-			tmpaddr = (void *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr));
+			tmpaddr = (void *)pmap_mapdev(vtophys(tmpaddr),
+			    dmat->maxsize);
 			newmap->origbuffer = *vaddr;
 			newmap->allocbuffer = tmpaddr;
 			mips_dcache_wbinv_range((vm_offset_t)*vaddr,
@@ -660,6 +646,8 @@
 		vaddr = map->origbuffer;
 	}
 
+	if (map->flags & DMAMAP_UNCACHEABLE)
+		pmap_unmapdev((vm_offset_t)map->allocbuffer, dmat->maxsize);
         if (map->flags & DMAMAP_MALLOCUSED)
 		free(vaddr, M_DEVBUF);
         else
@@ -1360,7 +1348,7 @@
 		}
 		bpage->busaddr = pmap_kextract(bpage->vaddr);
 		bpage->vaddr_nocache = 
-		    (vm_offset_t)MIPS_PHYS_TO_KSEG1(bpage->busaddr);
+		    (vm_offset_t)pmap_mapdev(bpage->busaddr, PAGE_SIZE);
 		mtx_lock(&bounce_lock);
 		STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links);
 		total_bpages++;
home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTim7zDxy9bYYvPT31t-mRB37NPpONsBHhouBPpG_>