• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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