188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang/* 288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * Copyright (C) 2016 Google, Inc. 388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * 488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * This software is licensed under the terms of the GNU General Public 588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * License version 2, as published by the Free Software Foundation, and 688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * may be copied, distributed, and modified under those terms. 788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * 888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * This program is distributed in the hope that it will be useful, 988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * but WITHOUT ANY WARRANTY; without even the implied warranty of 1088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * GNU General Public License for more details. 1288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang * 1388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang */ 1488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 1588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include "goldfish_dma.h" 1688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include "qemu_pipe.h" 1788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 1888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include <cutils/log.h> 1988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include <sys/mman.h> 2088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include <stdlib.h> 2188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang#include <string.h> 2288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 2388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangint goldfish_dma_lock(struct goldfish_dma_context* cxt) { 2488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang struct goldfish_dma_ioctl_info info; 2588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 2688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return ioctl(cxt->fd, GOLDFISH_DMA_IOC_LOCK, &info); 2788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 2888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 2988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangint goldfish_dma_unlock(struct goldfish_dma_context* cxt) { 3088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang struct goldfish_dma_ioctl_info info; 3188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 3288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return ioctl(cxt->fd, GOLDFISH_DMA_IOC_UNLOCK, &info); 3388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 3488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 3588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangint goldfish_dma_create_region(uint32_t sz, struct goldfish_dma_context* res) { 3688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 3788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang res->fd = qemu_pipe_open("opengles"); 3888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang res->mapped = NULL; 3988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang res->sz = 0; 4088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 4188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang if (res->fd > 0) { 4288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang // now alloc 4388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang struct goldfish_dma_ioctl_info info; 4488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang info.size = sz; 4588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang int alloc_res = ioctl(res->fd, GOLDFISH_DMA_IOC_CREATE_REGION, &info); 4688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 4788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang if (alloc_res) { 4888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGE("%s: failed to allocate DMA region. errno=%d", 4988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang __FUNCTION__, errno); 5088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang close(res->fd); 5188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang res->fd = -1; 5288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return alloc_res; 5388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang } 5488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 5588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang res->sz = sz; 5688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGV("%s: successfully allocated goldfish DMA region with size %lu cxt=%p", 5788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang __FUNCTION__, sz, res); 5888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return 0; 5988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang } else { 6088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGE("%s: could not obtain fd to device! fd %d errno=%d\n", 6188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang __FUNCTION__, res->fd, errno); 6288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return ENODEV; 6388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang } 6488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 6588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 6688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangvoid* goldfish_dma_map(struct goldfish_dma_context* cxt) { 6788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGV("%s: on fd %d errno=%d", __FUNCTION__, cxt->fd, errno); 6888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang cxt->mapped = mmap(0, cxt->sz, PROT_WRITE, MAP_SHARED, cxt->fd, 0); 6988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGV("%s: mapped addr=%p errno=%d", __FUNCTION__, cxt->mapped, errno); 7088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 7188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang if (cxt->mapped == MAP_FAILED) { 7288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang cxt->mapped = NULL; 7388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang } 7488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return cxt->mapped; 7588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 7688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 7788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangint goldfish_dma_unmap(struct goldfish_dma_context* cxt) { 7888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang munmap(cxt->mapped, cxt->sz); 7988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang cxt->mapped = NULL; 8088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang cxt->sz = 0; 8188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return 0; 8288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 8388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 8488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangvoid goldfish_dma_write(struct goldfish_dma_context* cxt, 8588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang void* to_write, 8688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang uint32_t sz) { 8788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ALOGV("%s: mapped addr=%p", __FUNCTION__, cxt->mapped); 8888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang memcpy(cxt->mapped, to_write, sz); 8988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 9088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 9188c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yangvoid goldfish_dma_free(goldfish_dma_context* cxt) { 9288c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang struct goldfish_dma_ioctl_info info; 9388c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang close(cxt->fd); 9488c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 9588c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang 9688c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yanguint64_t goldfish_dma_guest_paddr(struct goldfish_dma_context* cxt) { 9788c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang struct goldfish_dma_ioctl_info info; 9888c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang ioctl(cxt->fd, GOLDFISH_DMA_IOC_GETOFF, &info); 9988c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang return info.phys_begin; 10088c170cdf4d4a3c83ea61540d25bdcf4153fb5b8Lingfeng Yang} 101