- for DRM_NETBSD_HANDLE2ADDR/ADDR2HANDLE, do what uvm does to recover

the virtual address from a uoffset, e.g. uoffset + vm_map_min(kernel_map).

- Eliminate the bus_space_read/write-based DRM_READ/WRITE macros.  The
  memory we're reading/writing from is not always allocated with bus_space,
  and so this will not do.  Instead, since all of our bus_space maps are
  linear, volatile pointer dereferences will do just fine.

- Unify members of struct drm_dma_handle amongst freebsd and netbsd:
  the 'addr' member was superfluous; also, set dmah->tag from
  dev->pa.pa_dmat and use that.

- we don't need BUS_DMA_ALLOCNOW, as bus_dmamap_load is called immediately
  following bus_dmamap_create(), so there's no need to avoid deferring
  allocation to load time.

- Add check for nsegs != 1 in drm_pci_alloc().

- We don't need the DRM_PCI_DMAADDR macro right now--it was only
  used once.
This commit is contained in:
bjs 2008-07-25 06:54:33 +00:00
parent 8385c9b102
commit 8151294949
2 changed files with 30 additions and 44 deletions

View File

@ -329,8 +329,8 @@ extern drm_device_t *drm_units[];
#define DRM_MTRR_WC MTRR_TYPE_WC #define DRM_MTRR_WC MTRR_TYPE_WC
#define jiffies hardclock_ticks #define jiffies hardclock_ticks
#ifdef __x86_64__ #ifdef __x86_64__
#define DRM_NETBSD_ADDR2HANDLE(addr) (addr & 0x7fffffffffffffff) #define DRM_NETBSD_ADDR2HANDLE(v) ((vaddr_t)(v) - vm_map_min(kernel_map))
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle | 0x8000000000000000) #define DRM_NETBSD_HANDLE2ADDR(u) ((vaddr_t)(u) + vm_map_min(kernel_map))
#else #else
#define DRM_NETBSD_ADDR2HANDLE(addr) (addr) #define DRM_NETBSD_ADDR2HANDLE(addr) (addr)
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle) #define DRM_NETBSD_HANDLE2ADDR(handle) (handle)
@ -402,7 +402,6 @@ typedef u_int8_t u8;
"lock; addl $0,0(%%rsp)" : : : "memory"); "lock; addl $0,0(%%rsp)" : : : "memory");
#endif #endif
#ifdef __FreeBSD__
#define DRM_READ8(map, offset) \ #define DRM_READ8(map, offset) \
*(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
#define DRM_READ16(map, offset) \ #define DRM_READ16(map, offset) \
@ -416,31 +415,15 @@ typedef u_int8_t u8;
#define DRM_WRITE32(map, offset, val) \ #define DRM_WRITE32(map, offset, val) \
*(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
#ifdef __FreeBSD__
#define DRM_VERIFYAREA_READ( uaddr, size ) \ #define DRM_VERIFYAREA_READ( uaddr, size ) \
(!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ)) (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ))
#else
#else /* __FreeBSD__ */
typedef vaddr_t vm_offset_t; typedef vaddr_t vm_offset_t;
#define DRM_READ8(map, offset) \
bus_space_read_1( (map)->bst, (map)->bsh, (offset))
#define DRM_READ16(map, offset) \
bus_space_read_2( (map)->bst, (map)->bsh, (offset))
#define DRM_READ32(map, offset) \
bus_space_read_4( (map)->bst, (map)->bsh, (offset))
#define DRM_WRITE8(map, offset, val) \
bus_space_write_1((map)->bst, (map)->bsh, (offset), (val))
#define DRM_WRITE16(map, offset, val) \
bus_space_write_2((map)->bst, (map)->bsh, (offset), (val))
#define DRM_WRITE32(map, offset, val) \
bus_space_write_4((map)->bst, (map)->bsh, (offset), (val))
#define DRM_VERIFYAREA_READ( uaddr, size ) \ #define DRM_VERIFYAREA_READ( uaddr, size ) \
(!uvm_map_checkprot(&(curproc->p_vmspace->vm_map), \ (!uvm_map_checkprot(&(curproc->p_vmspace->vm_map), \
(vaddr_t)uaddr, (vaddr_t)uaddr+size, UVM_PROT_READ)) (vaddr_t)uaddr, (vaddr_t)uaddr+size, UVM_PROT_READ))
#endif
#endif /* !__FreeBSD__ */
#define DRM_COPY_TO_USER(user, kern, size) \ #define DRM_COPY_TO_USER(user, kern, size) \
copyout(kern, user, size) copyout(kern, user, size)
@ -599,16 +582,11 @@ typedef struct drm_freelist {
typedef struct drm_dma_handle { typedef struct drm_dma_handle {
void *vaddr; void *vaddr;
bus_addr_t busaddr; bus_addr_t busaddr;
#if defined(__FreeBSD__)
bus_dma_tag_t tag; bus_dma_tag_t tag;
bus_dmamap_t map; bus_dmamap_t map;
#elif defined(__NetBSD__) #if defined(__NetBSD__)
bus_dma_tag_t dmat;
bus_dmamap_t map;
#define DRM_PCI_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
bus_dma_segment_t segs[1]; bus_dma_segment_t segs[1];
size_t size; size_t size;
void *addr;
#endif #endif
} drm_dma_handle_t; } drm_dma_handle_t;

View File

@ -107,39 +107,46 @@ drm_pci_alloc(struct drm_device *dev, size_t size,
return dmah; return dmah;
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
if ((ret = bus_dmamem_alloc(dev->pa.pa_dmat, size, align, 0, dmah->tag = dev->pa.pa_dmat;
if ((ret = bus_dmamem_alloc(dmah->tag, size, align, maxaddr,
dmah->segs, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) { dmah->segs, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
printf("drm: Unable to allocate DMA, error %d\n", ret); printf("drm: Unable to allocate DMA, error %d\n", ret);
goto fail; goto fail;
} }
if ((ret = bus_dmamem_map(dev->pa.pa_dmat, dmah->segs, nsegs, size, /* XXX is there a better way to deal with this? */
&dmah->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { if (nsegs != 1) {
printf("drm: bad segment count from bus_dmamem_alloc\n");
goto free;
}
if ((ret = bus_dmamem_map(dmah->tag, dmah->segs, nsegs, size,
&dmah->vaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
printf("drm: Unable to map DMA, error %d\n", ret); printf("drm: Unable to map DMA, error %d\n", ret);
goto free; goto free;
} }
if ((ret = bus_dmamap_create(dev->pa.pa_dmat, size, 1, size, 0, if ((ret = bus_dmamap_create(dmah->tag, size, 1, size, maxaddr,
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dmah->map)) != 0) { BUS_DMA_NOWAIT, &dmah->map)) != 0) {
printf("drm: Unable to create DMA map, error %d\n", ret); printf("drm: Unable to create DMA map, error %d\n", ret);
goto unmap; goto unmap;
} }
if ((ret = bus_dmamap_load(dev->pa.pa_dmat, dmah->map, dmah->addr, size, if ((ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr,
NULL, BUS_DMA_NOWAIT)) != 0) { size, NULL, BUS_DMA_NOWAIT)) != 0) {
printf("drm: Unable to load DMA map, error %d\n", ret); printf("drm: Unable to load DMA map, error %d\n", ret);
goto destroy; goto destroy;
} }
dmah->busaddr = DRM_PCI_DMAADDR(dmah); dmah->busaddr = dmah->map->dm_segs[0].ds_addr;
dmah->vaddr = dmah->addr;
dmah->size = size; dmah->size = size;
return dmah; return dmah;
destroy: destroy:
bus_dmamap_destroy(dev->pa.pa_dmat, dmah->map); bus_dmamap_destroy(dmah->tag, dmah->map);
unmap: unmap:
bus_dmamem_unmap(dev->pa.pa_dmat, dmah->addr, size); bus_dmamem_unmap(dmah->tag, dmah->vaddr, size);
free: free:
bus_dmamem_free(dev->pa.pa_dmat, dmah->segs, 1); bus_dmamem_free(dmah->tag, dmah->segs, 1);
fail: fail:
dmah->tag = NULL;
free(dmah, M_DRM); free(dmah, M_DRM);
return NULL; return NULL;
@ -161,10 +168,11 @@ drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah)
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
if (dmah == NULL) if (dmah == NULL)
return; return;
bus_dmamap_unload(dev->pa.pa_dmat, dmah->map); bus_dmamap_unload(dmah->tag, dmah->map);
bus_dmamap_destroy(dev->pa.pa_dmat, dmah->map); bus_dmamap_destroy(dmah->tag, dmah->map);
bus_dmamem_unmap(dev->pa.pa_dmat, dmah->addr, dmah->size); bus_dmamem_unmap(dmah->tag, dmah->vaddr, dmah->size);
bus_dmamem_free(dev->pa.pa_dmat, dmah->segs, 1); bus_dmamem_free(dmah->tag, dmah->segs, 1);
dmah->tag = NULL;
#endif #endif
free(dmah, M_DRM); free(dmah, M_DRM);