From a4326e2cbc549ecdf7dd2131bfc79f8050fafba6 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Tue, 4 Mar 2025 15:27:42 +0800 Subject: [PATCH] feat[kmpp_obj]: Add more kmpp_obj functions 1. Add kmpp_obj_get_by_name for quick object creation. 2. Add kmpp_obj_get_by_sptr for quick shm import. 3. Add ioctl support and sample flow by KmppIoc. 4. Add KmppBuffer test to kmpp_obj_test. 5. Add kmpp_obj_set_shm_obj and kmpp_obj_get_shm_obj for obj access. 6. Rename obj handle to KmppShmPtr. Signed-off-by: Herman Chen Change-Id: I996fe5e6dc882c8ed943f0d3bd2c5c8a69a29cd0 --- mpp/base/inc/kmpp_obj.h | 19 +- mpp/base/kmpp_obj.c | 453 +++++++++++++++++++++++----------- mpp/base/test/kmpp_obj_test.c | 276 +++++++++++++++++---- mpp/kmpp.c | 8 +- 4 files changed, 561 insertions(+), 195 deletions(-) diff --git a/mpp/base/inc/kmpp_obj.h b/mpp/base/inc/kmpp_obj.h index 83ca346a..84856932 100644 --- a/mpp/base/inc/kmpp_obj.h +++ b/mpp/base/inc/kmpp_obj.h @@ -97,17 +97,20 @@ MppTrie kmpp_objdef_get_trie(KmppObjDef def); /* import kernel object ref */ rk_s32 kmpp_obj_get(KmppObj *obj, KmppObjDef def); -rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppObjDef def, KmppShmPtr *sptr); +rk_s32 kmpp_obj_get_by_name(KmppObj *obj, const char *name); +rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppShmPtr *sptr); rk_s32 kmpp_obj_put(KmppObj obj); rk_s32 kmpp_obj_check(KmppObj obj, const char *caller); +rk_s32 kmpp_obj_ioctl(KmppObj obj, rk_s32 cmd, KmppObj in, KmppObj out); -/* handle is the kernel share object userspace base address for kernel ioctl */ -void *kmpp_obj_get_hnd(KmppObj obj); -/* handle size defined the copy size for kernel ioctl */ -rk_s32 kmpp_obj_get_hnd_size(KmppObj obj); +/* KmppShmPtr is the kernel share object userspace base address for kernel ioctl */ +KmppShmPtr *kmpp_obj_to_shm(KmppObj obj); +/* KmppShmPtr size defined the copy size for kernel ioctl */ +rk_s32 kmpp_obj_to_shm_size(KmppObj obj); +const char *kmpp_obj_get_name(KmppObj obj); /* * entry is the userspace address for kernel share object body - * entry = handle + entry_offset + * entry = KmppShmPtr->uaddr + entry_offset */ void *kmpp_obj_get_entry(KmppObj obj); /* offset is the entry offset from kernel share object body */ @@ -155,6 +158,10 @@ rk_s32 kmpp_obj_get_shm(KmppObj obj, const char *name, KmppShmPtr *val); rk_s32 kmpp_obj_tbl_set_shm(KmppObj obj, KmppLocTbl *tbl, KmppShmPtr *val); rk_s32 kmpp_obj_tbl_get_shm(KmppObj obj, KmppLocTbl *tbl, KmppShmPtr *val); +/* helper for get share object from a share memory element */ +rk_s32 kmpp_obj_set_shm_obj(KmppObj obj, const char *name, KmppObj val); +rk_s32 kmpp_obj_get_shm_obj(KmppObj obj, const char *name, KmppObj *val); + /* run a callback function */ rk_s32 kmpp_obj_run(KmppObj obj, const char *name); /* dump by userspace */ diff --git a/mpp/base/kmpp_obj.c b/mpp/base/kmpp_obj.c index ff721548..d9b32a81 100644 --- a/mpp/base/kmpp_obj.c +++ b/mpp/base/kmpp_obj.c @@ -13,6 +13,7 @@ #include "mpp_mem.h" #include "mpp_debug.h" #include "mpp_common.h" +#include "mpp_lock.h" #include "mpp_trie.h" #include "kmpp_obj_impl.h" @@ -24,18 +25,23 @@ #define KMPP_SHM_IOC_PUT_SHM _IOW(KMPP_SHM_IOC_MAGIC, 4, unsigned int) #define KMPP_SHM_IOC_DUMP _IOW(KMPP_SHM_IOC_MAGIC, 5, unsigned int) -#define MPP_OBJ_DBG_FLOW (0x00000001) -#define MPP_OBJ_DBG_TRIE (0x00000002) -#define MPP_OBJ_DBG_SET (0x00000010) -#define MPP_OBJ_DBG_GET (0x00000020) +#define OBJ_DBG_FLOW (0x00000001) +#define OBJ_DBG_SHARE (0x00000002) +#define OBJ_DBG_ENTRY (0x00000004) +#define OBJ_DBG_HOOK (0x00000008) +#define OBJ_DBG_IOCTL (0x00000010) +#define OBJ_DBG_SET (0x00000040) +#define OBJ_DBG_GET (0x00000080) -#define kmpp_obj_dbg(flag, fmt, ...) _mpp_dbg(kmpp_obj_debug, flag, fmt, ## __VA_ARGS__) -#define kmpp_obj_dbg_f(flag, fmt, ...) _mpp_dbg_f(kmpp_obj_debug, flag, fmt, ## __VA_ARGS__) +#define obj_dbg(flag, fmt, ...) _mpp_dbg(kmpp_obj_debug, flag, fmt, ## __VA_ARGS__) -#define kmpp_obj_dbg_flow(fmt, ...) kmpp_obj_dbg(MPP_OBJ_DBG_FLOW, fmt, ## __VA_ARGS__) -#define kmpp_obj_dbg_trie(fmt, ...) kmpp_obj_dbg(MPP_OBJ_DBG_TRIE, fmt, ## __VA_ARGS__) -#define kmpp_obj_dbg_set(fmt, ...) kmpp_obj_dbg(MPP_OBJ_DBG_SET, fmt, ## __VA_ARGS__) -#define kmpp_obj_dbg_get(fmt, ...) kmpp_obj_dbg(MPP_OBJ_DBG_GET, fmt, ## __VA_ARGS__) +#define obj_dbg_flow(fmt, ...) obj_dbg(OBJ_DBG_FLOW, fmt, ## __VA_ARGS__) +#define obj_dbg_share(fmt, ...) obj_dbg(OBJ_DBG_SHARE, fmt, ## __VA_ARGS__) +#define obj_dbg_entry(fmt, ...) obj_dbg(OBJ_DBG_ENTRY, fmt, ## __VA_ARGS__) +#define obj_dbg_hook(fmt, ...) obj_dbg(OBJ_DBG_HOOK, fmt, ## __VA_ARGS__) +#define obj_dbg_ioctl(fmt, ...) obj_dbg(OBJ_DBG_IOCTL, fmt, ## __VA_ARGS__) +#define obj_dbg_set(fmt, ...) obj_dbg(OBJ_DBG_SET, fmt, ## __VA_ARGS__) +#define obj_dbg_get(fmt, ...) obj_dbg(OBJ_DBG_GET, fmt, ## __VA_ARGS__) #define U64_TO_PTR(ptr) ((void *)(intptr_t)(ptr)) @@ -52,28 +58,6 @@ #define ENTRY_TO_FLAG_PTR(tbl, entry) ((rk_u16 *)((char *)entry + tbl->flag_offset)) -/* kernel object trie share info */ -/* - * kernel object trie share info - * used in KMPP_SHM_IOC_QUERY_INFO - * - * input : object name userspace address - * output : trie_root userspace address (read only) - */ -typedef union KmppObjTrie_u { - __u64 name_uaddr; - __u64 trie_root; -} KmppObjTrie; - -/* kernel object share memory userspace visable header data */ -typedef struct KmppObjShm_t { - /* kobj_uaddr - the userspace base address for kernel object */ - __u64 kobj_uaddr; - /* kobj_kaddr - the kernel base address for kernel object */ - __u64 kobj_kaddr; - /* DO NOT access reserved data only used by kernel */ -} KmppObjShm; - /* kernel object share memory get / put ioctl data */ typedef struct KmppObjIocArg_t { /* address array element count */ @@ -85,24 +69,22 @@ typedef struct KmppObjIocArg_t { /* * at KMPP_SHM_IOC_GET_SHM * name_uaddr - kernel object name in userspace address - * kobj_uaddr - kernel object userspace address for KmppObjShm + * obj_sptr - kernel object userspace / kernel address of KmppShmPtr * * at KMPP_SHM_IOC_PUT_SHM - * kobj_uaddr - kernel object userspace address for KmppObjShm + * obj_sptr - kernel object userspace / kernel address of KmppShmPtr */ union { - __u64 name_uaddr[0]; - __u64 kobj_uaddr[0]; + __u64 name_uaddr[0]; + /* ioctl object userspace / kernel address */ + KmppShmPtr obj_sptr[0]; }; } KmppObjIocArg; typedef struct KmppObjDefImpl_t { MppTrie trie; - rk_s32 fd; rk_s32 index; rk_s32 ref_cnt; - rk_s32 priv_offset; - rk_s32 entry_offset; rk_s32 entry_size; const char *name_check; /* for object name address check */ const char *name; @@ -116,7 +98,7 @@ typedef struct KmppObjImpl_t { MppTrie trie; /* malloc flag */ rk_u32 need_free; - KmppObjShm *shm; + KmppShmPtr *shm; void *entry; } KmppObjImpl; @@ -125,27 +107,37 @@ typedef struct KmppObjs_t { rk_s32 count; rk_s32 entry_offset; rk_s32 priv_offset; + rk_s32 name_offset; MppTrie trie; + void *root; KmppObjDefImpl defs[0]; } KmppObjs; -//static rk_u32 kmpp_obj_debug = MPP_OBJ_DBG_SET | MPP_OBJ_DBG_GET; static rk_u32 kmpp_obj_debug = 0; -static LIST_HEAD(kmpp_obj_list); static KmppObjs *objs = NULL; const char *strof_entry_type(EntryType type) { static const char *entry_type_names[] = { - "rk_s32", - "rk_u32", - "rk_s64", - "rk_u64", - "void *", - "struct", + [ENTRY_TYPE_s32] = "s32", + [ENTRY_TYPE_u32] = "u32", + [ENTRY_TYPE_s64] = "s64", + [ENTRY_TYPE_u64] = "u64", + [ENTRY_TYPE_st] = "struct", + [ENTRY_TYPE_shm] = "shm_ptr", + [ENTRY_TYPE_kobj] = "kobj", + [ENTRY_TYPE_kptr] = "kptr", + [ENTRY_TYPE_kfp] = "kfunc_ptr", + [ENTRY_TYPE_uobj] = "uobj", + [ENTRY_TYPE_uptr] = "uptr", + [ENTRY_TYPE_ufp] = "ufunc_ptr", }; + static const char *invalid_type_str = "invalid"; - return entry_type_names[type]; + if (type & (~ENTRY_TYPE_BUTT)) + return invalid_type_str; + + return entry_type_names[type] ? entry_type_names[type] : invalid_type_str; } #define MPP_OBJ_ACCESS_IMPL(type, base_type, log_str) \ @@ -155,14 +147,14 @@ const char *strof_entry_type(EntryType type) base_type old = dst[0]; \ dst[0] = val; \ if (!tbl->flag_value) { \ - kmpp_obj_dbg_set("%p + %x set " #type " change " #log_str " -> " #log_str "\n", entry, tbl->data_offset, old, val); \ + obj_dbg_set("%p + %x set " #type " change " #log_str " -> " #log_str "\n", entry, tbl->data_offset, old, val); \ } else { \ if (old != val) { \ - kmpp_obj_dbg_set("%p + %x set " #type " update " #log_str " -> " #log_str " flag %d|%x\n", \ + obj_dbg_set("%p + %x set " #type " update " #log_str " -> " #log_str " flag %d|%x\n", \ entry, tbl->data_offset, old, val, tbl->flag_offset, tbl->flag_value); \ ENTRY_TO_FLAG_PTR(tbl, entry)[0] |= tbl->flag_value; \ } else { \ - kmpp_obj_dbg_set("%p + %x set " #type " keep " #log_str "\n", entry, tbl->data_offset, old); \ + obj_dbg_set("%p + %x set " #type " keep " #log_str "\n", entry, tbl->data_offset, old); \ } \ } \ return MPP_OK; \ @@ -171,7 +163,7 @@ const char *strof_entry_type(EntryType type) { \ if (tbl && tbl->data_size) { \ base_type *src = ENTRY_TO_##type##_PTR(tbl, entry); \ - kmpp_obj_dbg_get("%p + %x get " #type " value " #log_str "\n", entry, tbl->data_offset, src[0]); \ + obj_dbg_get("%p + %x get " #type " value " #log_str "\n", entry, tbl->data_offset, src[0]); \ val[0] = src[0]; \ return MPP_OK; \ } \ @@ -192,18 +184,18 @@ MPP_OBJ_ACCESS_IMPL(fp, void *, % p) void *dst = ENTRY_TO_##type##_PTR(tbl, entry); \ if (!tbl->flag_value) { \ /* simple copy */ \ - kmpp_obj_dbg_set("%p + %x set " #type " size %d change %p -> %p\n", entry, tbl->data_offset, tbl->data_size, dst, val); \ + obj_dbg_set("%p + %x set " #type " size %d change %p -> %p\n", entry, tbl->data_offset, tbl->data_size, dst, val); \ memcpy(dst, val, tbl->data_size); \ return MPP_OK; \ } \ /* copy with flag check and updata */ \ if (memcmp(dst, val, tbl->data_size)) { \ - kmpp_obj_dbg_set("%p + %x set " #type " size %d update %p -> %p flag %d|%x\n", \ + obj_dbg_set("%p + %x set " #type " size %d update %p -> %p flag %d|%x\n", \ entry, tbl->data_offset, tbl->data_size, dst, val, tbl->flag_offset, tbl->flag_value); \ memcpy(dst, val, tbl->data_size); \ ENTRY_TO_FLAG_PTR(tbl, entry)[0] |= tbl->flag_value; \ } else { \ - kmpp_obj_dbg_set("%p + %x set " #type " size %d keep %p\n", entry, tbl->data_offset, tbl->data_size, dst); \ + obj_dbg_set("%p + %x set " #type " size %d keep %p\n", entry, tbl->data_offset, tbl->data_size, dst); \ } \ return MPP_OK; \ } \ @@ -211,7 +203,7 @@ MPP_OBJ_ACCESS_IMPL(fp, void *, % p) { \ if (tbl && tbl->data_size) { \ void *src = ENTRY_TO_##type##_PTR(tbl, entry); \ - kmpp_obj_dbg_get("%p + %x get " #type " size %d value " #log_str "\n", entry, tbl->data_offset, tbl->data_size, src); \ + obj_dbg_get("%p + %x get " #type " size %d value " #log_str "\n", entry, tbl->data_offset, tbl->data_size, src); \ memcpy(val, src, tbl->data_size); \ return MPP_OK; \ } \ @@ -221,41 +213,79 @@ MPP_OBJ_ACCESS_IMPL(fp, void *, % p) MPP_OBJ_STRUCT_ACCESS_IMPL(st, void, % p) MPP_OBJ_STRUCT_ACCESS_IMPL(shm, KmppShmPtr, % p) +__attribute__ ((destructor)) +void kmpp_objs_deinit(void) +{ + KmppObjs *p = MPP_FETCH_AND(&objs, NULL); + + obj_dbg_flow("kmpp_objs_deinit objs %p\n", p); + + if (p) { + rk_s32 i; + + for (i = 0; i < p->count; i++) { + KmppObjDefImpl *impl = &p->defs[i]; + + if (impl->trie) { + mpp_trie_deinit(impl->trie); + impl->trie = NULL; + } + } + + if (p->trie) { + mpp_trie_deinit(p->trie); + p->trie = NULL; + } + + if (p->fd > 0) { + close(p->fd); + p->fd = -1; + } + + mpp_free(p); + } +} + __attribute__ ((constructor)) void kmpp_objs_init(void) { static const char *dev = "/dev/kmpp_objs"; - rk_s32 fd = -1; - rk_u64 ioc = 0; + KmppObjs *p = objs; void *root = NULL; MppTrie trie = NULL; MppTrieInfo *info; + rk_s32 fd = -1; rk_s32 offset; rk_s32 count; rk_s32 ret; rk_s32 i; - if (objs) { - mpp_loge_f("objs already inited %p\n", objs); - return; + if (p) { + obj_dbg_flow("objs already inited %p\n", p); + kmpp_objs_deinit(); + p = NULL; } mpp_env_get_u32("kmpp_obj_debug", &kmpp_obj_debug, 0); fd = open(dev, O_RDWR); if (fd < 0) { - kmpp_obj_dbg_flow("%s open failed ret fd %d\n", dev, fd); + obj_dbg_flow("%s open failed ret fd %d\n", dev, fd); goto __failed; } - ret = ioctl(fd, KMPP_SHM_IOC_QUERY_INFO, &ioc); - if (ret < 0) { - mpp_loge_f("%s ioctl failed ret %d\n", dev, ret); - goto __failed; - } + { + rk_u64 uaddr = 0; - root = (void *)(intptr_t)ioc; - kmpp_obj_dbg_trie("query fd %d root %p from kernel\n", fd, root); + ret = ioctl(fd, KMPP_SHM_IOC_QUERY_INFO, &uaddr); + if (ret < 0) { + mpp_loge_f("%s ioctl failed ret %d\n", dev, ret); + goto __failed; + } + + root = (void *)(intptr_t)uaddr; + obj_dbg_share("query fd %d root %p from kernel\n", fd, root); + } ret = mpp_trie_init_by_root(&trie, root); if (ret || !trie) { @@ -263,36 +293,40 @@ void kmpp_objs_init(void) goto __failed; } - if (kmpp_obj_debug & MPP_OBJ_DBG_TRIE) + if (kmpp_obj_debug & OBJ_DBG_SHARE) mpp_trie_dump_f(trie); info = mpp_trie_get_info(trie, "__count"); count = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0; - objs = mpp_calloc_size(KmppObjs, sizeof(KmppObjs) + sizeof(KmppObjDefImpl) * count); - if (!objs) { + p = mpp_calloc_size(KmppObjs, sizeof(KmppObjs) + sizeof(KmppObjDefImpl) * count); + if (!p) { mpp_loge_f("alloc objs failed\n"); goto __failed; } - objs->fd = fd; - objs->count = count; - objs->trie = trie; + p->fd = fd; + p->count = count; + p->trie = trie; + p->root = root; info = mpp_trie_get_info(trie, "__offset"); offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0; - objs->entry_offset = offset; + p->entry_offset = offset; info = mpp_trie_get_info(trie, "__priv"); offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0; - objs->priv_offset = offset; + p->priv_offset = offset; + info = mpp_trie_get_info(trie, "__name_offset"); + offset = info ? *(rk_s32 *)mpp_trie_info_ctx(info) : 0; + p->name_offset = offset; - kmpp_obj_dbg_trie("count %d object entry at %d priv at %d\n", count, - objs->entry_offset, objs->priv_offset); + obj_dbg_share("count %d object offsets - priv %d name %d entry %d\n", count, + p->priv_offset, p->name_offset, p->entry_offset); info = mpp_trie_get_info_first(trie); for (i = 0; i < count && info; i++) { - KmppObjDefImpl *impl = &objs->defs[i]; + KmppObjDefImpl *impl = &p->defs[i]; const char *name = mpp_trie_info_name(info); MppTrie trie_objdef = NULL; MppTrieInfo *info_objdef; @@ -305,19 +339,20 @@ void kmpp_objs_init(void) } impl->trie = trie_objdef; - impl->index = i; - impl->fd = fd; + + info_objdef = mpp_trie_get_info(trie_objdef, "__index"); + impl->index = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : -1; info_objdef = mpp_trie_get_info(trie_objdef, "__size"); impl->entry_size = info_objdef ? *(rk_s32 *)mpp_trie_info_ctx(info_objdef) : 0; - impl->entry_offset = objs->entry_offset; - impl->priv_offset = objs->priv_offset; impl->name = name; - info = mpp_trie_get_info_next(trie_objdef, info); - kmpp_obj_dbg_trie("name %s offset %d entry_size %d\n", - name, offset, impl->entry_size); + info = mpp_trie_get_info_next(trie, info); + obj_dbg_share("%2d:%2d - %s offset %d entry_size %d\n", + count, i, name, offset, impl->entry_size); } + objs = p; + return; __failed: @@ -331,37 +366,6 @@ __failed: } } -__attribute__ ((destructor)) -void kmpp_objs_deinit(void) -{ - kmpp_obj_dbg_flow("kmpp_objs_deinit objs %p\n", objs); - - if (objs) { - rk_s32 i; - - if (objs->fd > 0) { - close(objs->fd); - objs->fd = -1; - } - - if (objs->trie) { - mpp_trie_deinit(objs->trie); - objs->trie = NULL; - } - - for (i = 0; i < objs->count; i++) { - KmppObjDefImpl *impl = &objs->defs[i]; - - if (impl->trie) { - mpp_trie_deinit(impl->trie); - impl->trie = NULL; - } - } - - mpp_free(objs); - } -} - rk_s32 kmpp_objdef_put(KmppObjDef def) { KmppObjDefImpl *impl = (KmppObjDefImpl *)def; @@ -490,6 +494,7 @@ rk_s32 kmpp_obj_get(KmppObj *obj, KmppObjDef def) KmppObjImpl *impl; KmppObjDefImpl *def_impl; KmppObjIocArg *ioc; + rk_u64 uaddr; rk_s32 ret = MPP_NOK; if (!obj || !def) { @@ -505,63 +510,111 @@ rk_s32 kmpp_obj_get(KmppObj *obj, KmppObjDef def) return ret; } - ioc = alloca(sizeof(KmppObjIocArg) + sizeof(rk_u64)); + ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr)); ioc->count = 1; ioc->flag = 0; ioc->name_uaddr[0] = (__u64)(intptr_t)def_impl->name; - ret = ioctl(def_impl->fd, KMPP_SHM_IOC_GET_SHM, ioc); + ret = ioctl(objs->fd, KMPP_SHM_IOC_GET_SHM, ioc); if (ret) { mpp_err("%s fd %d ioctl KMPP_SHM_IOC_GET_SHM failed\n", - def_impl->name, def_impl->fd); + def_impl->name, objs->fd); mpp_free(impl); return ret; } + uaddr = ioc->obj_sptr[0].uaddr; impl->name_check = def_impl->name_check; impl->def = def; impl->trie = def_impl->trie; impl->need_free = 1; - impl->shm = U64_TO_PTR(ioc->kobj_uaddr[0]); - impl->entry = U64_TO_PTR(ioc->kobj_uaddr[0] + def_impl->entry_offset); + impl->shm = U64_TO_PTR(uaddr); + impl->entry = U64_TO_PTR(uaddr + objs->entry_offset); /* write userspace object address to share memory userspace private value */ - *(RK_U64 *)U64_TO_PTR(ioc->kobj_uaddr[0] + def_impl->priv_offset) = (RK_U64)(intptr_t)impl; + *(RK_U64 *)U64_TO_PTR(uaddr + objs->priv_offset) = (RK_U64)(intptr_t)impl; *obj = impl; return MPP_OK; } -rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppObjDef def, KmppShmPtr *sptr) +rk_s32 kmpp_obj_get_by_name(KmppObj *obj, const char *name) +{ + KmppObjs *p = objs; + MppTrieInfo *info = NULL; + + if (!obj || !name || !p) { + mpp_loge_f("invalid param obj %p name %p objs %p\n", obj, name, p); + return MPP_NOK; + } + + info = mpp_trie_get_info(p->trie, name); + if (!info) { + mpp_loge_f("failed to get objdef %s\n", name); + return MPP_NOK; + } + + if (p->count > 0 && info->index < (RK_U32)p->count) { + KmppObjDefImpl *impl = &p->defs[info->index]; + + /* NOTE: do NOT increase ref_cnt here */ + return kmpp_obj_get(obj, impl); + } + + mpp_loge_f("failed to get objdef %s index %d max %d\n", + name, info->index, p->count); + + return MPP_NOK; +} + +rk_s32 kmpp_obj_get_by_sptr(KmppObj *obj, KmppShmPtr *sptr) { KmppObjImpl *impl; - KmppObjDefImpl *def_impl; + KmppObjDefImpl *def; + rk_u8 *uptr = sptr ? sptr->uptr : NULL; rk_s32 ret = MPP_NOK; - if (!obj || !def) { - mpp_loge_f("invalid param obj %p def %p\n", obj, def); + if (!obj || !sptr || !uptr) { + mpp_loge_f("invalid param obj %p sptr %p uptr %p\n", obj, sptr, uptr); return ret; } *obj = NULL; - def_impl = (KmppObjDefImpl *)def; + + { + rk_u32 val = *((rk_u32 *)(uptr + objs->name_offset)); + char *p; + + if (!val) { + mpp_loge_f("invalid obj name offset %d\n", val); + return ret; + } + + p = (char *)objs->root + val; + kmpp_objdef_get((KmppObjDef *)&def, p); + if (!def) { + mpp_loge_f("failed to get objdef %p - %s\n", p, p); + return ret; + } + } + impl = mpp_calloc(KmppObjImpl, 1); if (!impl) { mpp_loge_f("malloc obj impl %d failed\n", sizeof(KmppObjImpl)); return ret; } - impl->name_check = def_impl->name_check; + impl->name_check = def->name_check; impl->def = def; - impl->trie = def_impl->trie; + impl->trie = def->trie; impl->need_free = 1; - impl->shm = sptr->uptr; - impl->entry = sptr->uptr + def_impl->entry_offset; + impl->shm = (KmppShmPtr *)uptr; + impl->entry = uptr + objs->entry_offset; /* write userspace object address to share memory userspace private value */ - *(RK_U64 *)U64_TO_PTR(sptr->uaddr + def_impl->priv_offset) = (RK_U64)(intptr_t)impl; + *(RK_U64 *)U64_TO_PTR(sptr->uaddr + objs->priv_offset) = (RK_U64)(intptr_t)impl; *obj = impl; @@ -572,17 +625,17 @@ rk_s32 kmpp_obj_put(KmppObj obj) { if (obj) { KmppObjImpl *impl = (KmppObjImpl *)obj; - KmppObjDefImpl *def = impl->def; if (impl->shm) { - KmppObjIocArg *ioc = alloca(sizeof(KmppObjIocArg) + sizeof(rk_u64)); + KmppObjIocArg *ioc = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr)); rk_s32 ret; ioc->count = 1; ioc->flag = 0; - ioc->kobj_uaddr[0] = (__u64)(intptr_t)impl->shm; + ioc->obj_sptr[0].uaddr = impl->shm->uaddr; + ioc->obj_sptr[0].kaddr = impl->shm->kaddr; - ret = ioctl(def->fd, KMPP_SHM_IOC_PUT_SHM, ioc); + ret = ioctl(objs->fd, KMPP_SHM_IOC_PUT_SHM, ioc); if (ret) mpp_err("ioctl KMPP_SHM_IOC_PUT_SHM failed ret %d\n", ret); @@ -617,7 +670,67 @@ rk_s32 kmpp_obj_check(KmppObj obj, const char *caller) return MPP_OK; } -void *kmpp_obj_get_hnd(KmppObj obj) +rk_s32 kmpp_obj_ioctl(KmppObj obj, rk_s32 cmd, KmppObj in, KmppObj out) +{ + KmppObjIocArg *ioc_arg; + KmppObjImpl *ioc = NULL; + KmppObjImpl *impl = (KmppObjImpl *)obj; + rk_s32 ret; + rk_s32 fd; + + ret = kmpp_obj_get_by_name((KmppObj *)&ioc, "KmppIoc"); + if (ret) { + mpp_loge("failed to get KmppIoc ret %d\n", ret); + return MPP_NOK; + } + + fd = open("/dev/kmpp_ioctl", O_RDWR); + if (fd < 0) { + mpp_loge("failed to open /dev/kmpp_ioctl ret %d\n", fd); + return MPP_NOK; + } + + ioc_arg = alloca(sizeof(KmppObjIocArg) + sizeof(KmppShmPtr)); + ioc_arg->count = 1; + ioc_arg->flag = 0; + ioc_arg->obj_sptr[0].uaddr = ioc->shm->uaddr; + ioc_arg->obj_sptr[0].kaddr = ioc->shm->kaddr; + + obj_dbg_ioctl("ioctl arg %p obj_sptr [u:k] %llx : %llx\n", ioc_arg, + ioc_arg->obj_sptr[0].uaddr, ioc_arg->obj_sptr[0].kaddr); + + obj_dbg_ioctl("ioctl def %s - %d cmd %d\n", impl->def->name, impl->def->index, cmd); + + kmpp_obj_set_u32(ioc, "def", impl->def->index); + kmpp_obj_set_u32(ioc, "cmd", cmd); + kmpp_obj_set_u32(ioc, "flag", 0); + kmpp_obj_set_u32(ioc, "id", 0); + + if (in) { + KmppObjImpl *impl_in = (KmppObjImpl *)in; + + kmpp_obj_set_shm(ioc, "in", impl_in->shm); + obj_dbg_ioctl("ioctl [u:k] in %#llx : %#llx\n", + impl_in->shm->uaddr, impl_in->shm->kaddr); + } + if (out) { + KmppObjImpl *impl_out = (KmppObjImpl *)out; + + kmpp_obj_set_shm(ioc, "out", impl_out->shm); + obj_dbg_ioctl("ioctl [u:k] in %#llx : %#llx\n", + impl_out->shm->uaddr, impl_out->shm->kaddr); + } + + ret = ioctl(fd, 0, ioc_arg); + + kmpp_obj_put(ioc); + + close(fd); + + return ret; +} + +KmppShmPtr *kmpp_obj_to_shm(KmppObj obj) { KmppObjImpl *impl = (KmppObjImpl *)obj; @@ -629,10 +742,20 @@ void *kmpp_obj_get_hnd(KmppObj obj) return impl->shm; } -rk_s32 kmpp_obj_get_hnd_size(KmppObj obj) +rk_s32 kmpp_obj_to_shm_size(KmppObj obj) { (void)obj; - return sizeof(KmppObjShm); + return sizeof(KmppShmPtr); +} + +const char *kmpp_obj_get_name(KmppObj obj) +{ + KmppObjImpl *impl = (KmppObjImpl *)obj; + + if (impl && impl->def && impl->def->name) + return impl->def->name; + + return NULL; } void *kmpp_obj_get_entry(KmppObj obj) @@ -805,6 +928,50 @@ MPP_OBJ_TBL_ACCESS(fp, void *) MPP_OBJ_STRUCT_TBL_ACCESS(st, void) MPP_OBJ_STRUCT_TBL_ACCESS(shm, KmppShmPtr) +rk_s32 kmpp_obj_set_shm_obj(KmppObj obj, const char *name, KmppObj val) +{ + rk_s32 ret = MPP_NOK; + + if (!obj || !name || !val) { + mpp_loge_f("obj %p set shm obj %s to %p failed invalid param\n", + obj, name, val); + } else { + KmppShmPtr *sptr = kmpp_obj_to_shm(val); + + if (!sptr) { + mpp_loge_f("obj %p found invalid shm ptr\n", val); + } else { + ret = kmpp_obj_set_shm(obj, name, sptr); + } + } + + return ret; +} + +rk_s32 kmpp_obj_get_shm_obj(KmppObj obj, const char *name, KmppObj *val) +{ + rk_s32 ret = MPP_NOK; + + if (!obj || !name || !val) { + mpp_loge_f("obj %p get shm obj %s to %p failed invalid param\n", + obj, name, val); + } else { + KmppObjImpl *impl = (KmppObjImpl *)obj; + KmppShmPtr sptr = {0}; + + *val = NULL; + + ret = kmpp_obj_get_shm(obj, name, &sptr); + if (ret || !sptr.uptr) { + mpp_loge_f("obj %p get shm %s failed ret %d\n", impl, name, ret); + } else { + ret = kmpp_obj_get_by_sptr(val, &sptr); + } + } + + return ret; +} + static rk_s32 kmpp_obj_impl_run(rk_s32 (*run)(void *ctx), void *ctx) { return run(ctx); @@ -1032,7 +1199,7 @@ rk_s32 kmpp_obj_kdump_f(KmppObj obj, const char *caller) mpp_logi("dump obj %-12s - %p at %s by kernel\n", def->name, impl, caller); - ret = ioctl(def->fd, KMPP_SHM_IOC_DUMP, impl->shm); + ret = ioctl(objs->fd, KMPP_SHM_IOC_DUMP, impl->shm); if (ret) mpp_err("ioctl KMPP_SHM_IOC_DUMP failed ret %d\n", ret); diff --git a/mpp/base/test/kmpp_obj_test.c b/mpp/base/test/kmpp_obj_test.c index 5ed5e46b..bedaa1c5 100644 --- a/mpp/base/test/kmpp_obj_test.c +++ b/mpp/base/test/kmpp_obj_test.c @@ -6,89 +6,281 @@ #define MODULE_TAG "kmpp_obj_test" #include "mpp_log.h" +#include "mpp_common.h" + #include "kmpp_obj.h" -int main() +#define TEST_DETAIL 1 +#define TEST_DEF_DUMP 2 +#define TEST_OBJ_UDUMP 4 +#define TEST_OBJ_KDUMP 8 + +#define test_detail(fmt, ...) \ + do { \ + if (flag & TEST_DETAIL) \ + mpp_log(fmt, ##__VA_ARGS__); \ + } while (0) + +typedef struct KmppObjTest_t { + const char *name; + rk_u32 flag; + rk_s32 (*func)(const char *name, rk_u32 flag); +} KmppObjTest; + +static rk_s32 kmpp_obj_std_test(const char *name, rk_u32 flag) { - MPP_RET ret = MPP_NOK; KmppObjDef def = NULL; KmppObj obj = NULL; - const char *name = NULL; + MPP_RET ret = MPP_NOK; - mpp_log(MODULE_TAG " start\n"); - - ret = kmpp_objdef_get(&def, "KmppFrame"); + ret = kmpp_objdef_get(&def, name); if (ret) { - mpp_log(MODULE_TAG " kmpp_objdef_get failed\n"); + mpp_log("kmpp_objdef_get %s failed\n", name); goto done; } - name = kmpp_objdef_get_name(def); - kmpp_objdef_dump(def); + if (flag & TEST_DEF_DUMP) + kmpp_objdef_dump(def); ret = kmpp_obj_get(&obj, def); if (ret) { - mpp_log(MODULE_TAG " kmpp_obj_get %s failed ret %d\n", name, ret); + mpp_log("kmpp_obj_get %s failed ret %d\n", name, ret); goto done; } - kmpp_obj_udump(obj); - kmpp_obj_kdump(obj); + if (flag & TEST_OBJ_UDUMP) + kmpp_obj_udump(obj); + if (flag & TEST_OBJ_KDUMP) + kmpp_obj_kdump(obj); ret = kmpp_obj_put(obj); if (ret) { - mpp_log(MODULE_TAG " kmpp_obj_put %s failed\n", name); + mpp_log("kmpp_obj_put %s failed\n", name); goto done; } obj = NULL; ret = kmpp_objdef_put(def); if (ret) { - mpp_log(MODULE_TAG " kmpp_objdef_put %s failed\n", name); + mpp_log("kmpp_objdef_put %s failed\n", name); goto done; } def = NULL; - ret = kmpp_objdef_get(&def, "KmppVencInitCfg"); +done: + if (obj) + kmpp_obj_put(obj); + if (def) + kmpp_objdef_put(def); + + return ret; +} + +static rk_s32 kmpp_obj_by_name_test(const char *name, rk_u32 flag) +{ + KmppObj obj = NULL; + MPP_RET ret = MPP_NOK; + + ret = kmpp_obj_get_by_name(&obj, name); if (ret) { - mpp_log(MODULE_TAG " kmpp_objdef_get failed\n"); + mpp_log("kmpp_obj_get_by_name %s failed ret %d\n", name, ret); goto done; } - name = kmpp_objdef_get_name(def); - kmpp_objdef_dump(def); - - ret = kmpp_obj_get(&obj, def); - if (ret) { - mpp_log(MODULE_TAG " kmpp_obj_get %s failed ret %d\n", name, ret); - goto done; - } - - kmpp_obj_udump(obj); - kmpp_obj_kdump(obj); + if (flag & TEST_OBJ_UDUMP) + kmpp_obj_udump(obj); + if (flag & TEST_OBJ_KDUMP) + kmpp_obj_kdump(obj); ret = kmpp_obj_put(obj); if (ret) { - mpp_log(MODULE_TAG " kmpp_obj_put %s failed\n", name); + mpp_log("kmpp_obj_put %s failed\n", name); goto done; } obj = NULL; - ret = kmpp_objdef_put(def); - if (ret) { - mpp_log(MODULE_TAG " kmpp_objdef_put %s failed\n", name); - goto done; - } - done: - if (ret) { - if (obj) - kmpp_obj_put(obj); - - if (def) - kmpp_objdef_put(def); - } - mpp_log(MODULE_TAG " done %s \n", ret ? "failed" : "success"); + if (obj) + kmpp_obj_put(obj); + + return ret; +} + +static rk_s32 kmpp_buffer_test(const char *name, rk_u32 flag) +{ + KmppShmPtr sptr; + KmppObj grp = NULL; + KmppObj grp_cfg = NULL; + KmppObj buf = NULL; + KmppObj buf_cfg = NULL; + MPP_RET ret = MPP_NOK; + rk_u32 val = 0; + + ret = kmpp_obj_get_by_name(&grp, "KmppBufGrp"); + if (ret) { + mpp_log("buf grp get obj failed ret %d\n", ret); + goto done; + } + + /* KmppBufGrp object ready */ + test_detail("object %s ready\n", kmpp_obj_get_name(grp)); + + /* get KmppBufGrpCfg from KmppBufGrp to config */ + ret = kmpp_obj_get_shm_obj(grp, "cfg", &grp_cfg); + if (ret) { + mpp_log("buf grp get cfg failed ret %d\n", ret); + goto done; + } + + /* KmppBufGrpCfg object ready */ + test_detail("object %s ready\n", kmpp_obj_get_name(grp_cfg)); + + if (flag & TEST_OBJ_UDUMP) + kmpp_obj_udump(buf_cfg); + + /* write parameters to KmppBufGrpCfg */ + ret = kmpp_obj_set_u32(grp_cfg, "flag", 0); + if (ret) { + mpp_log("grp cfg set flag failed ret %d\n", ret); + goto done; + } + + ret = kmpp_obj_set_u32(grp_cfg, "count", 10); + if (ret) { + mpp_log("grp cfg set count failed ret %d\n", ret); + goto done; + } + + ret = kmpp_obj_set_u32(grp_cfg, "size", 4096); + if (ret) { + mpp_log("grp cfg set size failed ret %d\n", ret); + goto done; + } + + ret = kmpp_obj_set_s32(grp_cfg, "fd", -1); + if (ret) { + mpp_log("grp cfg set fd failed ret %d\n", ret); + goto done; + } + + /* set buffer group name to test */ + name = "allocator"; + sptr.kaddr = 0; + sptr.uptr = "rk dma heap"; + + ret = kmpp_obj_set_shm(grp_cfg, name, &sptr); + if (ret) { + mpp_log("grp cfg set %s failed ret %d\n", name, ret); + goto done; + } + + /* set buffer group name to test */ + name = "name"; + sptr.kaddr = 0; + sptr.uptr = "test"; + + ret = kmpp_obj_set_shm(grp_cfg, name, &sptr); + if (ret) { + mpp_log("grp cfg set %s failed ret %d\n", name, ret); + goto done; + } + + test_detail("object %s write parameters ready\n", kmpp_obj_get_name(grp_cfg)); + + /* enable KmppBufGrpCfg by ioctl */ + ret = kmpp_obj_ioctl(grp, 0, grp, NULL); + + test_detail("object %s ioctl ret %d\n", kmpp_obj_get_name(grp), ret); + + /* get KmppBuffer for buffer allocation */ + ret = kmpp_obj_get_by_name(&buf, "KmppBuffer"); + if (ret) { + mpp_log("kmpp_obj_get_by_name failed ret %d\n", ret); + goto done; + } + + test_detail("object %s ready\n", kmpp_obj_get_name(buf)); + + /* get KmppBufGrpCfg to setup */ + sptr.uaddr = 0; + sptr.kaddr = 0; + ret = kmpp_obj_get_shm_obj(buf, "cfg", &buf_cfg); + if (ret) { + mpp_log("buf get cfg failed ret %d\n", ret); + goto done; + } + + if (flag & TEST_OBJ_UDUMP) + kmpp_obj_udump(buf_cfg); + + test_detail("object %s ready\n", kmpp_obj_get_name(buf_cfg)); + + /* setup buffer config parameters */ + /* set buffer group */ + ret = kmpp_obj_set_shm_obj(buf_cfg, "group", grp); + if (ret) { + mpp_log("buf cfg set group failed ret %d\n", ret); + goto done; + } + + /* enable KmppBufferCfg by ioctl */ + ret = kmpp_obj_ioctl(buf, 0, buf, NULL); + + test_detail("object %s ioctl ret %d\n", kmpp_obj_get_name(buf), ret); + + kmpp_obj_get_u32(buf_cfg, "size", &val); + + test_detail("object %s size %d\n", kmpp_obj_get_name(buf_cfg), val); + +done: + if (grp) + kmpp_obj_put(grp); + + if (buf) + kmpp_obj_put(buf); + + return ret; +} + +static KmppObjTest obj_tests[] = { + { + "KmppFrame", + 0, + kmpp_obj_std_test, + }, + { + "KmppVencInitCfg", + 0, + kmpp_obj_by_name_test, + }, + { + "KmppBuffer", + 0, + kmpp_buffer_test, + }, +}; + +int main() +{ + MPP_RET ret = MPP_NOK; + rk_u32 i; + + mpp_log("start\n"); + + for (i = 0; i < MPP_ARRAY_ELEMS(obj_tests); i++) { + const char *name = obj_tests[i].name; + rk_u32 flag = obj_tests[i].flag; + + ret = obj_tests[i].func(name, flag); + if (ret) { + mpp_log("test %-16s failed ret %d\n", name, ret); + goto done; + } + mpp_log("test %-16s success\n", name); + } + +done: + mpp_log("done %s \n", ret ? "failed" : "success"); return ret; } diff --git a/mpp/kmpp.c b/mpp/kmpp.c index 57450368..616b381c 100644 --- a/mpp/kmpp.c +++ b/mpp/kmpp.c @@ -127,8 +127,8 @@ static MPP_RET init(Kmpp *ctx, MppCtxType type, MppCodingType coding) } } - hnd = kmpp_obj_get_hnd(ctx->mVencInitKcfg); - size = kmpp_obj_get_hnd_size(ctx->mVencInitKcfg); + hnd = kmpp_obj_to_shm(ctx->mVencInitKcfg); + size = kmpp_obj_to_shm_size(ctx->mVencInitKcfg); kmpp_obj_get_u32(ctx->mVencInitKcfg, "chan_dup", &ctx->mChanDup); ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_CREATE, 0, size, hnd); @@ -516,8 +516,8 @@ static MPP_RET control(Kmpp *ctx, MpiCmd cmd, MppParam param) case MPP_SET_VENC_INIT_KCFG: { KmppObj obj = param; - arg = kmpp_obj_get_hnd(obj); - size = kmpp_obj_get_hnd_size(obj); + arg = kmpp_obj_to_shm(obj); + size = kmpp_obj_to_shm_size(obj); } break; case MPP_SET_SELECT_TIMEOUT: { struct timeval *p = (struct timeval *)param;