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/cpp/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 }; 53 54 class GoldfishAddressSpaceBlockProvider { 55 public: 56 GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice); 57 ~GoldfishAddressSpaceBlockProvider(); 58 59 private: 60 GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs); 61 GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs); 62 63 bool is_opened() const; 64 void close(); 65 address_space_handle_t release(); 66 static void closeHandle(address_space_handle_t handle); 67 68 #ifdef __Fuchsia__ 69 fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr m_device; 70 fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr m_child_driver; 71 #else // __Fuchsia__ 72 address_space_handle_t m_handle; 73 #endif // !__Fuchsia__ 74 75 friend class GoldfishAddressSpaceBlock; 76 friend class GoldfishAddressSpaceHostMemoryAllocator; 77 }; 78 79 class GoldfishAddressSpaceBlock { 80 public: 81 GoldfishAddressSpaceBlock(); 82 ~GoldfishAddressSpaceBlock(); 83 84 bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size); 85 bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size); 86 uint64_t physAddr() const; 87 uint64_t hostAddr() const; offset()88 uint64_t offset() const { return m_offset; } size()89 size_t size() const { return m_size; } 90 void *mmap(uint64_t opaque); 91 void *guestPtr() const; 92 void replace(GoldfishAddressSpaceBlock *other); 93 void release(); 94 static int memoryMap(void *addr, size_t len, address_space_handle_t fd, uint64_t off, void** dst); 95 static void memoryUnmap(void *ptr, size_t size); 96 97 private: 98 void destroy(); 99 GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &); 100 101 #ifdef __Fuchsia__ 102 fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* m_driver; 103 uint32_t m_vmo; 104 #else // __Fuchsia__ 105 address_space_handle_t m_handle; 106 #endif // !__Fuchsia__ 107 108 void *m_mmaped_ptr; 109 uint64_t m_phys_addr; 110 uint64_t m_host_addr; 111 uint64_t m_offset; 112 uint64_t m_size; 113 bool m_is_shared_mapping; 114 }; 115 116 class GoldfishAddressSpaceHostMemoryAllocator { 117 public: 118 GoldfishAddressSpaceHostMemoryAllocator(bool useSharedSlots); 119 120 long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size); 121 void hostFree(GoldfishAddressSpaceBlock *block); 122 123 bool is_opened() const; release()124 address_space_handle_t release() { return m_provider.release(); } closeHandle(address_space_handle_t handle)125 static void closeHandle(address_space_handle_t handle) { GoldfishAddressSpaceBlockProvider::closeHandle(handle); } 126 127 private: 128 GoldfishAddressSpaceBlockProvider m_provider; 129 bool m_useSharedSlots; 130 }; 131 132 // Convenience functions that run address space driver api without wrapping in 133 // a class. Useful for when a client wants to manage the driver handle directly 134 // (e.g., mmaping() more than one region associated with a single handle will 135 // require different lifetime expectations versus GoldfishAddressSpaceBlock). 136 137 // We also expose the ping info struct that is shared between host and guest. 138 struct goldfish_address_space_ping { 139 uint64_t offset; 140 uint64_t size; 141 uint64_t metadata; 142 uint32_t version; 143 uint32_t wait_fd; 144 uint32_t wait_flags; 145 uint32_t direction; 146 }; 147 148 address_space_handle_t goldfish_address_space_open(); 149 void goldfish_address_space_close(address_space_handle_t); 150 151 bool goldfish_address_space_allocate( 152 address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset); 153 bool goldfish_address_space_free( 154 address_space_handle_t, uint64_t offset); 155 156 bool goldfish_address_space_claim_shared( 157 address_space_handle_t, uint64_t offset, uint64_t size); 158 bool goldfish_address_space_unclaim_shared( 159 address_space_handle_t, uint64_t offset); 160 161 // pgoff is the offset into the page to return in the result 162 void* goldfish_address_space_map( 163 address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0); 164 void goldfish_address_space_unmap(void* ptr, uint64_t size); 165 166 bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*); 167 bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*); 168 169 #endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H 170