~thopiekar/arm-mali/libump-sunxi

« back to all changes in this revision

Viewing changes to src/ump_ref_drv.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_ref_drv.c
 
19
 *
 
20
 * Implementation of the user space API extensions provided by the reference implementation.
 
21
 */
 
22
 
 
23
#include <ump/ump_ref_drv.h>
 
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
/* Allocate a buffer which can be used directly by hardware, 4kb aligned */
 
31
static ump_handle ump_ref_drv_allocate_internal(unsigned long size, ump_alloc_constraints constraints, ump_cache_enabled cache);
 
32
 
 
33
 
 
34
 
 
35
/* Allocate a buffer which can be used directly by hardware, 4kb aligned */
 
36
ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints constraints)
 
37
{
 
38
        ump_cache_enabled cache= UMP_CACHE_DISABLE;
 
39
        if ( 0!=(constraints&UMP_REF_DRV_CONSTRAINT_USE_CACHE) )
 
40
        {
 
41
                cache = UMP_CACHE_ENABLE;
 
42
        }
 
43
        return ump_ref_drv_allocate_internal(size, constraints, cache);
 
44
}
 
45
 
 
46
UMP_API_EXPORT int ump_cpu_msync_now(ump_handle memh, ump_cpu_msync_op op, void* address, int size)
 
47
{
 
48
        ump_mem * mem = (ump_mem*)memh;
 
49
        UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid"));
 
50
 
 
51
        /* If the op is readout, we do the readout from DD.
 
52
           Else we skip flushing if the userspace handle says that it is uncached */
 
53
        if ((UMP_MSYNC_READOUT_CACHE_ENABLED!=op) && (0 == mem->is_cached) ) return 0;
 
54
 
 
55
        UMP_DEBUG_ASSERT(0 < (((ump_mem*)mem)->ref_count), ("Reference count too low"));
 
56
        UMP_DEBUG_ASSERT((size>=0) && (size <= (int)((ump_mem*)mem)->size), ("Memory size of passed handle too low"));
 
57
        UMP_DEBUG_ASSERT(NULL != ((ump_mem*)mem)->mapped_mem, ("Error in mapping pointer (not mapped)"));
 
58
 
 
59
        if (size > (int)mem->size) size = mem->size;
 
60
 
 
61
        mem->is_cached = ump_arch_msync(mem->secure_id, mem->mapped_mem, mem->cookie, address, size, op);
 
62
        return mem->is_cached ;
 
63
}
 
64
 
 
65
/* Allocate a buffer which can be used directly by hardware, 4kb aligned */
 
66
static ump_handle ump_ref_drv_allocate_internal(unsigned long size, ump_alloc_constraints constraints, ump_cache_enabled cache)
 
67
{
 
68
        ump_secure_id secure_id;
 
69
        unsigned long allocated_size = size;
 
70
 
 
71
        UMP_DEBUG_PRINT(4, ("Allocating UMP memory of size %lu", size));
 
72
 
 
73
        secure_id = ump_arch_allocate(&allocated_size, constraints);
 
74
        if (secure_id != UMP_INVALID_SECURE_ID)
 
75
        {
 
76
                unsigned long cookie;
 
77
                void * mapping;
 
78
 
 
79
                mapping = ump_arch_map(secure_id, allocated_size, cache, &cookie);
 
80
                if (NULL != mapping)
 
81
                {
 
82
                        /*
 
83
                         * PS: By now we have actually increased the ref count in the device driver by 2,
 
84
                         * one for the allocation iteself, and one for the mapping.
 
85
                         */
 
86
                        ump_mem * mem;
 
87
                        mem = _ump_osu_calloc(1, sizeof(*mem));
 
88
                        if (NULL != mem)
 
89
                        {
 
90
                                mem->secure_id = secure_id;
 
91
                                mem->mapped_mem = mapping;
 
92
                                mem->size = allocated_size;
 
93
                                mem->cookie = cookie;
 
94
                                mem->is_cached = 1; /* Default to ON, is disabled later if not */
 
95
 
 
96
                                _ump_osu_lock_auto_init(&mem->ref_lock, 0, 0, 0);
 
97
                                UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n"));
 
98
                                mem->ref_count = 1;
 
99
 
 
100
                                /*
 
101
                                 * ump_arch_allocate() gave us a kernel space reference, and the same did ump_arch_map()
 
102
                                 * We release the one from ump_arch_allocate(), and rely solely on the one from the ump_arch_map()
 
103
                                 * That is, ump_arch_unmap() should now do the final release towards the UMP kernel space driver.
 
104
                                 */
 
105
                                ump_arch_reference_release(secure_id);
 
106
 
 
107
                                /* This is called only to set the cache settings in this handle */
 
108
                                ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0);
 
109
 
 
110
                                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));
 
111
 
 
112
                                return (ump_handle)mem;
 
113
                        }
 
114
 
 
115
                        ump_arch_unmap(mapping, allocated_size, cookie); /* Unmap the memory */
 
116
                        ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */
 
117
                }
 
118
 
 
119
                ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */
 
120
        }
 
121
 
 
122
        UMP_DEBUG_PRINT(4, ("Allocation of UMP memory failed"));
 
123
        return UMP_INVALID_MEMORY_HANDLE;
 
124
}