1 /* 2 * Copyright (C) 2016 Google, Inc. 3 * 4 * This software is licensed under the terms of the GNU General Public 5 * License version 2, as published by the Free Software Foundation, and 6 * may be copied, distributed, and modified under those terms. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 */ 14 15 #include "goldfish_dma.h" 16 #include "qemu_pipe.h" 17 18 #include <cutils/log.h> 19 #include <sys/mman.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 int goldfish_dma_lock(struct goldfish_dma_context* cxt) { 24 struct goldfish_dma_ioctl_info info; 25 26 return ioctl(cxt->fd, GOLDFISH_DMA_IOC_LOCK, &info); 27 } 28 29 int goldfish_dma_unlock(struct goldfish_dma_context* cxt) { 30 struct goldfish_dma_ioctl_info info; 31 32 return ioctl(cxt->fd, GOLDFISH_DMA_IOC_UNLOCK, &info); 33 } 34 35 int goldfish_dma_create_region(uint32_t sz, struct goldfish_dma_context* res) { 36 37 res->fd = qemu_pipe_open("opengles"); 38 res->mapped = NULL; 39 res->sz = 0; 40 41 if (res->fd > 0) { 42 // now alloc 43 struct goldfish_dma_ioctl_info info; 44 info.size = sz; 45 int alloc_res = ioctl(res->fd, GOLDFISH_DMA_IOC_CREATE_REGION, &info); 46 47 if (alloc_res) { 48 ALOGE("%s: failed to allocate DMA region. errno=%d", 49 __FUNCTION__, errno); 50 close(res->fd); 51 res->fd = -1; 52 return alloc_res; 53 } 54 55 res->sz = sz; 56 ALOGV("%s: successfully allocated goldfish DMA region with size %lu cxt=%p", 57 __FUNCTION__, sz, res); 58 return 0; 59 } else { 60 ALOGE("%s: could not obtain fd to device! fd %d errno=%d\n", 61 __FUNCTION__, res->fd, errno); 62 return ENODEV; 63 } 64 } 65 66 void* goldfish_dma_map(struct goldfish_dma_context* cxt) { 67 ALOGV("%s: on fd %d errno=%d", __FUNCTION__, cxt->fd, errno); 68 cxt->mapped = mmap(0, cxt->sz, PROT_WRITE, MAP_SHARED, cxt->fd, 0); 69 ALOGV("%s: mapped addr=%p errno=%d", __FUNCTION__, cxt->mapped, errno); 70 71 if (cxt->mapped == MAP_FAILED) { 72 cxt->mapped = NULL; 73 } 74 return cxt->mapped; 75 } 76 77 int goldfish_dma_unmap(struct goldfish_dma_context* cxt) { 78 munmap(cxt->mapped, cxt->sz); 79 cxt->mapped = NULL; 80 cxt->sz = 0; 81 return 0; 82 } 83 84 void goldfish_dma_write(struct goldfish_dma_context* cxt, 85 void* to_write, 86 uint32_t sz) { 87 ALOGV("%s: mapped addr=%p", __FUNCTION__, cxt->mapped); 88 memcpy(cxt->mapped, to_write, sz); 89 } 90 91 void goldfish_dma_free(goldfish_dma_context* cxt) { 92 struct goldfish_dma_ioctl_info info; 93 close(cxt->fd); 94 } 95 96 uint64_t goldfish_dma_guest_paddr(struct goldfish_dma_context* cxt) { 97 struct goldfish_dma_ioctl_info info; 98 ioctl(cxt->fd, GOLDFISH_DMA_IOC_GETOFF, &info); 99 return info.phys_begin; 100 } 101