/* * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved. * * SPDX-License-Identifier: MIT */ #include #include #include #include "FreeRTOS.h" #include "mailbox-htbl.h" #define PRINT(...) //printf(__VA_ARGS__) #define PRINT_DEBUG(...) //printf(__VA_ARGS__) #define PRINT_ERR(...) printf(__VA_ARGS__) static inline void *mbmemset(void *dst, int val, size_t count) { char *ptr = dst; while (count--) *ptr++ = val; return dst; } int mailbox_htbl_init(void **pHTbl) { size_t size = sizeof(struct entry) * MAX_ENTRY_NUM; struct entry *p = NULL; p = malloc(size); if (p == NULL) return ERR_MBOX(ENOMEM); mbmemset(p, 0x00, size); *pHTbl = p; p[0].tabLen = MAX_ENTRY_NUM; return 0; } int mailbox_htbl_init_size(void **pHTbl, uint32_t tabLen) { size_t size = sizeof(struct entry) * tabLen; struct entry *p = NULL; if (tabLen == 0) { PRINT_ERR("tabLen == 0\n"); return ERR_MBOX(EINVAL); } p = malloc(size); if (p == NULL) return ERR_MBOX(ENOMEM); mbmemset(p, 0x00, size); *pHTbl = p; p[0].tabLen = tabLen; return 0; } uint32_t mailbox_htbl_reg(void *pHTbl, uint32_t cmd, handler_t handler) { struct entry *p = pHTbl; uint32_t i; uint32_t tabLen = p[0].tabLen; for (i = 0; i != tabLen; i++) { if (p[i].cmd == cmd && p[i].handler != NULL) { PRINT_ERR("Err: reg repeat cmd=0x%x handler=%p\n", cmd, handler); return tabLen; } if (p[i].handler == NULL) { p[i].cmd = cmd; p[i].handler = handler; p[i].needFdBak = 0; PRINT_DEBUG("reg cmd=0x%x handler=%p\n", cmd, handler); return i; } } return tabLen; } uint32_t mailbox_htbl_reg_feedback(void *pHTbl, uint32_t cmd, handler_t handler, uint8_t needFdBak) { struct entry *p = pHTbl; uint32_t i; uint32_t tabLen = p[0].tabLen; for (i = 0; i != tabLen; i++) { if (p[i].cmd == cmd && p[i].handler != NULL) { PRINT_ERR("Err: reg repeat cmd=0x%x handler=%p\n", cmd, handler); return tabLen; } if (p[i].handler == NULL) { p[i].cmd = cmd; p[i].handler = handler; p[i].needFdBak = needFdBak; PRINT_DEBUG("reg cmd=0x%x handler=%p\n", cmd, handler); return i; } } return tabLen; } uint32_t mailbox_htbl_unreg(void *pHTbl, uint32_t cmd) { struct entry *p = pHTbl; uint32_t i; uint32_t tabLen = p[0].tabLen; for (i = 0; i != tabLen; i++) { if (p[i].cmd == cmd) { PRINT_DEBUG("unreg cmd=0x%x handler=%p\n", cmd, p[i].handler); p[i].cmd = 0; p[i].handler = NULL; p[i].needFdBak = 0; return i; } } return MAX_ENTRY_NUM; } uint32_t mailbox_htbl_invokeCmd(void *pHTbl, uint32_t cmd, void *arg) { struct entry *p = pHTbl; uint32_t i; uint32_t tabLen = p[0].tabLen; for (i = 0; i != tabLen; i++) { if (p[i].cmd == cmd) { PRINT_DEBUG("AOCPU idx=%d cmd=0x%x handler=%p arg=%p\n", i, p[i].cmd, p[i].handler, arg); if (p[i].handler == NULL) return tabLen; p[i].handler(arg); return p[i].needFdBak; } } PRINT_ERR("AOCPU unknown cmd=0x%x\n", (unsigned int)cmd); return tabLen; }