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 resourceId; 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 // typedef/struct to abstract over goldfish vs virtio-gpu implementations 174 typedef address_space_handle_t (*address_space_open_t)(void); 175 typedef void (*address_space_close_t)(address_space_handle_t); 176 177 typedef bool (*address_space_allocate_t)( 178 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 179 typedef bool (*address_space_free_t)( 180 address_space_handle_t, uint64_t offset); 181 182 typedef bool (*address_space_claim_shared_t)( 183 address_space_handle_t, uint64_t offset, uint64_t size); 184 typedef bool (*address_space_unclaim_shared_t)( 185 address_space_handle_t, uint64_t offset); 186 187 // pgoff is the offset into the page to return in the result 188 typedef void* (*address_space_map_t)( 189 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff); 190 typedef void (*address_space_unmap_t)(void* ptr, uint64_t size); 191 192 typedef bool (*address_space_set_subdevice_type_t)( 193 address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 194 typedef bool (*address_space_ping_t)( 195 address_space_handle_t, struct address_space_ping*); 196 197 struct address_space_ops { 198 address_space_open_t open; 199 address_space_close_t close; 200 address_space_claim_shared_t claim_shared; 201 address_space_unclaim_shared_t unclaim_shared; 202 address_space_map_t map; 203 address_space_unmap_t unmap; 204 address_space_set_subdevice_type_t set_subdevice_type; 205 address_space_ping_t ping; 206 }; 207 208 #endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 209