kmpp_obj.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. /* SPDX-License-Identifier: Apache-2.0 OR MIT */
  2. /*
  3. * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
  4. */
  5. #define MODULE_TAG "kmpp_obj"
  6. #include <string.h>
  7. #include <sys/ioctl.h>
  8. #include "mpp_list.h"
  9. #include "mpp_env.h"
  10. #include "mpp_mem.h"
  11. #include "mpp_debug.h"
  12. #include "mpp_common.h"
  13. #include "mpp_lock.h"
  14. #include "mpp_trie.h"
  15. #include "kmpp_obj_impl.h"
  16. #define KMPP_SHM_IOC_MAGIC 'm'
  17. #define KMPP_SHM_IOC_QUERY_INFO _IOW(KMPP_SHM_IOC_MAGIC, 1, unsigned int)
  18. #define KMPP_SHM_IOC_RELEASE_INFO _IOW(KMPP_SHM_IOC_MAGIC, 2, unsigned int)
  19. #define KMPP_SHM_IOC_GET_SHM _IOW(KMPP_SHM_IOC_MAGIC, 3, unsigned int)
  20. #define KMPP_SHM_IOC_PUT_SHM _IOW(KMPP_SHM_IOC_MAGIC, 4, unsigned int)
  21. #define KMPP_SHM_IOC_DUMP _IOW(KMPP_SHM_IOC_MAGIC, 5, unsigned int)
  22. #define OBJ_DBG_FLOW (0x00000001)
  23. #define OBJ_DBG_SHARE (0x00000002)
  24. #define OBJ_DBG_ENTRY (0x00000004)
  25. #define OBJ_DBG_HOOK (0x00000008)
  26. #define OBJ_DBG_IOCTL (0x00000010)
  27. #define OBJ_DBG_SET (0x00000040)
  28. #define OBJ_DBG_GET (0x00000080)
  29. #define obj_dbg(flag, fmt, ...) _mpp_dbg(kmpp_obj_debug, flag, fmt, ## __VA_ARGS__)
  30. #define obj_dbg_flow(fmt, ...) obj_dbg(OBJ_DBG_FLOW, fmt, ## __VA_ARGS__)
  31. #define obj_dbg_share(fmt, ...) obj_dbg(OBJ_DBG_SHARE, fmt, ## __VA_ARGS__)
  32. #define obj_dbg_entry(fmt, ...) obj_dbg(OBJ_DBG_ENTRY, fmt, ## __VA_ARGS__)
  33. #define obj_dbg_hook(fmt, ...) obj_dbg(OBJ_DBG_HOOK, fmt, ## __VA_ARGS__)
  34. #define obj_dbg_ioctl(fmt, ...) obj_dbg(OBJ_DBG_IOCTL, fmt, ## __VA_ARGS__)
  35. #define obj_dbg_set(fmt, ...) obj_dbg(OBJ_DBG_SET, fmt, ## __VA_ARGS__)
  36. #define obj_dbg_get(fmt, ...) obj_dbg(OBJ_DBG_GET, fmt, ## __VA_ARGS__)
  37. #define U64_TO_PTR(ptr) ((void *)(intptr_t)(ptr))
  38. #define ENTRY_TO_PTR(tbl, entry) (((char *)entry) + tbl->tbl.elem_offset)
  39. #define ENTRY_TO_s32_PTR(tbl, entry) ((rk_s32 *)ENTRY_TO_PTR(tbl, entry))
  40. #define ENTRY_TO_u32_PTR(tbl, entry) ((rk_u32 *)ENTRY_TO_PTR(tbl, entry))
  41. #define ENTRY_TO_s64_PTR(tbl, entry) ((rk_s64 *)ENTRY_TO_PTR(tbl, entry))
  42. #define ENTRY_TO_u64_PTR(tbl, entry) ((rk_u64 *)ENTRY_TO_PTR(tbl, entry))
  43. #define ENTRY_TO_obj_PTR(tbl, entry) ((KmppObj *)ENTRY_TO_PTR(tbl, entry))
  44. #define ENTRY_TO_ptr_PTR(tbl, entry) ((void **)ENTRY_TO_PTR(tbl, entry))
  45. #define ENTRY_TO_fp_PTR(tbl, entry) ((void **)ENTRY_TO_PTR(tbl, entry))
  46. #define ENTRY_TO_st_PTR(tbl, entry) ((void *)ENTRY_TO_PTR(tbl, entry))
  47. #define ENTRY_TO_shm_PTR(tbl, entry) ((void *)ENTRY_TO_PTR(tbl, entry))
  48. /* 32bit unsigned long pointer */
  49. #define ELEM_FLAG_U32_POS(offset) (((offset) & (~31)) / 8)
  50. #define ELEM_FLAG_BIT_POS(offset) ((offset) & 31)
  51. #define ENTRY_TO_FLAG_PTR(tbl, entry) ((rk_ul *)((rk_u8 *)entry + ELEM_FLAG_U32_POS(tbl->tbl.flag_offset)))
  52. #define ENTRY_SET_FLAG(tbl, entry) \
  53. *ENTRY_TO_FLAG_PTR(tbl, entry) |= 1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset))
  54. #define ENTRY_CLR_FLAG(tbl, entry) \
  55. *ENTRY_TO_FLAG_PTR(tbl, entry) &= ~(1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset)))
  56. #define ENTRY_TEST_FLAG(tbl, entry) \
  57. (*ENTRY_TO_FLAG_PTR(tbl, entry) & 1ul << (ELEM_FLAG_BIT_POS(tbl->tbl.flag_offset))) ? 1 : 0
  58. /* kernel object share memory get / put ioctl data */
  59. typedef struct KmppObjIocArg_t {
  60. /* address array element count */
  61. __u32 count;
  62. /* flag for batch operation */
  63. __u32 flag;
  64. /*
  65. * at KMPP_SHM_IOC_GET_SHM
  66. * name_uaddr - kernel object name in userspace address
  67. * obj_sptr - kernel object userspace / kernel address of KmppShmPtr
  68. *
  69. * at KMPP_SHM_IOC_PUT_SHM
  70. * obj_sptr - kernel object userspace / kernel address of KmppShmPtr
  71. */
  72. union {
  73. __u64 name_uaddr[0];
  74. /* ioctl object userspace / kernel address */
  75. KmppShmPtr obj_sptr[0];
  76. };
  77. } KmppObjIocArg;
  78. typedef struct KmppObjDefImpl_t {
  79. MppTrie trie;
  80. rk_s32 index;
  81. rk_s32 ref_cnt;
  82. rk_s32 entry_size;
  83. const char *name;
  84. } KmppObjDefImpl;
  85. typedef struct KmppObjImpl_t {
  86. const char *name;
  87. /* class infomation link */
  88. KmppObjDefImpl *def;
  89. /* trie for fast access */
  90. MppTrie trie;
  91. /* malloc flag */
  92. rk_u32 need_free;
  93. KmppShmPtr *shm;
  94. void *entry;
  95. } KmppObjImpl;
  96. typedef struct KmppObjs_t {
  97. rk_s32 fd;
  98. rk_s32 count;
  99. rk_s32 entry_offset;
  100. rk_s32 priv_offset;
  101. rk_s32 name_offset;
  102. MppTrie trie;
  103. void *root;
  104. KmppObjDefImpl defs[0];
  105. } KmppObjs;
  106. static rk_u32 kmpp_obj_debug = 0;
  107. static KmppObjs *objs = NULL;
  108. #define get_objs(caller) \
  109. ({ \
  110. KmppObjs *__tmp; \
  111. if (objs) { \
  112. __tmp = objs; \
  113. } else { \
  114. obj_dbg_flow("kmpp objs srv not init at %s\n", caller); \
  115. __tmp = NULL; \
  116. } \
  117. __tmp; \
  118. })
  119. #define get_objs_f() get_objs(__FUNCTION__)
  120. const char *strof_entry_type(EntryType type)
  121. {
  122. static const char *ELEM_TYPE_names[] = {
  123. [ELEM_TYPE_s32] = "s32",
  124. [ELEM_TYPE_u32] = "u32",
  125. [ELEM_TYPE_s64] = "s64",
  126. [ELEM_TYPE_u64] = "u64",
  127. [ELEM_TYPE_st] = "struct",
  128. [ELEM_TYPE_shm] = "shm_ptr",
  129. [ELEM_TYPE_kobj] = "kobj",
  130. [ELEM_TYPE_kptr] = "kptr",
  131. [ELEM_TYPE_kfp] = "kfunc_ptr",
  132. [ELEM_TYPE_uobj] = "uobj",
  133. [ELEM_TYPE_uptr] = "uptr",
  134. [ELEM_TYPE_ufp] = "ufunc_ptr",
  135. };
  136. static const char *invalid_type_str = "invalid";
  137. if (type & (~ELEM_TYPE_BUTT))
  138. return invalid_type_str;
  139. return ELEM_TYPE_names[type] ? ELEM_TYPE_names[type] : invalid_type_str;
  140. }
  141. #define MPP_OBJ_ACCESS_IMPL(type, base_type, log_str) \
  142. rk_s32 kmpp_obj_impl_set_##type(KmppEntry *tbl, void *entry, base_type val) \
  143. { \
  144. base_type *dst = ENTRY_TO_##type##_PTR(tbl, entry); \
  145. base_type old = dst[0]; \
  146. dst[0] = val; \
  147. if (!tbl->tbl.flag_offset) { \
  148. obj_dbg_set("%p + %x set " #type " change " #log_str " -> " #log_str "\n", entry, tbl->tbl.elem_offset, old, val); \
  149. } else { \
  150. if (old != val) { \
  151. obj_dbg_set("%p + %x set " #type " update " #log_str " -> " #log_str " flag %d\n", \
  152. entry, tbl->tbl.elem_offset, old, val, tbl->tbl.flag_offset); \
  153. ENTRY_SET_FLAG(tbl, entry); \
  154. } else { \
  155. obj_dbg_set("%p + %x set " #type " keep " #log_str "\n", entry, tbl->tbl.elem_offset, old); \
  156. } \
  157. } \
  158. return rk_ok; \
  159. } \
  160. rk_s32 kmpp_obj_impl_get_##type(KmppEntry *tbl, void *entry, base_type *val) \
  161. { \
  162. if (tbl && tbl->tbl.elem_size) { \
  163. base_type *src = ENTRY_TO_##type##_PTR(tbl, entry); \
  164. obj_dbg_get("%p + %x get " #type " value " #log_str "\n", entry, tbl->tbl.elem_offset, src[0]); \
  165. val[0] = src[0]; \
  166. return rk_ok; \
  167. } \
  168. return rk_nok; \
  169. }
  170. MPP_OBJ_ACCESS_IMPL(s32, rk_s32, % d)
  171. MPP_OBJ_ACCESS_IMPL(u32, rk_u32, % u)
  172. MPP_OBJ_ACCESS_IMPL(s64, rk_s64, % #llx)
  173. MPP_OBJ_ACCESS_IMPL(u64, rk_u64, % #llx)
  174. MPP_OBJ_ACCESS_IMPL(obj, KmppObj, % p)
  175. MPP_OBJ_ACCESS_IMPL(ptr, void *, % p)
  176. MPP_OBJ_ACCESS_IMPL(fp, void *, % p)
  177. #define MPP_OBJ_STRUCT_ACCESS_IMPL(type, base_type, log_str) \
  178. rk_s32 kmpp_obj_impl_set_##type(KmppEntry *tbl, void *entry, base_type *val) \
  179. { \
  180. void *dst = ENTRY_TO_##type##_PTR(tbl, entry); \
  181. if (!tbl->tbl.flag_offset) { \
  182. /* simple copy */ \
  183. obj_dbg_set("%p + %x set " #type " size %d change %p -> %p\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst, val); \
  184. memcpy(dst, val, tbl->tbl.elem_size); \
  185. return rk_ok; \
  186. } \
  187. /* copy with flag check and updata */ \
  188. if (memcmp(dst, val, tbl->tbl.elem_size)) { \
  189. obj_dbg_set("%p + %x set " #type " size %d update %p -> %p flag %d\n", \
  190. entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst, val, tbl->tbl.flag_offset); \
  191. memcpy(dst, val, tbl->tbl.elem_size); \
  192. ENTRY_SET_FLAG(tbl, entry); \
  193. } else { \
  194. obj_dbg_set("%p + %x set " #type " size %d keep %p\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, dst); \
  195. } \
  196. return rk_ok; \
  197. } \
  198. rk_s32 kmpp_obj_impl_get_##type(KmppEntry *tbl, void *entry, base_type *val) \
  199. { \
  200. if (tbl && tbl->tbl.elem_size) { \
  201. void *src = ENTRY_TO_##type##_PTR(tbl, entry); \
  202. obj_dbg_get("%p + %x get " #type " size %d value " #log_str "\n", entry, tbl->tbl.elem_offset, tbl->tbl.elem_size, src); \
  203. memcpy(val, src, tbl->tbl.elem_size); \
  204. return rk_ok; \
  205. } \
  206. return rk_nok; \
  207. }
  208. MPP_OBJ_STRUCT_ACCESS_IMPL(st, void, % p)
  209. MPP_OBJ_STRUCT_ACCESS_IMPL(shm, KmppShmPtr, % p)
  210. __attribute__ ((destructor))
  211. void kmpp_objs_deinit(void)
  212. {
  213. KmppObjs *p = MPP_FETCH_AND(&objs, NULL);
  214. obj_dbg_flow("kmpp_objs_deinit objs %p\n", p);
  215. if (p) {
  216. rk_s32 i;
  217. for (i = 0; i < p->count; i++) {
  218. KmppObjDefImpl *impl = &p->defs[i];
  219. if (impl->trie) {
  220. mpp_trie_deinit(impl->trie);
  221. impl->trie = NULL;
  222. }
  223. }
  224. if (p->trie) {
  225. mpp_trie_deinit(p->trie);
  226. p->trie = NULL;
  227. }
  228. if (p->fd > 0) {
  229. close(p->fd);
  230. p->fd = -1;
  231. }
  232. mpp_free(p);
  233. }
  234. }
  235. __attribute__ ((constructor))
  236. void kmpp_objs_init(void)
  237. {
  238. static const char *dev = "/dev/kmpp_objs";
  239. KmppObjs *p = objs;
  240. void *root = NULL;
  241. MppTrie trie = NULL;
  242. MppTrieInfo *info;
  243. rk_s32 fd = -1;
  244. rk_s32 offset;
  245. rk_s32 count;
  246. rk_s32 ret;
  247. rk_s32 i;
  248. if (p) {
  249. obj_dbg_flow("objs already inited %p\n", p);
  250. kmpp_objs_deinit();
  251. p = NULL;
  252. }
  253. mpp_env_get_u32("kmpp_obj_debug", &kmpp_obj_debug, 0);
  254. fd = open(dev, O_RDWR);
  255. if (fd < 0) {
  256. obj_dbg_flow("%s open failed ret fd %d\n", dev, fd);
  257. goto __failed;
  258. }
  259. {
  260. rk_u64 uaddr = 0;
  261. ret = ioctl(fd, KMPP_SHM_IOC_QUERY_INFO, &uaddr);
  262. if (ret < 0) {
  263. mpp_loge_f("%s ioctl failed ret %d\n", dev, ret);
  264. goto __failed;
  265. }
  266. root = (void *)(intptr_t)uaddr;
  267. obj_dbg_share("query fd %d root %p from kernel\n", fd, root);
  268. }
  269. ret = mpp_trie_init_by_root(&trie, root);
  270. if (ret || !trie) {
  271. mpp_loge_f("init trie by root failed ret %d\n", ret);
  272. goto __failed;
  273. }
  274. if (kmpp_obj_debug & OBJ_DBG_SHARE)
  275. mpp_trie_dump_f(trie);
  276. info = mpp_trie_get_info(trie, "__count");
  277. count = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
  278. p = mpp_calloc_size(KmppObjs, sizeof(KmppObjs) + sizeof(KmppObjDefImpl) * count);
  279. if (!p) {
  280. mpp_loge_f("alloc objs failed\n");
  281. goto __failed;
  282. }
  283. p->fd = fd;
  284. p->count = count;
  285. p->trie = trie;
  286. p->root = root;
  287. info = mpp_trie_get_info(trie, "__offset");
  288. offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
  289. p->entry_offset = offset;
  290. info = mpp_trie_get_info(trie, "__priv");
  291. offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
  292. p->priv_offset = offset;
  293. info = mpp_trie_get_info(trie, "__name_offset");
  294. offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0;
  295. p->name_offset = offset;
  296. obj_dbg_share("count %d object offsets - priv %d name %d entry %d\n", count,
  297. p->priv_offset, p->name_offset, p->entry_offset);
  298. info = mpp_trie_get_info_first(trie);
  299. for (i = 0; i < count && info; i++) {
  300. KmppObjDefImpl *impl = &p->defs[i];
  301. const char *name = mpp_trie_info_name(info);
  302. MppTrie trie_objdef = NULL;
  303. MppTrieInfo *info_objdef;
  304. offset = *(rk_s32 *)mpp_trie_info_ctx(info);
  305. ret = mpp_trie_init_by_root(&trie_objdef, root + offset);
  306. if (!trie_objdef) {
  307. mpp_loge_f("init %d:%d obj trie failed\n", count, i);
  308. break;
  309. }
  310. impl->trie = trie_objdef;
  311. info_objdef = mpp_trie_get_info(trie_objdef, "__index");
  312. impl->index = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : -1;
  313. info_objdef = mpp_trie_get_info(trie_objdef, "__size");
  314. impl->entry_size = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : 0;
  315. impl->name = name;
  316. info = mpp_trie_get_info_next(trie, info);
  317. obj_dbg_share("%2d:%2d - %s offset %d entry_size %d\n",
  318. count, i, name, offset, impl->entry_size);
  319. }
  320. objs = p;
  321. return;
  322. __failed:
  323. if (fd > 0) {
  324. close(fd);
  325. fd = -1;
  326. }
  327. if (trie) {
  328. mpp_trie_deinit(trie);
  329. trie = NULL;
  330. }
  331. }
  332. rk_s32 kmpp_objdef_put(KmppObjDef def)
  333. {
  334. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  335. rk_s32 ret = rk_nok;
  336. if (impl) {
  337. impl->ref_cnt--;
  338. if (!impl->ref_cnt) {
  339. if (impl->trie) {
  340. ret = mpp_trie_deinit(impl->trie);
  341. impl->trie = NULL;
  342. }
  343. }
  344. ret = rk_ok;
  345. }
  346. return ret;
  347. }
  348. rk_s32 kmpp_objdef_get(KmppObjDef *def, const char *name)
  349. {
  350. KmppObjs *p = get_objs_f();
  351. MppTrieInfo *info = NULL;
  352. if (!def || !name) {
  353. mpp_loge_f("invalid param def %p name %p objs %p\n", def, name, p);
  354. return rk_nok;
  355. }
  356. *def = NULL;
  357. if (!p)
  358. return rk_nok;
  359. info = mpp_trie_get_info(p->trie, name);
  360. if (!info) {
  361. mpp_loge_f("failed to get objdef %s\n", name);
  362. return rk_nok;
  363. }
  364. if (p->count > 0 && info->index < (RK_U32)p->count) {
  365. KmppObjDefImpl *impl = &p->defs[info->index];
  366. impl->ref_cnt++;
  367. *def = impl;
  368. return rk_ok;
  369. }
  370. mpp_loge_f("failed to get objdef %s index %d max %d\n",
  371. name, info->index, p->count);
  372. return rk_nok;
  373. }
  374. rk_s32 kmpp_objdef_get_entry(KmppObjDef def, const char *name, KmppEntry **tbl)
  375. {
  376. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  377. rk_s32 ret = rk_nok;
  378. if (impl->trie) {
  379. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
  380. if (info) {
  381. *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  382. ret = rk_ok;
  383. }
  384. }
  385. if (ret)
  386. mpp_loge("objdef %s get entry %s failed ret %d\n",
  387. impl ? impl->name : NULL, name, ret);
  388. return ret;
  389. }
  390. rk_s32 kmpp_objdef_get_offset(KmppObjDef def, const char *name)
  391. {
  392. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  393. rk_s32 offset = -1;
  394. if (impl->trie) {
  395. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
  396. if (info) {
  397. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  398. if (tbl)
  399. offset = tbl->tbl.elem_offset;
  400. }
  401. }
  402. return offset;
  403. }
  404. rk_s32 kmpp_objdef_dump(KmppObjDef def)
  405. {
  406. if (def) {
  407. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  408. MppTrie trie = impl->trie;
  409. MppTrieInfo *info = NULL;
  410. const char *name = impl->name;
  411. RK_S32 i = 0;
  412. mpp_logi("dump objdef %-16s entry_size %d element count %d\n",
  413. name, impl->entry_size, mpp_trie_get_info_count(trie));
  414. info = mpp_trie_get_info_first(trie);
  415. while (info) {
  416. name = mpp_trie_info_name(info);
  417. if (!strstr(name, "__")) {
  418. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  419. rk_s32 idx = i++;
  420. mpp_logi("%-2d - %-16s offset %4d size %d\n", idx,
  421. name, tbl->tbl.elem_offset, tbl->tbl.elem_size);
  422. }
  423. info = mpp_trie_get_info_next(trie, info);
  424. }
  425. info = mpp_trie_get_info_first(trie);
  426. while (info) {
  427. name = mpp_trie_info_name(info);
  428. if (strstr(name, "__")) {
  429. void *p = mpp_trie_info_ctx(info);
  430. rk_s32 idx = i++;
  431. if (info->ctx_len == sizeof(RK_U32)) {
  432. mpp_logi("%-2d - %-16s val %d\n", idx, name, *(RK_U32 *)p);
  433. } else {
  434. mpp_logi("%-2d - %-16s str %s\n", idx, name, p);
  435. }
  436. }
  437. info = mpp_trie_get_info_next(trie, info);
  438. }
  439. return rk_ok;
  440. }
  441. return rk_nok;
  442. }
  443. const char *kmpp_objdef_get_name(KmppObjDef def)
  444. {
  445. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  446. return impl ? impl->name : NULL;
  447. }
  448. rk_s32 kmpp_objdef_get_entry_size(KmppObjDef def)
  449. {
  450. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  451. return impl ? impl->entry_size : 0;
  452. }
  453. MppTrie kmpp_objdef_get_trie(KmppObjDef def)
  454. {
  455. KmppObjDefImpl *impl = (KmppObjDefImpl *)def;
  456. return impl ? impl->trie : NULL;
  457. }
  458. rk_s32 kmpp_obj_get(KmppObj *obj, KmppObjDef def, const char *caller)
  459. {
  460. KmppObjs *p = get_objs(caller);
  461. KmppObjImpl *impl;
  462. KmppObjDefImpl *def_impl;
  463. KmppObjIocArg *ioc;
  464. rk_u64 uaddr;
  465. rk_s32 ret = rk_nok;
  466. if (!obj || !def) {
  467. mpp_loge_f("invalid param obj %p def %p at %s\n", obj, def, caller);
  468. return ret;
  469. }
  470. *obj = NULL;
  471. if (!p)
  472. return ret;
  473. def_impl = (KmppObjDefImpl *)def;
  474. impl = mpp_calloc(KmppObjImpl, 1);
  475. if (!impl) {
  476. mpp_loge_f("malloc obj impl %d failed at %s\n", sizeof(KmppObjImpl), caller);
  477. return ret;
  478. }
  479. ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
  480. ioc->count = 1;
  481. ioc->flag = 0;
  482. ioc->name_uaddr[0] = (__u64)(intptr_t)def_impl->name;
  483. ret = ioctl(p->fd, KMPP_SHM_IOC_GET_SHM, ioc);
  484. if (ret) {
  485. mpp_err("%s fd %d ioctl KMPP_SHM_IOC_GET_SHM failed at %s\n",
  486. def_impl->name, p->fd, caller);
  487. mpp_free(impl);
  488. return ret;
  489. }
  490. uaddr = ioc->obj_sptr[0].uaddr;
  491. impl->name = def_impl->name;
  492. impl->def = def;
  493. impl->trie = def_impl->trie;
  494. impl->need_free = 1;
  495. impl->shm = U64_TO_PTR(uaddr);
  496. impl->entry = U64_TO_PTR(uaddr + p->entry_offset);
  497. obj_dbg_flow("get obj %s - %p entry [u:k] %llx:%llx at %s\n", def_impl->name,
  498. impl, uaddr, ioc->obj_sptr[0].kaddr, caller);
  499. /* write userspace object address to share memory userspace private value */
  500. *(RK_U64 *)U64_TO_PTR(uaddr + p->priv_offset) = (RK_U64)(intptr_t)impl;
  501. *obj = impl;
  502. return rk_ok;
  503. }
  504. rk_s32 kmpp_obj_get_by_name(KmppObj *obj, const char *name, const char *caller)
  505. {
  506. KmppObjs *p = get_objs(caller);
  507. MppTrieInfo *info = NULL;
  508. if (!obj || !name) {
  509. mpp_loge_f("invalid param obj %p name %p objs %p at %s\n",
  510. obj, name, p, caller);
  511. return rk_nok;
  512. }
  513. *obj = NULL;
  514. if (!p)
  515. return rk_nok;
  516. info = mpp_trie_get_info(p->trie, name);
  517. if (!info) {
  518. mpp_loge_f("failed to get objdef %s at %s\n", name, caller);
  519. return rk_nok;
  520. }
  521. if (p->count > 0 && info->index < (RK_U32)p->count) {
  522. KmppObjDefImpl *impl = &p->defs[info->index];
  523. /* NOTE: do NOT increase ref_cnt here */
  524. return kmpp_obj_get(obj, impl, caller);
  525. }
  526. mpp_loge_f("failed to get objdef %s index %d max %d at %s\n",
  527. name, info->index, p->count, caller);
  528. return rk_nok;
  529. }
  530. rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppShmPtr *sptr, const char *caller)
  531. {
  532. KmppObjs *p = get_objs(caller);
  533. KmppObjImpl *impl;
  534. KmppObjDefImpl *def;
  535. rk_u8 *uptr = sptr ? sptr->uptr : NULL;
  536. rk_s32 ret = rk_nok;
  537. if (!obj || !sptr || !uptr) {
  538. mpp_loge_f("invalid param obj %p sptr %p uptr %p at %s\n",
  539. obj, sptr, uptr, caller);
  540. return ret;
  541. }
  542. *obj = NULL;
  543. if (!p)
  544. return ret;
  545. {
  546. rk_u32 val = *((rk_u32 *)(uptr + p->name_offset));
  547. char *str;
  548. if (!val) {
  549. mpp_loge_f("invalid obj name offset %d at %s\n", val, caller);
  550. return ret;
  551. }
  552. str = (char *)p->root + val;
  553. kmpp_objdef_get((KmppObjDef *)&def, str);
  554. if (!def) {
  555. mpp_loge_f("failed to get objdef %p - %s at %s\n", str, str, caller);
  556. return ret;
  557. }
  558. }
  559. impl = mpp_calloc(KmppObjImpl, 1);
  560. if (!impl) {
  561. mpp_loge_f("malloc obj impl %d failed at %s\n", sizeof(KmppObjImpl), caller);
  562. return ret;
  563. }
  564. impl->name = def->name;
  565. impl->def = def;
  566. impl->trie = def->trie;
  567. impl->need_free = 1;
  568. impl->shm = (KmppShmPtr *)uptr;
  569. impl->entry = uptr + p->entry_offset;
  570. obj_dbg_flow("get obj %s - %p by sptr [u:k] %llx:%llx at %s\n", def->name,
  571. impl, sptr->uaddr, sptr->kaddr, caller);
  572. /* write userspace object address to share memory userspace private value */
  573. *(RK_U64 *)U64_TO_PTR(sptr->uaddr + p->priv_offset) = (RK_U64)(intptr_t)impl;
  574. *obj = impl;
  575. return rk_ok;
  576. }
  577. rk_s32 kmpp_obj_put(KmppObj obj, const char *caller)
  578. {
  579. if (obj) {
  580. KmppObjs *p = get_objs(caller);
  581. KmppObjImpl *impl = (KmppObjImpl *)obj;
  582. if (impl->shm && p && p->fd >= 0) {
  583. KmppObjIocArg *ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
  584. KmppObjDefImpl *def = impl->def;
  585. rk_s32 ret;
  586. ioc->count = 1;
  587. ioc->flag = 0;
  588. ioc->obj_sptr[0].uaddr = impl->shm->uaddr;
  589. ioc->obj_sptr[0].kaddr = impl->shm->kaddr;
  590. obj_dbg_flow("put obj %s - %p entry [u:k] %llx:%llx at %s\n", def ? def->name : NULL,
  591. impl, impl->shm->uaddr, impl->shm->kaddr, caller);
  592. ret = ioctl(p->fd, KMPP_SHM_IOC_PUT_SHM, ioc);
  593. if (ret)
  594. mpp_err("ioctl KMPP_SHM_IOC_PUT_SHM failed ret %d at %s\n", ret, caller);
  595. }
  596. impl->shm = NULL;
  597. if (impl->need_free)
  598. mpp_free(impl);
  599. return rk_ok;
  600. }
  601. return rk_nok;
  602. }
  603. rk_s32 kmpp_obj_check(KmppObj obj, const char *caller)
  604. {
  605. KmppObjImpl *impl = (KmppObjImpl *)obj;
  606. if (!impl) {
  607. mpp_loge_f("from %s failed for NULL arg\n", caller);
  608. return rk_nok;
  609. }
  610. if (!impl->name || !impl->def || impl->name != impl->def->name) {
  611. mpp_loge_f("from %s failed for name check %s but %s\n", caller,
  612. impl->def ? impl->def->name : NULL, impl->name);
  613. return rk_nok;
  614. }
  615. return rk_ok;
  616. }
  617. rk_s32 kmpp_obj_ioctl(KmppObj obj, rk_s32 cmd, KmppObj in, KmppObj out, const char *caller)
  618. {
  619. KmppObjIocArg *ioc_arg;
  620. KmppObjImpl *ioc = NULL;
  621. KmppObjImpl *impl = (KmppObjImpl *)obj;
  622. rk_s32 ret;
  623. rk_s32 fd;
  624. ret = kmpp_obj_get_by_name((KmppObj *)&ioc, "KmppIoc", caller);
  625. if (ret) {
  626. mpp_loge("failed to get KmppIoc ret %d\n", ret);
  627. return rk_nok;
  628. }
  629. fd = open("/dev/kmpp_ioctl", O_RDWR);
  630. if (fd < 0) {
  631. mpp_loge("failed to open /dev/kmpp_ioctl ret %d\n", fd);
  632. return rk_nok;
  633. }
  634. ioc_arg = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr));
  635. ioc_arg->count = 1;
  636. ioc_arg->flag = 0;
  637. ioc_arg->obj_sptr[0].uaddr = ioc->shm->uaddr;
  638. ioc_arg->obj_sptr[0].kaddr = ioc->shm->kaddr;
  639. obj_dbg_ioctl("ioctl arg %p obj_sptr [u:k] %llx : %llx\n", ioc_arg,
  640. ioc_arg->obj_sptr[0].uaddr, ioc_arg->obj_sptr[0].kaddr);
  641. obj_dbg_ioctl("ioctl def %s - %d cmd %d\n", impl->def->name, impl->def->index, cmd);
  642. kmpp_obj_set_u32(ioc, "def", impl->def->index);
  643. kmpp_obj_set_u32(ioc, "cmd", cmd);
  644. kmpp_obj_set_u32(ioc, "flag", 0);
  645. kmpp_obj_set_u32(ioc, "id", 0);
  646. if (in) {
  647. KmppObjImpl *impl_in = (KmppObjImpl *)in;
  648. kmpp_obj_set_shm(ioc, "in", impl_in->shm);
  649. obj_dbg_ioctl("ioctl [u:k] in %#llx : %#llx\n",
  650. impl_in->shm->uaddr, impl_in->shm->kaddr);
  651. }
  652. if (out) {
  653. KmppObjImpl *impl_out = (KmppObjImpl *)out;
  654. kmpp_obj_set_shm(ioc, "out", impl_out->shm);
  655. obj_dbg_ioctl("ioctl [u:k] in %#llx : %#llx\n",
  656. impl_out->shm->uaddr, impl_out->shm->kaddr);
  657. }
  658. ret = ioctl(fd, 0, ioc_arg);
  659. kmpp_obj_put(ioc, caller);
  660. close(fd);
  661. return ret;
  662. }
  663. KmppShmPtr *kmpp_obj_to_shm(KmppObj obj)
  664. {
  665. KmppObjImpl *impl = (KmppObjImpl *)obj;
  666. if (!impl) {
  667. mpp_loge("invalid obj %p\n", obj);
  668. return NULL;
  669. }
  670. return impl->shm;
  671. }
  672. rk_s32 kmpp_obj_to_shm_size(KmppObj obj)
  673. {
  674. (void)obj;
  675. return sizeof(KmppShmPtr);
  676. }
  677. const char *kmpp_obj_get_name(KmppObj obj)
  678. {
  679. KmppObjImpl *impl = (KmppObjImpl *)obj;
  680. if (impl && impl->def && impl->def->name)
  681. return impl->def->name;
  682. return NULL;
  683. }
  684. void *kmpp_obj_to_entry(KmppObj obj)
  685. {
  686. KmppObjImpl *impl = (KmppObjImpl *)obj;
  687. return impl ? impl->entry : NULL;
  688. }
  689. rk_s32 kmpp_obj_to_offset(KmppObj obj, const char *name)
  690. {
  691. KmppObjImpl *impl = (KmppObjImpl *)obj;
  692. if (!impl || !name) {
  693. mpp_loge("invalid obj %p name %s\n", obj, name);
  694. return -1;
  695. }
  696. if (impl->trie) {
  697. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
  698. if (info) {
  699. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  700. if (tbl)
  701. return tbl->tbl.elem_offset;
  702. }
  703. }
  704. mpp_loge("invalid offset for name %s\n", name);
  705. return -1;
  706. }
  707. #define MPP_OBJ_ACCESS(type, base_type) \
  708. rk_s32 kmpp_obj_set_##type(KmppObj obj, const char *name, base_type val) \
  709. { \
  710. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  711. rk_s32 ret = rk_nok; \
  712. if (impl->trie) { \
  713. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
  714. if (info) { \
  715. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
  716. ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
  717. } \
  718. } \
  719. if (ret) \
  720. mpp_loge("obj %s set %s " #type " failed ret %d\n", \
  721. impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
  722. return ret; \
  723. } \
  724. rk_s32 kmpp_obj_get_##type(KmppObj obj, const char *name, base_type *val) \
  725. { \
  726. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  727. rk_s32 ret = rk_nok; \
  728. if (impl->trie) { \
  729. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
  730. if (info) { \
  731. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
  732. ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
  733. } \
  734. } \
  735. if (ret) \
  736. mpp_loge("obj %s get %s " #type " failed ret %d\n", \
  737. impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
  738. return ret; \
  739. }
  740. MPP_OBJ_ACCESS(s32, rk_s32)
  741. MPP_OBJ_ACCESS(u32, rk_u32)
  742. MPP_OBJ_ACCESS(s64, rk_s64)
  743. MPP_OBJ_ACCESS(u64, rk_u64)
  744. MPP_OBJ_ACCESS(obj, KmppObj)
  745. MPP_OBJ_ACCESS(ptr, void *)
  746. MPP_OBJ_ACCESS(fp, void *)
  747. #define MPP_OBJ_STRUCT_ACCESS(type, base_type) \
  748. rk_s32 kmpp_obj_set_##type(KmppObj obj, const char *name, base_type *val) \
  749. { \
  750. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  751. rk_s32 ret = rk_nok; \
  752. if (impl->trie) { \
  753. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
  754. if (info) { \
  755. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
  756. ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
  757. } \
  758. } \
  759. if (ret) \
  760. mpp_loge("obj %s set %s " #type " failed ret %d\n", \
  761. impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
  762. return ret; \
  763. } \
  764. rk_s32 kmpp_obj_get_##type(KmppObj obj, const char *name, base_type *val) \
  765. { \
  766. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  767. rk_s32 ret = rk_nok; \
  768. if (impl->trie) { \
  769. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name); \
  770. if (info) { \
  771. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info); \
  772. ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
  773. } \
  774. } \
  775. if (ret) \
  776. mpp_loge("obj %s get %s " #type " failed ret %d\n", \
  777. impl ? impl->def ? impl->def->name : NULL : NULL, name, ret); \
  778. return ret; \
  779. }
  780. MPP_OBJ_STRUCT_ACCESS(st, void)
  781. MPP_OBJ_STRUCT_ACCESS(shm, KmppShmPtr)
  782. #define MPP_OBJ_TBL_ACCESS(type, base_type) \
  783. rk_s32 kmpp_obj_tbl_set_##type(KmppObj obj, KmppEntry *tbl, base_type val) \
  784. { \
  785. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  786. rk_s32 ret = rk_nok; \
  787. if (impl) \
  788. ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
  789. if (ret) \
  790. mpp_loge("obj %s tbl %08x set " #type " failed ret %d\n", \
  791. impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
  792. return ret; \
  793. } \
  794. rk_s32 kmpp_obj_tbl_get_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
  795. { \
  796. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  797. rk_s32 ret = rk_nok; \
  798. if (impl) \
  799. ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
  800. if (ret) \
  801. mpp_loge("obj %s tbl %08x get " #type " failed ret %d\n", \
  802. impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
  803. return ret; \
  804. }
  805. MPP_OBJ_TBL_ACCESS(s32, rk_s32)
  806. MPP_OBJ_TBL_ACCESS(u32, rk_u32)
  807. MPP_OBJ_TBL_ACCESS(s64, rk_s64)
  808. MPP_OBJ_TBL_ACCESS(u64, rk_u64)
  809. MPP_OBJ_TBL_ACCESS(obj, KmppObj)
  810. MPP_OBJ_TBL_ACCESS(ptr, void *)
  811. MPP_OBJ_TBL_ACCESS(fp, void *)
  812. #define MPP_OBJ_STRUCT_TBL_ACCESS(type, base_type) \
  813. rk_s32 kmpp_obj_tbl_set_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
  814. { \
  815. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  816. rk_s32 ret = rk_nok; \
  817. if (impl) \
  818. ret = kmpp_obj_impl_set_##type(tbl, impl->entry, val); \
  819. if (ret) \
  820. mpp_loge("obj %s tbl %08x set " #type " failed ret %d\n", \
  821. impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
  822. return ret; \
  823. } \
  824. rk_s32 kmpp_obj_tbl_get_##type(KmppObj obj, KmppEntry *tbl, base_type *val) \
  825. { \
  826. KmppObjImpl *impl = (KmppObjImpl *)obj; \
  827. rk_s32 ret = rk_nok; \
  828. if (impl) \
  829. ret = kmpp_obj_impl_get_##type(tbl, impl->entry, val); \
  830. if (ret) \
  831. mpp_loge("obj %s tbl %08x get " #type " failed ret %d\n", \
  832. impl ? impl->def ? impl->def->name : NULL : NULL, tbl ? tbl->val : 0, ret); \
  833. return ret; \
  834. }
  835. MPP_OBJ_STRUCT_TBL_ACCESS(st, void)
  836. MPP_OBJ_STRUCT_TBL_ACCESS(shm, KmppShmPtr)
  837. rk_s32 kmpp_obj_set_shm_obj(KmppObj obj, const char *name, KmppObj val)
  838. {
  839. rk_s32 ret = rk_nok;
  840. if (!obj || !name || !val) {
  841. mpp_loge_f("obj %p set shm obj %s to %p failed invalid param\n",
  842. obj, name, val);
  843. } else {
  844. KmppShmPtr *sptr = kmpp_obj_to_shm(val);
  845. if (!sptr) {
  846. mpp_loge_f("obj %p found invalid shm ptr\n", val);
  847. } else {
  848. ret = kmpp_obj_set_shm(obj, name, sptr);
  849. }
  850. }
  851. return ret;
  852. }
  853. rk_s32 kmpp_obj_get_shm_obj(KmppObj obj, const char *name, KmppObj *val)
  854. {
  855. rk_s32 ret = rk_nok;
  856. if (!obj || !name || !val) {
  857. mpp_loge_f("obj %p get shm obj %s to %p failed invalid param\n",
  858. obj, name, val);
  859. } else {
  860. KmppObjImpl *impl = (KmppObjImpl *)obj;
  861. KmppShmPtr sptr = {0};
  862. *val = NULL;
  863. ret = kmpp_obj_get_shm(obj, name, &sptr);
  864. if (ret || !sptr.uptr) {
  865. mpp_loge_f("obj %p get shm %s failed ret %d\n", impl, name, ret);
  866. } else {
  867. ret = kmpp_obj_get_by_sptr(val, &sptr, __FUNCTION__);
  868. }
  869. }
  870. return ret;
  871. }
  872. rk_s32 kmpp_obj_test(KmppObj obj, const char *name)
  873. {
  874. KmppObjImpl *impl = (KmppObjImpl *)obj;
  875. if (impl && impl->trie) {
  876. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
  877. if (info) {
  878. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  879. return ENTRY_TEST_FLAG(tbl, impl->entry);;
  880. }
  881. }
  882. return 0;
  883. }
  884. rk_s32 kmpp_obj_tbl_test(KmppObj obj, KmppEntry *tbl)
  885. {
  886. KmppObjImpl *impl = (KmppObjImpl *)obj;
  887. return (impl && tbl) ? ENTRY_TEST_FLAG(tbl, impl->entry) : 0;
  888. }
  889. static rk_s32 kmpp_obj_impl_run(rk_s32 (*run)(void *ctx), void *ctx)
  890. {
  891. return run(ctx);
  892. }
  893. rk_s32 kmpp_obj_run(KmppObj obj, const char *name)
  894. {
  895. KmppObjImpl *impl = (KmppObjImpl *)obj;
  896. rk_s32 ret = rk_nok;
  897. if (impl->trie) {
  898. MppTrieInfo *info = mpp_trie_get_info(impl->trie, name);
  899. void *val = NULL;
  900. if (info) {
  901. KmppEntry *tbl = (KmppEntry *)mpp_trie_info_ctx(info);
  902. ret = kmpp_obj_impl_get_fp(tbl, impl->entry, &val);
  903. }
  904. if (val)
  905. ret = kmpp_obj_impl_run(val, impl->entry);
  906. }
  907. return ret;
  908. }
  909. rk_s32 kmpp_obj_udump_f(KmppObj obj, const char *caller)
  910. {
  911. KmppObjImpl *impl = (KmppObjImpl *)obj;
  912. KmppObjDefImpl *def = impl ? impl->def : NULL;
  913. MppTrie trie = NULL;
  914. MppTrieInfo *info = NULL;
  915. MppTrieInfo *next = NULL;
  916. const char *name = NULL;
  917. rk_s32 ret = rk_nok;
  918. RK_S32 i = 0;
  919. if (!impl || !def) {
  920. mpp_loge_f("invalid obj %p def %p\n", impl, def);
  921. return rk_nok;
  922. }
  923. trie = impl->trie;
  924. name = def->name;
  925. mpp_logi("dump obj %-12s - %p at %s:\n", name, impl, caller);
  926. next = mpp_trie_get_info_first(trie);
  927. while (next) {
  928. KmppEntry *e;
  929. rk_s32 idx;
  930. info = next;
  931. next = mpp_trie_get_info_next(trie, info);
  932. e = (KmppEntry *)mpp_trie_info_ctx(info);
  933. name = mpp_trie_info_name(info);
  934. if (strstr(name, "__"))
  935. continue;
  936. idx = i++;
  937. switch (e->tbl.elem_type) {
  938. case ELEM_TYPE_s32 : {
  939. rk_s32 val;
  940. rk_s32 val_chk;
  941. ret = kmpp_obj_tbl_get_s32(obj, e, &val);
  942. if (!ret)
  943. mpp_logi("%-2d - %-16s s32 %#x:%d\n", idx, name, val, val);
  944. else
  945. mpp_loge("%-2d - %-16s s32 get failed\n", idx, name);
  946. kmpp_obj_get_s32(obj, name, &val_chk);
  947. if (val != val_chk)
  948. mpp_loge("%-2d - %-16s s32 check failed\n", idx, name);
  949. } break;
  950. case ELEM_TYPE_u32 : {
  951. rk_u32 val;
  952. rk_u32 val_chk;
  953. ret = kmpp_obj_tbl_get_u32(obj, e, &val);
  954. if (!ret)
  955. mpp_logi("%-2d - %-16s u32 %#x:%u\n", idx, name, val, val);
  956. else
  957. mpp_loge("%-2d - %-16s u32 get failed\n", idx, name);
  958. kmpp_obj_get_u32(obj, name, &val_chk);
  959. if (val != val_chk)
  960. mpp_loge("%-2d - %-16s u32 check failed\n", idx, name);
  961. } break;
  962. case ELEM_TYPE_s64 : {
  963. rk_s64 val;
  964. rk_s64 val_chk;
  965. ret = kmpp_obj_tbl_get_s64(obj, e, &val);
  966. if (!ret)
  967. mpp_logi("%-2d - %-16s s64 %#llx:%lld\n", idx, name, val, val);
  968. else
  969. mpp_loge("%-2d - %-16s s64 get failed\n", idx, name);
  970. kmpp_obj_get_s64(obj, name, &val_chk);
  971. if (val != val_chk)
  972. mpp_loge("%-2d - %-16s s64 check failed\n", idx, name);
  973. } break;
  974. case ELEM_TYPE_u64 : {
  975. rk_u64 val;
  976. rk_u64 val_chk;
  977. ret = kmpp_obj_tbl_get_u64(obj, e, &val);
  978. if (!ret)
  979. mpp_logi("%-2d - %-16s u64 %#llx:%llu\n", idx, name, val, val);
  980. else
  981. mpp_loge("%-2d - %-16s u64 get failed\n", idx, name);
  982. kmpp_obj_get_u64(obj, name, &val_chk);
  983. if (val != val_chk)
  984. mpp_loge("%-2d - %-16s u64 check failed\n", idx, name);
  985. } break;
  986. case ELEM_TYPE_st : {
  987. void *val_chk = mpp_malloc_size(void, e->tbl.elem_size);
  988. void *val = mpp_malloc_size(void, e->tbl.elem_size);
  989. rk_s32 data_size = e->tbl.elem_size;
  990. char logs[128];
  991. ret = kmpp_obj_tbl_get_st(obj, e, val);
  992. if (!ret) {
  993. rk_s32 pos;
  994. rk_s32 j;
  995. mpp_logi("%-2d - %-16s st %d:%d\n", idx, name, e->tbl.elem_offset, data_size);
  996. j = 0;
  997. for (; j < data_size / 4 - 8; j += 8) {
  998. snprintf(logs, sizeof(logs) - 1, " - %02x : %#08x %#08x %#08x %#08x %#08x %#08x %#08x %#08x", j,
  999. ((RK_U32 *)val)[j + 0], ((RK_U32 *)val)[j + 1],
  1000. ((RK_U32 *)val)[j + 2], ((RK_U32 *)val)[j + 3],
  1001. ((RK_U32 *)val)[j + 4], ((RK_U32 *)val)[j + 5],
  1002. ((RK_U32 *)val)[j + 6], ((RK_U32 *)val)[j + 7]);
  1003. mpp_logi("%s\n", logs);
  1004. }
  1005. pos = snprintf(logs, sizeof(logs) - 1, " - %02x :", j);
  1006. for (; j < data_size / 4; j++)
  1007. pos += snprintf(logs + pos, sizeof(logs) - 1 - pos, " %#08x", ((RK_U32 *)val)[j]);
  1008. mpp_logi("%s\n", logs);
  1009. } else
  1010. mpp_loge("%-2d - %-16s st get failed\n", idx, name);
  1011. kmpp_obj_get_st(obj, name, val_chk);
  1012. if (memcmp(val, val_chk, e->tbl.elem_size)) {
  1013. mpp_loge("%-2d - %-16s st check failed\n", idx, name);
  1014. mpp_loge("val %p\n", val);
  1015. mpp_loge("val_chk %p\n", val_chk);
  1016. }
  1017. MPP_FREE(val);
  1018. MPP_FREE(val_chk);
  1019. } break;
  1020. case ELEM_TYPE_shm : {
  1021. KmppShmPtr *val_chk = mpp_malloc_size(void, e->tbl.elem_size);
  1022. KmppShmPtr *val = mpp_malloc_size(void, e->tbl.elem_size);
  1023. ret = kmpp_obj_tbl_get_st(obj, e, val);
  1024. if (!ret)
  1025. mpp_logi("%-2d - %-16s shm u%#llx:k%#llx\n",
  1026. idx, name, val->uaddr, val->kaddr);
  1027. else
  1028. mpp_loge("%-2d - %-16s shm get failed\n", idx, name);
  1029. kmpp_obj_get_st(obj, name, val_chk);
  1030. if (memcmp(val, val_chk, e->tbl.elem_size)) {
  1031. mpp_loge("%-2d - %-16s shm check failed\n", idx, name);
  1032. mpp_loge("val %p - %#llx:%#llx\n", val, val->uaddr, val->kaddr);
  1033. mpp_loge("val_chk %p - %#llx:%#llx\n", val_chk, val_chk->uaddr, val_chk->kaddr);
  1034. }
  1035. MPP_FREE(val);
  1036. MPP_FREE(val_chk);
  1037. } break;
  1038. case ELEM_TYPE_uptr : {
  1039. void *val;
  1040. void *val_chk;
  1041. ret = kmpp_obj_tbl_get_ptr(obj, e, &val);
  1042. if (!ret)
  1043. mpp_logi("%-2d - %-16s ptr %p\n", idx, name, val);
  1044. else
  1045. mpp_loge("%-2d - %-16s ptr get failed\n", idx, name);
  1046. kmpp_obj_get_ptr(obj, name, &val_chk);
  1047. if (val != val_chk)
  1048. mpp_loge("%-2d - %-16s ptr check failed\n", idx, name);
  1049. } break;
  1050. case ELEM_TYPE_ufp : {
  1051. void *val;
  1052. void *val_chk;
  1053. ret = kmpp_obj_tbl_get_fp(obj, e, &val);
  1054. if (!ret)
  1055. mpp_logi("%-2d - %-16s fp %p\n", idx, name, val);
  1056. else
  1057. mpp_loge("%-2d - %-16s fp get failed\n", idx, name);
  1058. kmpp_obj_get_fp(obj, name, &val_chk);
  1059. if (val != val_chk)
  1060. mpp_loge("%-2d - %-16s fp check failed\n", idx, name);
  1061. } break;
  1062. default : {
  1063. mpp_loge("%-2d - %-16s found invalid type %d\n", idx, name, e->tbl.elem_type);
  1064. ret = rk_nok;
  1065. } break;
  1066. }
  1067. }
  1068. return ret ? rk_nok : rk_ok;
  1069. }
  1070. rk_s32 kmpp_obj_kdump_f(KmppObj obj, const char *caller)
  1071. {
  1072. KmppObjs *p = get_objs(caller);
  1073. KmppObjImpl *impl = (KmppObjImpl *)obj;
  1074. KmppObjDefImpl *def = impl ? impl->def : NULL;
  1075. rk_s32 ret = rk_nok;
  1076. if (!impl || !def || !p) {
  1077. mpp_loge_f("invalid obj %p def %p objs %p\n", impl, def, p);
  1078. return rk_nok;
  1079. }
  1080. mpp_logi("dump obj %-12s - %p at %s by kernel\n", def->name, impl, caller);
  1081. ret = ioctl(p->fd, KMPP_SHM_IOC_DUMP, impl->shm);
  1082. if (ret)
  1083. mpp_err("ioctl KMPP_SHM_IOC_DUMP failed ret %d\n", ret);
  1084. return ret ? rk_nok : rk_ok;
  1085. }