blob: dbb1f8dfec70fb0590c5c415beb5666e276efff5 [file] [log] [blame]
Lingfeng Yang88c170c2016-11-30 00:52:35 +00001/*
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
Luca Stefani1cb647a2019-03-07 21:58:17 +010018#if PLATFORM_SDK_VERSION < 26
Logan Chiend7bf00d2018-09-21 06:30:09 +000019#include <cutils/log.h>
Luca Stefani1cb647a2019-03-07 21:58:17 +010020#else
21#include <log/log.h>
22#endif
Lingfeng Yange38d15c2018-09-24 16:24:01 -070023#include <errno.h>
David Reveman74e99bb2019-02-15 18:47:25 -050024#ifdef __ANDROID__
Lingfeng Yange38d15c2018-09-24 16:24:01 -070025#include <linux/ioctl.h>
26#include <linux/types.h>
27#include <sys/cdefs.h>
David Reveman74e99bb2019-02-15 18:47:25 -050028#endif
29#include <sys/ioctl.h>
Lingfeng Yang88c170c2016-11-30 00:52:35 +000030#include <sys/mman.h>
Lingfeng Yange38d15c2018-09-24 16:24:01 -070031#include <fcntl.h>
32#include <stdlib.h>
Lingfeng Yang88c170c2016-11-30 00:52:35 +000033#include <stdlib.h>
34#include <string.h>
35
Lingfeng Yange38d15c2018-09-24 16:24:01 -070036/* There is an ioctl associated with goldfish dma driver.
37 * Make it conflict with ioctls that are not likely to be used
38 * in the emulator.
39 * 'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict!
40 * 'G' 00-0F linux/gigaset_dev.h conflict!
41 */
42#define GOLDFISH_DMA_IOC_MAGIC 'G'
43
44#define GOLDFISH_DMA_IOC_LOCK _IOWR(GOLDFISH_DMA_IOC_MAGIC, 0, struct goldfish_dma_ioctl_info)
45#define GOLDFISH_DMA_IOC_UNLOCK _IOWR(GOLDFISH_DMA_IOC_MAGIC, 1, struct goldfish_dma_ioctl_info)
46#define GOLDFISH_DMA_IOC_GETOFF _IOWR(GOLDFISH_DMA_IOC_MAGIC, 2, struct goldfish_dma_ioctl_info)
47#define GOLDFISH_DMA_IOC_CREATE_REGION _IOWR(GOLDFISH_DMA_IOC_MAGIC, 3, struct goldfish_dma_ioctl_info)
48
49struct goldfish_dma_ioctl_info {
50 uint64_t phys_begin;
51 uint64_t size;
52};
53
Lingfeng Yang88c170c2016-11-30 00:52:35 +000054int goldfish_dma_create_region(uint32_t sz, struct goldfish_dma_context* res) {
55
56 res->fd = qemu_pipe_open("opengles");
Roman Kiryanov96a068f2018-06-13 17:05:05 -070057 res->mapped_addr = 0;
58 res->size = 0;
Lingfeng Yang88c170c2016-11-30 00:52:35 +000059
60 if (res->fd > 0) {
61 // now alloc
62 struct goldfish_dma_ioctl_info info;
63 info.size = sz;
64 int alloc_res = ioctl(res->fd, GOLDFISH_DMA_IOC_CREATE_REGION, &info);
65
66 if (alloc_res) {
67 ALOGE("%s: failed to allocate DMA region. errno=%d",
68 __FUNCTION__, errno);
69 close(res->fd);
70 res->fd = -1;
71 return alloc_res;
72 }
73
Roman Kiryanov96a068f2018-06-13 17:05:05 -070074 res->size = sz;
Matt Wachowskif270f582018-08-10 12:47:56 -070075 ALOGV("%s: successfully allocated goldfish DMA region with size %u cxt=%p fd=%d",
Roman Kiryanov96a068f2018-06-13 17:05:05 -070076 __FUNCTION__, sz, res, res->fd);
Lingfeng Yang88c170c2016-11-30 00:52:35 +000077 return 0;
78 } else {
79 ALOGE("%s: could not obtain fd to device! fd %d errno=%d\n",
80 __FUNCTION__, res->fd, errno);
81 return ENODEV;
82 }
83}
84
85void* goldfish_dma_map(struct goldfish_dma_context* cxt) {
86 ALOGV("%s: on fd %d errno=%d", __FUNCTION__, cxt->fd, errno);
Roman Kiryanov96a068f2018-06-13 17:05:05 -070087 void *mapped = mmap(0, cxt->size, PROT_WRITE, MAP_SHARED, cxt->fd, 0);
Matt Wachowskif270f582018-08-10 12:47:56 -070088 ALOGV("%s: cxt=%p mapped=%p size=%u errno=%d",
Roman Kiryanov96a068f2018-06-13 17:05:05 -070089 __FUNCTION__, cxt, mapped, cxt->size, errno);
Lingfeng Yang88c170c2016-11-30 00:52:35 +000090
Roman Kiryanov96a068f2018-06-13 17:05:05 -070091 if (mapped == MAP_FAILED) {
92 mapped = NULL;
Lingfeng Yang88c170c2016-11-30 00:52:35 +000093 }
Roman Kiryanov96a068f2018-06-13 17:05:05 -070094
95 cxt->mapped_addr = reinterpret_cast<uint64_t>(mapped);
96 return mapped;
Lingfeng Yang88c170c2016-11-30 00:52:35 +000097}
98
99int goldfish_dma_unmap(struct goldfish_dma_context* cxt) {
Luca Stefani1cb647a2019-03-07 21:58:17 +0100100 ALOGV("%s: cxt=%p mapped=0x%" PRIu64, __FUNCTION__, cxt, cxt->mapped_addr);
Roman Kiryanov96a068f2018-06-13 17:05:05 -0700101 munmap(reinterpret_cast<void *>(cxt->mapped_addr), cxt->size);
102 cxt->mapped_addr = 0;
103 cxt->size = 0;
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000104 return 0;
105}
106
107void goldfish_dma_write(struct goldfish_dma_context* cxt,
Roman Kiryanov96a068f2018-06-13 17:05:05 -0700108 const void* to_write,
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000109 uint32_t sz) {
David Reveman74e99bb2019-02-15 18:47:25 -0500110 ALOGV("%s: cxt=%p mapped=0x%" PRIu64 " to_write=%p size=%u",
Matt Wachowskif270f582018-08-10 12:47:56 -0700111 __FUNCTION__, cxt, cxt->mapped_addr, to_write, sz);
Roman Kiryanov96a068f2018-06-13 17:05:05 -0700112 memcpy(reinterpret_cast<void *>(cxt->mapped_addr), to_write, sz);
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000113}
114
115void goldfish_dma_free(goldfish_dma_context* cxt) {
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000116 close(cxt->fd);
117}
118
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -0700119uint64_t goldfish_dma_guest_paddr(const struct goldfish_dma_context* cxt) {
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000120 struct goldfish_dma_ioctl_info info;
121 ioctl(cxt->fd, GOLDFISH_DMA_IOC_GETOFF, &info);
122 return info.phys_begin;
123}