xref: /rockchip-linux_mpp/kmpp/base/kmpp_obj.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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