1 // Copyright 2016 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 #pragma once
16 
17 #include "aemu/base/Compiler.h"
18 #include "aemu/base/files/Stream.h"
19 #include "aemu/base/Optional.h"
20 #include "aemu/base/synchronization/Lock.h"
21 
22 #include <unordered_map>
23 #include <inttypes.h>
24 
25 using android::base::Optional;
26 using android::base::kNullopt;
27 
28 namespace android {
29 
30 struct DmaBufferInfo {
31     void* hwpipe = nullptr;
32     uint64_t guestAddr = 0;
33     uint64_t bufferSize = 0;
34     Optional<void*> currHostAddr = kNullopt;
35 };
36 
37 using DmaBufferMap = std::unordered_map<uint64_t, DmaBufferInfo>;
38 
39 class DmaMap {
40 public:
41     // Constructor.
42     DmaMap() = default;
43 
44     // Destructor.
45     virtual ~DmaMap() = default;
46 
47     void addBuffer(void* hwpipe, uint64_t addr, uint64_t bufferSize);
48     void removeBuffer(uint64_t addr);
49     void* getHostAddr(uint64_t addr);
50     void invalidateHostMappings();
51     void resetHostMappings();
52     void* getPipeInstance(uint64_t addr);
53 
54     // get() / set are NOT thread-safe,
55     // but we don't expect multiple threads to call this
56     // concurrently at init time, and the worst that can happen is to leak
57     // a single instance. (c.f. VmLock)
58     static DmaMap* get();
59     static DmaMap* set(DmaMap* dmaMap);
60 
61     // Snapshotting.
62     void save(android::base::Stream* stream) const;
63     void load(android::base::Stream* stream);
64 protected:
65 
66     virtual void createMappingLocked(DmaBufferInfo* info);
67     virtual void removeMappingLocked(DmaBufferInfo* info);
68 
69     // These are meant to be replaced by a real implementation
70     // in subclasses.
71     virtual void* doMap(uint64_t addr, uint64_t bufferSize) = 0;
72     virtual void doUnmap(void* mapped, uint64_t bufferSize) = 0;
73 
74     DmaBufferMap mDmaBuffers;
75     android::base::ReadWriteLock mLock;
76     DISALLOW_COPY_ASSIGN_AND_MOVE(DmaMap);
77 };
78 
79 } // namespace android
80