1 /*
2 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
31 #ifndef OVERLAY_MEM_H
32 #define OVERLAY_MEM_H
33
34 #include <sys/mman.h>
35 #include <fcntl.h>
36 #include <alloc_controller.h>
37 #include <memalloc.h>
38
39 #include "gralloc_priv.h"
40 #include "overlayUtils.h"
41 #include "mdpWrapper.h"
42
43 #define SIZE_1M 0x00100000
44 #define SIZE_2M 0x00200000
45
46 namespace overlay {
47
48 /*
49 * Holds base address, offset and the fd
50 * */
51 class OvMem {
52 public:
53 /* ctor init*/
54 explicit OvMem();
55
56 /* dtor DO NOT call close so it can be copied */
57 ~OvMem();
58
59 /* Use libgralloc to retrieve fd, base addr, alloc type */
60 bool open(uint32_t numbufs,
61 uint32_t bufSz, bool isSecure);
62
63 /* close fd. assign base address to invalid*/
64 bool close();
65
66 /* return underlying fd */
67 int getFD() const;
68
69 /* return true if fd is valid and base address is valid */
70 bool valid() const;
71
72 /* dump the state of the object */
73 void dump() const;
74
75 /* return underlying address */
76 void* addr() const;
77
78 /* return underlying offset */
79 uint32_t bufSz() const;
80
81 /* return number of bufs */
82 uint32_t numBufs() const ;
83
84 /* Set / unset secure with MDP */
85 bool setSecure(bool enable);
86
87 private:
88 /* actual os fd */
89 int mFd;
90
91 /* points to base addr (mmap)*/
92 void* mBaseAddr;
93
94 /* allocated buffer type determined by gralloc (ashmem, ion, etc) */
95 int mAllocType;
96
97 /* holds buf size sent down by the client */
98 uint32_t mBufSz;
99
100 /* num of bufs */
101 uint32_t mNumBuffers;
102
103 /* gralloc alloc controller */
104 gralloc::IAllocController* mAlloc;
105
106 /*Holds the aligned buffer size used for actual allocation*/
107 uint32_t mBufSzAligned;
108
109 /* Flags if the buffer has been secured by MDP */
110 bool mSecured;
111 };
112
113 //-------------------Inlines-----------------------------------
114
115 using gralloc::IMemAlloc;
116 using gralloc::alloc_data;
117
OvMem()118 inline OvMem::OvMem() {
119 mFd = -1;
120 mBaseAddr = MAP_FAILED;
121 mAllocType = 0;
122 mBufSz = 0;
123 mNumBuffers = 0;
124 mSecured = false;
125 mAlloc = gralloc::IAllocController::getInstance();
126 }
127
~OvMem()128 inline OvMem::~OvMem() { }
129
open(uint32_t numbufs,uint32_t bufSz,bool isSecure)130 inline bool OvMem::open(uint32_t numbufs,
131 uint32_t bufSz, bool isSecure)
132 {
133 alloc_data data;
134 int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
135 int err = 0;
136 OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
137 mBufSz = bufSz;
138
139 if(isSecure) {
140 allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP;
141 allocFlags |= GRALLOC_USAGE_PROTECTED;
142 mBufSzAligned = utils::align(bufSz, SIZE_2M);
143 data.align = SIZE_2M;
144 } else {
145 mBufSzAligned = bufSz;
146 data.align = getpagesize();
147 }
148
149 // Allocate uncached rotator buffers
150 allocFlags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
151
152 mNumBuffers = numbufs;
153
154 data.base = 0;
155 data.fd = -1;
156 data.offset = 0;
157 data.size = mBufSzAligned * mNumBuffers;
158 data.uncached = true;
159
160 err = mAlloc->allocate(data, allocFlags);
161 if (err != 0) {
162 ALOGE("OvMem: Error allocating memory");
163 return false;
164 }
165
166 mFd = data.fd;
167 mBaseAddr = data.base;
168 mAllocType = data.allocType;
169
170 if(isSecure) {
171 setSecure(true);
172 }
173
174 return true;
175 }
176
close()177 inline bool OvMem::close()
178 {
179 int ret = 0;
180
181 if(!valid()) {
182 return true;
183 }
184
185 if(mSecured) {
186 setSecure(false);
187 }
188
189 IMemAlloc* memalloc = mAlloc->getAllocator(mAllocType);
190 ret = memalloc->free_buffer(mBaseAddr, mBufSzAligned * mNumBuffers, 0, mFd);
191 if (ret != 0) {
192 ALOGE("OvMem: error freeing buffer");
193 return false;
194 }
195
196 mFd = -1;
197 mBaseAddr = MAP_FAILED;
198 mAllocType = 0;
199 mBufSz = 0;
200 mBufSzAligned = 0;
201 mNumBuffers = 0;
202 return true;
203 }
204
setSecure(bool enable)205 inline bool OvMem::setSecure(bool enable) {
206 OvFD fbFd;
207 if(!utils::openDev(fbFd, 0, Res::fbPath, O_RDWR)) {
208 ALOGE("OvMem::%s failed to init fb0", __FUNCTION__);
209 return false;
210 }
211 struct msmfb_secure_config config;
212 utils::memset0(config);
213 config.fd = mFd;
214 config.enable = enable;
215 if(!mdp_wrapper::setSecureBuffer(fbFd.getFD(), config)) {
216 ALOGE("OvMem::%s failed enable=%d", __FUNCTION__, enable);
217 fbFd.close();
218 mSecured = false;
219 return false;
220 }
221 fbFd.close();
222 mSecured = enable;
223 return true;
224 }
225
valid()226 inline bool OvMem::valid() const
227 {
228 return (mFd != -1) && (mBaseAddr != MAP_FAILED);
229 }
230
getFD()231 inline int OvMem::getFD() const
232 {
233 return mFd;
234 }
235
addr()236 inline void* OvMem::addr() const
237 {
238 return mBaseAddr;
239 }
240
bufSz()241 inline uint32_t OvMem::bufSz() const
242 {
243 return mBufSz;
244 }
245
numBufs()246 inline uint32_t OvMem::numBufs() const
247 {
248 return mNumBuffers;
249 }
250
dump()251 inline void OvMem::dump() const
252 {
253 ALOGE("== Dump OvMem start ==");
254 ALOGE("fd=%d addr=%p type=%d bufsz=%u AlignedBufSz=%u",
255 mFd, mBaseAddr, mAllocType, mBufSz, mBufSzAligned);
256 ALOGE("== Dump OvMem end ==");
257 }
258
259 } // overlay
260
261 #endif // OVERLAY_MEM_H
262