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 #include "address_space.h"
26 
27 class GoldfishAddressSpaceBlock;
28 class GoldfishAddressSpaceHostMemoryAllocator;
29 
30 using GoldfishAddressSpaceSubdeviceType = AddressSpaceSubdeviceType;
31 
32 class GoldfishAddressSpaceBlockProvider {
33 public:
34     GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice);
35     ~GoldfishAddressSpaceBlockProvider();
36 
37 private:
38     GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs);
39     GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs);
40 
41     bool is_opened() const;
42     void close();
43     address_space_handle_t release();
44     static void closeHandle(address_space_handle_t handle);
45 
46 #ifdef __Fuchsia__
47     ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceDevice>
48         m_device;
49     ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceChildDriver>
50         m_child_driver;
51 #else // __Fuchsia__
52     address_space_handle_t m_handle;
53 #endif // !__Fuchsia__
54 
55     friend class GoldfishAddressSpaceBlock;
56     friend class GoldfishAddressSpaceHostMemoryAllocator;
57 };
58 
59 class GoldfishAddressSpaceBlock {
60 public:
61     GoldfishAddressSpaceBlock();
62     ~GoldfishAddressSpaceBlock();
63 
64     bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size);
65     bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size);
66     uint64_t physAddr() const;
67     uint64_t hostAddr() const;
offset()68     uint64_t offset() const { return m_offset; }
size()69     size_t size() const { return m_size; }
70     void *mmap(uint64_t opaque);
71     void *guestPtr() const;
72     void replace(GoldfishAddressSpaceBlock *other);
73     void release();
74     static int memoryMap(void *addr, size_t len, address_space_handle_t fd, uint64_t off, void** dst);
75     static void memoryUnmap(void *ptr, size_t size);
76 
77 private:
78     void destroy();
79     GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &);
80 
81 #ifdef __Fuchsia__
82     ::fidl::WireSyncClient<fuchsia_hardware_goldfish::AddressSpaceChildDriver>*
83         m_driver;
84     uint32_t  m_vmo;
85 #else // __Fuchsia__
86     address_space_handle_t m_handle;
87 #endif // !__Fuchsia__
88 
89     void     *m_mmaped_ptr;
90     uint64_t  m_phys_addr;
91     uint64_t  m_host_addr;
92     uint64_t  m_offset;
93     uint64_t  m_size;
94     bool      m_is_shared_mapping;
95 };
96 
97 class GoldfishAddressSpaceHostMemoryAllocator {
98 public:
99     GoldfishAddressSpaceHostMemoryAllocator(bool useSharedSlots);
100 
101     long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size);
102     void hostFree(GoldfishAddressSpaceBlock *block);
103 
104     bool is_opened() const;
release()105     address_space_handle_t release() { return m_provider.release(); }
closeHandle(address_space_handle_t handle)106     static void closeHandle(address_space_handle_t handle) { GoldfishAddressSpaceBlockProvider::closeHandle(handle); }
107 
108 private:
109     GoldfishAddressSpaceBlockProvider m_provider;
110     bool                              m_useSharedSlots;
111 };
112 
113 // Convenience functions that run address space driver api without wrapping in
114 // a class. Useful for when a client wants to manage the driver handle directly
115 // (e.g., mmaping() more than one region associated with a single handle will
116 // require different lifetime expectations versus GoldfishAddressSpaceBlock).
117 
118 address_space_handle_t goldfish_address_space_open();
119 void goldfish_address_space_close(address_space_handle_t);
120 
121 bool goldfish_address_space_allocate(
122     address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
123 bool goldfish_address_space_free(
124     address_space_handle_t, uint64_t offset);
125 
126 bool goldfish_address_space_claim_shared(
127     address_space_handle_t, uint64_t offset, uint64_t size);
128 bool goldfish_address_space_unclaim_shared(
129     address_space_handle_t, uint64_t offset);
130 
131 // pgoff is the offset into the page to return in the result
132 void* goldfish_address_space_map(
133     address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0);
134 void goldfish_address_space_unmap(void* ptr, uint64_t size);
135 
136 bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*);
137 bool goldfish_address_space_ping(address_space_handle_t, struct address_space_ping*);
138 
139 #endif  // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
140