linuxOS_D21X/source/uboot-2021.10/drivers/aicupg/upg_fat.c

184 lines
4.0 KiB
C
Raw Normal View History

2024-11-29 08:13:19 +00:00
// SPDX-License-Identifier: GPL-2.0+
/*
2024-11-29 08:33:21 +00:00
* Copyright (C) 2021-2024 ArtInChip Technology Co., Ltd
2024-11-29 08:13:19 +00:00
* Author: Jianfeng Li <jianfeng.li@artinchip.com>
2024-11-29 08:33:21 +00:00
* Author: Dehuang Wu <dehuang.wu@artinchip.com>
2024-11-29 08:13:19 +00:00
*/
#include <common.h>
#include <artinchip/aicupg.h>
#include "upg_internal.h"
2024-11-29 08:33:21 +00:00
static u32 image_size;
static u64 write_size;
static progress_cb g_progress_cb;
void aicupg_fat_set_process_cb(progress_cb cb)
{
g_progress_cb = cb;
}
2024-11-29 08:13:19 +00:00
static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
{
s32 ret;
struct fwc_info *fwc;
u8 *buf;
s32 total_len = 0;
int offset, write_once_size, len, remaining_size;
loff_t actread;
2024-11-29 08:33:21 +00:00
u32 percent;
2024-11-29 08:13:19 +00:00
fwc = NULL;
buf = NULL;
fwc = (struct fwc_info *)malloc(sizeof(struct fwc_info));
if (!fwc) {
pr_err("Error: malloc fwc failed.\n");
ret = -1;
goto err;
}
memset((void *)fwc, 0, sizeof(struct fwc_info));
printf("Firmware component: %s\n", pmeta->name);
printf(" partition: %s programming ...\n", pmeta->partition);
2024-11-29 08:33:21 +00:00
/* config fwc */
2024-11-29 08:13:19 +00:00
fwc_meta_config(fwc, pmeta);
2024-11-29 08:33:21 +00:00
/* start write data */
2024-11-29 08:13:19 +00:00
media_data_write_start(fwc);
2024-11-29 08:33:21 +00:00
/* config write size once */
2024-11-29 08:13:19 +00:00
write_once_size = DATA_WRITE_ONCE_SIZE;
if (write_once_size % fwc->block_size)
write_once_size = (write_once_size / fwc->block_size) * fwc->block_size;
2024-11-29 08:33:21 +00:00
/* malloc buf memory */
2024-11-29 08:13:19 +00:00
buf = (u8 *)memalign(ARCH_DMA_MINALIGN, write_once_size);
if (!buf) {
pr_err("Error: malloc buf failed.\n");
ret = -1;
goto err;
}
memset((void *)buf, 0, write_once_size);
offset = 0;
while (offset < pmeta->size) {
remaining_size = pmeta->size - offset;
len = min(remaining_size, write_once_size);
if (len % fwc->block_size)
len = ((len / fwc->block_size) + 1) * fwc->block_size;
ret = fat_read_file(image_name, (void *)buf,
pmeta->offset + offset, len, &actread);
if (actread != len && actread != remaining_size) {
printf("Error:read file failed!\n");
goto err;
}
2024-11-29 08:33:21 +00:00
/* write data to media */
2024-11-29 08:13:19 +00:00
ret = media_data_write(fwc, buf, len);
if (ret == 0) {
pr_err("Error: media write failed!..\n");
goto err;
}
total_len += ret;
offset += len;
2024-11-29 08:33:21 +00:00
write_size += ret;
percent = write_size * 100 / image_size;
if (g_progress_cb)
g_progress_cb(percent);
2024-11-29 08:13:19 +00:00
}
2024-11-29 08:33:21 +00:00
/* write data end*/
2024-11-29 08:13:19 +00:00
media_data_write_end(fwc);
2024-11-29 08:33:21 +00:00
/* check partition crc */
if (fwc->calc_partition_crc != pmeta->crc) {
pr_err("calc partition crc:0x%x, expect partition crc:0x%x\n",
fwc->calc_partition_crc, pmeta->crc);
goto err;
}
2024-11-29 08:13:19 +00:00
printf(" partition: %s programming done\n", pmeta->partition);
if (buf)
free(buf);
if (fwc)
free(fwc);
return total_len;
err:
2024-11-29 08:33:21 +00:00
printf(" Partition: %s programming failed.\n", pmeta->partition);
2024-11-29 08:13:19 +00:00
if (buf)
free(buf);
if (fwc)
free(fwc);
return 0;
}
/*fat upgrade function*/
s32 aicupg_fat_write(char *image_name, char *protection,
struct image_header_upgrade *header)
{
struct fwc_meta *p;
struct fwc_meta *pmeta;
int i;
int cnt;
s32 ret;
s32 write_len = 0;
loff_t actread;
pmeta = NULL;
pmeta = (struct fwc_meta *)malloc(header->meta_size);
if (!pmeta) {
pr_err("Error: malloc for meta failed.\n");
ret = -1;
goto err;
}
memset((void *)pmeta, 0, header->meta_size);
/*read meta info*/
ret = fat_read_file(image_name, (void *)pmeta, header->meta_offset,
header->meta_size, &actread);
if (actread != header->meta_size) {
printf("Error:read file failed!\n");
goto err;
}
/*prepare device*/
ret = media_device_prepare(NULL, header);
if (ret != 0) {
pr_err("Error:prepare device failed!\n");
goto err;
}
2024-11-29 08:33:21 +00:00
if (g_progress_cb)
g_progress_cb(0);
image_size = header->file_size;
2024-11-29 08:13:19 +00:00
p = pmeta;
cnt = header->meta_size / sizeof(struct fwc_meta);
for (i = 0; i < cnt; i++) {
if (!strcmp(p->partition, "") ||
strstr(protection, p->partition)) {
p++;
continue;
}
ret = media_device_write(image_name, p);
if (ret == 0) {
pr_err("media device write data failed!\n");
goto err;
}
p++;
write_len += ret;
}
2024-11-29 08:33:21 +00:00
if (g_progress_cb)
g_progress_cb(100);
2024-11-29 08:23:11 +00:00
printf("All firmware components programming done.\n");
2024-11-29 08:13:19 +00:00
free(pmeta);
return write_len;
err:
if (pmeta)
free(pmeta);
return 0;
}