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
45namespace overlay {
46
47/*
48* Holds base address, offset and the fd
49* */
50class OvMem {
51public:
52    /* ctor init*/
53    explicit OvMem();
54
55    /* dtor DO NOT call close so it can be copied */
56    ~OvMem();
57
58    /* Use libgralloc to retrieve fd, base addr, alloc type */
59    bool open(uint32_t numbufs,
60            uint32_t bufSz, bool isSecure);
61
62    /* close fd. assign base address to invalid*/
63    bool close();
64
65    /* return underlying fd */
66    int getFD() const;
67
68    /* return true if fd is valid and base address is valid */
69    bool valid() const;
70
71    /* dump the state of the object */
72    void dump() const;
73
74    /* return underlying address */
75    void* addr() const;
76
77    /* return underlying offset */
78    uint32_t bufSz() const;
79
80    /* return number of bufs */
81    uint32_t numBufs() const ;
82
83    /* Set / unset secure with MDP */
84    bool setSecure(bool enable);
85
86private:
87    /* actual os fd */
88    int mFd;
89
90    /* points to base addr (mmap)*/
91    void* mBaseAddr;
92
93    /* allocated buffer type determined by gralloc (ashmem, ion, etc) */
94    int mAllocType;
95
96    /* holds buf size sent down by the client */
97    uint32_t mBufSz;
98
99    /* num of bufs */
100    uint32_t mNumBuffers;
101
102    /* gralloc alloc controller */
103    gralloc::IAllocController* mAlloc;
104
105    /*Holds the aligned buffer size used for actual allocation*/
106    uint32_t mBufSzAligned;
107
108    /* Flags if the buffer has been secured by MDP */
109    bool mSecured;
110};
111
112//-------------------Inlines-----------------------------------
113
114using gralloc::IMemAlloc;
115using gralloc::alloc_data;
116
117inline OvMem::OvMem() {
118    mFd = -1;
119    mBaseAddr = MAP_FAILED;
120    mAllocType = 0;
121    mBufSz = 0;
122    mNumBuffers = 0;
123    mSecured = false;
124    mAlloc = gralloc::IAllocController::getInstance();
125}
126
127inline OvMem::~OvMem() { }
128
129inline bool OvMem::open(uint32_t numbufs,
130        uint32_t bufSz, bool isSecure)
131{
132    alloc_data data;
133    int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
134    int err = 0;
135    OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
136    mBufSz = bufSz;
137
138    if(isSecure) {
139        allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP;
140        allocFlags |= GRALLOC_USAGE_PROTECTED;
141        mBufSzAligned = utils::align(bufSz, SIZE_1M);
142        data.align = SIZE_1M;
143    } else {
144        mBufSzAligned = bufSz;
145        data.align = getpagesize();
146    }
147
148    // Allocate uncached rotator buffers
149    allocFlags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
150
151    mNumBuffers = numbufs;
152
153    data.base = 0;
154    data.fd = -1;
155    data.offset = 0;
156    data.size = mBufSzAligned * mNumBuffers;
157    data.uncached = true;
158
159    err = mAlloc->allocate(data, allocFlags);
160    if (err != 0) {
161        ALOGE("OvMem: Error allocating memory");
162        return false;
163    }
164
165    mFd = data.fd;
166    mBaseAddr = data.base;
167    mAllocType = data.allocType;
168
169    if(isSecure) {
170        setSecure(true);
171    }
172
173    return true;
174}
175
176inline bool OvMem::close()
177{
178    int ret = 0;
179
180    if(!valid()) {
181        return true;
182    }
183
184    if(mSecured) {
185        setSecure(false);
186    }
187
188    IMemAlloc* memalloc = mAlloc->getAllocator(mAllocType);
189    ret = memalloc->free_buffer(mBaseAddr, mBufSzAligned * mNumBuffers, 0, mFd);
190    if (ret != 0) {
191        ALOGE("OvMem: error freeing buffer");
192        return false;
193    }
194
195    mFd = -1;
196    mBaseAddr = MAP_FAILED;
197    mAllocType = 0;
198    mBufSz = 0;
199    mBufSzAligned = 0;
200    mNumBuffers = 0;
201    return true;
202}
203
204inline bool OvMem::setSecure(bool enable) {
205    OvFD fbFd;
206    if(!utils::openDev(fbFd, 0, Res::fbPath, O_RDWR)) {
207        ALOGE("OvMem::%s failed to init fb0", __FUNCTION__);
208        return false;
209    }
210    struct msmfb_secure_config config;
211    utils::memset0(config);
212    config.fd = mFd;
213    config.enable = enable;
214    if(!mdp_wrapper::setSecureBuffer(fbFd.getFD(), config)) {
215        ALOGE("OvMem::%s failed enable=%d", __FUNCTION__, enable);
216        fbFd.close();
217        mSecured = false;
218        return false;
219    }
220    fbFd.close();
221    mSecured = enable;
222    return true;
223}
224
225inline bool OvMem::valid() const
226{
227    return (mFd != -1) && (mBaseAddr != MAP_FAILED);
228}
229
230inline int OvMem::getFD() const
231{
232    return mFd;
233}
234
235inline void* OvMem::addr() const
236{
237    return mBaseAddr;
238}
239
240inline uint32_t OvMem::bufSz() const
241{
242    return mBufSz;
243}
244
245inline uint32_t OvMem::numBufs() const
246{
247    return mNumBuffers;
248}
249
250inline void OvMem::dump() const
251{
252    ALOGE("== Dump OvMem start ==");
253    ALOGE("fd=%d addr=%p type=%d bufsz=%u AlignedBufSz=%u",
254           mFd, mBaseAddr, mAllocType, mBufSz, mBufSzAligned);
255    ALOGE("== Dump OvMem end ==");
256}
257
258} // overlay
259
260#endif // OVERLAY_MEM_H
261