tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / r4p0_rel0 / linux / mali_ukk_profiling.c
1 /*
2  * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
3  * 
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  * 
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10 #include <linux/fs.h>       /* file system operations */
11 #include <asm/uaccess.h>    /* user space access */
12 #include <linux/slab.h>
13
14 #include "mali_ukk.h"
15 #include "mali_osk.h"
16 #include "mali_kernel_common.h"
17 #include "mali_session.h"
18 #include "mali_ukk_wrappers.h"
19
20 int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs)
21 {
22         _mali_uk_profiling_start_s kargs;
23         _mali_osk_errcode_t err;
24
25         MALI_CHECK_NON_NULL(uargs, -EINVAL);
26
27         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s))) {
28                 return -EFAULT;
29         }
30
31         kargs.ctx = session_data;
32         err = _mali_ukk_profiling_start(&kargs);
33         if (_MALI_OSK_ERR_OK != err) {
34                 return map_errcode(err);
35         }
36
37         if (0 != put_user(kargs.limit, &uargs->limit)) {
38                 return -EFAULT;
39         }
40
41         return 0;
42 }
43
44 int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs)
45 {
46         _mali_uk_profiling_add_event_s kargs;
47         _mali_osk_errcode_t err;
48
49         MALI_CHECK_NON_NULL(uargs, -EINVAL);
50
51         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) {
52                 return -EFAULT;
53         }
54
55         kargs.ctx = session_data;
56         err = _mali_ukk_profiling_add_event(&kargs);
57         if (_MALI_OSK_ERR_OK != err) {
58                 return map_errcode(err);
59         }
60
61         return 0;
62 }
63
64 int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs)
65 {
66         _mali_uk_profiling_stop_s kargs;
67         _mali_osk_errcode_t err;
68
69         MALI_CHECK_NON_NULL(uargs, -EINVAL);
70
71         kargs.ctx = session_data;
72         err = _mali_ukk_profiling_stop(&kargs);
73         if (_MALI_OSK_ERR_OK != err) {
74                 return map_errcode(err);
75         }
76
77         if (0 != put_user(kargs.count, &uargs->count)) {
78                 return -EFAULT;
79         }
80
81         return 0;
82 }
83
84 int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs)
85 {
86         _mali_uk_profiling_get_event_s kargs;
87         _mali_osk_errcode_t err;
88
89         MALI_CHECK_NON_NULL(uargs, -EINVAL);
90
91         if (0 != get_user(kargs.index, &uargs->index)) {
92                 return -EFAULT;
93         }
94
95         kargs.ctx = session_data;
96
97         err = _mali_ukk_profiling_get_event(&kargs);
98         if (_MALI_OSK_ERR_OK != err) {
99                 return map_errcode(err);
100         }
101
102         kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
103         if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s))) {
104                 return -EFAULT;
105         }
106
107         return 0;
108 }
109
110 int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs)
111 {
112         _mali_uk_profiling_clear_s kargs;
113         _mali_osk_errcode_t err;
114
115         MALI_CHECK_NON_NULL(uargs, -EINVAL);
116
117         kargs.ctx = session_data;
118         err = _mali_ukk_profiling_clear(&kargs);
119         if (_MALI_OSK_ERR_OK != err) {
120                 return map_errcode(err);
121         }
122
123         return 0;
124 }
125
126 int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
127 {
128         _mali_uk_sw_counters_report_s kargs;
129         _mali_osk_errcode_t err;
130         u32 *counter_buffer;
131
132         MALI_CHECK_NON_NULL(uargs, -EINVAL);
133
134         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) {
135                 return -EFAULT;
136         }
137
138         /* make sure that kargs.num_counters is [at least somewhat] sane */
139         if (kargs.num_counters > 10000) {
140                 MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
141                 return -EINVAL;
142         }
143
144         counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
145         if (NULL == counter_buffer) {
146                 return -ENOMEM;
147         }
148
149         if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters)) {
150                 kfree(counter_buffer);
151                 return -EFAULT;
152         }
153
154         kargs.ctx = session_data;
155         kargs.counters = counter_buffer;
156
157         err = _mali_ukk_sw_counters_report(&kargs);
158
159         kfree(counter_buffer);
160
161         if (_MALI_OSK_ERR_OK != err) {
162                 return map_errcode(err);
163         }
164
165         return 0;
166 }
167
168