185 lines
4.2 KiB
C
185 lines
4.2 KiB
C
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
/*
|
|
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
|
*/
|
|
|
|
//#include <common.h>
|
|
#include <command.h>
|
|
#include <environment.h>
|
|
#include <malloc.h>
|
|
#include <asm/byteorder.h>
|
|
#include <config.h>
|
|
#include <asm/arch/io.h>
|
|
#include <partition_table.h>
|
|
#include <libavb.h>
|
|
#include <version.h>
|
|
#include <amlogic/storage.h>
|
|
#include <fastboot.h>
|
|
#include <u-boot/sha1.h>
|
|
|
|
#ifdef CONFIG_CMD_CAR_PARAMS
|
|
|
|
// calibrator_message used 1024K-1026K by misc partition
|
|
typedef struct calibrator_message {
|
|
uint32_t magic; //magic number
|
|
uint8_t rsv[4];
|
|
int64_t camera[9]; //camera Internal parameter matrix
|
|
int64_t distortion[5]; //Distortion matrix
|
|
int64_t matrix_rtos[9]; //projection matrix for rtos
|
|
int64_t matrix_gles[9];//projection matrix for gles
|
|
int64_t car[5]; //car parameters
|
|
|
|
// rounds up to 2048-byte.
|
|
uint8_t reserve[1740];
|
|
|
|
// CRC32 of all 28 bytes preceding this field (little endian
|
|
// format).
|
|
uint32_t crc32_le;
|
|
} calibrator_message;
|
|
|
|
#define CALIBRATOR_OFFSET (1024 * 1024)
|
|
#define CALIBRATOR_SIZE 2048
|
|
#define CALIBRATOR_MAGIC 0x51504948 /* magic number */
|
|
|
|
static uint32_t car_crc32(const uint8_t *buf, size_t size)
|
|
{
|
|
static uint32_t crc_table[256];
|
|
uint32_t ret = -1;
|
|
|
|
// Compute the CRC-32 table only once.
|
|
if (!crc_table[1]) {
|
|
for (uint32_t i = 0; i < 256; ++i) {
|
|
uint32_t crc = i;
|
|
|
|
for (uint32_t j = 0; j < 8; ++j) {
|
|
uint32_t mask = -(crc & 1);
|
|
|
|
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
|
}
|
|
crc_table[i] = crc;
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
ret = (ret >> 8) ^ crc_table[(ret ^ buf[i]) & 0xFF];
|
|
|
|
return ~ret;
|
|
}
|
|
|
|
bool calibrator_info_validate(calibrator_message *info)
|
|
{
|
|
uint32_t crc;
|
|
|
|
if (info->magic != CALIBRATOR_MAGIC) {
|
|
printf("Magic 0x%x is incorrect.\n", info->magic);
|
|
return false;
|
|
}
|
|
|
|
crc = car_crc32((const uint8_t *)info,
|
|
sizeof(calibrator_message) - sizeof(uint32_t));
|
|
if (info->crc32_le != crc) {
|
|
printf("crc 0x%x != 0x%x\n", info->crc32_le, crc);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void calibrator_info_reset(calibrator_message *info)
|
|
{
|
|
memset(info, '\0', sizeof(calibrator_message));
|
|
info->magic = CALIBRATOR_MAGIC;
|
|
}
|
|
|
|
void dump_info(calibrator_message *info)
|
|
{
|
|
int i;
|
|
|
|
printf("info->magic = 0x%x\n", info->magic);
|
|
for (i = 0; i < 9; ++i) {
|
|
printf("info->camera[%d] = %lld\n",
|
|
i, info->camera[i]);
|
|
}
|
|
for (i = 0; i < 5; ++i) {
|
|
printf("info->distortion[%d] = %lld\n",
|
|
i, info->distortion[i]);
|
|
}
|
|
for (i = 0; i < 9; ++i) {
|
|
printf("info->matrix_rtos[%d] = %lld\n",
|
|
i, info->matrix_rtos[i]);
|
|
}
|
|
for (i = 0; i < 9; ++i) {
|
|
printf("info->matrix_gles[%d] = %lld\n",
|
|
i, info->matrix_gles[i]);
|
|
}
|
|
for (i = 0; i < 5; ++i) {
|
|
printf("info->car[%d] = %lld\n",
|
|
i, info->car[i]);
|
|
}
|
|
}
|
|
|
|
int calibrator_info_open_partition(unsigned char *miscbuf)
|
|
{
|
|
char *partition = "misc";
|
|
|
|
printf("Start read %s partition datas!\n", partition);
|
|
if (store_read((const char *)partition,
|
|
CALIBRATOR_OFFSET, CALIBRATOR_SIZE, miscbuf) < 0) {
|
|
printf("failed to store read %s.\n", partition);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool calibrator_info_save(calibrator_message *info)
|
|
{
|
|
char *partition = "misc";
|
|
|
|
printf("save calibrator-info\n");
|
|
info->crc32_le = car_crc32((const uint8_t *)info,
|
|
sizeof(calibrator_message) - sizeof(uint32_t));
|
|
|
|
dump_info(info);
|
|
store_write((const char *)partition, CALIBRATOR_OFFSET, CALIBRATOR_SIZE,
|
|
(unsigned char *)info);
|
|
return true;
|
|
}
|
|
|
|
static int do_ReadCarParams(cmd_tbl_t *cmdtp,
|
|
int flag,
|
|
int argc,
|
|
char * const argv[])
|
|
{
|
|
calibrator_message *info = NULL;
|
|
unsigned char *loadaddr = 0;
|
|
|
|
if (argc > 2)
|
|
loadaddr = (unsigned char *)simple_strtoul(argv[2], NULL, 16);
|
|
else
|
|
loadaddr = (unsigned char *)simple_strtoul(env_get("car_mem_addr"), NULL, 16);
|
|
|
|
info = (calibrator_message *)loadaddr;
|
|
|
|
calibrator_info_open_partition(loadaddr);
|
|
|
|
if (!calibrator_info_validate(info)) {
|
|
printf("calibrator-info is invalid. resetting\n");
|
|
calibrator_info_reset(info);
|
|
calibrator_info_save(info);
|
|
} else {
|
|
dump_info(info);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
U_BOOT_CMD(read_car_params, 3, 0, do_ReadCarParams,
|
|
"read_car_params",
|
|
"\nThis command will read car params to mem\n"
|
|
"partition by mark to decide whether execute command!\n"
|
|
"So you can execute command: read_car_params"
|
|
);
|
|
|