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