summaryrefslogtreecommitdiff
path: root/alloc_ump.cpp (plain)
blob: cc073dfa42d91e4c54f4eabbfc97c9ff7a1957ef
1/*
2 * Copyright (C) 2013 ARM Limited. All rights reserved.
3 *
4 * Copyright (C) 2008 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <string.h>
20#include <errno.h>
21#include <pthread.h>
22
23#include <cutils/log.h>
24#include <cutils/atomic.h>
25#include <hardware/hardware.h>
26#include <hardware/gralloc.h>
27
28#include <sys/ioctl.h>
29
30#include "alloc_device.h"
31#include "gralloc_priv.h"
32#include "gralloc_helper.h"
33#include "framebuffer_device.h"
34
35#include <ump/ump.h>
36#include <ump/ump_ref_drv.h>
37
38#if GRALLOC_SIMULATE_FAILURES
39#include <cutils/properties.h>
40
41/* system property keys for controlling simulated UMP allocation failures */
42#define PROP_MALI_TEST_GRALLOC_FAIL_FIRST "mali.test.gralloc.fail_first"
43#define PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL "mali.test.gralloc.fail_interval"
44
45static int __ump_alloc_should_fail()
46{
47
48 static unsigned int call_count = 0;
49 unsigned int first_fail = 0;
50 int fail_period = 0;
51 int fail = 0;
52
53 ++call_count;
54
55 /* read the system properties that control failure simulation */
56 {
57 char prop_value[PROPERTY_VALUE_MAX];
58
59 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_FIRST, prop_value, "0") > 0)
60 {
61 sscanf(prop_value, "%11u", &first_fail);
62 }
63
64 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL, prop_value, "0") > 0)
65 {
66 sscanf(prop_value, "%11u", &fail_period);
67 }
68 }
69
70 /* failure simulation is enabled by setting the first_fail property to non-zero */
71 if (first_fail > 0)
72 {
73 LOGI("iteration %u (fail=%u, period=%u)\n", call_count, first_fail, fail_period);
74
75 fail = (call_count == first_fail) ||
76 (call_count > first_fail && fail_period > 0 && 0 == (call_count - first_fail) % fail_period);
77
78 if (fail)
79 {
80 AERR("failed ump_ref_drv_allocate on iteration #%d\n", call_count);
81 }
82 }
83 return fail;
84}
85#endif
86
87int alloc_backend_alloc(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle)
88{
89 {
90 ump_handle ump_mem_handle;
91 void *cpu_ptr;
92 ump_secure_id ump_id;
93 ump_alloc_constraints constraints;
94
95 size = round_up_to_page_size(size);
96
97 if ( (usage&GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
98 {
99 constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE;
100 }
101 else
102 {
103 constraints = UMP_REF_DRV_CONSTRAINT_NONE;
104 }
105
106#ifdef GRALLOC_SIMULATE_FAILURES
107 /* if the failure condition matches, fail this iteration */
108 if (__ump_alloc_should_fail())
109 {
110 ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
111 }
112 else
113#endif
114 {
115 /* protected memory not supported in UMP */
116 if (!(usage & GRALLOC_USAGE_PROTECTED))
117 {
118 ump_mem_handle = ump_ref_drv_allocate(size, constraints);
119
120 if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
121 {
122 cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);
123 if (NULL != cpu_ptr)
124 {
125 ump_id = ump_secure_id_get(ump_mem_handle);
126 if (UMP_INVALID_SECURE_ID != ump_id)
127 {
128 private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP,
129 usage,
130 size,
131 cpu_ptr,
132 private_handle_t::LOCK_STATE_MAPPED,
133 ump_id,
134 ump_mem_handle);
135
136 if (NULL != hnd)
137 {
138 *pHandle = hnd;
139 return 0;
140 }
141 else
142 {
143 AERR( "gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id );
144 }
145 }
146 else
147 {
148 AERR( "gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle );
149 }
150
151 ump_mapped_pointer_release(ump_mem_handle);
152 }
153 else
154 {
155 AERR( "gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle );
156 }
157
158 ump_reference_release(ump_mem_handle);
159 }
160 else
161 {
162 AERR( "gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints );
163 }
164 }
165 else
166 {
167 AERR( "gralloc_alloc_buffer() protected UMP memory is not supported.");
168 }
169 }
170 return -1;
171 }
172}
173
174int alloc_backend_alloc_framebuffer(private_module_t* m, private_handle_t* hnd, uint32_t idx)
175{
176 hnd->ump_id = m->framebuffer->ump_id;
177 /* create a backing ump memory handle if the framebuffer is exposed as a secure ID */
178 if ( (int)UMP_INVALID_SECURE_ID != hnd->ump_id )
179 {
180 hnd->ump_mem_handle = ump_handle_create_from_secure_id( hnd->ump_id );
181 if ( UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle )
182 {
183 AERR("unable to create UMP handle from secure ID %i\n", hnd->ump_id);
184 return -1;
185 }
186 }
187
188 return 0;
189}
190
191void alloc_backend_alloc_free(private_handle_t const* hnd, private_module_t* m)
192{
193 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
194 {
195 if ( UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle )
196 {
197 ump_reference_release((ump_handle)hnd->ump_mem_handle);
198 }
199 }
200 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
201 {
202 /* Buffer might be unregistered so we need to check for invalid ump handle*/
203 if ( UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle )
204 {
205 ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
206 ump_reference_release((ump_handle)hnd->ump_mem_handle);
207 }
208 }
209 else if ( hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION )
210 {
211 AERR( "Can't free dma_buf memory for handle:%p. Not supported.", hnd);
212 }
213}
214
215int alloc_backend_open(alloc_device_t *dev)
216{
217 ump_result ump_res = ump_open();
218 if (UMP_OK != ump_res)
219 {
220 AERR( "UMP open failed with %d", ump_res );
221 return -1;
222 }
223
224 return 0;
225}
226
227int alloc_backend_close(struct hw_device_t *device)
228{
229 alloc_device_t* dev = reinterpret_cast<alloc_device_t*>(device);
230 if (dev)
231 {
232 ump_close(); // Our UMP memory refs will be released automatically here...
233 }
234 return 0;
235}
236