847 lines
23 KiB
C
Executable File
847 lines
23 KiB
C
Executable File
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
|
|
#include "iot_pkt.h"
|
|
#include "iot_mem_pool.h"
|
|
#include "iot_module.h"
|
|
#include "iot_errno.h"
|
|
#include "iot_dbglog_api.h"
|
|
#include "iot_dbglog.h"
|
|
#include "iot_config.h"
|
|
#include "iot_io.h"
|
|
#include "iot_system_api.h"
|
|
|
|
typedef struct _iot_pkt_global {
|
|
uint32_t pool_cnt : 16,
|
|
req_cnt : 16;
|
|
iot_pkt_config_t config;
|
|
iot_mem_pool_t *pool[IOT_PKT_POOL_MAX];
|
|
#if DEBUG_PKT_OVERWRITE
|
|
os_mutex_h mutex;
|
|
#endif
|
|
#if PLC_MEM_ALLOC_STAT > 1
|
|
uint16_t efficiency[IOT_PKT_POOL_MAX];
|
|
#endif
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
os_mutex_h free_callback_lock;
|
|
#endif
|
|
} iot_pkt_global_t;
|
|
|
|
static iot_pkt_global_t *p_pkt_glb = NULL;
|
|
|
|
static inline void __iot_pkt_reset(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
buf->head = (uint8_t*)buf + sizeof(iot_pkt_t);
|
|
buf->data = buf->head;
|
|
buf->tail = buf->head;
|
|
|
|
buf->end = buf->head + size;
|
|
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
iot_list_head_t *entry;
|
|
entry = (iot_list_head_t *)&(buf->entry);
|
|
iot_list_init(entry);
|
|
|
|
buf->free_func = NULL;
|
|
buf->param = NULL;
|
|
#endif
|
|
}
|
|
|
|
#if IOT_PKT_INFO_DUMP_DEBUG
|
|
void iot_pkt_dump_info(void)
|
|
{
|
|
uint32_t toltal_cnt, buf_size, free_cnt, i;
|
|
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
toltal_cnt = p_pkt_glb->config.pool_cfg[i].count;
|
|
buf_size = p_pkt_glb->config.pool_cfg[i].size;
|
|
free_cnt = iot_mem_pool_get_freenum(p_pkt_glb->pool[i]);
|
|
iot_printf("PKT:%d-%d/%d. ", buf_size, free_cnt, toltal_cnt);
|
|
}
|
|
iot_printf("\n");
|
|
}
|
|
#endif
|
|
|
|
/* according to MID, get the pool owner mask */
|
|
static inline uint32_t iot_pkt_get_target_owner(module_id_t module_id)
|
|
{
|
|
uint32_t owner = 0;
|
|
|
|
if (IOT_CLI_MID == module_id)
|
|
{
|
|
owner= PKT_OWNER_IOT;
|
|
}
|
|
else if ((module_id >= PLC_MID_BASE) && (module_id < NB_MID_BASE))
|
|
{
|
|
owner = PKT_OWNER_PLC;
|
|
}
|
|
else if ((module_id >= NB_MID_BASE) && (module_id < OS_RISCV_BASE))
|
|
{
|
|
owner = PKT_OWNER_NB;
|
|
}
|
|
else
|
|
{
|
|
owner = PKT_OWNER_PLC;
|
|
}
|
|
return owner;
|
|
}
|
|
|
|
void iot_pkt_init(const iot_pkt_config_t *cfg)
|
|
{
|
|
uint16_t size, count;
|
|
uint32_t i, j, owner;
|
|
iot_mem_pool_t *tmp_pool;
|
|
iot_pkt_config_t *config;
|
|
|
|
p_pkt_glb = os_mem_malloc(IOT_PKT_MID, sizeof(*p_pkt_glb));
|
|
IOT_ASSERT(p_pkt_glb);
|
|
#if DEBUG_PKT_OVERWRITE
|
|
if (NULL == (p_pkt_glb->mutex = os_create_mutex(IOT_PKT_MID))) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
#endif
|
|
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
if (NULL ==
|
|
(p_pkt_glb->free_callback_lock = os_create_mutex(IOT_PKT_MID))) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
#endif
|
|
config = &p_pkt_glb->config;
|
|
|
|
for (i = 0; i < IOT_PKT_POOL_MAX; i++) {
|
|
if (cfg->pool_cfg[i].count == 0)
|
|
break;
|
|
config->pool_cfg[i].size = cfg->pool_cfg[i].size;
|
|
config->pool_cfg[i].count = cfg->pool_cfg[i].count;
|
|
config->pool_cfg[i].owner = cfg->pool_cfg[i].owner;
|
|
}
|
|
p_pkt_glb->pool_cnt = i;
|
|
IOT_ASSERT(p_pkt_glb->pool_cnt);
|
|
p_pkt_glb->req_cnt = 0;
|
|
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
if (config->pool_cfg[i].count) {
|
|
iot_mem_pool_new(IOT_PKT_MID, config->pool_cfg[i].count,
|
|
sizeof(iot_pkt_t) + config->pool_cfg[i].size,
|
|
&p_pkt_glb->pool[i], 1);
|
|
IOT_ASSERT(p_pkt_glb->pool[i]);
|
|
#if PLC_MEM_ALLOC_STAT
|
|
iot_printf("data buf: %d, num %d x size %d = %d bytes, owner = 0x%X, "
|
|
"@0x%x, align_size:%d\n", \
|
|
i, config->pool_cfg[i].count, \
|
|
sizeof(iot_pkt_t) + config->pool_cfg[i].size,
|
|
config->pool_cfg[i].count * \
|
|
(sizeof(iot_pkt_t) + config->pool_cfg[i].size),
|
|
config->pool_cfg[i].owner, p_pkt_glb->pool[i],\
|
|
iot_mem_pool_get_align_size(p_pkt_glb->pool[i]));
|
|
#endif
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* sort the pkt size pool from least to largest */
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
for (j = i + 1; j < p_pkt_glb->pool_cnt; j++) {
|
|
if (config->pool_cfg[i].size > config->pool_cfg[j].size) {
|
|
size = config->pool_cfg[i].size;
|
|
count = config->pool_cfg[i].count;
|
|
owner = config->pool_cfg[i].owner;
|
|
tmp_pool = p_pkt_glb->pool[i];
|
|
config->pool_cfg[i].size = config->pool_cfg[j].size;
|
|
config->pool_cfg[i].count = config->pool_cfg[j].count;
|
|
config->pool_cfg[i].owner = config->pool_cfg[j].owner;
|
|
p_pkt_glb->pool[i] = p_pkt_glb->pool[j];
|
|
config->pool_cfg[j].size = size;
|
|
config->pool_cfg[j].count = count;
|
|
config->pool_cfg[j].owner = owner;
|
|
p_pkt_glb->pool[j] = tmp_pool;
|
|
} else if (config->pool_cfg[i].size == config->pool_cfg[j].size) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if IOT_PKT_DEBUG
|
|
|
|
iot_pkt_t* iot_pkt_mem_alloc(uint32_t size, module_id_t module_id,
|
|
uint8_t init_mem, const char *file_name, uint32_t line_num)
|
|
{
|
|
uint32_t i, n, next, module_owner;
|
|
iot_pkt_t* result = NULL;
|
|
iot_pkt_t* printf_buf = NULL;
|
|
iot_mem_pool_entry_t* p_entry = NULL;
|
|
if (size == 0) {
|
|
goto out;
|
|
}
|
|
|
|
module_owner = iot_pkt_get_target_owner(module_id);
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
if (size <= p_pkt_glb->config.pool_cfg[i].size) {
|
|
if (p_pkt_glb->config.pool_cfg[i].owner & module_owner)
|
|
{
|
|
result = iot_mem_pool_alloc(p_pkt_glb->pool[i]);
|
|
if (result) {
|
|
result->file_name = file_name;
|
|
result->line_num = line_num;
|
|
__iot_pkt_reset(result, p_pkt_glb->config.pool_cfg[i].size);
|
|
if (init_mem) {
|
|
os_mem_set(result->head, 0,
|
|
(result->end - result->head));
|
|
}
|
|
goto out;
|
|
} else {
|
|
iot_printf("%s in Line %d ----buf_size:%d, pool_size:%d, "
|
|
"this pool use up\n", file_name, line_num, size,
|
|
p_pkt_glb->config.pool_cfg[i].size);
|
|
p_entry = p_pkt_glb->pool[i]->entries;
|
|
next = p_pkt_glb->pool[i]->align_block_word_size;
|
|
if (p_entry != NULL) {
|
|
for (n = 0; n < p_pkt_glb->pool[i]->num; n++) {
|
|
printf_buf = (iot_pkt_t*)p_entry;
|
|
iot_printf("%s in Line %d ----pool_size:%d, "
|
|
"addr = [0x%08X]\n", printf_buf->file_name,
|
|
printf_buf->line_num,
|
|
p_pkt_glb->config.pool_cfg[i].size, printf_buf);
|
|
p_entry = p_entry + next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
return result;
|
|
}
|
|
|
|
#else /* IOT_PKT_DEBUG */
|
|
|
|
iot_pkt_t* iot_pkt_mem_alloc(uint32_t size, module_id_t module_id,
|
|
uint8_t init_mem)
|
|
{
|
|
uint32_t i = 0, module_owner;
|
|
iot_pkt_t* result = NULL;
|
|
#if DEBUG_PKT_OVERWRITE
|
|
uint32_t ast_ra = 0;
|
|
RISC_GET_REG_RA(ast_ra);
|
|
#endif
|
|
|
|
if (size == 0) {
|
|
goto out;
|
|
}
|
|
|
|
module_owner = iot_pkt_get_target_owner(module_id);
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
if (size <= p_pkt_glb->config.pool_cfg[i].size) {
|
|
if ( p_pkt_glb->config.pool_cfg[i].owner & module_owner) {
|
|
result = iot_mem_pool_alloc(p_pkt_glb->pool[i]);
|
|
if (result) {
|
|
__iot_pkt_reset(result,
|
|
p_pkt_glb->config.pool_cfg[i].size);
|
|
#if DEBUG_PKT_OVERWRITE
|
|
iot_printf("pkt_alloc:@%x,ra:0x%x\n", \
|
|
(uint32_t)result, ast_ra);
|
|
os_acquire_mutex(p_pkt_glb->mutex);
|
|
iot_pkt_check_end_overwrite(result);
|
|
os_release_mutex(p_pkt_glb->mutex);
|
|
#endif
|
|
if (init_mem) {
|
|
os_mem_set(result->head, 0,
|
|
(result->end - result->head));
|
|
}
|
|
#if PLC_MEM_ALLOC_STAT > 1
|
|
/* 1/8 avg efficiency contribution for this time */
|
|
p_pkt_glb->efficiency[i] = \
|
|
(p_pkt_glb->efficiency[i] - \
|
|
(p_pkt_glb->efficiency[i] >> 3)) + \
|
|
((size & 0xffff) >> 3);
|
|
#endif
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
#if PLC_MEM_ALLOC_STAT > 1
|
|
if ((++p_pkt_glb->req_cnt & IOTPKT_STAT_DISPLAY_FREQ) \
|
|
== IOTPKT_STAT_DISPLAY_FREQ)
|
|
{
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
iot_printf("pu%dpm%d/%d:e%d/%d;",
|
|
p_pkt_glb->pool[i]->num - p_pkt_glb->pool[i]->free_num,
|
|
p_pkt_glb->pool[i]->max_num,
|
|
p_pkt_glb->pool[i]->num, p_pkt_glb->efficiency[i],
|
|
(p_pkt_glb->pool[i]->align_block_word_size << 2));
|
|
}
|
|
iot_printf("\n");
|
|
}
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
#endif /* IOT_PKT_DEBUG */
|
|
|
|
uint32_t iot_pkt_set_free_callback(iot_pkt_t *buf,
|
|
iot_pkt_free_func_t free_callback, void *param)
|
|
{
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
if (buf) {
|
|
buf->free_func = free_callback;
|
|
buf->param = param;
|
|
return ERR_OK;
|
|
}
|
|
#else
|
|
(void)buf;
|
|
(void)free_callback;
|
|
(void)param;
|
|
#endif
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
void iot_pkt_get_free_callback(iot_pkt_t *buf,
|
|
iot_pkt_free_func_t *free_callback, void **param)
|
|
{
|
|
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
if (buf && buf->free_func) {
|
|
*free_callback = buf->free_func;
|
|
*param = buf->param;
|
|
return;
|
|
}
|
|
#endif
|
|
(void)buf;
|
|
*free_callback = NULL;
|
|
*param = NULL;
|
|
}
|
|
|
|
static void iot_pkt_exe_free_callback(iot_pkt_t *buf, uint8_t state)
|
|
{
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
uint32_t ret;
|
|
iot_list_head_t *entry = (iot_list_head_t *)&(buf->entry);
|
|
|
|
os_acquire_mutex(p_pkt_glb->free_callback_lock);
|
|
ret = iot_list_empty(entry);
|
|
if (!ret) {
|
|
iot_list_del(entry);
|
|
}
|
|
os_release_mutex(p_pkt_glb->free_callback_lock);
|
|
|
|
if (ret && buf->free_func) {
|
|
buf->free_func(buf->param, state);
|
|
}
|
|
#else
|
|
(void)buf;
|
|
(void)state;
|
|
#endif
|
|
}
|
|
|
|
void iot_pkt_free(iot_pkt_t* buf)
|
|
{
|
|
iot_pkt_free_tx_done(buf, IOT_PKT_STATE_UNKNOWN);
|
|
}
|
|
|
|
void iot_pkt_free_tx_done(iot_pkt_t* buf, uint8_t state)
|
|
{
|
|
uint32_t i, buf_len;
|
|
#if DEBUG_PKT_OVERWRITE
|
|
uint32_t ast_ra = 0;
|
|
RISC_GET_REG_RA(ast_ra);
|
|
#endif
|
|
|
|
if (buf == NULL) {
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
buf_len = iot_pkt_block_len(buf, IOT_PKT_BLOCK_ALL);
|
|
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
if (buf_len == p_pkt_glb->config.pool_cfg[i].size) {
|
|
iot_pkt_exe_free_callback(buf, state);
|
|
#if DEBUG_PKT_OVERWRITE
|
|
iot_printf("pkt_free@%x,ra:0x%x\n", (uint32_t)buf, ast_ra);
|
|
os_acquire_mutex(p_pkt_glb->mutex);
|
|
iot_pkt_check_end_overwrite(buf);
|
|
/* init the tail and end value for debug. */
|
|
buf->tail = NULL;
|
|
buf->end = NULL;
|
|
iot_mem_pool_free(p_pkt_glb->pool[i], buf);
|
|
os_release_mutex(p_pkt_glb->mutex);
|
|
#else
|
|
iot_mem_pool_free(p_pkt_glb->pool[i], buf);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= p_pkt_glb->pool_cnt) {
|
|
uint32_t ret;
|
|
/* buffer corrupted */
|
|
iot_printf("pkt 0x%x not found with len %d\n", buf, buf_len);
|
|
iot_pkt_exe_free_callback(buf, state);
|
|
for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
|
|
ret = iot_mem_pool_force_free(p_pkt_glb->pool[i], buf);
|
|
if (ret == ERR_OK) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
out:
|
|
return;
|
|
}
|
|
|
|
uint8_t** iot_pkt_dataptr_addr(iot_pkt_t* buf)
|
|
{
|
|
if (buf) {
|
|
return (&buf->data);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* iot_pkt_reserve(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && buf->tail + size <= buf->end) {
|
|
buf->data += size;
|
|
buf->tail += size;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* iot_pkt_put(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && buf->tail + size <= buf->end) {
|
|
buf->tail += size;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* iot_pkt_shrink(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && buf->tail - size >= buf->data) {
|
|
buf->tail -= size;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* iot_pkt_push(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && buf->data - size >= buf->head) {
|
|
buf->data -= size;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* iot_pkt_pull(iot_pkt_t* buf, uint32_t size)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && buf->data + size <= buf->tail) {
|
|
buf->data += size;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* IRAM_ATTR iot_pkt_set_data(iot_pkt_t* buf, void* new_data)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && (uint8_t*)new_data >= buf->head
|
|
&& (uint8_t*)new_data <= buf->tail) {
|
|
buf->data = (uint8_t*)new_data;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* IRAM_ATTR iot_pkt_set_tail(iot_pkt_t* buf, void* new_tail)
|
|
{
|
|
if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (buf && (uint8_t*)new_tail >= buf->data
|
|
&& (uint8_t*)new_tail <= buf->end) {
|
|
buf->tail = (uint8_t*)new_tail;
|
|
|
|
return buf->data;
|
|
}
|
|
IOT_ASSERT(0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t* IRAM_ATTR iot_pkt_block_ptr(iot_pkt_t* buf, uint8_t block_type)
|
|
{
|
|
if (buf == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
void* result = NULL;
|
|
switch (block_type)
|
|
{
|
|
case IOT_PKT_BLOCK_ALL:
|
|
case IOT_PKT_BLOCK_HEAD:
|
|
result = buf->head;
|
|
break;
|
|
case IOT_PKT_BLOCK_DATA:
|
|
result = buf->data;
|
|
break;
|
|
case IOT_PKT_BLOCK_TAIL:
|
|
result = buf->tail;
|
|
break;
|
|
case IOT_PKT_BLOCK_END:
|
|
result = buf->end;
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
uint32_t IRAM_ATTR iot_pkt_block_len(iot_pkt_t* buf, uint8_t block_type)
|
|
{
|
|
if (buf == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
uint32_t len = 0;
|
|
switch (block_type)
|
|
{
|
|
case IOT_PKT_BLOCK_ALL:
|
|
len = buf->end - buf->head;
|
|
break;
|
|
case IOT_PKT_BLOCK_HEAD:
|
|
len = buf->data - buf->head;
|
|
break;
|
|
case IOT_PKT_BLOCK_DATA:
|
|
len = buf->tail - buf->data;
|
|
break;
|
|
case IOT_PKT_BLOCK_TAIL:
|
|
len = buf->end - buf->tail;
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
void iot_pkt_reset(iot_pkt_t *buf)
|
|
{
|
|
os_mem_set(buf->head, 0, (buf->end - buf->head));
|
|
buf->data = buf->tail = buf->head;
|
|
}
|
|
|
|
void iot_pkt_cpy(iot_pkt_t *dst, iot_pkt_t *src)
|
|
{
|
|
if ((dst->end - dst->head) < (src->tail - src->head)) {
|
|
IOT_ASSERT(0);
|
|
} else {
|
|
dst->data = dst->head + (src->data - src->head);
|
|
dst->tail = dst->data + (src->tail - src->data);
|
|
os_mem_cpy(dst->data, src->data, (src->tail - src->data));
|
|
|
|
#if IOT_PKT_FREE_CALLBACK_ENABLE
|
|
iot_list_head_t *src_entry, *dst_entry;
|
|
src_entry = (iot_list_head_t *)&(src->entry);
|
|
dst_entry = (iot_list_head_t *)&(dst->entry);
|
|
os_acquire_mutex(p_pkt_glb->free_callback_lock);
|
|
iot_list_add(dst_entry, src_entry);
|
|
os_release_mutex(p_pkt_glb->free_callback_lock);
|
|
|
|
if (src->free_func) {
|
|
dst->free_func = src->free_func;
|
|
dst->param = src->param;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void iot_pkt_cpy_with_head(iot_pkt_t *dst, iot_pkt_t *src)
|
|
{
|
|
iot_pkt_cpy(dst, src);
|
|
os_mem_cpy(dst->head, src->head, (src->data - src->head));
|
|
}
|
|
|
|
uint32_t iot_pkt_list_block_data_len(iot_pkt_ls *pkt_list)
|
|
{
|
|
uint32_t toltal_len = 0;
|
|
iot_pkt_ls *lst = pkt_list;
|
|
|
|
while(lst)
|
|
{
|
|
if(lst->pkt)
|
|
toltal_len += iot_pkt_block_len(lst->pkt, IOT_PKT_BLOCK_DATA);
|
|
lst = lst->next;
|
|
}
|
|
|
|
return toltal_len;
|
|
}
|
|
|
|
uint32_t iot_pkt_list_item_count(iot_pkt_ls *pkt_list)
|
|
{
|
|
uint32_t cnt = 0;
|
|
iot_pkt_ls *lst = pkt_list;
|
|
|
|
while(lst)
|
|
{
|
|
cnt ++;
|
|
lst = lst->next;
|
|
}
|
|
|
|
return cnt;
|
|
}
|
|
|
|
void iot_pkt_list_free_every_pkt_mem(iot_pkt_ls *pkt_list)
|
|
{
|
|
iot_pkt_ls *lst = pkt_list;
|
|
|
|
while(lst)
|
|
{
|
|
if(lst->pkt)
|
|
{
|
|
iot_pkt_free(lst->pkt);
|
|
lst->pkt = NULL;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
uint32_t iot_pkt_pktpool_status(uint8_t pool_idx, uint32_t* bufsz, \
|
|
uint32_t* freenum, uint32_t* totalnum)
|
|
{
|
|
if ((pool_idx >= IOT_PKT_POOL_MAX) || (bufsz == NULL) ||
|
|
(freenum == NULL) || (totalnum == NULL))
|
|
{
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
*bufsz = p_pkt_glb->config.pool_cfg[pool_idx].size;
|
|
*freenum = iot_mem_pool_get_freenum(p_pkt_glb->pool[pool_idx]);
|
|
*totalnum = p_pkt_glb->config.pool_cfg[pool_idx].count;
|
|
return ERR_OK;
|
|
}
|
|
|
|
|
|
void mem_dump(uint32_t *word_ptr, uint32_t word_cnt)
|
|
{
|
|
for (uint32_t j = 0; j < (word_cnt >> 2); j++) {
|
|
iot_printf("0x%08x:", word_ptr + (j << 2));
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
{
|
|
iot_printf("0x%08x ", *(word_ptr + (j << 2) + i));
|
|
}
|
|
iot_printf("\n");
|
|
}
|
|
return;
|
|
}
|
|
|
|
void mem_dump_byte(uint8_t *byte_ptr, uint32_t byte_cnt)
|
|
{
|
|
uint32_t i, j;
|
|
for (i = 0; i < byte_cnt; ) {
|
|
iot_printf("0x%08x:", (uint32_t)byte_ptr + i);
|
|
for (j = 0; j < 8; j++) {
|
|
if ((i + j) >= byte_cnt) {
|
|
break;
|
|
}
|
|
iot_printf("0x%02x ", byte_ptr[i + j]);
|
|
}
|
|
iot_printf("\n");
|
|
i += j;
|
|
}
|
|
}
|
|
|
|
uint32_t iot_pkt_validation(iot_pkt_t *pkt)
|
|
{
|
|
if (!iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(pkt,
|
|
IOT_PKT_BLOCK_HEAD))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(pkt,
|
|
IOT_PKT_BLOCK_DATA))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(pkt,
|
|
IOT_PKT_BLOCK_TAIL))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(pkt,
|
|
IOT_PKT_BLOCK_END)))
|
|
{
|
|
iot_printf("iot_pkt overwrite found @0x%x, "
|
|
"4 pointers' are: 0x%x, 0x%x, 0x%x, 0x%x\n",
|
|
pkt,
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END));
|
|
iot_dbglog_input(PLC_MAC_RX_HW_MID, DBGLOG_ERR,
|
|
IOT_MAC_RX_OVERWRITE_ID, 5, pkt,
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL),
|
|
iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END));
|
|
return ERR_INVAL;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
#if DEBUG_PKT_OVERWRITE
|
|
|
|
uint32_t iot_pkt_check_end_overwrite(iot_pkt_t *buf)
|
|
{
|
|
uint32_t align_size = 0;
|
|
uint32_t pool_num, size, count;
|
|
uint32_t head_addr, data_addr, tail_addr, end_addr;
|
|
uint32_t last_pkt_addr;
|
|
|
|
if (!buf) {
|
|
iot_printf("pkt_check invalid\n");
|
|
IOT_ASSERT(0);
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
size = iot_pkt_block_len(buf, IOT_PKT_BLOCK_ALL);
|
|
for (pool_num = 0; pool_num < p_pkt_glb->pool_cnt; ) {
|
|
if (size == p_pkt_glb->config.pool_cfg[pool_num].size) {
|
|
align_size = iot_mem_pool_get_align_size(p_pkt_glb->pool[pool_num]);
|
|
break;
|
|
}
|
|
++pool_num;
|
|
}
|
|
|
|
if (align_size == 0) {
|
|
iot_printf("pkt_check not found pool\n");
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
/* calculation the actual next pkt */
|
|
iot_pkt_t *pkt = (iot_pkt_t *)((uint32_t)buf + align_size);
|
|
|
|
size = iot_mem_pool_get_align_size(p_pkt_glb->pool[pool_num]);
|
|
count = p_pkt_glb->config.pool_cfg[pool_num].count;
|
|
/* get this pool last pkt addr */
|
|
last_pkt_addr = (uint32_t)p_pkt_glb->pool[pool_num]->entries \
|
|
+ (size * (count - 1));
|
|
|
|
/* the next pkt is the next pool first pkt.
|
|
* but each pool address is discontinuous.
|
|
*/
|
|
if ((uint32_t)pkt > last_pkt_addr) {
|
|
pool_num++; // set pool to next pool num
|
|
/* next pool's pkt size = 0, means current pool is last pool.
|
|
* don't need to check the next pkt. */
|
|
if (0 == p_pkt_glb->config.pool_cfg[pool_num].size) {
|
|
return ERR_OK;
|
|
}
|
|
pkt = (iot_pkt_t *)p_pkt_glb->pool[pool_num]->entries;
|
|
}
|
|
|
|
if (!pkt) {
|
|
iot_printf("pkt_check buf=0x%x, last=0x%x\n",
|
|
(uint32_t)buf, (uint32_t)last_pkt_addr);
|
|
//align_size * 2 / 4
|
|
IOT_ASSERT_DUMP(0, (uint32_t *)buf, align_size >> 1);
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
/* get this pkt's head/data/tail/end address */
|
|
head_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD);
|
|
data_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
|
|
tail_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL);
|
|
end_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END);
|
|
|
|
if (((0 == head_addr) || iot_data_addr_legal(head_addr))
|
|
&& ((uint32_t)IOT_MEM_POOL_POISON == data_addr)
|
|
&& !tail_addr
|
|
&& !end_addr) {
|
|
/* the next pkt not allocated ,not need check.
|
|
* for the not allocated pkt:
|
|
* pkt->head is the pool block's head, the value is NULL or
|
|
* next_pool_block_ptr.
|
|
* pkt->data must be IOT_MEM_POOL_POISON
|
|
* pkt->tail and pkt->end must be NULL
|
|
* for the allocated pkt, the head/data/tail/end must be valid address.
|
|
*/
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* next pkt */
|
|
if (ERR_OK != iot_pkt_validation(pkt)) {
|
|
//align_size * 2 / 4
|
|
iot_printf("pkt_end_overwrite:0x%x-0x%x\n",
|
|
(uint32_t)buf, (uint32_t)pkt);
|
|
IOT_ASSERT_DUMP(0, (uint32_t *)buf, align_size >> 1);
|
|
return ERR_INVAL;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
#else /* DEBUG_PKT_OVERWRITE */
|
|
|
|
uint32_t iot_pkt_check_end_overwrite(iot_pkt_t *buf)
|
|
{
|
|
(void)buf;
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif /* DEBUG_PKT_OVERWRITE */
|
|
|