1 // Copyright 2019 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 #include "host-common/HostmemIdMapping.h"
15
16 #include <utility>
17
18 using android::base::ManagedDescriptor;
19
20 namespace android {
21 namespace emulation {
22
23 using Id = uint64_t;
24
25 // static
26 const Id HostmemIdMapping::kInvalidHostmemId = 0;
27
sMapping()28 static HostmemIdMapping* sMapping() {
29 static HostmemIdMapping* s = new HostmemIdMapping;
30 return s;
31 }
32
33 // static
get()34 HostmemIdMapping* HostmemIdMapping::get() {
35 return sMapping();
36 }
37
38 // TODO: Add registerHostmemFixed version that takes a predetermined id,
39 // for snapshots
add(const struct MemEntry * entry)40 Id HostmemIdMapping::add(const struct MemEntry *entry) {
41 if (entry->hva == 0 || entry->size == 0) return kInvalidHostmemId;
42
43 Id wantedId;
44
45 if (entry->register_fixed) {
46 wantedId = entry->fixed_id;
47 mCurrentId = wantedId + 1;
48 } else {
49 wantedId = mCurrentId++;
50 }
51
52 HostmemIdMapping::Entry hostmem_entry;
53 hostmem_entry.id = wantedId;
54 hostmem_entry.hva = entry->hva;
55 hostmem_entry.size = entry->size;
56 hostmem_entry.caching = entry->caching;
57 mEntries.set(wantedId, hostmem_entry);
58 return wantedId;
59 }
60
remove(Id id)61 void HostmemIdMapping::remove(Id id) {
62 mEntries.erase(id);
63 }
64
addMapping(Id id,const struct MemEntry * entry)65 void HostmemIdMapping::addMapping(Id id, const struct MemEntry *entry) {
66 HostmemIdMapping::Entry hostmem_entry;
67 hostmem_entry.id = id;
68 hostmem_entry.hva = entry->hva;
69 hostmem_entry.size = entry->size;
70 hostmem_entry.caching = entry->caching;
71 mEntries.set(id, hostmem_entry);
72 }
73
addDescriptorInfo(Id id,ManagedDescriptor descriptor,uint32_t handleType,uint32_t caching,std::optional<VulkanInfo> vulkanInfoOpt)74 void HostmemIdMapping::addDescriptorInfo(Id id, ManagedDescriptor descriptor,
75 uint32_t handleType, uint32_t caching,
76 std::optional<VulkanInfo> vulkanInfoOpt) {
77 struct ManagedDescriptorInfo info =
78 {
79 .descriptor = std::move(descriptor),
80 .handleType = handleType,
81 .caching = caching,
82 .vulkanInfoOpt = std::move(vulkanInfoOpt),
83 };
84
85
86 mDescriptorInfos.insert(std::make_pair(id, std::move(info)));
87 }
88
removeDescriptorInfo(Id id)89 std::optional<ManagedDescriptorInfo> HostmemIdMapping::removeDescriptorInfo(Id id) {
90 auto found = mDescriptorInfos.find(id);
91 if (found != mDescriptorInfos.end()) {
92 std::optional<ManagedDescriptorInfo> ret = std::move(found->second);
93 mDescriptorInfos.erase(found);
94 return ret;
95 }
96
97 return std::nullopt;
98 }
99
get(Id id) const100 HostmemIdMapping::Entry HostmemIdMapping::get(Id id) const {
101 const HostmemIdMapping::Entry badEntry {
102 kInvalidHostmemId, 0, 0,
103 };
104
105 if (kInvalidHostmemId == id) return badEntry;
106
107 auto entry = mEntries.get(id);
108
109 if (!entry) return badEntry;
110
111 return *entry;
112 }
113
clear()114 void HostmemIdMapping::clear() {
115 mEntries.clear();
116 }
117
118 } // namespace android
119 } // namespace emulation
120
121 // C interface for use with vm operations
122 extern "C" {
123
android_emulation_hostmem_register(const struct MemEntry * entry)124 uint64_t android_emulation_hostmem_register(const struct MemEntry *entry) {
125 return static_cast<uint64_t>(
126 android::emulation::HostmemIdMapping::get()->add(entry));
127 }
128
android_emulation_hostmem_unregister(uint64_t id)129 void android_emulation_hostmem_unregister(uint64_t id) {
130 android::emulation::HostmemIdMapping::get()->remove(id);
131 }
132
android_emulation_hostmem_get_info(uint64_t id)133 HostmemEntry android_emulation_hostmem_get_info(uint64_t id) {
134 return static_cast<HostmemEntry>(
135 android::emulation::HostmemIdMapping::get()->get(id));
136 }
137
138 } // extern "C"
139