diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-07-13 16:47:04 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-07-13 16:47:04 +0000 |
commit | 1a95ff1763e2465e059cbf64df14c72c6a5fdaf7 (patch) | |
tree | aabdc7e2e7c3be8de24c42b0913855b9599a9ab4 | |
parent | 198a704e5c783d35632f7f6ef223b22b626e0a35 (diff) |
dma_alloc() and dma_free(). This is a thin shim on top of a bag of
pools, sized by powers of 2, which are constrained to dma memory.
ok matthew tedu thib
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/kern/dma_alloc.c | 76 | ||||
-rw-r--r-- | sys/sys/pool.h | 7 | ||||
-rw-r--r-- | sys/uvm/uvm_init.c | 7 |
4 files changed, 90 insertions, 3 deletions
diff --git a/sys/conf/files b/sys/conf/files index c3ac3f56cac..6187472e38f 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.496 2010/07/05 23:10:16 tedu Exp $ +# $OpenBSD: files,v 1.497 2010/07/13 16:47:03 deraadt Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -731,6 +731,7 @@ file kern/subr_evcount.c file kern/subr_extent.c file kern/subr_log.c file kern/subr_pool.c +file kern/dma_alloc.c file kern/subr_prf.c file kern/subr_prof.c file kern/subr_userconf.c boot_config diff --git a/sys/kern/dma_alloc.c b/sys/kern/dma_alloc.c new file mode 100644 index 00000000000..7c61f906ffd --- /dev/null +++ b/sys/kern/dma_alloc.c @@ -0,0 +1,76 @@ +/* $OpenBSD: dma_alloc.c,v 1.1 2010/07/13 16:47:03 deraadt Exp $ */ +/* + * Copyright (c) 2010 Theo de Raadt <deraadt@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/pool.h> +#include <uvm/uvm.h> + +static __inline int dma_alloc_index(size_t size); + +#define DMA_BUCKET_OFFSET 4 +static char dmanames[PAGE_SHIFT - DMA_BUCKET_OFFSET][8]; +struct pool dmapools[PAGE_SHIFT - DMA_BUCKET_OFFSET]; + +void +dma_alloc_init(void) +{ + int i; + + for (i = 0; i < nitems(dmapools); i++) { + snprintf(dmanames[i], sizeof(dmanames[0]), "dma%d", + 1 << (i + DMA_BUCKET_OFFSET)); + pool_init(&dmapools[i], 1 << (i + DMA_BUCKET_OFFSET), 0, 0, 0, + dmanames[i], NULL); + pool_set_constraints(&dmapools[i], &dma_constraint, 1); + /* XXX need pool_setlowat(&dmapools[i], dmalowat); */ + } +} + +static __inline int +dma_alloc_index(size_t sz) +{ + int b; + + for (b = 0; b < nitems(dmapools); b++) + if (sz <= (1 << (b + DMA_BUCKET_OFFSET))) + return (b); +#ifdef DEBUG + printf("dma_alloc/free: object %d too large\n", sz) +#endif + return (-1); +} + +void * +dma_alloc(size_t size, int prflags) +{ + int pi = dma_alloc_index(size); + + if (pi == -1) + return (NULL); + return pool_get(&dmapools[pi], prflags); +} + + +void +dma_free(void *m, size_t size) +{ + int pi = dma_alloc_index(size); + + if (pi == -1) + return; + pool_put(&dmapools[pi], m); +} diff --git a/sys/sys/pool.h b/sys/sys/pool.h index e49d075d407..b1a471ad20c 100644 --- a/sys/sys/pool.h +++ b/sys/sys/pool.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pool.h,v 1.34 2010/06/27 03:03:48 thib Exp $ */ +/* $OpenBSD: pool.h,v 1.35 2010/07/13 16:47:02 deraadt Exp $ */ /* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */ /*- @@ -170,6 +170,11 @@ int pool_chk(struct pool *, const char *); void pool_walk(struct pool *, int, int (*)(const char *, ...), void (*)(void *, int, int (*)(const char *, ...))); #endif + +/* the allocator for dma-able memory is a thin layer on top of pool */ +void dma_alloc_init(void); +void *dma_alloc(size_t size, int flags); +void dma_free(void *m, size_t size); #endif /* _KERNEL */ #endif /* _SYS_POOL_H_ */ diff --git a/sys/uvm/uvm_init.c b/sys/uvm/uvm_init.c index 69502ec87b3..68ea0330b14 100644 --- a/sys/uvm/uvm_init.c +++ b/sys/uvm/uvm_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_init.c,v 1.25 2009/08/06 15:28:14 oga Exp $ */ +/* $OpenBSD: uvm_init.c,v 1.26 2010/07/13 16:47:03 deraadt Exp $ */ /* $NetBSD: uvm_init.c,v 1.14 2000/06/27 17:29:23 mrg Exp $ */ /* @@ -126,6 +126,11 @@ uvm_init(void) kmeminit(); /* + * step 6.5: init the dma allocator, which is backed by pools. + */ + dma_alloc_init(); + + /* * step 7: init all pagers and the pager_map. */ |