kernel_samsung_a53x/drivers/vision3/dsp/dl/dsp-rule-reader.c
2024-06-15 16:02:09 -03:00

402 lines
8.2 KiB
C
Executable file

// SPDX-License-Identifier: GPL-2.0
/*
* Samsung Exynos SoC series dsp driver
*
* Copyright (c) 2019 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*/
#include "dl/dsp-rule-reader.h"
void dsp_type_print(struct dsp_type *type)
{
if (type->sign == SIGNED)
DL_BUF_STR("s");
else
DL_BUF_STR("u");
DL_BUF_STR("%d\n", type->bit_sz);
DL_PRINT_BUF(INFO);
}
void dsp_exp_binary_op(struct dsp_list_head *head, struct dsp_list_head *head1,
struct dsp_list_head *head2, char op)
{
struct dsp_exp_element *tmp = (struct dsp_exp_element *)dsp_dl_malloc(
sizeof(*tmp), "Exp elem");
tmp->type = EXP_OP;
tmp->op = op;
dsp_list_node_init(&tmp->list_node);
dsp_list_merge(head, head1, head2);
dsp_list_node_push_back(head, &tmp->list_node);
}
void dsp_exp_print(struct dsp_list_head *head)
{
struct dsp_list_node *node;
dsp_list_for_each(node, head) {
struct dsp_exp_element *element =
container_of(node, struct dsp_exp_element, list_node);
if (element->type == EXP_INTEGER)
DL_BUF_STR("%d ", element->integer);
if (element->type == EXP_OP)
DL_BUF_STR("%c ", element->op);
if (element->type == EXP_LINKER_VALUE) {
switch (element->linker_value) {
case ADDEND:
DL_BUF_STR("addend ");
break;
case BLOCK_ADDR_AR:
DL_BUF_STR("block_addr_AR ");
break;
case BLOCK_ADDR_BR:
DL_BUF_STR("block_addr_BR ");
break;
case ITEM_ADDR_AR:
DL_BUF_STR("item_addr_AR ");
break;
case ITEM_ADDR_BR:
DL_BUF_STR("item_addr_BR ");
break;
case ITEM_VALUE:
DL_BUF_STR("item_value ");
break;
case STORED_VALUE:
DL_BUF_STR("stored_value ");
break;
case SYMBOL_ADDR_AR:
DL_BUF_STR("symbol_addr_AR ");
break;
case SYMBOL_ADDR_BR:
DL_BUF_STR("symbol_addr_BR ");
break;
case SYMBOL_BLOCK_ADDR_AR:
DL_BUF_STR("symbol_block_addr_AR ");
break;
case SYMBOL_BLOCK_ADDR_BR:
DL_BUF_STR("symbol_block_addr_BR ");
break;
}
}
}
DL_BUF_STR("\n");
DL_PRINT_BUF(INFO);
}
int dsp_exp_import(struct dsp_exp_element *exp, struct dsp_dl_lib_file *file)
{
int ret;
ret = dsp_dl_lib_file_read((char *)exp, sizeof(*exp), file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
return 0;
}
void dsp_exp_free(struct dsp_list_head *head)
{
dsp_list_free(head, struct dsp_exp_element, list_node);
}
void dsp_bit_ext_print(enum dsp_bit_ext_type ext)
{
switch (ext) {
case BIT_ONE:
DL_BUF_STR("one ");
break;
case BIT_ZERO:
DL_BUF_STR("zero ");
break;
case BIT_SIGN:
DL_BUF_STR("sign ");
break;
case BIT_NONE:
break;
}
}
void dsp_bit_slice_print(struct dsp_list_head *head)
{
struct dsp_list_node *node;
dsp_list_for_each(node, head) {
struct dsp_bit_slice *elem =
container_of(node, struct dsp_bit_slice, list_node);
if (elem->high == elem->low) {
DL_BUF_STR("[ ");
dsp_bit_ext_print(elem->h_ext);
DL_BUF_STR("%d ", elem->high);
dsp_bit_ext_print(elem->l_ext);
DL_BUF_STR("]@%d ", elem->value);
} else {
DL_BUF_STR("[");
dsp_bit_ext_print(elem->h_ext);
DL_BUF_STR("%d..%d", elem->high, elem->low);
dsp_bit_ext_print(elem->l_ext);
DL_BUF_STR("]");
DL_BUF_STR("@%d ", elem->value);
}
}
DL_BUF_STR("\n");
DL_PRINT_BUF(INFO);
}
int dsp_bit_slice_import(struct dsp_bit_slice *bs, struct dsp_dl_lib_file *file)
{
int ret;
ret = dsp_dl_lib_file_read((char *)bs, sizeof(*bs), file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
return 0;
}
void dsp_bit_slice_free(struct dsp_list_head *head)
{
dsp_list_free(head, struct dsp_bit_slice, list_node);
}
void dsp_pos_print(struct dsp_list_head *head)
{
struct dsp_list_node *node;
dsp_list_for_each(node, head) {
struct dsp_pos *elem =
container_of(node, struct dsp_pos, list_node);
if (elem->type == BIT_POS)
DL_INFO("@%d\n", elem->bit_pos);
else
dsp_bit_slice_print(&elem->bit_slice_list);
}
}
int dsp_pos_import(struct dsp_pos *pos, struct dsp_dl_lib_file *file)
{
int ret, idx;
ret = dsp_dl_lib_file_read((char *)pos, sizeof(*pos), file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
if (pos->type == BIT_SLICE_LIST) {
int list_num = pos->bit_slice_list.num;
dsp_list_head_init(&pos->bit_slice_list);
for (idx = 0; idx < list_num; idx++) {
struct dsp_bit_slice *bs =
(struct dsp_bit_slice *)dsp_dl_malloc(
sizeof(*bs),
"Bit slice");
dsp_bit_slice_import(bs, file);
dsp_list_node_init(&bs->list_node);
dsp_list_node_push_back(&pos->bit_slice_list,
&bs->list_node);
}
}
return 0;
}
void dsp_pos_free(struct dsp_list_head *head)
{
struct dsp_list_node *cur, *next;
cur = head->next;
while (cur != NULL) {
struct dsp_pos *pos =
container_of(cur, struct dsp_pos, list_node);
next = cur->next;
if (pos->type == BIT_SLICE_LIST)
dsp_bit_slice_free(&pos->bit_slice_list);
dsp_dl_free(pos);
cur = next;
}
}
void dsp_cont_print(struct dsp_cont *cont)
{
if (cont->inst_num > 1)
DL_BUF_STR("[%d]", cont->inst_num);
dsp_type_print(&cont->type);
}
void dsp_range_print(enum dsp_range_type ran)
{
if (ran == RANGE_STRICT)
DL_BUF_STR("strict\n");
else if (ran == RANGE_NOSTRICT)
DL_BUF_STR("nostrict\n");
DL_PRINT_BUF(INFO);
}
void dsp_reloc_rule_print(struct dsp_reloc_rule *rule)
{
DL_INFO("Reloc rule[%d]\n", rule->idx);
DL_INFO("Exp:\n");
dsp_exp_print(&rule->exp);
DL_BUF_STR("Type: ");
dsp_type_print(&rule->type);
DL_INFO("Pos(%d):\n", rule->pos_list.num);
dsp_pos_print(&rule->pos_list);
DL_BUF_STR("Cont: ");
dsp_cont_print(&rule->cont);
DL_BUF_STR("Range: ");
dsp_range_print(rule->range_chk);
}
int dsp_reloc_rule_import(struct dsp_reloc_rule *rule,
struct dsp_dl_lib_file *file)
{
int ret;
int list_num, idx;
ret = dsp_dl_lib_file_read((char *)rule, sizeof(*rule), file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
list_num = rule->exp.num;
dsp_list_head_init(&rule->exp);
for (idx = 0; idx < list_num; idx++) {
struct dsp_exp_element *exp =
(struct dsp_exp_element *)
dsp_dl_malloc(
sizeof(*exp),
"Exp elem");
ret = dsp_exp_import(exp, file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
dsp_list_node_init(&exp->list_node);
dsp_list_node_push_back(&rule->exp, &exp->list_node);
}
list_num = rule->pos_list.num;
dsp_list_head_init(&rule->pos_list);
for (idx = 0; idx < list_num; idx++) {
struct dsp_pos *pos = (struct dsp_pos *)dsp_dl_malloc(
sizeof(*pos), "Pos");
ret = dsp_pos_import(pos, file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
dsp_list_node_init(&pos->list_node);
dsp_list_node_push_back(&rule->pos_list, &pos->list_node);
}
return 0;
}
void dsp_reloc_rule_free(struct dsp_reloc_rule *rule)
{
dsp_exp_free(&rule->exp);
dsp_pos_free(&rule->pos_list);
}
void dsp_reloc_rule_list_print(struct dsp_reloc_rule_list *list)
{
int idx;
DL_INFO(DL_BORDER);
DL_INFO("Reloc rules\n");
for (idx = 0; idx < list->cnt; idx++) {
dsp_reloc_rule_print(list->list[idx]);
DL_INFO("\n");
}
}
int dsp_reloc_rule_list_import(struct dsp_reloc_rule_list *list,
struct dsp_dl_lib_file *file)
{
int ret;
char magic[4];
int idx;
DL_DEBUG("Rule list import\n");
dsp_dl_lib_file_reset(file);
ret = dsp_dl_lib_file_read(magic, sizeof(char) * 4, file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
if (magic[0] != 'R' || magic[1] != 'U' || magic[2] != 'L' ||
magic[3] != 'E') {
DL_ERROR("Magic number is incorrect\n");
return -1;
}
ret = dsp_dl_lib_file_read((char *)&list->cnt, sizeof(int), file);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
return -1;
}
if (list->cnt > RULE_MAX) {
DL_ERROR("Rule list count(%d) is over RULE_MAX(%d)\n",
list->cnt, RULE_MAX);
return -1;
}
DL_DEBUG("Rule list count %d\n", list->cnt);
for (idx = 0; idx < list->cnt; idx++) {
list->list[idx] = (struct dsp_reloc_rule *)dsp_dl_malloc(
sizeof(*list->list[idx]),
"Reloc rule");
dsp_reloc_rule_import(list->list[idx], file);
}
return 0;
}
void dsp_reloc_rule_list_free(struct dsp_reloc_rule_list *list)
{
int idx;
for (idx = 0; idx < list->cnt; idx++) {
struct dsp_reloc_rule *rule = list->list[idx];
dsp_reloc_rule_free(rule);
dsp_dl_free(rule);
}
}