1/* 2 * Copyright (c) 2014 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <string.h> 11 12#include <barrelfish/barrelfish.h> 13 14#include <dma_internal.h> 15#include <dma_mem_utils.h> 16 17/** 18 * \brief allocates and maps a memory region to be used for DMA purposes 19 * 20 * \param bytes minimum size of the memory region in bytes 21 * \param flags VREGION flags how the region gets mapped 22 * \param mem returns the mapping information 23 * 24 * \returns SYS_ERR_OK on success 25 * errval on error 26 */ 27errval_t dma_mem_alloc(size_t bytes, 28 vregion_flags_t flags, 29 struct dma_mem *mem) 30{ 31 errval_t err; 32 33 if (mem == NULL) { 34 return DMA_ERR_ARG_INVALID; 35 } 36 37 err = frame_alloc(&mem->frame, bytes, &mem->bytes); 38 if (err_is_fail(err)) { 39 return err; 40 } 41 42 struct frame_identity id; 43 err = frame_identify(mem->frame, &id); 44 if (err_is_fail(err)) { 45 dma_mem_free(mem); 46 return err; 47 } 48 49 mem->paddr = id.base; 50 51 void *addr; 52 err = vspace_map_one_frame_attr(&addr, mem->bytes, mem->frame, flags, NULL, 53 NULL); 54 if (err_is_fail(err)) { 55 dma_mem_free(mem); 56 return err; 57 } 58 59 mem->vaddr = (lvaddr_t)addr; 60 61 return SYS_ERR_OK; 62} 63 64/** 65 * \brief tries to free the allocated memory region 66 * 67 * \returns SYS_ERR_OK on success 68 * errval on error 69 */ 70errval_t dma_mem_free(struct dma_mem *mem) 71{ 72 errval_t err; 73 74 if (mem->vaddr) { 75 err = vspace_unmap((void*)mem->vaddr); 76 if (err_is_fail(err)) { 77 /* todo: error handling ignoring for now */ 78 } 79 } 80 81 if (!capref_is_null(mem->frame)) { 82 err = cap_destroy(mem->frame); 83 if (err_is_fail(err)) { 84 /* todo: error handling ignoring for now */ 85 86 } 87 } 88 89 memset(mem, 0, sizeof(*mem)); 90 91 return SYS_ERR_OK; 92} 93