2 * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
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.
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.
10 #include <linux/fs.h> /* file system operations */
11 #include <asm/uaccess.h> /* user space access */
15 #include "mali_kernel_common.h"
16 #include "mali_session.h"
17 #include "mali_ukk_wrappers.h"
19 int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs)
21 _mali_uk_init_mem_s kargs;
22 _mali_osk_errcode_t err;
24 MALI_CHECK_NON_NULL(uargs, -EINVAL);
26 kargs.ctx = session_data;
27 err = _mali_ukk_init_mem(&kargs);
28 if (_MALI_OSK_ERR_OK != err)
30 return map_errcode(err);
33 if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback;
34 if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback;
40 _mali_uk_term_mem_s kargs;
41 kargs.ctx = session_data;
42 err = _mali_ukk_term_mem(&kargs);
43 if (_MALI_OSK_ERR_OK != err)
45 MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n"));
51 int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs)
53 _mali_uk_term_mem_s kargs;
54 _mali_osk_errcode_t err;
56 MALI_CHECK_NON_NULL(uargs, -EINVAL);
58 kargs.ctx = session_data;
59 err = _mali_ukk_term_mem(&kargs);
60 if (_MALI_OSK_ERR_OK != err)
62 return map_errcode(err);
68 int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument)
70 _mali_uk_map_external_mem_s uk_args;
71 _mali_osk_errcode_t err_code;
74 /* the session_data pointer was validated by caller */
75 MALI_CHECK_NON_NULL( argument, -EINVAL);
77 /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
78 if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) )
83 uk_args.ctx = session_data;
84 err_code = _mali_ukk_map_external_mem( &uk_args );
86 if (0 != put_user(uk_args.cookie, &argument->cookie))
88 if (_MALI_OSK_ERR_OK == err_code)
91 _mali_uk_unmap_external_mem_s uk_args_unmap;
93 uk_args_unmap.ctx = session_data;
94 uk_args_unmap.cookie = uk_args.cookie;
95 err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap );
96 if (_MALI_OSK_ERR_OK != err_code)
98 MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n"));
104 /* Return the error that _mali_ukk_free_big_block produced */
105 return map_errcode(err_code);
108 int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument)
110 _mali_uk_unmap_external_mem_s uk_args;
111 _mali_osk_errcode_t err_code;
114 /* the session_data pointer was validated by caller */
115 MALI_CHECK_NON_NULL( argument, -EINVAL);
117 /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
118 if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) )
123 uk_args.ctx = session_data;
124 err_code = _mali_ukk_unmap_external_mem( &uk_args );
126 /* Return the error that _mali_ukk_free_big_block produced */
127 return map_errcode(err_code);
130 #if defined(CONFIG_MALI400_UMP)
131 int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument)
133 _mali_uk_release_ump_mem_s uk_args;
134 _mali_osk_errcode_t err_code;
137 /* the session_data pointer was validated by caller */
138 MALI_CHECK_NON_NULL( argument, -EINVAL);
140 /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
141 if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) )
146 uk_args.ctx = session_data;
147 err_code = _mali_ukk_release_ump_mem( &uk_args );
149 /* Return the error that _mali_ukk_free_big_block produced */
150 return map_errcode(err_code);
153 int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument)
155 _mali_uk_attach_ump_mem_s uk_args;
156 _mali_osk_errcode_t err_code;
159 /* the session_data pointer was validated by caller */
160 MALI_CHECK_NON_NULL( argument, -EINVAL);
162 /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
163 if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) )
168 uk_args.ctx = session_data;
169 err_code = _mali_ukk_attach_ump_mem( &uk_args );
171 if (0 != put_user(uk_args.cookie, &argument->cookie))
173 if (_MALI_OSK_ERR_OK == err_code)
176 _mali_uk_release_ump_mem_s uk_args_unmap;
178 uk_args_unmap.ctx = session_data;
179 uk_args_unmap.cookie = uk_args.cookie;
180 err_code = _mali_ukk_release_ump_mem( &uk_args_unmap );
181 if (_MALI_OSK_ERR_OK != err_code)
183 MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n"));
189 /* Return the error that _mali_ukk_map_external_ump_mem produced */
190 return map_errcode(err_code);
192 #endif /* CONFIG_MALI400_UMP */
194 int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs)
196 _mali_uk_query_mmu_page_table_dump_size_s kargs;
197 _mali_osk_errcode_t err;
199 MALI_CHECK_NON_NULL(uargs, -EINVAL);
200 MALI_CHECK_NON_NULL(session_data, -EINVAL);
202 kargs.ctx = session_data;
204 err = _mali_ukk_query_mmu_page_table_dump_size(&kargs);
205 if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
207 if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT;
212 int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs)
214 _mali_uk_dump_mmu_page_table_s kargs;
215 _mali_osk_errcode_t err;
220 MALI_CHECK_NON_NULL(uargs, -EINVAL);
221 /* the session_data pointer was validated by caller */
225 /* get location of user buffer */
226 if (0 != get_user(buffer, &uargs->buffer)) goto err_exit;
227 /* get size of mmu page table info buffer from user space */
228 if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit;
229 /* verify we can access the whole of the user buffer */
230 if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit;
232 /* allocate temporary buffer (kernel side) to store mmu page table info */
233 kargs.buffer = _mali_osk_valloc(kargs.size);
234 if (NULL == kargs.buffer)
240 kargs.ctx = session_data;
241 err = _mali_ukk_dump_mmu_page_table(&kargs);
242 if (_MALI_OSK_ERR_OK != err)
244 rc = map_errcode(err);
248 /* copy mmu page table info back to user space and update pointers */
249 if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit;
250 if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit;
251 if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit;
252 if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit;
253 if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit;
257 if (kargs.buffer) _mali_osk_vfree(kargs.buffer);