blob: 064f60145dc69e5e0d2bff5fa866e15433ad792a [file] [log] [blame]
Roman Kiryanovdaecd142018-11-14 14:56:27 -08001/*
2 * Copyright (C) 2018 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#ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
16#define ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
17
18#include <inttypes.h>
David Reveman74e99bb2019-02-15 18:47:25 -050019#include <stddef.h>
Roman Kiryanovdaecd142018-11-14 14:56:27 -080020
David Revemanaa65ad62019-05-02 08:23:46 -040021#ifdef __Fuchsia__
Yilong Lib373b392019-10-17 15:30:14 -070022#include <fuchsia/hardware/goldfish/cpp/fidl.h>
David Revemanaa65ad62019-05-02 08:23:46 -040023#endif
24
Roman Kiryanovdaecd142018-11-14 14:56:27 -080025class GoldfishAddressSpaceBlock;
Roman Kiryanov136c39a2019-06-03 19:41:51 -070026class GoldfishAddressSpaceHostMemoryAllocator;
Roman Kiryanovdaecd142018-11-14 14:56:27 -080027
Lingfeng Yangc08fbfb2018-12-05 21:05:17 -080028#ifdef HOST_BUILD
Lingfeng Yanga963ea02019-03-21 21:27:04 -070029
Lingfeng Yang6a777e92019-05-23 16:44:51 -070030namespace android {
Lingfeng Yanga963ea02019-03-21 21:27:04 -070031
Lingfeng Yang6a777e92019-05-23 16:44:51 -070032class HostAddressSpaceDevice;
Lingfeng Yanga963ea02019-03-21 21:27:04 -070033
Lingfeng Yang6a777e92019-05-23 16:44:51 -070034} // namespace android
35
36#endif
37
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070038#if defined(__Fuchsia__)
39 typedef void* address_space_handle_t;
40#elif defined(HOST_BUILD)
41 typedef uint32_t address_space_handle_t;
42#else
43 typedef int address_space_handle_t;
44#endif
45
Lingfeng Yang23fef582019-10-30 18:26:54 -070046enum GoldfishAddressSpaceSubdeviceType {
47 NoSubdevice = -1,
48 Graphics = 0,
bohuaa0d5002019-12-03 15:08:35 -080049 Media = 1,
Lingfeng Yang23fef582019-10-30 18:26:54 -070050 HostMemoryAllocator = 5,
51};
52
Roman Kiryanovdaecd142018-11-14 14:56:27 -080053class GoldfishAddressSpaceBlockProvider {
54public:
Lingfeng Yang23fef582019-10-30 18:26:54 -070055 GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice);
Roman Kiryanovdaecd142018-11-14 14:56:27 -080056 ~GoldfishAddressSpaceBlockProvider();
57
58private:
Roman Kiryanov89393792019-06-03 12:39:16 -070059 GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs);
60 GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs);
Roman Kiryanovdaecd142018-11-14 14:56:27 -080061
Roman Kiryanov89393792019-06-03 12:39:16 -070062 bool is_opened() const;
63 void close();
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070064 address_space_handle_t release();
Roman Kiryanov4126ae32019-10-11 09:30:45 -070065 static void closeHandle(address_space_handle_t handle);
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070066
David Reveman1b2a7792019-04-08 11:30:05 -040067#ifdef __Fuchsia__
Yilong Lib373b392019-10-17 15:30:14 -070068 fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr m_device;
Lingfeng Yang51f58b02019-12-05 13:44:44 -080069 fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr m_child_driver;
Lingfeng Yang6a777e92019-05-23 16:44:51 -070070#else // __Fuchsia__
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070071 address_space_handle_t m_handle;
Lingfeng Yang6a777e92019-05-23 16:44:51 -070072#endif // !__Fuchsia__
Roman Kiryanovdaecd142018-11-14 14:56:27 -080073
Roman Kiryanov89393792019-06-03 12:39:16 -070074 friend class GoldfishAddressSpaceBlock;
Roman Kiryanov136c39a2019-06-03 19:41:51 -070075 friend class GoldfishAddressSpaceHostMemoryAllocator;
Roman Kiryanovdaecd142018-11-14 14:56:27 -080076};
Roman Kiryanovdaecd142018-11-14 14:56:27 -080077
78class GoldfishAddressSpaceBlock {
79public:
80 GoldfishAddressSpaceBlock();
81 ~GoldfishAddressSpaceBlock();
82
83 bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size);
Lingfeng Yang8d04bdd2019-10-19 10:59:53 -070084 bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size);
Roman Kiryanovdaecd142018-11-14 14:56:27 -080085 uint64_t physAddr() const;
86 uint64_t hostAddr() const;
Roman Kiryanov79632592019-06-03 12:31:49 -070087 uint64_t offset() const { return m_offset; }
88 size_t size() const { return m_size; }
Roman Kiryanovdaecd142018-11-14 14:56:27 -080089 void *mmap(uint64_t opaque);
90 void *guestPtr() const;
Roman Kiryanov79632592019-06-03 12:31:49 -070091 void replace(GoldfishAddressSpaceBlock *other);
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070092 void release();
Roman Kiryanov2111c062019-10-14 14:23:51 -070093 static int memoryMap(void *addr, size_t len, address_space_handle_t fd, uint64_t off, void** dst);
Roman Kiryanov4126ae32019-10-11 09:30:45 -070094 static void memoryUnmap(void *ptr, size_t size);
Roman Kiryanovdaecd142018-11-14 14:56:27 -080095
96private:
97 void destroy();
98 GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &);
99
David Reveman5b7c5842019-02-20 01:06:48 -0500100#ifdef __Fuchsia__
Lingfeng Yang51f58b02019-12-05 13:44:44 -0800101 fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* m_driver;
David Reveman5b7c5842019-02-20 01:06:48 -0500102 uint32_t m_vmo;
Lingfeng Yang6a777e92019-05-23 16:44:51 -0700103#else // __Fuchsia__
Roman Kiryanov754c3eb2019-10-10 14:09:23 -0700104 address_space_handle_t m_handle;
Lingfeng Yang6a777e92019-05-23 16:44:51 -0700105#endif // !__Fuchsia__
Lingfeng Yang6a777e92019-05-23 16:44:51 -0700106
Roman Kiryanovdaecd142018-11-14 14:56:27 -0800107 void *m_mmaped_ptr;
108 uint64_t m_phys_addr;
109 uint64_t m_host_addr;
Roman Kiryanov2e9eba72019-05-17 09:25:05 -0700110 uint64_t m_offset;
Roman Kiryanov79632592019-06-03 12:31:49 -0700111 uint64_t m_size;
Lingfeng Yang8d04bdd2019-10-19 10:59:53 -0700112 bool m_is_shared_mapping;
Roman Kiryanovdaecd142018-11-14 14:56:27 -0800113};
114
Roman Kiryanov136c39a2019-06-03 19:41:51 -0700115class GoldfishAddressSpaceHostMemoryAllocator {
116public:
117 GoldfishAddressSpaceHostMemoryAllocator();
118
119 long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size);
120 void hostFree(GoldfishAddressSpaceBlock *block);
121
Roman Kiryanov754c3eb2019-10-10 14:09:23 -0700122 bool is_opened() const;
123 address_space_handle_t release() { return m_provider.release(); }
Roman Kiryanov4126ae32019-10-11 09:30:45 -0700124 static void closeHandle(address_space_handle_t handle) { GoldfishAddressSpaceBlockProvider::closeHandle(handle); }
Roman Kiryanov754c3eb2019-10-10 14:09:23 -0700125
Roman Kiryanov136c39a2019-06-03 19:41:51 -0700126private:
127 GoldfishAddressSpaceBlockProvider m_provider;
128};
129
Lingfeng Yang6000a8e2019-10-19 11:56:56 -0700130// Convenience functions that run address space driver api without wrapping in
131// a class. Useful for when a client wants to manage the driver handle directly
132// (e.g., mmaping() more than one region associated with a single handle will
133// require different lifetime expectations versus GoldfishAddressSpaceBlock).
134
135// We also expose the ping info struct that is shared between host and guest.
136struct goldfish_address_space_ping {
137 uint64_t offset;
138 uint64_t size;
139 uint64_t metadata;
140 uint32_t version;
141 uint32_t wait_fd;
142 uint32_t wait_flags;
143 uint32_t direction;
144};
145
146address_space_handle_t goldfish_address_space_open();
147void goldfish_address_space_close(address_space_handle_t);
148
149bool goldfish_address_space_allocate(
150 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
151bool goldfish_address_space_free(
152 address_space_handle_t, uint64_t offset);
153
154bool goldfish_address_space_claim_shared(
155 address_space_handle_t, uint64_t offset, uint64_t size);
156bool goldfish_address_space_unclaim_shared(
157 address_space_handle_t, uint64_t offset);
158
159// pgoff is the offset into the page to return in the result
160void* goldfish_address_space_map(
161 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0);
162void goldfish_address_space_unmap(void* ptr, uint64_t size);
163
Lingfeng Yang23fef582019-10-30 18:26:54 -0700164bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*);
Lingfeng Yang6000a8e2019-10-19 11:56:56 -0700165bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*);
166
Roman Kiryanove5f1c652019-05-14 11:01:22 -0700167#endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H