From 88a5255bc4779adcbb7904ebd4038702a41d1bcb Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 17 Apr 2007 21:05:34 +0000 Subject: [PATCH] Honor the BUS_DMA_NOCACHE flag to bus_dmamem_alloc() on amd64 and i386 by mapping the pages as UC (uncacheable) using pmap_change_attr(). MFC after: 1 week Requested by: ariff Reviewed by: scottl --- sys/amd64/amd64/busdma_machdep.c | 5 +++++ sys/i386/i386/busdma_machdep.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index 03e3c5c3c8d2..a2b19d6a3a80 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define MAX_BPAGES 8192 @@ -522,6 +523,9 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) { printf("bus_dmamem_alloc failed to align memory properly.\n"); } + if (flags & BUS_DMA_NOCACHE) + pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize, + PAT_UNCACHEABLE); CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, ENOMEM); return (0); @@ -540,6 +544,7 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) */ if (map != NULL) panic("bus_dmamem_free: Invalid map freed\n"); + pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK); if ((dmat->maxsize <= PAGE_SIZE) && (dmat->alignment < dmat->maxsize) && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index ab5b66cf4ab2..b11805be8df1 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define MAX_BPAGES 512 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 @@ -530,6 +531,9 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) { printf("bus_dmamem_alloc failed to align memory properly.\n"); } + if (flags & BUS_DMA_NOCACHE) + pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize, + PAT_UNCACHEABLE); CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, ENOMEM); return (0); @@ -548,6 +552,7 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) */ if (map != NULL) panic("bus_dmamem_free: Invalid map freed\n"); + pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK); if ((dmat->maxsize <= PAGE_SIZE) && (dmat->alignment < dmat->maxsize) && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))