tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / mali / linux / mali_ukk_profiling.c
1 /*
2  * Copyright (C) 2011-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         {
29                 return -EFAULT;
30         }
31
32         kargs.ctx = session_data;
33         err = _mali_ukk_profiling_start(&kargs);
34         if (_MALI_OSK_ERR_OK != err)
35         {
36                 return map_errcode(err);
37         }
38
39         if (0 != put_user(kargs.limit, &uargs->limit))
40         {
41                 return -EFAULT;
42         }
43
44         return 0;
45 }
46
47 int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs)
48 {
49         _mali_uk_profiling_add_event_s kargs;
50         _mali_osk_errcode_t err;
51
52         MALI_CHECK_NON_NULL(uargs, -EINVAL);
53
54         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s)))
55         {
56                 return -EFAULT;
57         }
58
59         kargs.ctx = session_data;
60         err = _mali_ukk_profiling_add_event(&kargs);
61         if (_MALI_OSK_ERR_OK != err)
62         {
63                 return map_errcode(err);
64         }
65
66         return 0;
67 }
68
69 int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs)
70 {
71         _mali_uk_profiling_stop_s kargs;
72         _mali_osk_errcode_t err;
73
74         MALI_CHECK_NON_NULL(uargs, -EINVAL);
75
76         kargs.ctx = session_data;
77         err = _mali_ukk_profiling_stop(&kargs);
78         if (_MALI_OSK_ERR_OK != err)
79         {
80                 return map_errcode(err);
81         }
82
83         if (0 != put_user(kargs.count, &uargs->count))
84         {
85                 return -EFAULT;
86         }
87
88         return 0;
89 }
90
91 int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs)
92 {
93         _mali_uk_profiling_get_event_s kargs;
94         _mali_osk_errcode_t err;
95
96         MALI_CHECK_NON_NULL(uargs, -EINVAL);
97
98         if (0 != get_user(kargs.index, &uargs->index))
99         {
100                 return -EFAULT;
101         }
102
103         kargs.ctx = session_data;
104
105         err = _mali_ukk_profiling_get_event(&kargs);
106         if (_MALI_OSK_ERR_OK != err)
107         {
108                 return map_errcode(err);
109         }
110
111         kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
112         if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s)))
113         {
114                 return -EFAULT;
115         }
116
117         return 0;
118 }
119
120 int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs)
121 {
122         _mali_uk_profiling_clear_s kargs;
123         _mali_osk_errcode_t err;
124
125         MALI_CHECK_NON_NULL(uargs, -EINVAL);
126
127         kargs.ctx = session_data;
128         err = _mali_ukk_profiling_clear(&kargs);
129         if (_MALI_OSK_ERR_OK != err)
130         {
131                 return map_errcode(err);
132         }
133
134         return 0;
135 }
136
137 int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
138 {
139         _mali_uk_sw_counters_report_s kargs;
140         _mali_osk_errcode_t err;
141         u32 *counter_buffer;
142
143         MALI_CHECK_NON_NULL(uargs, -EINVAL);
144
145         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s)))
146         {
147                 return -EFAULT;
148         }
149
150         /* make sure that kargs.num_counters is [at least somewhat] sane */
151         if (kargs.num_counters > 10000) {
152                 MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
153                 return -EINVAL;
154         }
155
156         counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
157         if (NULL == counter_buffer)
158         {
159                 return -ENOMEM;
160         }
161
162         if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters))
163         {
164                 kfree(counter_buffer);
165                 return -EFAULT;
166         }
167
168         kargs.ctx = session_data;
169         kargs.counters = counter_buffer;
170
171         err = _mali_ukk_sw_counters_report(&kargs);
172
173         kfree(counter_buffer);
174
175         if (_MALI_OSK_ERR_OK != err)
176         {
177                 return map_errcode(err);
178         }
179
180         return 0;
181 }