344 lines
11 KiB
C
Executable File
344 lines
11 KiB
C
Executable File
// Copyright 2020-2021 Beken
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include <os/os.h>
|
|
#include "cli.h"
|
|
#include <driver/otp.h>
|
|
|
|
#if CONFIG_TFM_OTP_NSC
|
|
#include "tfm_otp_nsc.h"
|
|
#endif
|
|
|
|
#if CONFIG_SOC_BK7236XX
|
|
|
|
uint32_t findFirstZeroBit(uint8_t num)
|
|
{
|
|
uint32_t positition = 0;
|
|
while((num & 1) && (positition < 8)){
|
|
num = num >> 1;
|
|
++positition;
|
|
}
|
|
return positition;
|
|
}
|
|
|
|
extern int hexstr2bin(const char *hex, u8 *buf, size_t len);
|
|
|
|
static void cli_otp_help(void)
|
|
{
|
|
CLI_LOGI("write data must be string like 01ab03, you can use pre-write to check data\r\n");
|
|
|
|
CLI_LOGI("otp_apb self_test \r\n");
|
|
CLI_LOGI("otp_apb read [item_id][size] \r\n");
|
|
CLI_LOGI("otp_apb write [item_id][size][data] \r\n");
|
|
|
|
CLI_LOGI("otp_apb read_mask/read_permission [item_id] \r\n");
|
|
CLI_LOGI("otp_apb write_mask/write_permission [item_id][permission] \r\n");
|
|
|
|
CLI_LOGI("otp_apb read_random [size] \r\n");
|
|
CLI_LOGI("otp_apb pre-write [size][data] \r\n");
|
|
|
|
CLI_LOGI("otp_ahb read [item_id][size] \r\n");
|
|
CLI_LOGI("otp_ahb write [item_id][size][data] \r\n");
|
|
|
|
CLI_LOGI("otp_ahb read_permission [item_id] \r\n");
|
|
CLI_LOGI("otp_ahb write_permission [item_id][permission] \r\n");
|
|
|
|
CLI_LOGI("otp_ahb read_random [size] \r\n");
|
|
CLI_LOGI("otp_ahb pre-write [size][data] \r\n");
|
|
|
|
#if CONFIG_TFM_OTP_NSC
|
|
CLI_LOGI("otp_nsc read [item_id] \r\n");
|
|
CLI_LOGI("otp_nsc write [map_id][item_id][size][data] \r\n");
|
|
CLI_LOGI("otp_nsc read_permission/write_permission [map_id][item_id][permission] \r\n");
|
|
#endif
|
|
}
|
|
|
|
static void cli_otp_apb_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
extern bk_err_t bk_otp_fully_flow_test();
|
|
|
|
if (argc < 2) {
|
|
cli_otp_help();
|
|
return;
|
|
}
|
|
if (os_strcmp(argv[1], "self_test") == 0){
|
|
#if CONFIG_ATE_TEST
|
|
uint32_t ret = bk_otp_fully_flow_test();
|
|
BK_RAW_LOGI(NULL, "ret = %u\r\n",ret);
|
|
#endif
|
|
BK_RAW_LOGI(NULL,"Enable ATE_TEST\r\n");
|
|
} else if (os_strcmp(argv[1], "read") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t size = os_strtoul(argv[3], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0xFF, size);
|
|
int ret = bk_otp_apb_read(item,data,size);
|
|
BK_RAW_LOGI(NULL, "read ret = %d, data in little endian:\r\n",ret);
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL,"\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else if (os_strcmp(argv[1], "write") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t size = os_strtoul(argv[3], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0, size);
|
|
hexstr2bin(argv[4], data, size);
|
|
BK_RAW_LOGI(NULL, "data to be written:\r\n");
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
uint32_t ret = bk_otp_apb_update(item,data,size);
|
|
bk_otp_apb_read(item,data,size);
|
|
BK_RAW_LOGI(NULL, "\r\nwrite ret = %d, after write data:\r\n",ret);
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else if (os_strcmp(argv[1], "read_mask") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t value;
|
|
value = bk_otp_apb_read_mask(item);
|
|
os_printf("permission value = %#x\r\n",value);
|
|
} else if (os_strcmp(argv[1], "write_mask") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
otp_privilege_t permission = os_strtoul(argv[3], NULL, 16);
|
|
uint32_t value;
|
|
int ret = bk_otp_apb_write_mask(item, permission);
|
|
value = bk_otp_apb_read_permission(item);
|
|
os_printf("permission value = %#x,ret = %d\r\n",value, ret);
|
|
}else if (os_strcmp(argv[1], "read_permission") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t value;
|
|
value = bk_otp_apb_read_permission(item);
|
|
os_printf("permission value = %#x\r\n",value);
|
|
} else if (os_strcmp(argv[1], "write_permission") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
otp_privilege_t permission = os_strtoul(argv[3], NULL, 16);
|
|
uint32_t value;
|
|
int ret = bk_otp_apb_write_permission(item, permission);
|
|
value = bk_otp_apb_read_permission(item);
|
|
os_printf("permission value = %#x,ret = %d\r\n",value, ret);
|
|
} else if (os_strcmp(argv[1], "read_random") == 0){
|
|
uint32_t size = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t* data = (uint32_t*)os_malloc(size*sizeof(uint32_t));
|
|
memset(data, 0, size);
|
|
bk_otp_read_random_number(data, size);
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x\r\n",data[i]);
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
BK_RAW_LOGI(NULL, "\r\n");
|
|
} else if (os_strcmp(argv[1], "pre-write") == 0){
|
|
uint32_t size = os_strtoul(argv[2], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0, size);
|
|
hexstr2bin(argv[3], data, size);
|
|
BK_RAW_LOGI(NULL, "please check write data:\r\n");
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else {
|
|
cli_otp_help();
|
|
}
|
|
}
|
|
|
|
static void cli_otp_ahb_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
extern otp_privilege_t bk_otp_ahb_read_permission(otp2_id_t item);
|
|
extern bk_err_t bk_otp_ahb_write_permission(otp2_id_t item, otp_privilege_t permission);
|
|
if (argc < 2) {
|
|
cli_otp_help();
|
|
return;
|
|
}
|
|
|
|
if (os_strcmp(argv[1], "read") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t size = os_strtoul(argv[3], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0xFF, size);
|
|
int ret = bk_otp_ahb_read(item,data,size);
|
|
BK_RAW_LOGI(NULL, "read ret = %d, data in little endian:\r\n",ret);
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL,"\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else if (os_strcmp(argv[1], "write") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t size = os_strtoul(argv[3], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0, size);
|
|
hexstr2bin(argv[4], data, size);
|
|
BK_RAW_LOGI(NULL, "data to be written:\r\n");
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
uint32_t ret = bk_otp_ahb_update(item,data,size);
|
|
bk_otp_ahb_read(item,data,size);
|
|
BK_RAW_LOGI(NULL, "\r\nwrite ret = %d, after write data:\r\n",ret);
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else if (os_strcmp(argv[1], "read_permission") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t value;
|
|
value = bk_otp_ahb_read_permission(item);
|
|
os_printf("permission value = %#x\r\n",value);
|
|
} else if (os_strcmp(argv[1], "write_permission") == 0){
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
otp_privilege_t permission = os_strtoul(argv[3], NULL, 16);
|
|
uint32_t value;
|
|
int ret = bk_otp_ahb_write_permission(item, permission);
|
|
value = bk_otp_ahb_read_permission(item);
|
|
os_printf("after write permission value = %#x,ret = %d\r\n",value, ret);
|
|
} else if (os_strcmp(argv[1], "pre-write") == 0){
|
|
uint32_t size = os_strtoul(argv[2], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0, size);
|
|
hexstr2bin(argv[3], data, size);
|
|
BK_RAW_LOGI(NULL, "please check write data:\r\n");
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
os_free(data);
|
|
data = NULL;
|
|
} else {
|
|
cli_otp_help();
|
|
}
|
|
}
|
|
#if CONFIG_TFM_OTP_NSC
|
|
static void cli_otp_nsc_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
if (os_strcmp(argv[1], "read") == 0) {
|
|
uint32_t item = os_strtoul(argv[2], NULL, 10);
|
|
int ret = bk_otp_read_nsc(item);
|
|
BK_RAW_LOGI(NULL, "read ret = %d\r\n",ret);
|
|
} else if (os_strcmp(argv[1], "write") == 0) {
|
|
uint32_t map_id = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t item = os_strtoul(argv[3], NULL, 10);
|
|
uint32_t size = os_strtoul(argv[4], NULL, 10);
|
|
uint8_t* data = (uint8_t*)os_malloc(size*sizeof(uint8_t));
|
|
memset(data, 0, size);
|
|
hexstr2bin(argv[5], data, size);
|
|
BK_RAW_LOGI(NULL, "data to be written:\r\n");
|
|
for(int i = 0;i < size; i++){
|
|
BK_RAW_LOGI(NULL, "%x ",data[i]);
|
|
if(i % 8 == 7) BK_RAW_LOGI(NULL, "\r\n");
|
|
}
|
|
int ret = bk_otp_update_nsc(map_id,item,data,size);
|
|
BK_RAW_LOGI(NULL, "write ret = %d\r\n",ret);
|
|
os_free(data);
|
|
data = NULL;
|
|
} else if (os_strcmp(argv[1], "read_permission") == 0) {
|
|
uint32_t map_id = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t item = os_strtoul(argv[3], NULL, 10);
|
|
uint32_t permission;
|
|
int ret = bk_otp_read_permission_nsc(map_id, item, &permission);
|
|
BK_RAW_LOGI(NULL, "read ret = %d, permission = %#x\r\n",ret, permission);
|
|
} else if (os_strcmp(argv[1], "write_permission") == 0) {
|
|
uint32_t map_id = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t item = os_strtoul(argv[3], NULL, 10);
|
|
uint32_t permission = os_strtoul(argv[4], NULL, 16);
|
|
int ret = bk_otp_write_permission_nsc(map_id, item, permission);
|
|
bk_otp_read_permission_nsc(map_id, item, &permission);
|
|
BK_RAW_LOGI(NULL, "write ret = %d, permission = %#x\r\n",ret, permission);
|
|
} else if (os_strcmp(argv[1], "write_mask") == 0) {
|
|
uint32_t map_id = os_strtoul(argv[2], NULL, 10);
|
|
uint32_t item = os_strtoul(argv[3], NULL, 10);
|
|
uint32_t permission = os_strtoul(argv[4], NULL, 16);
|
|
int ret = bk_otp_write_mask_nsc(map_id, item, permission);
|
|
bk_otp_read_permission_nsc(map_id, item, &permission);
|
|
BK_RAW_LOGI(NULL, "write ret = %d, permission = %#x\r\n",ret, permission);
|
|
} else {
|
|
cli_otp_help();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#else /* CONFIG_SOC_BK7236XX */
|
|
|
|
#define OTP_BANK_SIZE (0x800)
|
|
static void cli_otp_help(void)
|
|
{
|
|
CLI_LOGI("otp_test read [addr] [length]\r\n");
|
|
}
|
|
|
|
static void cli_otp_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
cli_otp_help();
|
|
return;
|
|
}
|
|
|
|
uint32_t addr, length;
|
|
uint8_t *buff_p, *record_p;
|
|
|
|
if (os_strcmp(argv[1], "read") == 0) {
|
|
addr = os_strtoul(argv[2], NULL, 16);
|
|
length = os_strtoul(argv[3], NULL, 16);
|
|
|
|
if((addr > OTP_BANK_SIZE) || ((addr + length) > OTP_BANK_SIZE))
|
|
{
|
|
CLI_LOGI("\r\n addr or length invalid! \r\n");
|
|
return ;
|
|
}
|
|
|
|
record_p = buff_p = (uint8_t *)malloc(length);
|
|
memset(buff_p, 0x0, length);
|
|
|
|
BK_LOG_ON_ERR(bk_otp_read_bytes_nonsecure(buff_p, addr, length));
|
|
|
|
for(int i=0; i<length; i++){
|
|
bk_printf("%02x",*buff_p);
|
|
buff_p++;
|
|
}
|
|
free(record_p);
|
|
CLI_LOGI("\r\n read OTP suc! \r\n");
|
|
} else {
|
|
cli_otp_help();
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define OTP_CMD_CNT (sizeof(s_otp_commands) / sizeof(struct cli_command))
|
|
static const struct cli_command s_otp_commands[] = {
|
|
{"otp_apb", "otp_apb {read}", cli_otp_apb_cmd},
|
|
{"otp_ahb", "otp_ahb {read}", cli_otp_ahb_cmd},
|
|
#if CONFIG_TFM_OTP_NSC
|
|
{"otp_nsc","otp_test {read}", cli_otp_nsc_cmd},
|
|
#endif
|
|
};
|
|
|
|
int cli_otp_init(void)
|
|
{
|
|
return cli_register_commands(s_otp_commands, OTP_CMD_CNT);
|
|
}
|