Files
luban-lite-t3e-pro/application/baremetal/bootloader/lib/common/config_parse.c
刘可亮 8bca5e8332 v1.0.4
2024-04-03 16:40:57 +08:00

175 lines
4.3 KiB
C

/*
* Copyright (c) 2023, Artinchip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Jianfeng Li <jianfeng.li@artinchip.com>
*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <config_parse.h>
u32 boot_cfg_get_key_val(char *cfgtxt, u32 len, const char *key, u32 klen,
char *val, u32 vlen)
{
u32 idx = 0, cnt = 0;
memset(val, 0, vlen);
while (idx < len) {
/* Begin of one string line */
/* Skip blank */
if (aic_isspace(cfgtxt[idx])) {
idx++;
continue;
}
/* Skip comment line */
if (cfgtxt[idx] == '#') {
while ((idx < len) && (cfgtxt[idx] != '\n'))
idx++;
continue;
}
if (strncmp(&cfgtxt[idx], key, klen)) {
/* Skip line if key is not matched */
while ((idx < len) && (cfgtxt[idx] != '\n'))
idx++;
continue;
}
/* Key is matched, but need to skip blank and '=' */
idx += klen;
while ((cfgtxt[idx] == ' ') || (cfgtxt[idx] == '\t') ||
(cfgtxt[idx] == '=')) {
idx++;
if (idx >= len)
break;
}
/* Now it is clean, get value */
cnt = 0;
while ((idx < len) && (cfgtxt[idx] != '\r') && (cfgtxt[idx] != '\n')) {
val[cnt] = cfgtxt[idx];
cnt++;
idx++;
if (cnt == vlen)
break;
}
break;
}
return cnt;
}
/*
* Check key value format:
* - boot0=size@offset
* - boot0=example.bin
*/
static u32 boot_cfg_is_offset_format(char *val, u32 len)
{
u32 i = 0, sign_idx;
sign_idx = 0;
for (i = 0; i < len; i++) {
if (aic_isspace(val[i]))
continue;
if ((val[i] == 'x') || (val[i] == 'X'))
continue;
if (val[i] == '@') {
sign_idx = i;
continue;
}
if (!aic_isxdigit(val[i])) {
sign_idx = 0;
break;
}
}
return sign_idx;
}
/*
* Get the given key's data file name and valid data length
* - cfgtxt: The bootcfg.txt file data content
* - clen: The bootcfg.txt file data length
* - key: Key name
* - fname: The output data file name
* - nsiz: The fname buffer size
* - offset: The firmware data's start offset in the file data(fname)
* - flen: The firmware data's valid length
*/
int boot_cfg_parse_file(char *cfgtxt, u32 clen, char *key, char *fname,
u32 nsiz, ulong *offset, ulong *flen)
{
char val[IMG_NAME_MAX_SIZ];
u32 vlen = 0, sign_idx;
vlen = boot_cfg_get_key_val(cfgtxt, clen, key, strlen(key), val,
IMG_NAME_MAX_SIZ);
if (vlen == 0)
return -1;
sign_idx = boot_cfg_is_offset_format(val, vlen);
if (sign_idx) {
*flen = (ulong)strtoul(val, NULL, 16);
*offset = (ulong)strtoul(&val[sign_idx + 1], NULL, 16);
vlen = boot_cfg_get_key_val(cfgtxt, clen, "image", 5, val, IMG_NAME_MAX_SIZ);
memcpy(fname, val, min(vlen, nsiz));
fname[vlen] = 0;
} else {
*flen = 0;
*offset = 0;
memcpy(fname, val, min(vlen, nsiz));
fname[vlen] = 0;
}
printf("0x%x @ %s\n", (u32)(*offset), fname);
return vlen;
}
int boot_cfg_get_boot0(char *cfgtxt, u32 clen, char *name, u32 nsiz,
ulong *offset, ulong *boot1len)
{
return boot_cfg_parse_file(cfgtxt, clen, "boot0", name, nsiz, offset,
boot1len);
}
int boot_cfg_get_boot1(char *cfgtxt, u32 clen, char *name, u32 nsiz,
ulong *offset, ulong *boot1len)
{
return boot_cfg_parse_file(cfgtxt, clen, "boot1", name, nsiz, offset,
boot1len);
}
int boot_cfg_get_image(char *cfgtxt, u32 clen, char *name, u32 nsiz)
{
u32 ret = 0;
if (NULL == name)
return -1;
ret = boot_cfg_get_key_val(cfgtxt, clen, "image", 5, name, nsiz);
if (ret <= 0)
return -1;
return 0;
}
int boot_cfg_get_protection(char *cfgtxt, u32 clen, char *name, u32 nsiz)
{
u32 ret = 0;
if (NULL == name)
return -1;
ret = boot_cfg_get_key_val(cfgtxt, clen, "protection", 10, name, nsiz);
if (ret <= 0)
return -1;
return 0;
}