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