1 // Copyright 2018 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 16 #define ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 17 18 #include <inttypes.h> 19 #include <stddef.h> 20 21 #ifdef __Fuchsia__ 22 #include <fidl/fuchsia.hardware.goldfish/cpp/wire.h> 23 #endif 24 25 class GoldfishAddressSpaceBlock; 26 class GoldfishAddressSpaceHostMemoryAllocator; 27 28 #ifdef HOST_BUILD 29 30 namespace android { 31 32 class HostAddressSpaceDevice; 33 34 } // namespace android 35 36 #endif 37 38 #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 46 enum GoldfishAddressSpaceSubdeviceType { 47 NoSubdevice = -1, 48 Graphics = 0, 49 Media = 1, 50 HostMemoryAllocator = 5, 51 SharedSlotsHostMemoryAllocator = 6, 52 VirtioGpuGraphics = 10, 53 }; 54 55 class GoldfishAddressSpaceBlockProvider { 56 public: 57 GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice); 58 ~GoldfishAddressSpaceBlockProvider(); 59 60 private: 61 GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs); 62 GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs); 63 64 bool is_opened() const; 65 void close(); 66 address_space_handle_t release(); 67 static void closeHandle(address_space_handle_t handle); 68 69 #ifdef __Fuchsia__ 70 ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceDevice> 71 m_device; 72 ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceChildDriver> 73 m_child_driver; 74 #else // __Fuchsia__ 75 address_space_handle_t m_handle; 76 #endif // !__Fuchsia__ 77 78 friend class GoldfishAddressSpaceBlock; 79 friend class GoldfishAddressSpaceHostMemoryAllocator; 80 }; 81 82 class GoldfishAddressSpaceBlock { 83 public: 84 GoldfishAddressSpaceBlock(); 85 ~GoldfishAddressSpaceBlock(); 86 87 bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size); 88 bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size); 89 uint64_t physAddr() const; 90 uint64_t hostAddr() const; offset()91 uint64_t offset() const { return m_offset; } size()92 size_t size() const { return m_size; } 93 void *mmap(uint64_t opaque); 94 void *guestPtr() const; 95 void replace(GoldfishAddressSpaceBlock *other); 96 void release(); 97 static int memoryMap(void *addr, size_t len, address_space_handle_t fd, uint64_t off, void** dst); 98 static void memoryUnmap(void *ptr, size_t size); 99 100 private: 101 void destroy(); 102 GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &); 103 104 #ifdef __Fuchsia__ 105 ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceChildDriver>* 106 m_driver; 107 uint32_t m_vmo; 108 #else // __Fuchsia__ 109 address_space_handle_t m_handle; 110 #endif // !__Fuchsia__ 111 112 void *m_mmaped_ptr; 113 uint64_t m_phys_addr; 114 uint64_t m_host_addr; 115 uint64_t m_offset; 116 uint64_t m_size; 117 bool m_is_shared_mapping; 118 }; 119 120 class GoldfishAddressSpaceHostMemoryAllocator { 121 public: 122 GoldfishAddressSpaceHostMemoryAllocator(bool useSharedSlots); 123 124 long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size); 125 void hostFree(GoldfishAddressSpaceBlock *block); 126 127 bool is_opened() const; release()128 address_space_handle_t release() { return m_provider.release(); } closeHandle(address_space_handle_t handle)129 static void closeHandle(address_space_handle_t handle) { GoldfishAddressSpaceBlockProvider::closeHandle(handle); } 130 131 private: 132 GoldfishAddressSpaceBlockProvider m_provider; 133 bool m_useSharedSlots; 134 }; 135 136 // Convenience functions that run address space driver api without wrapping in 137 // a class. Useful for when a client wants to manage the driver handle directly 138 // (e.g., mmaping() more than one region associated with a single handle will 139 // require different lifetime expectations versus GoldfishAddressSpaceBlock). 140 141 // We also expose the ping info struct that is shared between host and guest. 142 struct address_space_ping { 143 uint64_t offset; 144 uint64_t size; 145 uint64_t metadata; 146 uint32_t version; 147 uint32_t wait_fd; 148 uint32_t wait_flags; 149 uint32_t direction; 150 }; 151 152 address_space_handle_t goldfish_address_space_open(); 153 void goldfish_address_space_close(address_space_handle_t); 154 155 bool goldfish_address_space_allocate( 156 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 157 bool goldfish_address_space_free( 158 address_space_handle_t, uint64_t offset); 159 160 bool goldfish_address_space_claim_shared( 161 address_space_handle_t, uint64_t offset, uint64_t size); 162 bool goldfish_address_space_unclaim_shared( 163 address_space_handle_t, uint64_t offset); 164 165 // pgoff is the offset into the page to return in the result 166 void* goldfish_address_space_map( 167 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0); 168 void goldfish_address_space_unmap(void* ptr, uint64_t size); 169 170 bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 171 bool goldfish_address_space_ping(address_space_handle_t, struct address_space_ping*); 172 173 // virtio-gpu version 174 175 struct address_space_virtgpu_hostmem_info { 176 uint32_t id; 177 uint32_t bo; 178 void* ptr; 179 }; 180 181 struct address_space_virtgpu_info { 182 int fd; 183 uint32_t resp_bo; 184 uint32_t resp_resid; 185 void* resp_mapped_ptr; 186 }; 187 188 address_space_handle_t virtgpu_address_space_open(); 189 void virtgpu_address_space_close(address_space_handle_t); 190 191 // Ping with no response 192 bool virtgpu_address_space_ping(address_space_handle_t, struct address_space_ping*); 193 194 bool virtgpu_address_space_create_context_with_subdevice( 195 address_space_handle_t, 196 uint32_t subdevice_type, 197 struct address_space_virtgpu_info* info_out); 198 199 bool virtgpu_address_space_allocate_hostmem( 200 address_space_handle_t fd, 201 size_t size, 202 uint64_t hostmem_id, 203 struct address_space_virtgpu_hostmem_info* hostmem_info_out); 204 205 // Ping with response 206 bool virtgpu_address_space_ping_with_response( 207 struct address_space_virtgpu_info* info, 208 struct address_space_ping* ping); 209 210 // typedef/struct to abstract over goldfish vs virtio-gpu implementations 211 typedef address_space_handle_t (*address_space_open_t)(void); 212 typedef void (*address_space_close_t)(address_space_handle_t); 213 214 typedef bool (*address_space_allocate_t)( 215 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 216 typedef bool (*address_space_free_t)( 217 address_space_handle_t, uint64_t offset); 218 219 typedef bool (*address_space_claim_shared_t)( 220 address_space_handle_t, uint64_t offset, uint64_t size); 221 typedef bool (*address_space_unclaim_shared_t)( 222 address_space_handle_t, uint64_t offset); 223 224 // pgoff is the offset into the page to return in the result 225 typedef void* (*address_space_map_t)( 226 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff); 227 typedef void (*address_space_unmap_t)(void* ptr, uint64_t size); 228 229 typedef bool (*address_space_set_subdevice_type_t)( 230 address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 231 typedef bool (*address_space_ping_t)( 232 address_space_handle_t, struct address_space_ping*); 233 234 // Specific to virtio-gpu 235 typedef bool (*address_space_create_context_with_subdevice_t)( 236 address_space_handle_t, 237 uint32_t subdevice_type, 238 struct address_space_virtgpu_info* info_out); 239 240 typedef bool (*address_space_allocate_hostmem_t)( 241 address_space_handle_t fd, 242 size_t size, 243 uint64_t hostmem_id, 244 struct address_space_virtgpu_hostmem_info* hostmem_info_out); 245 246 typedef bool (*address_space_ping_with_response_t)( 247 struct address_space_virtgpu_info* info, 248 struct address_space_ping* ping); 249 250 struct address_space_ops { 251 address_space_open_t open; 252 address_space_close_t close; 253 address_space_claim_shared_t claim_shared; 254 address_space_unclaim_shared_t unclaim_shared; 255 address_space_map_t map; 256 address_space_unmap_t unmap; 257 address_space_set_subdevice_type_t set_subdevice_type; 258 address_space_ping_t ping; 259 address_space_create_context_with_subdevice_t create_context_with_subdevice; 260 address_space_allocate_hostmem_t allocate_hostmem; 261 address_space_ping_with_response_t ping_with_response; 262 }; 263 264 #endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 265