~thopiekar/arm-mali/libump-sunxi

« back to all changes in this revision

Viewing changes to src/ump_frontend.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_frontend.c
 
19
 *
 
20
 * This file implements the user space API of the UMP API.
 
21
 * It relies heavily on a arch backend to do the communication with the UMP device driver.
 
22
 */
 
23
 
 
24
#include <ump/ump.h>
 
25
#include "ump_internal.h"
 
26
#include "ump_arch.h"
 
27
#include <ump/ump_debug.h>
 
28
#include <ump/ump_osu.h>
 
29
 
 
30
UMP_API_EXPORT ump_result ump_open(void)
 
31
{
 
32
        return ump_arch_open();
 
33
}
 
34
 
 
35
UMP_API_EXPORT void ump_close(void)
 
36
{
 
37
        ump_arch_close();
 
38
}
 
39
 
 
40
UMP_API_EXPORT ump_secure_id ump_secure_id_get(ump_handle memh)
 
41
{
 
42
        ump_mem * mem = (ump_mem*)memh;
 
43
 
 
44
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
45
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid"));
 
46
        UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low"));
 
47
        UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low"));
 
48
 
 
49
        return mem->secure_id;
 
50
}
 
51
 
 
52
UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id)
 
53
{
 
54
        unsigned long size;
 
55
 
 
56
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != secure_id, ("Secure ID is invalid"));
 
57
 
 
58
        size = ump_arch_size_get(secure_id);
 
59
        if (0 != size)
 
60
        {
 
61
                unsigned long cookie;
 
62
                /*
 
63
                 * The UMP memory which the secure_id referes to could now be deleted and re-created
 
64
                 * since we don't have any references to it yet. The mapping below will however fail if
 
65
                 * we have supplied incorrect size, so we are safe.
 
66
                 */
 
67
                void * mapping = ump_arch_map(secure_id, size, UMP_CACHE_DISABLE, &cookie);
 
68
                if (NULL != mapping)
 
69
                {
 
70
                        ump_mem * mem = _ump_osu_calloc(1, sizeof(*mem));
 
71
                        if (NULL != mem)
 
72
                        {
 
73
                                mem->secure_id = secure_id;
 
74
                                mem->mapped_mem = mapping;
 
75
                                mem->size = size;
 
76
                                mem->cookie = cookie;
 
77
                                mem->is_cached = 1; /* Is set to actually check in the ump_cpu_msync_now() function */
 
78
 
 
79
                                _ump_osu_lock_auto_init(&mem->ref_lock, 0, 0, 0);
 
80
                                UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n"));
 
81
                                mem->ref_count = 1;
 
82
 
 
83
                                /* This is called only to set the cache settings in this handle */
 
84
                                ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0);
 
85
 
 
86
                                UMP_DEBUG_PRINT(4, ("UMP handle created for ID %u of size %lu, mapped into address 0x%08lx", mem->secure_id, mem->size, (unsigned long)mem->mapped_mem));
 
87
 
 
88
                                return (ump_handle)mem;
 
89
                        }
 
90
 
 
91
                        ump_arch_unmap(mapping, size, cookie);
 
92
                }
 
93
        }
 
94
 
 
95
        UMP_DEBUG_PRINT(2, ("UMP handle creation failed for ID %u", secure_id));
 
96
 
 
97
        return UMP_INVALID_MEMORY_HANDLE;
 
98
}
 
99
 
 
100
UMP_API_EXPORT unsigned long ump_size_get(ump_handle memh)
 
101
{
 
102
        ump_mem * mem = (ump_mem*)memh;
 
103
 
 
104
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
105
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid"));
 
106
        UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low"));
 
107
        UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low"));
 
108
 
 
109
        return mem->size;
 
110
}
 
111
 
 
112
UMP_API_EXPORT void ump_read(void *dst, ump_handle srch, unsigned long offset, unsigned long length)
 
113
{
 
114
        ump_mem * src = (ump_mem*)srch;
 
115
 
 
116
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != srch, ("Handle is invalid"));
 
117
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != src->secure_id, ("Secure ID is inavlid"));
 
118
        UMP_DEBUG_ASSERT(0 < src->ref_count, ("Reference count too low"));
 
119
        UMP_DEBUG_ASSERT(0 < src->size, ("Memory size of passed handle too low"));
 
120
        UMP_DEBUG_ASSERT(NULL != src->mapped_mem, ("UMP Memory is not mapped"));
 
121
        UMP_DEBUG_ASSERT((src->size) >= (offset + length), ("Requested read beyond end of UMP memory"));
 
122
 
 
123
        _ump_osu_memcpy(dst,(char*)(src->mapped_mem) + offset, length);
 
124
}
 
125
 
 
126
UMP_API_EXPORT void ump_write(ump_handle dsth, unsigned long offset, const void *src, unsigned long length)
 
127
{
 
128
        ump_mem * dst = (ump_mem*)dsth;
 
129
 
 
130
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != dsth, ("Handle is invalid"));
 
131
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != dst->secure_id, ("Secure ID is inavlid"));
 
132
        UMP_DEBUG_ASSERT(0 < dst->ref_count, ("Reference count too low"));
 
133
        UMP_DEBUG_ASSERT(0 < dst->size, ("Memory size of passed handle too low"));
 
134
        UMP_DEBUG_ASSERT(NULL != dst->mapped_mem, ("UMP Memory is not mapped"));
 
135
        UMP_DEBUG_ASSERT((dst->size) >= (offset + length), ("Requested write beyond end of UMP memory"));
 
136
 
 
137
        _ump_osu_memcpy((char*)(dst->mapped_mem) + offset, src, length);
 
138
}
 
139
 
 
140
 
 
141
 
 
142
UMP_API_EXPORT void* ump_mapped_pointer_get(ump_handle memh)
 
143
{
 
144
        ump_mem * mem = (ump_mem*)memh;
 
145
 
 
146
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
147
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid"));
 
148
        UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low"));
 
149
        UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low"));
 
150
        UMP_DEBUG_ASSERT(NULL != mem->mapped_mem, ("Error in mapping pointer (not mapped)"));
 
151
 
 
152
        return mem->mapped_mem;
 
153
}
 
154
 
 
155
 
 
156
 
 
157
UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle memh)
 
158
{
 
159
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
160
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != ((ump_mem*)memh)->secure_id, ("Secure ID is inavlid"));
 
161
        UMP_DEBUG_ASSERT(0 < ((ump_mem*)memh)->ref_count, ("Reference count too low"));
 
162
        UMP_DEBUG_ASSERT(0 < ((ump_mem*)memh)->size, ("Memory size of passed handle too low"));
 
163
        UMP_DEBUG_ASSERT(NULL != ((ump_mem*)memh)->mapped_mem, ("Error in mapping pointer (not mapped)"));
 
164
 
 
165
        /* noop, cos we map in the pointer when handle is created, and unmap it when handle is destroyed */
 
166
}
 
167
 
 
168
 
 
169
 
 
170
UMP_API_EXPORT void ump_reference_add(ump_handle memh)
 
171
{
 
172
        ump_mem * mem = (ump_mem*)memh;
 
173
 
 
174
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
175
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid"));
 
176
        UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low"));
 
177
        UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low"));
 
178
 
 
179
        _ump_osu_lock_wait(mem->ref_lock, _UMP_OSU_LOCKMODE_RW);
 
180
        mem->ref_count += 1;
 
181
        _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW);
 
182
}
 
183
 
 
184
 
 
185
 
 
186
UMP_API_EXPORT void ump_reference_release(ump_handle memh)
 
187
{
 
188
        ump_mem * mem = (ump_mem*)memh;
 
189
 
 
190
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
191
        UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != ((ump_mem*)mem)->secure_id, ("Secure ID is inavlid"));
 
192
        UMP_DEBUG_ASSERT(0 < (((ump_mem*)mem)->ref_count), ("Reference count too low"));
 
193
        UMP_DEBUG_ASSERT(0 < ((ump_mem*)mem)->size, ("Memory size of passed handle too low"));
 
194
        UMP_DEBUG_ASSERT(NULL != ((ump_mem*)mem)->mapped_mem, ("Error in mapping pointer (not mapped)"));
 
195
 
 
196
        _ump_osu_lock_wait(mem->ref_lock, _UMP_OSU_LOCKMODE_RW);
 
197
        mem->ref_count -= 1;
 
198
        if (0 == mem->ref_count)
 
199
        {
 
200
                /* Remove memory mapping, which holds our only reference towards the UMP kernel space driver */
 
201
                ump_arch_unmap(mem->mapped_mem, mem->size, mem->cookie);
 
202
 
 
203
                _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW);
 
204
 
 
205
                /* Free the lock protecting the reference count */
 
206
                _ump_osu_lock_term(mem->ref_lock);
 
207
 
 
208
                /* Free the memory for this handle */
 
209
                _ump_osu_free(mem);
 
210
        } else {
 
211
                _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW);
 
212
        }
 
213
}