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
46namespace overlay {
47
48/*
49* Holds base address, offset and the fd
50* */
51class OvMem {
52public:
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
87private:
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
115using gralloc::IMemAlloc;
116using gralloc::alloc_data;
117
118inline 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
128inline OvMem::~OvMem() { }
129
130inline 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
177inline 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
205inline 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
226inline bool OvMem::valid() const
227{
228    return (mFd != -1) && (mBaseAddr != MAP_FAILED);
229}
230
231inline int OvMem::getFD() const
232{
233    return mFd;
234}
235
236inline void* OvMem::addr() const
237{
238    return mBaseAddr;
239}
240
241inline uint32_t OvMem::bufSz() const
242{
243    return mBufSz;
244}
245
246inline uint32_t OvMem::numBufs() const
247{
248    return mNumBuffers;
249}
250
251inline 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