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 <fuchsia/hardware/goldfish/llcpp/fidl.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 std::unique_ptr< 71 llcpp::fuchsia::hardware::goldfish::AddressSpaceDevice::SyncClient> 72 m_device; 73 std::unique_ptr< 74 llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriver::SyncClient> 75 m_child_driver; 76 #else // __Fuchsia__ 77 address_space_handle_t m_handle; 78 #endif // !__Fuchsia__ 79 80 friend class GoldfishAddressSpaceBlock; 81 friend class GoldfishAddressSpaceHostMemoryAllocator; 82 }; 83 84 class GoldfishAddressSpaceBlock { 85 public: 86 GoldfishAddressSpaceBlock(); 87 ~GoldfishAddressSpaceBlock(); 88 89 bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size); 90 bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size); 91 uint64_t physAddr() const; 92 uint64_t hostAddr() const; offset()93 uint64_t offset() const { return m_offset; } size()94 size_t size() const { return m_size; } 95 void *mmap(uint64_t opaque); 96 void *guestPtr() const; 97 void replace(GoldfishAddressSpaceBlock *other); 98 void release(); 99 static int memoryMap(void *addr, size_t len, address_space_handle_t fd, uint64_t off, void** dst); 100 static void memoryUnmap(void *ptr, size_t size); 101 102 private: 103 void destroy(); 104 GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &); 105 106 #ifdef __Fuchsia__ 107 llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriver::SyncClient* 108 m_driver; 109 uint32_t m_vmo; 110 #else // __Fuchsia__ 111 address_space_handle_t m_handle; 112 #endif // !__Fuchsia__ 113 114 void *m_mmaped_ptr; 115 uint64_t m_phys_addr; 116 uint64_t m_host_addr; 117 uint64_t m_offset; 118 uint64_t m_size; 119 bool m_is_shared_mapping; 120 }; 121 122 class GoldfishAddressSpaceHostMemoryAllocator { 123 public: 124 GoldfishAddressSpaceHostMemoryAllocator(bool useSharedSlots); 125 126 long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size); 127 void hostFree(GoldfishAddressSpaceBlock *block); 128 129 bool is_opened() const; release()130 address_space_handle_t release() { return m_provider.release(); } closeHandle(address_space_handle_t handle)131 static void closeHandle(address_space_handle_t handle) { GoldfishAddressSpaceBlockProvider::closeHandle(handle); } 132 133 private: 134 GoldfishAddressSpaceBlockProvider m_provider; 135 bool m_useSharedSlots; 136 }; 137 138 // Convenience functions that run address space driver api without wrapping in 139 // a class. Useful for when a client wants to manage the driver handle directly 140 // (e.g., mmaping() more than one region associated with a single handle will 141 // require different lifetime expectations versus GoldfishAddressSpaceBlock). 142 143 // We also expose the ping info struct that is shared between host and guest. 144 struct address_space_ping { 145 uint64_t offset; 146 uint64_t size; 147 uint64_t metadata; 148 uint32_t version; 149 uint32_t wait_fd; 150 uint32_t wait_flags; 151 uint32_t direction; 152 }; 153 154 address_space_handle_t goldfish_address_space_open(); 155 void goldfish_address_space_close(address_space_handle_t); 156 157 bool goldfish_address_space_allocate( 158 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 159 bool goldfish_address_space_free( 160 address_space_handle_t, uint64_t offset); 161 162 bool goldfish_address_space_claim_shared( 163 address_space_handle_t, uint64_t offset, uint64_t size); 164 bool goldfish_address_space_unclaim_shared( 165 address_space_handle_t, uint64_t offset); 166 167 // pgoff is the offset into the page to return in the result 168 void* goldfish_address_space_map( 169 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0); 170 void goldfish_address_space_unmap(void* ptr, uint64_t size); 171 172 bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 173 bool goldfish_address_space_ping(address_space_handle_t, struct address_space_ping*); 174 175 // virtio-gpu version 176 177 struct address_space_virtgpu_hostmem_info { 178 uint32_t id; 179 uint32_t bo; 180 void* ptr; 181 }; 182 183 struct address_space_virtgpu_info { 184 int fd; 185 uint32_t resp_bo; 186 uint32_t resp_resid; 187 void* resp_mapped_ptr; 188 }; 189 190 address_space_handle_t virtgpu_address_space_open(); 191 void virtgpu_address_space_close(address_space_handle_t); 192 193 // Ping with no response 194 bool virtgpu_address_space_ping(address_space_handle_t, struct address_space_ping*); 195 196 bool virtgpu_address_space_create_context_with_subdevice( 197 address_space_handle_t, 198 uint32_t subdevice_type, 199 struct address_space_virtgpu_info* info_out); 200 201 bool virtgpu_address_space_allocate_hostmem( 202 address_space_handle_t fd, 203 size_t size, 204 uint64_t hostmem_id, 205 struct address_space_virtgpu_hostmem_info* hostmem_info_out); 206 207 // Ping with response 208 bool virtgpu_address_space_ping_with_response( 209 struct address_space_virtgpu_info* info, 210 struct address_space_ping* ping); 211 212 // typedef/struct to abstract over goldfish vs virtio-gpu implementations 213 typedef address_space_handle_t (*address_space_open_t)(void); 214 typedef void (*address_space_close_t)(address_space_handle_t); 215 216 typedef bool (*address_space_allocate_t)( 217 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 218 typedef bool (*address_space_free_t)( 219 address_space_handle_t, uint64_t offset); 220 221 typedef bool (*address_space_claim_shared_t)( 222 address_space_handle_t, uint64_t offset, uint64_t size); 223 typedef bool (*address_space_unclaim_shared_t)( 224 address_space_handle_t, uint64_t offset); 225 226 // pgoff is the offset into the page to return in the result 227 typedef void* (*address_space_map_t)( 228 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff); 229 typedef void (*address_space_unmap_t)(void* ptr, uint64_t size); 230 231 typedef bool (*address_space_set_subdevice_type_t)( 232 address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 233 typedef bool (*address_space_ping_t)( 234 address_space_handle_t, struct address_space_ping*); 235 236 // Specific to virtio-gpu 237 typedef bool (*address_space_create_context_with_subdevice_t)( 238 address_space_handle_t, 239 uint32_t subdevice_type, 240 struct address_space_virtgpu_info* info_out); 241 242 typedef bool (*address_space_allocate_hostmem_t)( 243 address_space_handle_t fd, 244 size_t size, 245 uint64_t hostmem_id, 246 struct address_space_virtgpu_hostmem_info* hostmem_info_out); 247 248 typedef bool (*address_space_ping_with_response_t)( 249 struct address_space_virtgpu_info* info, 250 struct address_space_ping* ping); 251 252 struct address_space_ops { 253 address_space_open_t open; 254 address_space_close_t close; 255 address_space_claim_shared_t claim_shared; 256 address_space_unclaim_shared_t unclaim_shared; 257 address_space_map_t map; 258 address_space_unmap_t unmap; 259 address_space_set_subdevice_type_t set_subdevice_type; 260 address_space_ping_t ping; 261 address_space_create_context_with_subdevice_t create_context_with_subdevice; 262 address_space_allocate_hostmem_t allocate_hostmem; 263 address_space_ping_with_response_t ping_with_response; 264 }; 265 266 #endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 267