~thopiekar/arm-mali/libump-sunxi

« back to all changes in this revision

Viewing changes to src/ump_arch.c

  • Committer: Luc Verhaegen
  • Date: 2014-03-25 21:04:12 UTC
  • Revision ID: git-v1:fa5ad94ac2873793dcca65dafc3ea211de5e7226
import ump r2p4 source

Signed-off-by: Luc Verhaegen <libv@skynet.be>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 * 
 
8
 *       http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
/**
 
18
 * @file ump_arch.c
 
19
 *
 
20
 * UMP arch layer for UMP-UDD
 
21
 */
 
22
 
 
23
#include <ump/ump.h>
 
24
#include "ump_arch.h"
 
25
#include <ump/ump_debug.h>
 
26
 
 
27
#include <ump/ump_uk_types.h>
 
28
#include "ump_uku.h"
 
29
 
 
30
/** Pointer to an OS-Specific context that we should pass in _uku_ calls */
 
31
void *ump_uk_ctx = NULL;
 
32
 
 
33
/** Reference counting of ump_arch_open() and ump_arch_close(). */
 
34
static volatile int ump_ref_count = 0;
 
35
 
 
36
/** Lock for critical section in open/close */
 
37
_ump_osu_lock_t * ump_lock_arch = NULL;
 
38
 
 
39
ump_result ump_arch_open(void)
 
40
{
 
41
        ump_result retval = UMP_OK;
 
42
 
 
43
        _ump_osu_lock_auto_init( &ump_lock_arch, 0, 0, 0 );
 
44
 
 
45
        /* Check that the lock was initialized */
 
46
        if (NULL == ump_lock_arch)
 
47
        {
 
48
                UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to init lock\n"));
 
49
                return UMP_ERROR;
 
50
        }
 
51
 
 
52
        /* Attempt to obtain a lock */
 
53
        if( _UMP_OSU_ERR_OK !=  _ump_osu_lock_wait( ump_lock_arch, _UMP_OSU_LOCKMODE_RW ) )
 
54
        {
 
55
                UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to acquire lock\n"));
 
56
                return UMP_ERROR;
 
57
        }
 
58
 
 
59
        /* ASSERT NEEDED */
 
60
        UMP_DEBUG_ASSERT(0 <= ump_ref_count, ("UMP: Reference count invalid at _ump_base_arch_open()"));
 
61
        ump_ref_count++;
 
62
 
 
63
        if (1 == ump_ref_count)
 
64
        {
 
65
                /* We are the first, open the UMP device driver */
 
66
 
 
67
                if (_UMP_OSU_ERR_OK != _ump_uku_open( &ump_uk_ctx ))
 
68
                {
 
69
                        UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to open UMP device driver\n"));
 
70
                        retval = UMP_ERROR;
 
71
                        ump_ref_count--;
 
72
                }
 
73
        }
 
74
 
 
75
        /* Signal the lock so someone else can use it */
 
76
         _ump_osu_lock_signal( ump_lock_arch, _UMP_OSU_LOCKMODE_RW );
 
77
 
 
78
        return retval;
 
79
}
 
80
 
 
81
 
 
82
 
 
83
void ump_arch_close(void)
 
84
{
 
85
        _ump_osu_lock_auto_init( &ump_lock_arch, 0, 0, 0 );
 
86
 
 
87
        /* Check that the lock was initialized */
 
88
        if(NULL == ump_lock_arch)
 
89
        {
 
90
                UMP_DEBUG_PRINT(1, ("UMP: ump_arch_close() failed to init lock\n"));
 
91
                return;
 
92
        }
 
93
 
 
94
        /* Attempt to obtain a lock */
 
95
        if( _UMP_OSU_ERR_OK !=  _ump_osu_lock_wait( ump_lock_arch, _UMP_OSU_LOCKMODE_RW ) )
 
96
        {
 
97
                UMP_DEBUG_PRINT(1, ("UMP: ump_arch_close() failed to acquire lock\n"));
 
98
                return;
 
99
        }
 
100
 
 
101
        UMP_DEBUG_ASSERT(0 < ump_ref_count, ("UMP: ump_arch_close() called while no references exist"));
 
102
        if (ump_ref_count > 0)
 
103
        {
 
104
                ump_ref_count--;
 
105
                if (0 == ump_ref_count)
 
106
                {
 
107
                        _ump_osu_errcode_t retval = _ump_uku_close(&ump_uk_ctx);
 
108
                        UMP_DEBUG_ASSERT(retval == _UMP_OSU_ERR_OK, ("UMP: Failed to close UMP interface"));
 
109
                        UMP_IGNORE(retval);
 
110
                        ump_uk_ctx = NULL;
 
111
                        _ump_osu_lock_signal( ump_lock_arch, _UMP_OSU_LOCKMODE_RW );
 
112
                        _ump_osu_lock_term( ump_lock_arch ); /* Not 100% thread safe, since another thread can already be waiting for this lock in ump_arch_open() */
 
113
                        ump_lock_arch = NULL;
 
114
                        return;
 
115
                }
 
116
        }
 
117
 
 
118
        /* Signal the lock so someone else can use it */
 
119
         _ump_osu_lock_signal( ump_lock_arch, _UMP_OSU_LOCKMODE_RW );
 
120
}
 
121
 
 
122
 
 
123
 
 
124
ump_secure_id ump_arch_allocate(unsigned long * size, ump_alloc_constraints constraints)
 
125
{
 
126
        _ump_uk_allocate_s call_arg;
 
127
 
 
128
        if ( NULL == size )
 
129
        {
 
130
                return UMP_INVALID_SECURE_ID;
 
131
        }
 
132
 
 
133
        call_arg.ctx = ump_uk_ctx;
 
134
        call_arg.secure_id = UMP_INVALID_SECURE_ID;
 
135
        call_arg.size = *size;
 
136
#ifdef UMP_DEBUG_SKIP_CODE
 
137
        /** Run-time ASSERTing that _ump_uk_api_version_s and ump_alloc_constraints are
 
138
         * interchangable */
 
139
        switch (constraints)
 
140
        {
 
141
        case UMP_REF_DRV_CONSTRAINT_NONE:
 
142
                UMP_DEBUG_ASSERT( UMP_REF_DRV_UK_CONSTRAINT_NONE == constraints, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints") );
 
143
                break;
 
144
        case UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR:
 
145
                UMP_DEBUG_ASSERT( UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR == constraints, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints") );
 
146
                break;
 
147
        default:
 
148
                UMP_DEBUG_ASSERT( 1, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints: %d unrecognized", constraints) );
 
149
                break;
 
150
        }
 
151
#endif
 
152
        call_arg.constraints = (ump_uk_alloc_constraints)constraints;
 
153
 
 
154
        if ( _UMP_OSU_ERR_OK != _ump_uku_allocate(&call_arg) )
 
155
        {
 
156
                return UMP_INVALID_SECURE_ID;
 
157
        }
 
158
 
 
159
        *size = call_arg.size;
 
160
 
 
161
        UMP_DEBUG_PRINT(4, ("UMP: Allocated ID %u, size %ul", call_arg.secure_id, call_arg.size));
 
162
 
 
163
        return call_arg.secure_id;
 
164
}
 
165
 
 
166
 
 
167
 
 
168
unsigned long ump_arch_size_get(ump_secure_id secure_id)
 
169
{
 
170
        _ump_uk_size_get_s dd_size_call_arg;
 
171
 
 
172
        dd_size_call_arg.ctx = ump_uk_ctx;
 
173
        dd_size_call_arg.secure_id = secure_id;
 
174
        dd_size_call_arg.size = 0;
 
175
 
 
176
        if (_UMP_OSU_ERR_OK == _ump_uku_size_get( &dd_size_call_arg ) )
 
177
        {
 
178
                return dd_size_call_arg.size;
 
179
        }
 
180
 
 
181
        return 0;
 
182
}
 
183
 
 
184
 
 
185
void ump_arch_reference_release(ump_secure_id secure_id)
 
186
{
 
187
        _ump_uk_release_s dd_release_call_arg;
 
188
        _ump_osu_errcode_t retval;
 
189
 
 
190
        dd_release_call_arg.ctx = ump_uk_ctx;
 
191
        dd_release_call_arg.secure_id = secure_id;
 
192
 
 
193
        UMP_DEBUG_PRINT(4, ("UMP: Releasing ID %u", secure_id));
 
194
 
 
195
        retval = _ump_uku_release( &dd_release_call_arg );
 
196
        UMP_DEBUG_ASSERT(retval == _UMP_OSU_ERR_OK, ("UMP: Failed to release reference to UMP memory"));
 
197
        UMP_IGNORE(retval);
 
198
}
 
199
 
 
200
 
 
201
void* ump_arch_map(ump_secure_id secure_id, unsigned long size, ump_cache_enabled cache, unsigned long *cookie_out)
 
202
{
 
203
        _ump_uk_map_mem_s dd_map_call_arg;
 
204
 
 
205
        UMP_DEBUG_ASSERT_POINTER( cookie_out );
 
206
 
 
207
        dd_map_call_arg.ctx = ump_uk_ctx;
 
208
        dd_map_call_arg.secure_id = secure_id;
 
209
        dd_map_call_arg.size = size;
 
210
        dd_map_call_arg.is_cached = (u32) (UMP_CACHE_ENABLE==cache);
 
211
 
 
212
        if ( -1 == _ump_uku_map_mem( &dd_map_call_arg ) )
 
213
        {
 
214
                UMP_DEBUG_PRINT(4, ("UMP: Mapping failed for ID %u", secure_id));
 
215
                return NULL;
 
216
        }
 
217
 
 
218
        UMP_DEBUG_PRINT(4, ("Mapped %u at 0x%08lx", secure_id, (unsigned long)dd_map_call_arg.mapping));
 
219
 
 
220
        *cookie_out = dd_map_call_arg.cookie;
 
221
        return dd_map_call_arg.mapping;
 
222
}
 
223
 
 
224
 
 
225
 
 
226
void ump_arch_unmap(void* mapping, unsigned long size, unsigned long cookie)
 
227
{
 
228
        _ump_uk_unmap_mem_s dd_unmap_call_arg;
 
229
 
 
230
        dd_unmap_call_arg.ctx = ump_uk_ctx;
 
231
        dd_unmap_call_arg.mapping = mapping;
 
232
        dd_unmap_call_arg.size = size;
 
233
        dd_unmap_call_arg.cookie = cookie;
 
234
 
 
235
        UMP_DEBUG_PRINT(4, ("Unmapping 0x%08lx", (unsigned long)mapping));
 
236
        _ump_uku_unmap_mem( &dd_unmap_call_arg );
 
237
}
 
238
 
 
239
/** Memory synchronization - cache flushing of mapped memory */
 
240
int ump_arch_msync(ump_secure_id secure_id, void* mapping, unsigned long cookie, void * address, unsigned long size,  ump_cpu_msync_op op)
 
241
{
 
242
        _ump_uk_msync_s dd_msync_call_arg;
 
243
 
 
244
        dd_msync_call_arg.ctx = ump_uk_ctx;
 
245
        dd_msync_call_arg.mapping = mapping;
 
246
        dd_msync_call_arg.address = address;
 
247
        dd_msync_call_arg.size = size;
 
248
        dd_msync_call_arg.op = (ump_uk_msync_op)op;
 
249
        dd_msync_call_arg.cookie = cookie;
 
250
        dd_msync_call_arg.secure_id = secure_id;
 
251
        dd_msync_call_arg.is_cached = 0;
 
252
 
 
253
        UMP_DEBUG_PRINT(4, ("Msync 0x%08lx", (unsigned long)mapping));
 
254
        _ump_uku_msynch( &dd_msync_call_arg );
 
255
        if ( 0==dd_msync_call_arg.is_cached )
 
256
        {
 
257
                UMP_DEBUG_PRINT(4, ("Trying to flush uncached UMP mem ID: %d", secure_id));
 
258
        }
 
259
        return dd_msync_call_arg.is_cached;
 
260
}