1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "kmpp_obj"
7
8 #include <linux/types.h>
9
10 #include <string.h>
11 #include <sys/ioctl.h>
12
13 #include "mpp_env.h"
14 #include "mpp_list.h"
15 #include "mpp_lock.h"
16 #include "mpp_debug.h"
17 #include "mpp_common.h"
18 #include "mpp_mem_pool.h"
19 #include "mpp_singleton.h"
20
21 #include "mpp_trie.h"
22 #include "mpp_cfg_io.h"
23 #include "kmpp_ioc.h"
24 #include "kmpp_obj_impl.h"
25
26 #define KMPP_SHM_IOC_MAGIC 'm'
27 #define KMPP_SHM_IOC_QUERY_INFO _IOW(KMPP_SHM_IOC_MAGIC, 1, unsigned int)
28 #define KMPP_SHM_IOC_RELEASE_INFO _IOW(KMPP_SHM_IOC_MAGIC, 2, unsigned int)
29 #define KMPP_SHM_IOC_GET_SHM _IOW(KMPP_SHM_IOC_MAGIC, 3, unsigned int)
30 #define KMPP_SHM_IOC_PUT_SHM _IOW(KMPP_SHM_IOC_MAGIC, 4, unsigned int)
31 #define KMPP_SHM_IOC_DUMP _IOW(KMPP_SHM_IOC_MAGIC, 5, unsigned int)
32
33 #define KMPP_IOCTL_IOC_MAGIC 'i'
34 #define KMPP_IOCTL_IOC_QUERY_INFO _IOW(KMPP_IOCTL_IOC_MAGIC, 1, unsigned int)
35 #define KMPP_IOCTL_IOC_PROC _IOW(KMPP_IOCTL_IOC_MAGIC, 2, unsigned int)
36
37 #define OBJ_DBG_FLOW (0x00000001)
38 #define OBJ_DBG_SHARE (0x00000002)
39 #define OBJ_DBG_ENTRY (0x00000004)
40 #define OBJ_DBG_POOL (0x00000008)
41 #define OBJ_DBG_IOCTL (0x00000010)
42 #define OBJ_DBG_UPDATE (0x00000020)
43 #define OBJ_DBG_SET (0x00000040)
44 #define OBJ_DBG_GET (0x00000080)
45
46 #define obj_dbg(flag, fmt, ...) _mpp_dbg(kmpp_obj_debug, flag, fmt, ## __VA_ARGS__)
47
48 #define obj_dbg_flow(fmt, ...) obj_dbg(OBJ_DBG_FLOW, fmt, ## __VA_ARGS__)
49 #define obj_dbg_share(fmt, ...) obj_dbg(OBJ_DBG_SHARE, fmt, ## __VA_ARGS__)
50 #define obj_dbg_entry(fmt, ...) obj_dbg(OBJ_DBG_ENTRY, fmt, ## __VA_ARGS__)
51 #define obj_dbg_pool(fmt, ...) obj_dbg(OBJ_DBG_POOL, fmt, ## __VA_ARGS__)
52 #define obj_dbg_ioctl(fmt, ...) obj_dbg(OBJ_DBG_IOCTL, fmt, ## __VA_ARGS__)
53 #define obj_dbg_update(fmt, ...) obj_dbg(OBJ_DBG_UPDATE, fmt, ## __VA_ARGS__)
54 #define obj_dbg_set(fmt, ...) obj_dbg(OBJ_DBG_SET, fmt, ## __VA_ARGS__)
55 #define obj_dbg_get(fmt, ...) obj_dbg(OBJ_DBG_GET, fmt, ## __VA_ARGS__)
56
57 #define U64_TO_PTR(ptr) ((void *)(intptr_t)(ptr))
58
59 #define ENTRY_TO_PTR(tbl, entry) (((char *)entry) + tbl->tbl.elem_offset)
60 #define ENTRY_TO_s32_PTR(tbl, entry) ((rk_s32 *)ENTRY_TO_PTR(tbl, entry))
61 #define ENTRY_TO_u32_PTR(tbl, entry) ((rk_u32 *)ENTRY_TO_PTR(tbl, entry))
62 #define ENTRY_TO_s64_PTR(tbl, entry) ((rk_s64 *)ENTRY_TO_PTR(tbl, entry))
63 #define ENTRY_TO_u64_PTR(tbl, entry) ((rk_u64 *)ENTRY_TO_PTR(tbl, entry))
64 #define ENTRY_TO_obj_PTR(tbl, entry) ((KmppObj *)ENTRY_TO_PTR(tbl, entry))
65 #define ENTRY_TO_ptr_PTR(tbl, entry) ((void **)ENTRY_TO_PTR(tbl, entry))
66 #define ENTRY_TO_fp_PTR(tbl, entry) ((void **)ENTRY_TO_PTR(tbl, entry))
67 #define ENTRY_TO_st_PTR(tbl, entry) ((void *)ENTRY_TO_PTR(tbl, entry))
68 #define ENTRY_TO_shm_PTR(tbl, entry) ((void *)ENTRY_TO_PTR(tbl, entry))
69
70 /* 32bit unsigned long pointer */
71 #define ELEM_FLAG_U32_POS(offset) (((offset) & (~31)) / 8)
72 #define ELEM_FLAG_BIT_POS(offset) ((offset) & 31)
73 #define ENTRY_TO_FLAG_PTR(e, entry) ((rk_ul *)((rk_u8 *)entry + ELEM_FLAG_U32_POS(e->tbl.flag_offset)))
74
75 #define ENTRY_SET_FLAG(e, entry) \
76 *ENTRY_TO_FLAG_PTR(e, entry) |= 1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset))
77
78 #define ENTRY_CLR_FLAG(e, entry) \
79 *ENTRY_TO_FLAG_PTR(e, entry) &= ~(1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset)))
80
81 #define ENTRY_TEST_FLAG(e, entry) \
82 (*ENTRY_TO_FLAG_PTR(e, entry) & 1ul << (ELEM_FLAG_BIT_POS(e->tbl.flag_offset))) ? 1 : 0
83
84 typedef struct KmppShmReq_t {
85 /* shm_name - NULL name addresss for shm direct allocation */
86 __u64 shm_name;
87 /* shm_size - share memory size for shm direct allocation */
88 __u32 shm_size;
89 /* shm_flag - share memory allocation flags */
90 __u32 shm_flag;
91 } KmppShmReq;
92
93 /* kernel object share memory get / put ioctl data */
94 typedef struct KmppObjIocArg_t {
95 /* address array element count */
96 __u32 count;
97
98 /* flag for batch operation */
99 __u32 flag;
100
101 /*
102 * at KMPP_SHM_IOC_GET_SHM
103 * name_uaddr - kernel object name in userspace address
104 * obj_sptr - kernel object userspace / kernel address of KmppShmPtr
105 *
106 * at KMPP_SHM_IOC_PUT_SHM
107 * obj_sptr - kernel object userspace / kernel address of KmppShmPtr
108 */
109 union {
110 __u64 name_uaddr[0];
111 /* ioctl object userspace / kernel address */
112 KmppShmPtr obj_sptr[0];
113 KmppShmReq shm_req[0];
114 };
115 } KmppObjIocArg;
116
117 typedef struct KmppObjDefImpl_t {
118 /* userspace objdef */
119 MppCfgObj cfg;
120 MppMemPool pool;
121 /* object define from kernel or userspace */
122 rk_s32 is_kobj;
123 KmppObjInit init;
124 KmppObjDeinit deinit;
125 KmppObjPreset preset;
126 KmppObjDump dump;
127
128 /* comment data of userspace / kernel objdef */
129 MppTrie trie;
130 MppTrie ioctl;
131 /* objdef index in kernel (/dev/kmpp_objs) */
132 rk_s32 index;
133 /* objdef set index in objdefset for ioctl */
134 rk_s32 defs_idx;
135 rk_s32 ref_cnt;
136 /* private data size for priv in KmppObjImpl */
137 rk_s32 priv_size;
138 /* entry size for entry in KmppObjImpl */
139 rk_s32 entry_size;
140 rk_s32 flag_max_pos;
141 rk_s32 flag_offset;
142 /* entry size + flag size for entry in KmppObjImpl */
143 rk_s32 buf_size;
144 /* all size for sizeof(KmppObjImpl) + priv_size + entry_size + flag_size */
145 rk_s32 all_size;
146
147 /* properties */
148 rk_s32 disable_mismatch_log;
149
150 const char *name;
151 } KmppObjDefImpl;
152
153 typedef struct KmppObjImpl_t {
154 const char *name;
155 /* class infomation link */
156 KmppObjDefImpl *def;
157 /* trie for fast access */
158 MppTrie trie;
159 void *priv;
160 KmppShmPtr *shm;
161 void *entry;
162 } KmppObjImpl;
163
164 typedef struct KmppKtrieInfo_t {
165 rk_s32 fd;
166 MppTrie trie;
167 void *root;
168 } KmppKtrieInfo;
169
170 typedef struct KmppObjs_t {
171 KmppKtrieInfo obj;
172 KmppKtrieInfo ioc;
173 rk_s32 count;
174 rk_s32 entry_offset;
175 rk_s32 priv_offset;
176 rk_s32 name_offset;
177 KmppObjDefImpl defs[0];
178 } KmppObjs;
179
180 static rk_u32 kmpp_obj_debug = 0;
181 static KmppObjs *objs = NULL;
182
183 #define get_objs(caller) \
184 ({ \
185 KmppObjs *__tmp; \
186 if (objs) { \
187 __tmp = objs; \
188 } else { \
189 obj_dbg_flow("kmpp objs srv not init at %s\n", caller); \
190 __tmp = NULL; \
191 } \
192 __tmp; \
193 })
194
195 #define get_objs_f() get_objs(__FUNCTION__)
196
strof_elem_type(ElemType type)197 const char *strof_elem_type(ElemType type)
198 {
199 static const char *ELEM_TYPE_names[] = {
200 [ELEM_TYPE_s32] = "s32",
201 [ELEM_TYPE_u32] = "u32",
202 [ELEM_TYPE_s64] = "s64",
203 [ELEM_TYPE_u64] = "u64",
204 [ELEM_TYPE_ptr] = "ptr",
205 [ELEM_TYPE_st] = "struct",
206 [ELEM_TYPE_shm] = "shm_ptr",
207 [ELEM_TYPE_kobj] = "kobj",
208 [ELEM_TYPE_kptr] = "kptr",
209 [ELEM_TYPE_kfp] = "kfunc_ptr",
210 [ELEM_TYPE_uobj] = "uobj",
211 [ELEM_TYPE_uptr] = "uptr",
212 [ELEM_TYPE_ufp] = "ufunc_ptr",
213 };
214 static const char *invalid_type_str = "invalid";
215
216 if (type & (~ELEM_TYPE_BUTT))
217 return invalid_type_str;
218
219 return ELEM_TYPE_names[type] ? ELEM_TYPE_names[type] : invalid_type_str;
220 }
221
222 #define MPP_OBJ_ACCESS_IMPL(type, base_type, log_str) \
223 rk_s32 kmpp_obj_impl_set_##type(KmppEntry *tbl, void *entry, base_type val) \
224 { \
225 base_type *dst = ENTRY_TO_##type##_PTR(tbl, entry); \
226 base_type old = dst[0]; \
227 dst[0] = val; \
228 if (!tbl->tbl.flag_offset) { \
229 obj_dbg_set("%p + %x set " #type " change " #log_str " -> " #log_str "\n", entry, tbl->tbl.elem_offset, old, val); \
230 } else { \
231 if (old != val) { \
232 obj_dbg_set("%p + %x set " #type " update " #log_str " -> " #log_str " flag %d\n", \
233 entry, tbl->tbl.elem_offset, old, val, tbl->tbl.flag_offset); \
234 ENTRY_SET_FLAG(tbl, entry); \
235 } else { \
236 obj_dbg_set("%p + %x set " #type " keep " #log_str "\n", entry, tbl->tbl.elem_offset, old); \
237 } \
238 } \
239 return rk_ok; \
240 } \
241 rk_s32 kmpp_obj_impl_get_##type(KmppEntry *tbl, void *entry, base_type *val) \
242 { \
243 if (tbl && tbl->tbl.elem_size) { \
244 base_type *src = ENTRY_TO_##type##_PTR(tbl, entry); \
245 obj_dbg_get("%p + %x get " #type " value " #log_str "\n", entry, tbl->tbl.elem_offset, src[0]); \
246 val[0] = src[0]; \
247 return rk_ok; \
248 } \
249 return rk_nok; \
250 }
251
252 MPP_OBJ_ACCESS_IMPL(s32, rk_s32, % d)
253 MPP_OBJ_ACCESS_IMPL(u32, rk_u32, % u)
254 MPP_OBJ_ACCESS_IMPL(s64, rk_s64, % #llx)
255 MPP_OBJ_ACCESS_IMPL(u64, rk_u64, % #llx)
256 MPP_OBJ_ACCESS_IMPL(obj, KmppObj, % p)
257 MPP_OBJ_ACCESS_IMPL(ptr, void *, % p)
258 MPP_OBJ_ACCESS_IMPL(fp, void *, % p)
259
260 #define MPP_OBJ_STRUCT_ACCESS_IMPL(type, base_type, log_str) \
261 rk_s32 kmpp_obj_impl_set_##type(KmppEntry *tbl, void *entry, base_type *val) \
262 { \
263 void *dst = ENTRY_TO_##type##_PTR(tbl, entry); \
264 if (!tbl->tbl.flag_offset) { \
265 /* simple copy */ \
266 obj_dbg_set("%p + %x set " #type " size %d change %p -> %p\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst, val); \
267 memcpy(dst, val, tbl->tbl.elem_size); \
268 return rk_ok; \
269 } \
270 /* copy with flag check and updata */ \
271 if (memcmp(dst, val, tbl->tbl.elem_size)) { \
272 obj_dbg_set("%p + %x set " #type " size %d update %p -> %p flag %d\n", \
273 entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst, val, tbl->tbl.flag_offset); \
274 memcpy(dst, val, tbl->tbl.elem_size); \
275 ENTRY_SET_FLAG(tbl, entry); \
276 } else { \
277 obj_dbg_set("%p + %x set " #type " size %d keep %p\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst); \
278 } \
279 return rk_ok; \
280 } \
281 rk_s32 kmpp_obj_impl_get_##type(KmppEntry *tbl, void *entry, base_type *val) \
282 { \
283 if (tbl && tbl->tbl.elem_size) { \
284 void *src = ENTRY_TO_##type##_PTR(tbl, entry); \
285 obj_dbg_get("%p + %x get " #type " size %d value " #log_str "\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, src); \
286 memcpy(val, src, tbl->tbl.elem_size); \
287 return rk_ok; \
288 } \
289 return rk_nok; \
290 }
291
292 MPP_OBJ_STRUCT_ACCESS_IMPL(st, void, % p)
293 MPP_OBJ_STRUCT_ACCESS_IMPL(shm, KmppShmPtr, % p)
294
kmpp_ktrie_get(KmppKtrieInfo * info,const char * path,rk_ul cmd)295 static rk_s32 kmpp_ktrie_get(KmppKtrieInfo *info, const char *path, rk_ul cmd)
296 {
297 rk_s32 fd = open(path, O_RDWR);
298 MppTrie trie = NULL;
299 rk_u64 uaddr = 0;
300 void *root;
301 rk_s32 ret;
302
303 info->fd = fd;
304 info->trie = NULL;
305 info->root = NULL;
306
307 if (fd < 0) {
308 obj_dbg_flow("%s open failed ret fd %d\n", path, fd);
309 return rk_nok;
310 }
311
312 ret = ioctl(fd, cmd, &uaddr);
313 if (ret < 0) {
314 obj_dbg_flow("%s ioctl failed ret %d\n", path, ret);
315 goto __ret;
316 }
317
318 root = (void *)(intptr_t)uaddr;
319 obj_dbg_share("query fd %d root %p from kernel\n", fd, root);
320
321 ret = mpp_trie_init_by_root(&trie, root);
322 if (ret || !trie) {
323 mpp_loge_f("init trie by root failed ret %d\n", ret);
324 goto __ret;
325 }
326
327 if (kmpp_obj_debug & OBJ_DBG_SHARE)
328 mpp_trie_dump_f(trie);
329
330 info->trie = trie;
331 info->root = root;
332
333 __ret:
334 return rk_ok;
335 }
336
kmpp_ktrie_put(KmppKtrieInfo * info)337 rk_s32 kmpp_ktrie_put(KmppKtrieInfo *info)
338 {
339 if (info->fd >= 0) {
340 close(info->fd);
341 info->fd = -1;
342 }
343
344 if (info->trie) {
345 mpp_trie_deinit(info->trie);
346 info->trie = NULL;
347 }
348
349 info->root = NULL;
350
351 return rk_ok;
352 }
353
kmpp_objs_deinit(void)354 static void kmpp_objs_deinit(void)
355 {
356 KmppObjs *p = MPP_FETCH_AND(&objs, NULL);
357
358 obj_dbg_flow("kmpp_objs_deinit objs %p\n", p);
359
360 if (p) {
361 rk_s32 i;
362
363 for (i = 0; i < p->count; i++) {
364 KmppObjDefImpl *impl = &p->defs[i];
365
366 if (impl->pool) {
367 mpp_mem_pool_deinit_f(impl->pool);
368 impl->pool = NULL;
369 }
370
371 if (impl->trie) {
372 mpp_trie_deinit(impl->trie);
373 impl->trie = NULL;
374 }
375
376 if (impl->ioctl) {
377 mpp_trie_deinit(impl->ioctl);
378 impl->ioctl = NULL;
379 }
380 }
381
382 kmpp_ktrie_put(&p->obj);
383 kmpp_ktrie_put(&p->ioc);
384
385 mpp_free(p);
386 }
387 }
388
kmpp_objs_init(void)389 static void kmpp_objs_init(void)
390 {
391 static const char *dev_obj = "/dev/kmpp_objs";
392 static const char *dev_ioc = "/dev/kmpp_ioctl";
393 KmppObjs *p = objs;
394 KmppKtrieInfo obj;
395 KmppKtrieInfo ioc;
396 void *root = NULL;
397 MppTrie trie = NULL;
398 MppTrieInfo *info;
399 rk_s32 offset;
400 rk_s32 count;
401 rk_s32 ret;
402 rk_s32 i;
403
404 if (p) {
405 obj_dbg_flow("objs already inited %p\n", p);
406 kmpp_objs_deinit();
407 p = NULL;
408 }
409
410 mpp_env_get_u32("kmpp_obj_debug", &kmpp_obj_debug, 0);
411
412 /* skip kmpp_ioctls failure and call ioc init first to avoid deinit crash */
413 kmpp_ktrie_get(&ioc, dev_ioc, KMPP_IOCTL_IOC_QUERY_INFO);
414
415 ret = kmpp_ktrie_get(&obj, dev_obj, KMPP_SHM_IOC_QUERY_INFO);
416 if (ret < 0)
417 goto __failed;
418
419 trie = obj.trie;
420 root = obj.root;
421 info = mpp_trie_get_info(trie, "__count");
422 count = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
423
424 p = mpp_calloc_size(KmppObjs, sizeof(KmppObjs) + sizeof(KmppObjDefImpl) * count);
425 if (!p) {
426 mpp_loge_f("alloc objs failed\n");
427 goto __failed;
428 }
429
430 p->obj = obj;
431 p->ioc = ioc;
432 p->count = count;
433
434 info = mpp_trie_get_info(trie, "__offset");
435 offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
436 p->entry_offset = offset;
437 info = mpp_trie_get_info(trie, "__priv");
438 offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
439 p->priv_offset = offset;
440 info = mpp_trie_get_info(trie, "__name_offset");
441 offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
442 p->name_offset = offset;
443
444 obj_dbg_share("count %d object offsets - priv %d name %d entry %d\n", count,
445 p->priv_offset, p->name_offset, p->entry_offset);
446
447 info = mpp_trie_get_info_first(trie);
448
449 for (i = 0; i < count && info; i++) {
450 KmppObjDefImpl *impl = &p->defs[i];
451 const char *name = mpp_trie_info_name(info);
452 MppTrie trie_objdef = NULL;
453 MppTrieInfo *info_objdef;
454
455 offset = *(rk_s32 *)mpp_trie_info_ctx(info);
456 ret = mpp_trie_init_by_root(&trie_objdef, root + offset);
457 if (!trie_objdef) {
458 mpp_loge_f("init %d:%d obj trie failed\n", count, i);
459 break;
460 }
461
462 impl->trie = trie_objdef;
463
464 info_objdef = mpp_trie_get_info(trie_objdef, "__index");
465 impl->index = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : -1;
466 impl->defs_idx = info->index;
467 info_objdef = mpp_trie_get_info(trie_objdef, "__size");
468 impl->entry_size = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : 0;
469 impl->name = name;
470 impl->is_kobj = 1;
471
472 info = mpp_trie_get_info_next(trie, info);
473 obj_dbg_share("%2d:%2d - %s offset %d entry_size %d\n",
474 count, i, name, offset, impl->entry_size);
475
476 obj_dbg_flow("objdef %-16s in kernel size %4d\n",
477 name, impl->entry_size);
478
479 /* check ioctl functions */
480 if (ioc.root) {
481 MppTrieInfo *ioc_info = mpp_trie_get_info(ioc.trie, name);
482
483 if (ioc_info) {
484 rk_s32 ioc_offset = *(rk_s32 *)mpp_trie_info_ctx(ioc_info);
485
486 mpp_trie_init_by_root(&impl->ioctl, ioc.root + ioc_offset);
487 if (impl->ioctl)
488 obj_dbg_flow("objdef %-16s in kernel support ioctl %d\n",
489 name, mpp_trie_get_info_count(impl->ioctl));
490 }
491 }
492 }
493
494 objs = p;
495
496 return;
497
498 __failed:
499 kmpp_ktrie_put(&obj);
500 kmpp_ktrie_put(&ioc);
501 }
502
503 MPP_SINGLETON(MPP_SGLN_KOBJ, kmpp_obj, kmpp_objs_init, kmpp_objs_deinit);
504
kmpp_objdef_put(KmppObjDef def)505 rk_s32 kmpp_objdef_put(KmppObjDef def)
506 {
507 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
508 rk_s32 ret = rk_nok;
509
510 if (impl) {
511 rk_s32 release = 0;
512
513 if (impl->is_kobj) {
514 impl->ref_cnt--;
515 if (!impl->ref_cnt)
516 release = 1;
517 else
518 mpp_loge_f("objdef %-16s non-zero ref_cnt %d\n",
519 impl->name, impl->ref_cnt);
520 } else {
521 if (impl->cfg) {
522 mpp_cfg_put_all(impl->cfg);
523 impl->cfg = NULL;
524 }
525 release = 1;
526 }
527
528 if (release) {
529 if (impl->pool) {
530 mpp_mem_pool_deinit_f(impl->pool);
531 impl->pool = NULL;
532 }
533
534 if (impl->trie) {
535 mpp_trie_deinit(impl->trie);
536 impl->trie = NULL;
537 }
538 }
539
540 if (!impl->is_kobj)
541 mpp_free(impl);
542
543 ret = rk_ok;
544 }
545
546 return ret;
547 }
548
kmpp_objdef_register(KmppObjDef * def,rk_s32 priv_size,rk_s32 size,const char * name)549 rk_s32 kmpp_objdef_register(KmppObjDef *def, rk_s32 priv_size, rk_s32 size, const char *name)
550 {
551 KmppObjDefImpl *impl = NULL;
552 rk_s32 name_len;
553 rk_s32 name_buf_size;
554 char *buf;
555
556 if (!def || !name || size <= 0) {
557 mpp_loge_f("invalid param def %p size %d name %p\n", def, size, name);
558 return rk_nok;
559 }
560
561 *def = NULL;
562 name_len = strlen(name);
563 name_buf_size = MPP_ALIGN(name_len + 1, sizeof(rk_s32));
564 impl = mpp_calloc_size(KmppObjDefImpl, sizeof(KmppObjDefImpl) + name_buf_size);
565 if (!impl) {
566 mpp_loge_f("alloc objdef size %d failed\n", sizeof(KmppObjDefImpl) + name_buf_size);
567 return rk_nok;
568 }
569
570 buf = (char *)(impl + 1);
571 memcpy(buf, name, name_len);
572 buf[name_len] = '\0';
573 impl->name = buf;
574 impl->priv_size = MPP_ALIGN(priv_size, sizeof(void *));
575 impl->entry_size = size;
576 impl->buf_size = size + sizeof(KmppObjImpl);
577 impl->ref_cnt = 1;
578
579 obj_dbg_flow("objdef %-16s registered size %4d\n", name, size, impl);
580
581 *def = impl;
582
583 return rk_ok;
584 }
585
kmpp_objdef_find(KmppObjDef * def,const char * name)586 rk_s32 kmpp_objdef_find(KmppObjDef *def, const char *name)
587 {
588 KmppObjs *p = get_objs_f();
589 MppTrieInfo *info = NULL;
590
591 if (!def || !name) {
592 mpp_loge_f("invalid param def %p name %p objs %p\n", def, name, p);
593 return rk_nok;
594 }
595
596 *def = NULL;
597
598 if (!p)
599 return rk_nok;
600
601 info = mpp_trie_get_info(p->obj.trie, name);
602 if (!info) {
603 obj_dbg_flow("objdef %-16s can not be found in kernel\n", name);
604 return rk_nok;
605 }
606
607 if (p->count > 0 && info->index < (RK_U32)p->count) {
608 *def = &p->defs[info->index];
609 return rk_ok;
610 }
611
612 mpp_loge_f("objdef %-16s is found but with invalid index %d max %d\n",
613 name, info->index, p->count);
614
615 return rk_nok;
616 }
617
create_objdef_mem_pool(KmppObjDefImpl * impl)618 static rk_s32 create_objdef_mem_pool(KmppObjDefImpl *impl)
619 {
620 rk_s32 old_size = impl->all_size;
621
622 /* When last entry finish update and create memory pool */
623 if (impl->flag_max_pos) {
624 rk_s32 flag_max_pos = MPP_ALIGN(impl->flag_max_pos, 8);
625 rk_s32 flag_size = flag_max_pos / 8;
626
627 impl->flag_offset = impl->entry_size;
628 impl->flag_max_pos = flag_max_pos;
629
630 flag_size -= impl->entry_size;
631 flag_size = MPP_ALIGN(flag_size, 4);
632
633 impl->buf_size = impl->entry_size + flag_size;
634 }
635
636 impl->all_size = sizeof(KmppObjImpl) + impl->priv_size + impl->buf_size;
637
638 obj_dbg_pool("objdef %-16s entry size %4d buf size %4d -> %4d\n", impl->name,
639 impl->entry_size, old_size, impl->all_size);
640
641 impl->pool = mpp_mem_pool_init_f(impl->name, impl->all_size);
642 if (!impl->pool)
643 mpp_loge_f("get mem pool size %d failed\n", impl->all_size);
644
645 return impl->pool ? rk_ok : rk_nok;
646 }
647
kmpp_objdef_get(KmppObjDef * def,rk_s32 priv_size,const char * name)648 rk_s32 kmpp_objdef_get(KmppObjDef *def, rk_s32 priv_size, const char *name)
649 {
650 KmppObjDefImpl *impl = NULL;
651
652 if (!def || !name) {
653 mpp_loge_f("invalid param def %p name %p\n", def, name);
654 return rk_nok;
655 }
656
657 if (kmpp_objdef_find((KmppObjDef *)&impl, name)) {
658 *def = NULL;
659 return rk_nok;
660 }
661
662 mpp_assert(impl);
663 impl->priv_size = priv_size;
664 create_objdef_mem_pool(impl);
665 if (impl->ref_cnt)
666 mpp_logw_f("objdef %-16s already get ref %d\n", name, impl->ref_cnt);
667 else
668 impl->ref_cnt++;
669
670 *def = impl;
671
672 return rk_ok;
673 }
674
kmpp_objdef_add_cfg_root(KmppObjDef def,MppCfgObj root)675 rk_s32 kmpp_objdef_add_cfg_root(KmppObjDef def, MppCfgObj root)
676 {
677 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
678 rk_s32 ret = rk_nok;
679
680 if (impl) {
681 impl->cfg = root;
682 ret = rk_ok;
683 }
684
685 return ret;
686 }
687
kmpp_objdef_get_cfg_root(KmppObjDef def)688 MppCfgObj kmpp_objdef_get_cfg_root(KmppObjDef def)
689 {
690 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
691
692 return impl ? impl->cfg : NULL;
693 }
694
kmpp_objdef_add_entry(KmppObjDef def,const char * name,KmppEntry * tbl)695 rk_s32 kmpp_objdef_add_entry(KmppObjDef def, const char *name, KmppEntry *tbl)
696 {
697 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
698 rk_s32 ret = rk_nok;
699
700 if (!impl->trie) {
701 if (!name) {
702 /* NOTE: no entry objdef still need to create mempool */
703 return create_objdef_mem_pool(impl);
704 }
705
706 mpp_trie_init(&impl->trie, impl->name);
707 }
708
709 if (impl->trie) {
710 MppTrie trie = impl->trie;
711
712 if (name) {
713 ret = mpp_trie_add_info(trie, name, tbl, tbl ? sizeof(*tbl) : 0);
714
715 if (tbl->tbl.flag_offset > impl->flag_max_pos)
716 impl->flag_max_pos = tbl->tbl.flag_offset;
717
718 obj_dbg_entry("objdef %-16s add entry %-16s flag offset %4d\n",
719 impl->name, name, tbl->tbl.flag_offset);
720 } else {
721 /* record object impl size */
722 ret = mpp_trie_add_info(trie, "__index", &impl->index, sizeof(rk_s32));
723 ret = mpp_trie_add_info(trie, "__size", &impl->entry_size, sizeof(rk_s32));
724 ret |= mpp_trie_add_info(trie, NULL, NULL, 0);
725 ret |= create_objdef_mem_pool(impl);
726 }
727 }
728
729 if (ret)
730 mpp_loge("objdef %s add entry %s failed ret %d\n", impl ? impl->name : NULL, name, ret);
731
732 return ret;
733 }
734
kmpp_objdef_add_init(KmppObjDef def,KmppObjInit init)735 rk_s32 kmpp_objdef_add_init(KmppObjDef def, KmppObjInit init)
736 {
737 if (def) {
738 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
739
740 impl->init = init;
741 return rk_ok;
742 }
743
744 return rk_nok;
745 }
746
kmpp_objdef_add_deinit(KmppObjDef def,KmppObjDeinit deinit)747 rk_s32 kmpp_objdef_add_deinit(KmppObjDef def, KmppObjDeinit deinit)
748 {
749 if (def) {
750 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
751
752 impl->deinit = deinit;
753 return rk_ok;
754 }
755
756 return rk_nok;
757 }
758
kmpp_objdef_add_preset(KmppObjDef def,KmppObjPreset preset)759 rk_s32 kmpp_objdef_add_preset(KmppObjDef def, KmppObjPreset preset)
760 {
761 if (def) {
762 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
763
764 impl->preset = preset;
765 return rk_ok;
766 }
767
768 return rk_nok;
769 }
770
kmpp_objdef_add_dump(KmppObjDef def,KmppObjDump dump)771 rk_s32 kmpp_objdef_add_dump(KmppObjDef def, KmppObjDump dump)
772 {
773 if (def) {
774 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
775
776 impl->dump = dump;
777 return rk_ok;
778 }
779
780 return rk_nok;
781 }
782
kmpp_objdef_set_prop(KmppObjDef def,const char * op,rk_s32 value)783 rk_s32 kmpp_objdef_set_prop(KmppObjDef def, const char *op, rk_s32 value)
784 {
785 if (def && op) {
786 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
787
788 if (!strcmp(op, "disable_mismatch_log")) {
789 impl->disable_mismatch_log = value ? 1 : 0;
790 } else {
791 mpp_loge_f("unknown property %s value %d\n", op, value);
792 return rk_nok;
793 }
794
795 return rk_ok;
796 }
797
798 return rk_nok;
799 }
800
kmpp_objdef_get_entry(KmppObjDef def,const char * name,KmppEntry ** tbl)801 rk_s32 kmpp_objdef_get_entry(KmppObjDef def, const char *name, KmppEntry **tbl)
802 {
803 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
804 rk_s32 ret = rk_nok;
805
806 if (impl->trie) {
807 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
808
809 if (info) {
810 *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
811 ret = rk_ok;
812 }
813 }
814
815 if (ret && !impl->disable_mismatch_log)
816 mpp_loge("objdef %s get entry %s failed ret %d\n",
817 impl ? impl->name : NULL, name, ret);
818
819 return ret;
820 }
821
kmpp_objdef_get_offset(KmppObjDef def,const char * name)822 rk_s32 kmpp_objdef_get_offset(KmppObjDef def, const char *name)
823 {
824 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
825 rk_s32 offset = -1;
826
827 if (impl->trie) {
828 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
829
830 if (info) {
831 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
832
833 if (tbl)
834 offset = tbl->tbl.elem_offset;
835 }
836 }
837
838 return offset;
839 }
840
kmpp_objdef_get_cmd(KmppObjDef def,const char * name)841 rk_s32 kmpp_objdef_get_cmd(KmppObjDef def, const char *name)
842 {
843 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
844
845 if (impl->ioctl) {
846 MppTrieInfo *info = mpp_trie_get_info(impl->ioctl, name);
847
848 if (info)
849 return info->index;
850 }
851
852 return -1;
853 }
854
kmpp_objdef_dump(KmppObjDef def)855 rk_s32 kmpp_objdef_dump(KmppObjDef def)
856 {
857 if (def) {
858 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
859 MppTrie trie = impl->trie;
860 MppTrieInfo *info = NULL;
861 const char *name = impl->name;
862 RK_S32 i = 0;
863
864 mpp_logi("dump objdef %-16s entry_size %d element count %d\n",
865 name, impl->entry_size, mpp_trie_get_info_count(trie));
866
867 info = mpp_trie_get_info_first(trie);
868 while (info) {
869 name = mpp_trie_info_name(info);
870 if (!strstr(name, "__")) {
871 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
872 rk_s32 idx = i++;
873
874 mpp_logi("%-2d - %-16s offset %4d size %d\n", idx,
875 name, tbl->tbl.elem_offset, tbl->tbl.elem_size);
876 }
877 info = mpp_trie_get_info_next(trie, info);
878 }
879
880 info = mpp_trie_get_info_first(trie);
881 while (info) {
882 name = mpp_trie_info_name(info);
883 if (strstr(name, "__")) {
884 void *p = mpp_trie_info_ctx(info);
885 rk_s32 idx = i++;
886
887 if (info->ctx_len == sizeof(RK_U32)) {
888
889 mpp_logi("%-2d - %-16s val %d\n", idx, name, *(RK_U32 *)p);
890 } else {
891 mpp_logi("%-2d - %-16s str %s\n", idx, name, p);
892 }
893 }
894 info = mpp_trie_get_info_next(trie, info);
895 }
896
897 return rk_ok;
898 }
899
900 return rk_nok;
901 }
902
kmpp_objdef_get_name(KmppObjDef def)903 const char *kmpp_objdef_get_name(KmppObjDef def)
904 {
905 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
906
907 return impl ? impl->name : NULL;
908 }
909
kmpp_objdef_get_entry_size(KmppObjDef def)910 rk_s32 kmpp_objdef_get_entry_size(KmppObjDef def)
911 {
912 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
913
914 return impl ? impl->entry_size : 0;
915 }
916
kmpp_objdef_get_trie(KmppObjDef def)917 MppTrie kmpp_objdef_get_trie(KmppObjDef def)
918 {
919 KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
920
921 return impl ? impl->trie : NULL;
922 }
923
924 #define get_obj_from_def(p, def, shm, caller) \
925 _get_obj_from_def(p, def, shm, caller, __FUNCTION__)
926
_get_obj_from_def(KmppObjs * p,KmppObjDefImpl * def,KmppShmPtr * shm,const char * caller,const char * func)927 static KmppObjImpl *_get_obj_from_def(KmppObjs *p, KmppObjDefImpl *def, KmppShmPtr *shm,
928 const char *caller, const char *func)
929 {
930 KmppObjImpl *impl = mpp_mem_pool_get(def->pool, caller);
931 rk_u8 *base;
932
933 if (!impl) {
934 mpp_loge("%s get obj %s impl %d failed at %s\n",
935 func, def->name, def->all_size, caller);
936 return NULL;
937 }
938
939 base = (rk_u8 *)(impl + 1);
940 impl->name = def->name;
941 impl->def = def;
942 impl->trie = def->trie;
943
944 if (def->priv_size) {
945 impl->priv = base;
946 base += def->priv_size;
947 } else {
948 impl->priv = NULL;
949 }
950
951 if (shm && p) {
952 impl->shm = shm;
953 impl->entry = (void *)(shm->uptr + p->entry_offset);
954
955 /* write userspace object address to share memory userspace private value */
956 *(RK_U64 *)(shm->uptr + p->priv_offset) = (RK_U64)(intptr_t)impl;
957
958 obj_dbg_flow("%s get kobj %-16s - %p entry [u:k] %llx:%llx at %s\n", func,
959 def->name, impl, shm->uaddr, shm->kaddr, caller);
960 } else {
961 impl->shm = NULL;
962 impl->entry = base;
963
964 obj_dbg_flow("%s get uobj %-16s - %p entry %p at %s\n", func,
965 def->name, impl, base, caller);
966 }
967
968 if (def->init)
969 def->init(impl->entry, impl, caller);
970
971 return impl;
972 }
973
kmpp_obj_get(KmppObj * obj,KmppObjDef def,const char * caller)974 rk_s32 kmpp_obj_get(KmppObj *obj, KmppObjDef def, const char *caller)
975 {
976 KmppObjs *p;
977 KmppObjDefImpl *def_impl;
978 KmppObjIocArg *ioc;
979 rk_u64 uaddr;
980 rk_s32 ret = rk_nok;
981
982 if (!obj || !def) {
983 mpp_loge_f("invalid param obj %p def %p at %s\n", obj, def, caller);
984 return ret;
985 }
986
987 *obj = NULL;
988
989 def_impl = (KmppObjDefImpl *)def;
990
991 /* use buf_size to check userspace objdef or kernel objdef */
992 if (!def_impl->pool) {
993 mpp_loge_f("invalid objdef %s without pool at %s\n", def_impl->name, caller);
994 return ret;
995 }
996
997 /* userspace objdef path */
998 if (!def_impl->is_kobj) {
999 *obj = get_obj_from_def(NULL, def_impl, NULL, caller);
1000
1001 return *obj ? rk_ok : rk_nok;
1002 }
1003
1004 /* kernel objdef path */
1005 p = get_objs(caller);
1006 if (!p)
1007 return ret;
1008
1009 ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
1010
1011 ioc->count = 1;
1012 ioc->flag = 0;
1013 ioc->name_uaddr[0] = (__u64)(intptr_t)def_impl->name;
1014
1015 ret = ioctl(p->obj.fd, KMPP_SHM_IOC_GET_SHM, ioc);
1016 if (ret) {
1017 mpp_err("%s fd %d ioctl KMPP_SHM_IOC_GET_SHM failed at %s\n",
1018 def_impl->name, p->obj.fd, caller);
1019 return ret;
1020 }
1021
1022 uaddr = ioc->obj_sptr[0].uaddr;
1023
1024 *obj = get_obj_from_def(p, def_impl, (KmppShmPtr *)U64_TO_PTR(uaddr), caller);
1025
1026 return *obj ? rk_ok : rk_nok;
1027 }
1028
kmpp_obj_get_by_name(KmppObj * obj,const char * name,const char * caller)1029 rk_s32 kmpp_obj_get_by_name(KmppObj *obj, const char *name, const char *caller)
1030 {
1031 KmppObjDefImpl *def;
1032
1033 if (!obj || !name) {
1034 mpp_loge_f("invalid param obj %p name %p at %s\n",
1035 obj, name, caller);
1036 return rk_nok;
1037 }
1038
1039 if (kmpp_objdef_find((KmppObjDef *)&def, name)) {
1040 *obj = NULL;
1041 return rk_nok;
1042 }
1043
1044 mpp_assert(def);
1045 if (def->is_kobj && !def->pool)
1046 create_objdef_mem_pool(def);
1047
1048 return kmpp_obj_get(obj, def, caller);
1049 }
1050
kmpp_obj_get_by_sptr(KmppObj * obj,KmppShmPtr * sptr,const char * caller)1051 rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppShmPtr *sptr, const char *caller)
1052 {
1053 KmppObjs *p = get_objs(caller);
1054 KmppObjImpl *impl;
1055 KmppObjDefImpl *def;
1056 rk_u8 *uptr = sptr ? sptr->uptr : NULL;
1057
1058 if (!obj) {
1059 mpp_loge_f("invalid param obj %p sptr %p uptr %p at %s\n",
1060 obj, sptr, uptr, caller);
1061 return rk_nok;
1062 }
1063
1064 *obj = NULL;
1065
1066 /* allow NULL sptr and NULL uptr return NULL object value without error */
1067 if (!sptr || !uptr)
1068 return rk_ok;
1069
1070 if (!p)
1071 return rk_nok;
1072
1073 impl = (KmppObjImpl *)(intptr_t) * (rk_u64 *)(uptr + p->priv_offset);
1074 if (impl) {
1075 if (!kmpp_obj_check_f((KmppObj)impl))
1076 goto done;
1077 }
1078
1079 {
1080 rk_u32 val = *((rk_u32 *)(uptr + p->name_offset));
1081 char *str;
1082
1083 if (!val) {
1084 mpp_loge_f("invalid obj name offset %d at %s\n", val, caller);
1085 return rk_nok;
1086 }
1087
1088 str = (char *)p->obj.root + val;
1089 if (kmpp_objdef_find((KmppObjDef *)&def, str)) {
1090 mpp_loge_f("failed to get objdef %p - %s at %s\n", str, str, caller);
1091 return rk_nok;
1092 }
1093 }
1094
1095 mpp_assert(def && def->pool);
1096 impl = get_obj_from_def(p, def, (KmppShmPtr *)uptr, caller);
1097
1098 done:
1099 *obj = impl;
1100
1101 return impl ? rk_ok : rk_nok;
1102 }
1103
kmpp_obj_put(KmppObj obj,const char * caller)1104 rk_s32 kmpp_obj_put(KmppObj obj, const char *caller)
1105 {
1106 if (obj) {
1107 KmppObjImpl *impl = (KmppObjImpl *)obj;
1108 KmppObjDefImpl *def = impl->def;
1109 KmppObjs *p;
1110
1111 mpp_assert(def && def->pool);
1112
1113 if (def && def->deinit)
1114 def->deinit(impl->entry, impl, caller);
1115
1116 /* use shm to check userspace objdef or kernel objdef */
1117 /* userspace objdef path */
1118 if (impl->shm) {
1119 p = get_objs(caller);
1120 if (p && p->obj.fd >= 0) {
1121 KmppObjIocArg *ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
1122 rk_s32 ret;
1123
1124 ioc->count = 1;
1125 ioc->flag = 0;
1126 ioc->obj_sptr[0].uaddr = impl->shm->uaddr;
1127 ioc->obj_sptr[0].kaddr = impl->shm->kaddr;
1128
1129 obj_dbg_flow("put obj %-16s - %p entry [u:k] %llx:%llx at %s\n", def ? def->name : NULL,
1130 impl, impl->shm->uaddr, impl->shm->kaddr, caller);
1131
1132 ret = ioctl(p->obj.fd, KMPP_SHM_IOC_PUT_SHM, ioc);
1133 if (ret)
1134 mpp_err("ioctl KMPP_SHM_IOC_PUT_SHM failed ret %d at %s\n", ret, caller);
1135 }
1136 impl->shm = NULL;
1137 }
1138
1139 mpp_mem_pool_put(def->pool, impl, caller);
1140
1141 return rk_ok;
1142 }
1143
1144 return rk_nok;
1145 }
1146
kmpp_obj_impl_put(KmppObj obj,const char * caller)1147 rk_s32 kmpp_obj_impl_put(KmppObj obj, const char *caller)
1148 {
1149 if (obj) {
1150 KmppObjImpl *impl = (KmppObjImpl *)obj;
1151 KmppObjDefImpl *def = impl->def;
1152
1153 mpp_assert(def);
1154
1155 if (def) {
1156 if (def->deinit)
1157 def->deinit(impl->entry, impl, caller);
1158
1159 mpp_assert(def->pool);
1160 mpp_mem_pool_put(def->pool, impl, caller);
1161
1162 return rk_ok;
1163 }
1164 }
1165
1166 return rk_nok;
1167 }
1168
kmpp_obj_preset(KmppObj obj,const char * arg,const char * caller)1169 rk_s32 kmpp_obj_preset(KmppObj obj, const char *arg, const char *caller)
1170 {
1171 if (obj) {
1172 KmppObjImpl *impl = (KmppObjImpl *)obj;
1173 KmppObjDefImpl *def = impl->def;
1174
1175 mpp_assert(def);
1176
1177 if (def && def->preset)
1178 return def->preset(impl->entry, impl, arg, caller);
1179 }
1180
1181 return rk_ok;
1182 }
1183
kmpp_obj_check(KmppObj obj,const char * caller)1184 rk_s32 kmpp_obj_check(KmppObj obj, const char *caller)
1185 {
1186 KmppObjImpl *impl = (KmppObjImpl *)obj;
1187
1188 if (!impl) {
1189 mpp_loge_f("from %s failed for NULL arg\n", caller);
1190 return rk_nok;
1191 }
1192
1193 if (!impl->name || !impl->def || impl->name != impl->def->name) {
1194 mpp_loge_f("from %s failed for name check %s but %s\n", caller,
1195 impl->def ? impl->def->name : NULL, impl->name);
1196 return rk_nok;
1197 }
1198
1199 if (!impl->entry || !impl->def->trie) {
1200 mpp_loge_f("from %s failed for entry %p and def trie %p\n", caller,
1201 impl->entry, impl->def->trie);
1202 return rk_nok;
1203 }
1204
1205 return rk_ok;
1206 }
1207
kmpp_obj_ioctl(KmppObj ctx,rk_s32 cmd,KmppObj in,KmppObj * out,const char * caller)1208 rk_s32 kmpp_obj_ioctl(KmppObj ctx, rk_s32 cmd, KmppObj in, KmppObj *out, const char *caller)
1209 {
1210 KmppObjs *p = get_objs_f();
1211 KmppObjDef def_ioc = kmpp_ioc_objdef();
1212 KmppObjImpl *impl = (KmppObjImpl *)ctx;
1213 KmppObjImpl *ioc = NULL;
1214 KmppObjIocArg *ioc_arg;
1215 KmppObjDefImpl *def;
1216 rk_s32 ret;
1217
1218 if (!p)
1219 return rk_nok;
1220
1221 if (!def_ioc) {
1222 static rk_s32 once = 1;
1223
1224 if (once) {
1225 mpp_loge("KmppIoc is not defined\n");
1226 once = 0;
1227 }
1228
1229 return rk_nok;
1230 }
1231
1232 if (!impl || !impl->def) {
1233 mpp_err("invalid ioctl ctx %p def %p failed at %s\n",
1234 impl, impl ? impl->def : NULL, caller);
1235 return rk_nok;
1236 }
1237
1238 def = impl->def;
1239
1240 obj_dbg_ioctl("ioctl def %s:%d cmd %d ctx %p in %p out %p at %s\n",
1241 def->name, def->defs_idx, cmd, ctx, in, out, caller);
1242
1243 ret = kmpp_obj_get((KmppObj *)&ioc, def_ioc, caller);
1244 if (ret) {
1245 mpp_loge("failed to get KmppIoc ret %d\n", ret);
1246 return rk_nok;
1247 }
1248
1249 ioc_arg = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
1250 ioc_arg->count = 1;
1251 ioc_arg->flag = 0;
1252 ioc_arg->obj_sptr[0].uaddr = ioc->shm->uaddr;
1253 ioc_arg->obj_sptr[0].kaddr = ioc->shm->kaddr;
1254
1255 obj_dbg_ioctl("ioctl arg %p obj_sptr [u:k] %llx : %llx\n", ioc_arg,
1256 ioc_arg->obj_sptr[0].uaddr, ioc_arg->obj_sptr[0].kaddr);
1257
1258 kmpp_ioc_set_def(ioc, def->defs_idx);
1259 kmpp_ioc_set_cmd(ioc, cmd);
1260 kmpp_ioc_set_flags(ioc, 0);
1261 kmpp_ioc_set_id(ioc, 0);
1262
1263 {
1264 static rk_s32 has_ctx = -1;
1265
1266 if (has_ctx < 0)
1267 has_ctx = kmpp_objdef_get_offset(def_ioc, "ctx") >= 0;
1268
1269 if (has_ctx) {
1270 KmppShmPtr *sptr = kmpp_obj_to_shm(ctx);
1271
1272 kmpp_ioc_set_ctx(ioc, sptr);
1273 obj_dbg_ioctl("ioctl [u:k] ctx %#llx : %#llx\n", sptr->uaddr, sptr->kaddr);
1274 }
1275 }
1276
1277 if (in) {
1278 KmppShmPtr *sptr = kmpp_obj_to_shm(in);
1279
1280 kmpp_ioc_set_in(ioc, sptr);
1281 obj_dbg_ioctl("ioctl [u:k] in %#llx : %#llx\n", sptr->uaddr, sptr->kaddr);
1282 }
1283
1284 ret = ioctl(p->ioc.fd, 0, ioc_arg);
1285
1286 /* if defined ret in ioc object use ret in ioc object */
1287 kmpp_ioc_get_ret(ioc, &ret);
1288
1289 if (out) {
1290 *out = NULL;
1291
1292 if (!ret) {
1293 KmppShmPtr sptr = { 0 };
1294
1295 kmpp_ioc_get_out(ioc, &sptr);
1296 kmpp_obj_get_by_sptr(out, &sptr, caller);
1297
1298 obj_dbg_ioctl("ioctl [u:k] out %#llx : %#llx obj %p\n",
1299 sptr.uaddr, sptr.kaddr, *out);
1300 }
1301 }
1302
1303 kmpp_obj_put(ioc, caller);
1304
1305 return ret;
1306 }
1307
kmpp_obj_is_kobj(KmppObj obj)1308 rk_s32 kmpp_obj_is_kobj(KmppObj obj)
1309 {
1310 KmppObjImpl *impl = (KmppObjImpl *)obj;
1311
1312 return (impl && impl->def) ? impl->def->is_kobj : 0;
1313 }
1314
kmpp_obj_to_objdef(KmppObj obj)1315 KmppObjDef kmpp_obj_to_objdef(KmppObj obj)
1316 {
1317 KmppObjImpl *impl = (KmppObjImpl *)obj;
1318
1319 return impl ? impl->def : NULL;
1320 }
1321
kmpp_obj_to_flags(KmppObj obj)1322 void *kmpp_obj_to_flags(KmppObj obj)
1323 {
1324 KmppObjImpl *impl = (KmppObjImpl *)obj;
1325
1326 if (impl && impl->def && impl->def->flag_offset)
1327 return impl->entry + impl->def->flag_offset;
1328
1329 return NULL;
1330 }
1331
kmpp_obj_to_flags_size(KmppObj obj)1332 rk_s32 kmpp_obj_to_flags_size(KmppObj obj)
1333 {
1334 KmppObjImpl *impl = (KmppObjImpl *)obj;
1335
1336 if (impl && impl->def && impl->def->flag_max_pos) {
1337 KmppObjDefImpl *def = impl->def;
1338 rk_s32 max_pos = MPP_ALIGN(def->flag_max_pos, 8) / 8;
1339
1340 return MPP_ALIGN(max_pos - def->flag_offset, 4);
1341 }
1342
1343 return 0;
1344 }
1345
kmpp_obj_to_shm(KmppObj obj)1346 KmppShmPtr *kmpp_obj_to_shm(KmppObj obj)
1347 {
1348 KmppObjImpl *impl = (KmppObjImpl *)obj;
1349
1350 if (!impl) {
1351 mpp_loge("invalid obj %p\n", obj);
1352 return NULL;
1353 }
1354
1355 return impl->shm;
1356 }
1357
kmpp_obj_to_shm_size(KmppObj obj)1358 rk_s32 kmpp_obj_to_shm_size(KmppObj obj)
1359 {
1360 (void)obj;
1361 return sizeof(KmppShmPtr);
1362 }
1363
kmpp_obj_get_name(KmppObj obj)1364 const char *kmpp_obj_get_name(KmppObj obj)
1365 {
1366 KmppObjImpl *impl = (KmppObjImpl *)obj;
1367
1368 if (impl && impl->def && impl->def->name)
1369 return impl->def->name;
1370
1371 return NULL;
1372 }
1373
kmpp_obj_to_priv(KmppObj obj)1374 void *kmpp_obj_to_priv(KmppObj obj)
1375 {
1376 KmppObjImpl *impl = (KmppObjImpl *)obj;
1377
1378 return impl ? impl->priv : NULL;
1379 }
1380
kmpp_obj_to_entry(KmppObj obj)1381 void *kmpp_obj_to_entry(KmppObj obj)
1382 {
1383 KmppObjImpl *impl = (KmppObjImpl *)obj;
1384
1385 return impl ? impl->entry : NULL;
1386 }
1387
kmpp_obj_to_offset(KmppObj obj,const char * name)1388 rk_s32 kmpp_obj_to_offset(KmppObj obj, const char *name)
1389 {
1390 KmppObjImpl *impl = (KmppObjImpl *)obj;
1391
1392 if (!impl || !name) {
1393 mpp_loge("invalid obj %p name %s\n", obj, name);
1394 return -1;
1395 }
1396
1397 if (impl->trie) {
1398 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
1399
1400 if (info) {
1401 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
1402
1403 if (tbl)
1404 return tbl->tbl.elem_offset;
1405 }
1406 }
1407
1408 mpp_loge("invalid offset for name %s\n", name);
1409
1410 return -1;
1411 }
1412
1413 #define MPP_OBJ_ACCESS(type, base_type) \
1414 rk_s32 kmpp_obj_set_##type(KmppObj obj, const char *name, base_type val) \
1415 { \
1416 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1417 rk_s32 ret = rk_nok; \
1418 if (impl->trie) { \
1419 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
1420 if (info) { \
1421 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
1422 ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
1423 } \
1424 } \
1425 if (ret) \
1426 mpp_loge("obj %s set %s " #type " failed ret %d\n", \
1427 impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
1428 return ret; \
1429 } \
1430 rk_s32 kmpp_obj_get_##type(KmppObj obj, const char *name, base_type *val) \
1431 { \
1432 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1433 rk_s32 ret = rk_nok; \
1434 if (impl->trie) { \
1435 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
1436 if (info) { \
1437 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
1438 ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
1439 } \
1440 } \
1441 if (ret) \
1442 mpp_loge("obj %s get %s " #type " failed ret %d\n", \
1443 impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
1444 return ret; \
1445 }
1446
MPP_OBJ_ACCESS(s32,rk_s32)1447 MPP_OBJ_ACCESS(s32, rk_s32)
1448 MPP_OBJ_ACCESS(u32, rk_u32)
1449 MPP_OBJ_ACCESS(s64, rk_s64)
1450 MPP_OBJ_ACCESS(u64, rk_u64)
1451 MPP_OBJ_ACCESS(obj, KmppObj)
1452 MPP_OBJ_ACCESS(fp, void *)
1453
1454 /* compatible for pointer and structure setup */
1455 rk_s32 kmpp_obj_set_ptr(KmppObj obj, const char *name, void* val)
1456 {
1457 KmppObjImpl *impl = (KmppObjImpl *)obj;
1458 rk_s32 ret = rk_nok;
1459
1460 if (impl->trie) {
1461 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
1462
1463 if (info) {
1464 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
1465
1466 if (tbl->tbl.elem_type == ELEM_TYPE_st)
1467 ret = kmpp_obj_impl_set_st(tbl, impl->entry, val);
1468 else
1469 ret = kmpp_obj_impl_set_ptr(tbl, impl->entry, val);
1470 }
1471 }
1472
1473 if (ret)
1474 mpp_loge("obj %s set %s ptr failed ret %d\n",
1475 (impl && impl->def && impl->def->name) ? impl->def->name : NULL, name, ret);
1476
1477 return ret;
1478 }
1479
kmpp_obj_get_ptr(KmppObj obj,const char * name,void ** val)1480 rk_s32 kmpp_obj_get_ptr(KmppObj obj, const char *name, void **val)
1481 {
1482 KmppObjImpl *impl = (KmppObjImpl *)obj;
1483 rk_s32 ret = rk_nok;
1484
1485 if (impl->trie) {
1486 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
1487
1488 if (info) {
1489 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
1490
1491 if (tbl->tbl.elem_type == ELEM_TYPE_st)
1492 ret = kmpp_obj_impl_get_st(tbl, impl->entry, val);
1493 else
1494 ret = kmpp_obj_impl_get_ptr(tbl, impl->entry, val);
1495 }
1496 }
1497
1498 if (ret)
1499 mpp_loge("obj %s get %s ptr failed ret %d\n",
1500 (impl && impl->def && impl->def->name) ? impl->def->name : NULL, name, ret);
1501
1502 return ret;
1503 }
1504
1505 #define MPP_OBJ_STRUCT_ACCESS(type, base_type) \
1506 rk_s32 kmpp_obj_set_##type(KmppObj obj, const char *name, base_type *val) \
1507 { \
1508 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1509 rk_s32 ret = rk_nok; \
1510 if (impl->trie) { \
1511 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
1512 if (info) { \
1513 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
1514 ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
1515 } \
1516 } \
1517 if (ret) \
1518 mpp_loge("obj %s set %s " #type " failed ret %d\n", \
1519 impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
1520 return ret; \
1521 } \
1522 rk_s32 kmpp_obj_get_##type(KmppObj obj, const char *name, base_type *val) \
1523 { \
1524 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1525 rk_s32 ret = rk_nok; \
1526 if (impl->trie) { \
1527 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
1528 if (info) { \
1529 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
1530 ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
1531 } \
1532 } \
1533 if (ret) \
1534 mpp_loge("obj %s get %s " #type " failed ret %d\n", \
1535 impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
1536 return ret; \
1537 }
1538
MPP_OBJ_STRUCT_ACCESS(st,void)1539 MPP_OBJ_STRUCT_ACCESS(st, void)
1540 MPP_OBJ_STRUCT_ACCESS(shm, KmppShmPtr)
1541
1542 #define MPP_OBJ_TBL_ACCESS(type, base_type) \
1543 rk_s32 kmpp_obj_tbl_set_##type(KmppObj obj, KmppEntry *tbl, base_type val) \
1544 { \
1545 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1546 rk_s32 ret = rk_nok; \
1547 if (impl) \
1548 ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
1549 if (ret) \
1550 mpp_loge("obj %s tbl %08x set " #type " failed ret %d\n", \
1551 impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
1552 return ret; \
1553 } \
1554 rk_s32 kmpp_obj_tbl_get_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
1555 { \
1556 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1557 rk_s32 ret = rk_nok; \
1558 if (impl) \
1559 ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
1560 if (ret) \
1561 mpp_loge("obj %s tbl %08x get " #type " failed ret %d\n", \
1562 impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
1563 return ret; \
1564 }
1565
1566 MPP_OBJ_TBL_ACCESS(s32, rk_s32)
1567 MPP_OBJ_TBL_ACCESS(u32, rk_u32)
1568 MPP_OBJ_TBL_ACCESS(s64, rk_s64)
1569 MPP_OBJ_TBL_ACCESS(u64, rk_u64)
1570 MPP_OBJ_TBL_ACCESS(obj, KmppObj)
1571 MPP_OBJ_TBL_ACCESS(ptr, void *)
1572 MPP_OBJ_TBL_ACCESS(fp, void *)
1573
1574 #define MPP_OBJ_STRUCT_TBL_ACCESS(type, base_type) \
1575 rk_s32 kmpp_obj_tbl_set_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
1576 { \
1577 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1578 rk_s32 ret = rk_nok; \
1579 if (impl) \
1580 ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
1581 if (ret) \
1582 mpp_loge("obj %s tbl %08x set " #type " failed ret %d\n", \
1583 impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
1584 return ret; \
1585 } \
1586 rk_s32 kmpp_obj_tbl_get_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
1587 { \
1588 KmppObjImpl *impl = (KmppObjImpl *)obj; \
1589 rk_s32 ret = rk_nok; \
1590 if (impl) \
1591 ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
1592 if (ret) \
1593 mpp_loge("obj %s tbl %08x get " #type " failed ret %d\n", \
1594 impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
1595 return ret; \
1596 }
1597
1598 MPP_OBJ_STRUCT_TBL_ACCESS(st, void)
1599 MPP_OBJ_STRUCT_TBL_ACCESS(shm, KmppShmPtr)
1600
1601 rk_s32 kmpp_obj_set_shm_obj(KmppObj obj, const char *name, KmppObj val)
1602 {
1603 rk_s32 ret = rk_nok;
1604
1605 if (!obj || !name || !val) {
1606 mpp_loge_f("obj %p set shm obj %s to %p failed invalid param\n",
1607 obj, name, val);
1608 } else {
1609 KmppShmPtr *sptr = kmpp_obj_to_shm(val);
1610
1611 if (!sptr) {
1612 mpp_loge_f("obj %p found invalid shm ptr\n", val);
1613 } else {
1614 ret = kmpp_obj_set_shm(obj, name, sptr);
1615 }
1616 }
1617
1618 return ret;
1619 }
1620
kmpp_obj_get_shm_obj(KmppObj obj,const char * name,KmppObj * val)1621 rk_s32 kmpp_obj_get_shm_obj(KmppObj obj, const char *name, KmppObj *val)
1622 {
1623 rk_s32 ret = rk_nok;
1624
1625 if (!obj || !name || !val) {
1626 mpp_loge_f("obj %p get shm obj %s to %p failed invalid param\n",
1627 obj, name, val);
1628 } else {
1629 KmppObjImpl *impl = (KmppObjImpl *)obj;
1630 KmppShmPtr sptr = {0};
1631
1632 *val = NULL;
1633
1634 ret = kmpp_obj_get_shm(obj, name, &sptr);
1635 if (ret || !sptr.uptr) {
1636 mpp_loge_f("obj %p get shm %s failed ret %d\n", impl, name, ret);
1637 } else {
1638 ret = kmpp_obj_get_by_sptr(val, &sptr, __FUNCTION__);
1639 }
1640 }
1641
1642 return ret;
1643 }
1644
kmpp_obj_test(KmppObj obj,const char * name)1645 rk_s32 kmpp_obj_test(KmppObj obj, const char *name)
1646 {
1647 KmppObjImpl *impl = (KmppObjImpl *)obj;
1648
1649 if (impl && impl->trie) {
1650 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
1651
1652 if (info) {
1653 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
1654
1655 return ENTRY_TEST_FLAG(tbl, impl->entry);;
1656 }
1657 }
1658
1659 return 0;
1660 }
1661
kmpp_obj_tbl_test(KmppObj obj,KmppEntry * tbl)1662 rk_s32 kmpp_obj_tbl_test(KmppObj obj, KmppEntry *tbl)
1663 {
1664 KmppObjImpl *impl = (KmppObjImpl *)obj;
1665
1666 return (impl && tbl) ? ENTRY_TEST_FLAG(tbl, impl->entry) : 0;
1667 }
1668
kmpp_obj_update(KmppObj dst,KmppObj src)1669 rk_s32 kmpp_obj_update(KmppObj dst, KmppObj src)
1670 {
1671 KmppObjImpl *dst_impl = (KmppObjImpl *)dst;
1672 KmppObjImpl *src_impl = (KmppObjImpl *)src;
1673 MppTrie trie = NULL;
1674 MppTrieInfo *info = NULL;
1675
1676 if (kmpp_obj_check_f(src) || kmpp_obj_check_f(dst) || src_impl->def != dst_impl->def) {
1677 mpp_loge_f("obj %p update to %p failed invalid param\n", src, dst);
1678 return rk_nok;
1679 }
1680
1681 trie = src_impl->def->trie;
1682
1683 info = mpp_trie_get_info_first(trie);
1684 do {
1685 KmppEntry *e;
1686
1687 if (mpp_trie_info_is_self(info))
1688 continue;
1689
1690 e = (KmppEntry *)mpp_trie_info_ctx(info);
1691 if (e->tbl.flag_offset && ENTRY_TEST_FLAG(e, src_impl->entry)) {
1692 rk_s32 offset = e->tbl.elem_offset;
1693 rk_s32 size = e->tbl.elem_size;
1694
1695 obj_dbg_update("obj %s %p update %s\n", src_impl->name,
1696 dst, mpp_trie_info_name(info));
1697 memcpy(dst_impl->entry + offset, src_impl->entry + offset, size);
1698 }
1699 } while ((info = mpp_trie_get_info_next(trie, info)));
1700
1701 if (src_impl->def) {
1702 KmppObjDefImpl *def = src_impl->def;
1703 rk_s32 flag_offset = def->flag_offset;
1704 rk_s32 flag_size = kmpp_obj_to_flags_size(src);
1705
1706 if (flag_offset && flag_size) {
1707 rk_s32 i;
1708
1709 for (i = flag_offset; i < flag_offset + flag_size; i += 4)
1710 obj_dbg_update("obj %s %p update flag at %#06x - %08x\n", src_impl->def->name,
1711 dst, i, *((rk_u32 *)((rk_u8 *)src_impl->entry + i)));
1712
1713 memcpy(dst_impl->entry + flag_offset,
1714 src_impl->entry + flag_offset, flag_size);
1715 memset(src_impl->entry + flag_offset, 0, flag_size);
1716 }
1717 }
1718
1719 return rk_ok;
1720 }
1721
kmpp_obj_update_entry(void * entry,KmppObj src)1722 rk_s32 kmpp_obj_update_entry(void *entry, KmppObj src)
1723 {
1724 KmppObjImpl *src_impl = (KmppObjImpl *)src;
1725 MppTrie trie = NULL;
1726 MppTrieInfo *info = NULL;
1727
1728 if (kmpp_obj_check_f(src) || !entry) {
1729 mpp_loge_f("obj %p update to entry %p failed invalid param\n", src, entry);
1730 return rk_nok;
1731 }
1732
1733 trie = src_impl->def->trie;
1734
1735 info = mpp_trie_get_info_first(trie);
1736 do {
1737 KmppEntry *e;
1738
1739 if (mpp_trie_info_is_self(info))
1740 continue;
1741
1742 e = (KmppEntry *)mpp_trie_info_ctx(info);
1743 if (e->tbl.flag_offset && ENTRY_TEST_FLAG(e, src_impl->entry)) {
1744 rk_s32 offset = e->tbl.elem_offset;
1745 rk_s32 size = e->tbl.elem_size;
1746
1747 obj_dbg_update("obj %s %p -> %p update %s\n", src_impl->name,
1748 src_impl, entry, mpp_trie_info_name(info));
1749 memcpy(entry + offset, src_impl->entry + offset, size);
1750 }
1751 } while ((info = mpp_trie_get_info_next(trie, info)));
1752
1753 return rk_ok;
1754 }
1755
kmpp_obj_copy_entry(KmppObj dst,KmppObj src)1756 rk_s32 kmpp_obj_copy_entry(KmppObj dst, KmppObj src)
1757 {
1758 KmppObjImpl *dst_impl = (KmppObjImpl *)dst;
1759 KmppObjImpl *src_impl = (KmppObjImpl *)src;
1760
1761 if (kmpp_obj_check_f(src) || kmpp_obj_check_f(dst) || src_impl->def != dst_impl->def) {
1762 mpp_loge_f("obj %p copy entry to %p failed invalid param\n", src, dst);
1763 return rk_nok;
1764 }
1765
1766 memcpy(dst_impl->entry, src_impl->entry, src_impl->def->entry_size);
1767 { /* NOTE: clear dst update flags */
1768 rk_s32 offset = src_impl->def->flag_offset;
1769 rk_s32 size = kmpp_obj_to_flags_size(src);
1770
1771 memset(dst_impl->entry + offset, 0, size);
1772 }
1773
1774 return rk_ok;
1775 }
1776
kmpp_obj_impl_run(rk_s32 (* run)(void * ctx),void * ctx)1777 static rk_s32 kmpp_obj_impl_run(rk_s32 (*run)(void *ctx), void *ctx)
1778 {
1779 return run(ctx);
1780 }
1781
kmpp_obj_run(KmppObj obj,const char * name)1782 rk_s32 kmpp_obj_run(KmppObj obj, const char *name)
1783 {
1784 KmppObjImpl *impl = (KmppObjImpl *)obj;
1785 rk_s32 ret = rk_nok;
1786
1787 if (impl->trie) {
1788 MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
1789 void *val = NULL;
1790
1791 if (info) {
1792 KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
1793
1794 ret = kmpp_obj_impl_get_fp(tbl, impl->entry, &val);
1795 }
1796
1797 if (val)
1798 ret = kmpp_obj_impl_run(val, impl->entry);
1799 }
1800
1801 return ret;
1802 }
1803
kmpp_obj_udump_f(KmppObj obj,const char * caller)1804 rk_s32 kmpp_obj_udump_f(KmppObj obj, const char *caller)
1805 {
1806 KmppObjImpl *impl = (KmppObjImpl *)obj;
1807 KmppObjDefImpl *def = impl ? impl->def : NULL;
1808 MppTrie trie = NULL;
1809 MppTrieInfo *info = NULL;
1810 MppTrieInfo *next = NULL;
1811 const char *name = NULL;
1812 rk_s32 ret = rk_nok;
1813 RK_S32 i = 0;
1814
1815 if (!impl || !def) {
1816 mpp_loge_f("invalid obj %p def %p\n", impl, def);
1817 return rk_nok;
1818 }
1819
1820 trie = impl->trie;
1821 name = def->name;
1822
1823 mpp_logi("dump obj %-12s - %p at %s:\n", name, impl, caller);
1824
1825 if (def->dump)
1826 return def->dump(impl->entry);
1827
1828 next = mpp_trie_get_info_first(trie);
1829 while (next) {
1830 KmppEntry *e;
1831 rk_s32 idx;
1832
1833 info = next;
1834 next = mpp_trie_get_info_next(trie, info);
1835
1836 e = (KmppEntry *)mpp_trie_info_ctx(info);
1837 name = mpp_trie_info_name(info);
1838
1839 if (mpp_trie_info_is_self(info))
1840 continue;
1841
1842 idx = i++;
1843
1844 switch (e->tbl.elem_type) {
1845 case ELEM_TYPE_s32 : {
1846 rk_s32 val;
1847 rk_s32 val_chk;
1848
1849 ret = kmpp_obj_tbl_get_s32(obj, e, &val);
1850 if (!ret)
1851 mpp_logi("%-2d - %-16s s32 %#x:%d\n", idx, name, val, val);
1852 else
1853 mpp_loge("%-2d - %-16s s32 get failed\n", idx, name);
1854
1855 kmpp_obj_get_s32(obj, name, &val_chk);
1856 if (val != val_chk)
1857 mpp_loge("%-2d - %-16s s32 check failed\n", idx, name);
1858 } break;
1859 case ELEM_TYPE_u32 : {
1860 rk_u32 val;
1861 rk_u32 val_chk;
1862
1863 ret = kmpp_obj_tbl_get_u32(obj, e, &val);
1864 if (!ret)
1865 mpp_logi("%-2d - %-16s u32 %#x:%u\n", idx, name, val, val);
1866 else
1867 mpp_loge("%-2d - %-16s u32 get failed\n", idx, name);
1868
1869 kmpp_obj_get_u32(obj, name, &val_chk);
1870 if (val != val_chk)
1871 mpp_loge("%-2d - %-16s u32 check failed\n", idx, name);
1872 } break;
1873 case ELEM_TYPE_s64 : {
1874 rk_s64 val;
1875 rk_s64 val_chk;
1876
1877 ret = kmpp_obj_tbl_get_s64(obj, e, &val);
1878 if (!ret)
1879 mpp_logi("%-2d - %-16s s64 %#llx:%lld\n", idx, name, val, val);
1880 else
1881 mpp_loge("%-2d - %-16s s64 get failed\n", idx, name);
1882
1883 kmpp_obj_get_s64(obj, name, &val_chk);
1884 if (val != val_chk)
1885 mpp_loge("%-2d - %-16s s64 check failed\n", idx, name);
1886 } break;
1887 case ELEM_TYPE_u64 : {
1888 rk_u64 val;
1889 rk_u64 val_chk;
1890
1891 ret = kmpp_obj_tbl_get_u64(obj, e, &val);
1892 if (!ret)
1893 mpp_logi("%-2d - %-16s u64 %#llx:%llu\n", idx, name, val, val);
1894 else
1895 mpp_loge("%-2d - %-16s u64 get failed\n", idx, name);
1896
1897 kmpp_obj_get_u64(obj, name, &val_chk);
1898 if (val != val_chk)
1899 mpp_loge("%-2d - %-16s u64 check failed\n", idx, name);
1900 } break;
1901 case ELEM_TYPE_st : {
1902 void *val_chk = mpp_malloc_size(void, e->tbl.elem_size);
1903 void *val = mpp_malloc_size(void, e->tbl.elem_size);
1904 rk_s32 data_size = e->tbl.elem_size;
1905 char logs[128];
1906
1907 ret = kmpp_obj_tbl_get_st(obj, e, val);
1908 if (!ret) {
1909 rk_s32 pos;
1910 rk_s32 j;
1911
1912 mpp_logi("%-2d - %-16s st %d:%d\n", idx, name, e->tbl.elem_offset, data_size);
1913
1914 j = 0;
1915 for (; j < data_size / 4 - 8; j += 8) {
1916 snprintf(logs, sizeof(logs) - 1, " - %02x : %#08x %#08x %#08x %#08x %#08x %#08x %#08x %#08x", j,
1917 ((RK_U32 *)val)[j + 0], ((RK_U32 *)val)[j + 1],
1918 ((RK_U32 *)val)[j + 2], ((RK_U32 *)val)[j + 3],
1919 ((RK_U32 *)val)[j + 4], ((RK_U32 *)val)[j + 5],
1920 ((RK_U32 *)val)[j + 6], ((RK_U32 *)val)[j + 7]);
1921
1922 mpp_logi("%s\n", logs);
1923 }
1924
1925 pos = snprintf(logs, sizeof(logs) - 1, " - %02x :", j);
1926 for (; j < data_size / 4; j++)
1927 pos += snprintf(logs + pos, sizeof(logs) - 1 - pos, " %#08x", ((RK_U32 *)val)[j]);
1928
1929 mpp_logi("%s\n", logs);
1930 } else
1931 mpp_loge("%-2d - %-16s st get failed\n", idx, name);
1932
1933 kmpp_obj_get_st(obj, name, val_chk);
1934 if (memcmp(val, val_chk, e->tbl.elem_size)) {
1935 mpp_loge("%-2d - %-16s st check failed\n", idx, name);
1936 mpp_loge("val %p\n", val);
1937 mpp_loge("val_chk %p\n", val_chk);
1938 }
1939
1940 MPP_FREE(val);
1941 MPP_FREE(val_chk);
1942 } break;
1943 case ELEM_TYPE_shm : {
1944 KmppShmPtr *val_chk = mpp_malloc_size(void, e->tbl.elem_size);
1945 KmppShmPtr *val = mpp_malloc_size(void, e->tbl.elem_size);
1946
1947 ret = kmpp_obj_tbl_get_st(obj, e, val);
1948 if (!ret)
1949 mpp_logi("%-2d - %-16s shm u%#llx:k%#llx\n",
1950 idx, name, val->uaddr, val->kaddr);
1951 else
1952 mpp_loge("%-2d - %-16s shm get failed\n", idx, name);
1953
1954 kmpp_obj_get_st(obj, name, val_chk);
1955 if (memcmp(val, val_chk, e->tbl.elem_size)) {
1956 mpp_loge("%-2d - %-16s shm check failed\n", idx, name);
1957 mpp_loge("val %p - %#llx:%#llx\n", val, val->uaddr, val->kaddr);
1958 mpp_loge("val_chk %p - %#llx:%#llx\n", val_chk, val_chk->uaddr, val_chk->kaddr);
1959 }
1960
1961 MPP_FREE(val);
1962 MPP_FREE(val_chk);
1963 } break;
1964 case ELEM_TYPE_uptr : {
1965 void *val;
1966 void *val_chk;
1967
1968 ret = kmpp_obj_tbl_get_ptr(obj, e, &val);
1969 if (!ret)
1970 mpp_logi("%-2d - %-16s ptr %p\n", idx, name, val);
1971 else
1972 mpp_loge("%-2d - %-16s ptr get failed\n", idx, name);
1973
1974 kmpp_obj_get_ptr(obj, name, &val_chk);
1975 if (val != val_chk)
1976 mpp_loge("%-2d - %-16s ptr check failed\n", idx, name);
1977 } break;
1978 case ELEM_TYPE_ufp : {
1979 void *val;
1980 void *val_chk;
1981
1982 ret = kmpp_obj_tbl_get_fp(obj, e, &val);
1983 if (!ret)
1984 mpp_logi("%-2d - %-16s fp %p\n", idx, name, val);
1985 else
1986 mpp_loge("%-2d - %-16s fp get failed\n", idx, name);
1987
1988 kmpp_obj_get_fp(obj, name, &val_chk);
1989 if (val != val_chk)
1990 mpp_loge("%-2d - %-16s fp check failed\n", idx, name);
1991 } break;
1992 default : {
1993 mpp_loge("%-2d - %-16s found invalid type %d\n", idx, name, e->tbl.elem_type);
1994 ret = rk_nok;
1995 } break;
1996 }
1997 }
1998
1999 return ret ? rk_nok : rk_ok;
2000 }
2001
kmpp_obj_kdump_f(KmppObj obj,const char * caller)2002 rk_s32 kmpp_obj_kdump_f(KmppObj obj, const char *caller)
2003 {
2004 KmppObjs *p = get_objs(caller);
2005 KmppObjImpl *impl = (KmppObjImpl *)obj;
2006 KmppObjDefImpl *def = impl ? impl->def : NULL;
2007 rk_s32 ret = rk_nok;
2008
2009 if (!impl || !def || !p) {
2010 mpp_loge_f("invalid obj %p def %p objs %p\n", impl, def, p);
2011 return rk_nok;
2012 }
2013
2014 mpp_logi("dump obj %-12s - %p at %s by kernel\n", def->name, impl, caller);
2015
2016 ret = ioctl(p->obj.fd, KMPP_SHM_IOC_DUMP, impl->shm);
2017 if (ret)
2018 mpp_err("ioctl KMPP_SHM_IOC_DUMP failed ret %d\n", ret);
2019
2020 return ret ? rk_nok : rk_ok;
2021 }
2022
kmpp_shm_get(KmppShm * shm,rk_s32 size,const char * caller)2023 rk_s32 kmpp_shm_get(KmppShm *shm, rk_s32 size, const char *caller)
2024 {
2025 KmppObjs *p;
2026 KmppObjIocArg *ioc;
2027 rk_s32 ret = rk_nok;
2028
2029 if (!shm || !size) {
2030 mpp_loge_f("invalid param shm %p size %d at %s\n", shm, size, caller);
2031 return ret;
2032 }
2033
2034 *shm = NULL;
2035
2036 /* kernel objdef path */
2037 p = get_objs(caller);
2038 if (!p)
2039 return ret;
2040
2041 ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
2042
2043 ioc->count = 1;
2044 ioc->flag = 0;
2045 ioc->shm_req->shm_name = 0;
2046 ioc->shm_req->shm_size = size;
2047 ioc->shm_req->shm_flag = 0;
2048
2049 ret = ioctl(p->obj.fd, KMPP_SHM_IOC_GET_SHM, ioc);
2050 if (ret) {
2051 mpp_err("shm fd %d ioctl KMPP_SHM_IOC_GET_SHM failed at %s\n",
2052 p->obj.fd, caller);
2053 return ret;
2054 }
2055
2056 *shm = U64_TO_PTR(ioc->obj_sptr[0].uaddr);
2057
2058 return *shm ? rk_ok : rk_nok;
2059 }
2060
kmpp_shm_put(KmppShm shm,const char * caller)2061 rk_s32 kmpp_shm_put(KmppShm shm, const char *caller)
2062 {
2063 KmppObjs *p = get_objs(caller);
2064 rk_s32 ret = rk_nok;
2065
2066 if (!shm) {
2067 mpp_loge_f("invalid param shm %p at %s\n", shm, caller);
2068 return ret;
2069 }
2070
2071 if (!p)
2072 return ret;
2073
2074 if (p && p->obj.fd >= 0) {
2075 KmppShmPtr *sptr = (KmppShmPtr *)shm;
2076 KmppObjIocArg *ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
2077
2078 ioc->count = 1;
2079 ioc->flag = 0;
2080
2081 ioc->count = 1;
2082 ioc->flag = 0;
2083 ioc->obj_sptr[0].uaddr = sptr->uaddr;
2084 ioc->obj_sptr[0].kaddr = sptr->kaddr;
2085
2086 obj_dbg_flow("put shm %p entry [u:k] %llx:%llx at %s\n",
2087 sptr, sptr->uaddr, sptr->kaddr, caller);
2088
2089 ret = ioctl(p->obj.fd, KMPP_SHM_IOC_PUT_SHM, ioc);
2090 if (ret)
2091 mpp_err("ioctl KMPP_SHM_IOC_PUT_SHM failed ret %d at %s\n", ret, caller);
2092 }
2093
2094 return ret;
2095 }
2096
kmpp_shm_to_entry(KmppShm shm,const char * caller)2097 void *kmpp_shm_to_entry(KmppShm shm, const char *caller)
2098 {
2099 KmppObjs *p = get_objs(caller);
2100 KmppShmPtr *sptr = (KmppShmPtr *)shm;
2101
2102 if (!shm) {
2103 mpp_loge_f("invalid param shm %p at %s\n", shm, caller);
2104 return NULL;
2105 }
2106
2107 return sptr->uptr + p->entry_offset;
2108 }
2109