This commit is contained in:
刘可亮
2024-06-04 19:00:30 +08:00
parent 990c72f5be
commit 0a13af6a1d
1668 changed files with 342810 additions and 37726 deletions

View File

@@ -8,6 +8,7 @@ cwd = GetCurrentDir()
src = Glob('run.c')
src += Glob('reset.c')
src += Glob('aicupg.c')
src += Glob('aicupg_erase.c')
src += Glob('ram_boot.c')
src += Glob('crc32.c')
if GetDepend('AIC_BOOTLOADER_CMD_PROGRESS_BAR'):

View File

@@ -308,6 +308,8 @@ static int do_fat_upg(int intf, char *const blktype)
pr_err("set blk dev failed.\n");
return ret;
}
#else
pr_err("udisk upgrade disabled.\n");
#endif
} else if (!strcmp(blktype, "mmc")) {
#if defined(AICUPG_SDCARD_ENABLE)
@@ -322,6 +324,8 @@ static int do_fat_upg(int intf, char *const blktype)
pr_err("set blk dev failed.\n");
return ret;
}
#else
pr_err("sdcard upgrade disabled.\n");
#endif
} else {
return ret;
@@ -352,9 +356,9 @@ static int do_fat_upg(int intf, char *const blktype)
pr_warn("No protected partition.\n");
else
pr_info("Protected=%s\n", protection);
do_fat_upg_by_single_image(image_name, protection);
ret = do_fat_upg_by_single_image(image_name, protection);
} else {
do_fat_upg_in_direct_mode(file_buf, actread);
ret = do_fat_upg_in_direct_mode(file_buf, actread);
}
err:

View File

@@ -0,0 +1,301 @@
/*
* Copyright (c) 2023, Artinchip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Wu Dehuang <dehuang.wu@artinchip.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include <console.h>
#include <aic_core.h>
#include <aic_common.h>
#include <aic_errno.h>
#include <aic_utils.h>
#if defined(AICUPG_NOR_ARTINCHIP)
#include <sfud.h>
#endif
#if defined(AICUPG_NAND_ARTINCHIP)
#include <spinand_port.h>
#endif
#if defined(AICUPG_MMC_ARTINCHIP)
#include <mmc.h>
#endif
#define AIC_IMAGE_MAGIC 0x20434941
#define AIC_PAGE_TABLE 0x50434941
#define AIC_SPL_SIZE (128 * 1024)
#define AICUPG_ERASE_HELP \
"ArtInChip data erase command for upgdrading mode:\n" \
"erase [boot]\n" \
" Erase boot program in flash/mmc\n" \
"erase <offset> <length>\n" \
" Erase data in flash/mmc\n"
#define OP_STORAGE_SPINOR 1
#define OP_STORAGE_SPINAND 2
#define OP_STORAGE_MMC 3
static void aicupg_erase_help(void)
{
puts(AICUPG_ERASE_HELP);
}
#if defined(AICUPG_NOR_ARTINCHIP)
extern sfud_flash *sfud_probe(u32 spi_bus);
static int spinor_erase_boot(sfud_flash *flash)
{
u8 data[256];
u32 head;
int i, err;
/* Two image backup */
for (i = 0; i < 2; i++) {
err = sfud_read(flash, i * AIC_SPL_SIZE, 256, data);
if (err) {
printf("Failed to read data from spinor.\n");
return -1;
}
memcpy(&head, data, 4);
if (head == AIC_IMAGE_MAGIC) {
err = sfud_erase(flash, i * AIC_SPL_SIZE, AIC_SPL_SIZE);
if (err) {
printf("Failed to erase spinor.\n");
return -1;
}
}
}
return 0;
}
#endif
static int do_spinor_erase(int argc, char *argv[])
{
int err = -1;
#if defined(AICUPG_NOR_ARTINCHIP)
sfud_flash *flash;
unsigned long offset, length;
flash = sfud_probe(0);
if (!flash) {
printf("Failed to init spinor\n");
return -1;
}
if ((argc == 2) && (!strcmp(argv[1], "boot")))
return spinor_erase_boot(flash);
/* erase <offset> <length> */
if (argc != 3) {
aicupg_erase_help();
return -1;
}
offset = strtol(argv[1], NULL, 0);
length = strtol(argv[2], NULL, 0);
if (offset % 0x1000) {
printf("The start offset is not alignment with 4KB.\n");
return -1;
}
if (length % 0x1000) {
printf("The length is not alignment with 4KB.\n");
return -1;
}
err = sfud_erase(flash, offset, length);
if (err) {
printf("Failed to erase spinor.\n");
return -1;
}
#endif
return err;
}
#if defined(AICUPG_NAND_ARTINCHIP)
#define SPL_CANDIDATE_BLOCK_NUM 18
extern int nand_spl_get_candidate_blocks(u32 *blks, u32 size);
static int spinand_erase_boot(struct aic_spinand *flash)
{
u32 spl_blocks[SPL_CANDIDATE_BLOCK_NUM];
u32 offset, blk_size, head;
int ret, i;
u8 *data;
data = aicos_malloc_align(0, 4096, CACHE_LINE_SIZE);
if (!data) {
printf("Failed to malloc buffer.\n");
return -1;
}
nand_spl_get_candidate_blocks(spl_blocks, SPL_CANDIDATE_BLOCK_NUM);
blk_size = flash->info->page_size * flash->info->pages_per_eraseblock;
for (i = 0; i < SPL_CANDIDATE_BLOCK_NUM; i++) {
offset = spl_blocks[i] * blk_size;
ret = spinand_read(flash, data, offset, flash->info->page_size);
if (ret) {
printf("Failed to read data from spinand.\n");
return -1;
}
memcpy(&head, data, 4);
if (head == AIC_PAGE_TABLE) {
ret = spinand_erase(flash, offset, blk_size);
if (ret) {
printf("Failed to erase spinand.\n");
return -1;
}
}
}
aicos_free_align(0, data);
return ret;
}
#endif
static int do_spinand_erase(int argc, char *argv[])
{
int ret = -1;
#if defined(AICUPG_NAND_ARTINCHIP)
unsigned long offset, length;
struct aic_spinand *flash;
u32 blk_size;
flash = spinand_probe(0);
if (!flash) {
printf("Failed to init spinand\n");
return -1;
}
if ((argc == 2) && (!strcmp(argv[1], "boot")))
return spinand_erase_boot(flash);
/* erase <offset> <length> */
if (argc != 3) {
aicupg_erase_help();
return -1;
}
offset = strtol(argv[1], NULL, 0);
length = strtol(argv[2], NULL, 0);
blk_size = flash->info->page_size * flash->info->pages_per_eraseblock;
if (offset % blk_size) {
printf("The start offset is not alignment with block size.\n");
return -1;
}
if (length % blk_size) {
printf("The length is not alignment with block size.\n");
return -1;
}
ret = spinand_erase(flash, offset, length);
if (ret) {
printf("Failed to erase spinand.\n");
return -1;
}
#endif
return ret;
}
#if defined(AICUPG_MMC_ARTINCHIP)
static int mmc_erase_boot(struct aic_sdmc *host)
{
u32 blkoffset, blkcnt, head;
u8 data[512];
memset(data, 0, 512);
blkcnt = (AIC_SPL_SIZE / 512);
for (int i = 0; i < 2; i++) {
blkoffset = 34 + i * blkcnt;
mmc_bread(host, blkoffset, 1, (void *)data);
memcpy(&head, data, 4);
if (head == AIC_IMAGE_MAGIC) {
memset(data, 0, 512);
mmc_bwrite(host, blkoffset, 1, (void *)data);
}
}
return 0;
}
#endif
static int do_mmc_erase(int argc, char *argv[])
{
int ret = -1;
#if defined(AICUPG_MMC_ARTINCHIP)
unsigned long offset, length, grp_size;
u32 blkoffset, blkcnt;
struct aic_sdmc *host;
ret = mmc_init(0);
if (ret) {
printf("sdmc init failed.\n");
return ret;
}
host = find_mmc_dev_by_index(0);
if (host== NULL) {
printf("can't find mmc device!");
return -1;
}
if ((argc == 2) && (!strcmp(argv[1], "boot")))
return mmc_erase_boot(host);
/* erase <offset> <length> */
if (argc != 3) {
aicupg_erase_help();
return -1;
}
offset = strtol(argv[1], NULL, 0);
length = strtol(argv[2], NULL, 0);
grp_size = host->dev->erase_grp_size * 512;
if (offset % grp_size) {
printf("The start offset is not alignment with group size %ld.\n",
grp_size);
return -1;
}
if (length % grp_size) {
printf("The length is not alignment with group size: %ld.\n", grp_size);
return -1;
}
blkoffset = offset / 512;
blkcnt = length / 512;
mmc_berase(host, blkoffset, blkcnt);
ret = 0;
#endif
return ret;
}
static int do_aicupg_erase(int argc, char *argv[])
{
int ret = -1, target;
target = 0;
#if defined(AICUPG_MMC_ARTINCHIP)
/* When Flash and eMMC/SD are all enabled, the MMC priority is low */
target = OP_STORAGE_MMC;
#endif
#if defined(AICUPG_NOR_ARTINCHIP)
target = OP_STORAGE_SPINOR;
#endif
#if defined(AICUPG_NAND_ARTINCHIP)
target = OP_STORAGE_SPINAND;
#endif
if (target == OP_STORAGE_SPINOR)
ret = do_spinor_erase(argc, argv);
if (target == OP_STORAGE_SPINAND)
ret = do_spinand_erase(argc, argv);
if (target == OP_STORAGE_MMC)
ret = do_mmc_erase(argc, argv);
return ret;
}
CONSOLE_CMD(erase, do_aicupg_erase, "Erase command in upgrading mode.");

View File

@@ -22,6 +22,26 @@
#define APPLICATION_PART "os"
#ifdef AIC_AB_SYSTEM_INTERFACE
#include <absystem.h>
char target[32] = { 0 };
#endif
static struct aic_partition *find_boot_part(struct aic_partition *part, char *name)
{
struct aic_partition *p = part;
while (p) {
if (!strcmp(p->name, name))
break;
p = p->next;
}
return p;
}
static int do_mmc_boot(int argc, char *argv[])
{
int ret = 0, mmc_id = 0;
@@ -57,13 +77,28 @@ static int do_mmc_boot(int argc, char *argv[])
}
part = parts;
while (part) {
if (!strcmp(part->name, APPLICATION_PART))
break;
part = part->next;
#ifdef AIC_AB_SYSTEM_INTERFACE
ret = aic_ota_check();
if (ret) {
printf("Aic ota check error.\n");
}
ret = aic_get_os_to_startup(target);
if (ret) {
printf("Aic get os fail, startup from %s default.\n", APPLICATION_PART);
part = find_boot_part(part, APPLICATION_PART);
} else {
part = find_boot_part(part, target);
printf("Start-up from %s\n", target);
}
#else
part = find_boot_part(part, APPLICATION_PART);
#endif
if (!part) {
printf("Failed to get application partition.\n");
goto out;
@@ -74,6 +109,7 @@ static int do_mmc_boot(int argc, char *argv[])
info.dev_type = DEVICE_MMC;
info.bl_len = MMC_BLOCK_SIZE;
entry_point = 0;
ret = spl_load_simple_fit(&info, &entry_point);
if (ret < 0)
goto out;

View File

@@ -66,6 +66,7 @@ static int do_nand_boot(int argc, char *argv[])
info.bl_len = mtd->writesize;
info.dev_type = DEVICE_SPINAND;
entry_point = 0;
ret = spl_load_simple_fit(&info, &entry_point);
if (ret < 0)
goto out;

View File

@@ -65,6 +65,7 @@ static int do_nor_boot(int argc, char *argv[])
info.bl_len = 1;
info.dev_type = DEVICE_SPINOR;
entry_point = 0;
ret = spl_load_simple_fit(&info, &entry_point);
if (ret < 0)
goto out;

View File

@@ -13,10 +13,7 @@
#include <string.h>
#include <console.h>
#include <artinchip_fb.h>
#ifdef AIC_BOOTLOADER_CMD_FB_CONSOLE
#include <video_font_data.h>
#endif
#undef ALIGN_DOWM
#define ALIGN_DOWM(x, align) ((x) & ~(align - 1))
@@ -48,6 +45,12 @@ static void progress_bar_help(void)
puts(PROGRESS_BAR_HELP);
}
#if ((AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE != 0) && \
(AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE != 90) && \
(AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE != 270))
#error progress bar support rotate 0/90/270 degress
#endif
#ifdef AIC_BOOTLOADER_CMD_FB_CONSOLE
static u32 colour_fg = 0;
static u32 colour_bg = 0;
@@ -153,7 +156,11 @@ void aicfb_draw_rect(struct aicfb_screeninfo *info,
*(fb++) = red;
*(fb++) = 0xFF;
}
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
fb -= info->stride - width * pbytes;
#else
fb += info->stride - width * pbytes;
#endif
}
break;
case MPP_FMT_RGB_565:
@@ -164,7 +171,11 @@ void aicfb_draw_rect(struct aicfb_screeninfo *info,
| (blue >> 3);
fb += sizeof(uint16_t) / sizeof(*fb);
}
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
fb -= info->stride + width * pbytes;
#else
fb += info->stride - width * pbytes;
#endif
}
break;
default:
@@ -236,8 +247,13 @@ static void aicfb_console_put_string(struct aicfb_screeninfo *info,
int i;
for (s = str, i = 0; *s; s++, i++)
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
aicfb_console_putc(info, x, y - (i * VIDEO_FONT_WIDTH), *s);
#else
aicfb_console_putc(info, x + (i * VIDEO_FONT_WIDTH), y, *s);
#endif
#endif /* AIC_BOOTLOADER_CMD_FB_CONSOLE */
}
static void console_set_default_colors(struct aicfb_screeninfo *info)
@@ -256,7 +272,8 @@ static void console_set_default_colors(struct aicfb_screeninfo *info)
void aicfb_draw_bar(unsigned int value)
{
struct aicfb_screeninfo info;
unsigned int x, y, width, height;
unsigned int bar_x, bar_y, width, height;
unsigned int console_x, console_y;
static bool power_on = false;
char str[5];
@@ -273,30 +290,62 @@ void aicfb_draw_bar(unsigned int value)
console_set_default_colors(&info);
}
width = SPLIT_WIDTH(info.width);
height = BAR_HEIGHT;
x = (info.width - width) / 2;
y = (info.height - height) / 2;
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
width = BAR_HEIGHT;
height = SPLIT_WIDTH(info.height);
bar_x = (info.width - width) / 2;
bar_y = (info.height - height) / 2 + height;
console_x = bar_x + BAR_HEIGHT + 5;
console_y = info.height / 2;
#else
width = SPLIT_WIDTH(info.width);
height = BAR_HEIGHT;
bar_x = (info.width - width) / 2;
bar_y = (info.height - height) / 2;
console_x = info.width / 2;
console_y = bar_y + BAR_HEIGHT + 5;
#endif
if (value == 0) {
aicfb_draw_rect(&info, x, y, width, height, BAR_BACKGROUND_COLOR);
aicfb_console_put_string(&info, info.width / 2, y + BAR_HEIGHT + 5, "0%");
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE != 90)
console_x -= VIDEO_FONT_WIDTH;
#endif
aicfb_draw_rect(&info, bar_x, bar_y, width, height, BAR_BACKGROUND_COLOR);
aicfb_console_put_string(&info, console_x, console_y,"0%");
return;
}
if (value < 100)
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
height = height * value / 100;
#else
width = width * value / 100;
#endif
aicfb_draw_rect(&info, x, y, width, height, BAR_FILL_COLOR);
aicfb_draw_rect(&info, bar_x, bar_y, width, height, BAR_FILL_COLOR);
if (value == 100) {
aicfb_console_put_string(&info, info.width / 2, y + BAR_HEIGHT + 5,
"100%,Done!");
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
console_y += VIDEO_FONT_WIDTH;
#else
console_x -= VIDEO_FONT_WIDTH * 2;
#endif
aicfb_console_put_string(&info, console_x, console_y, "100%");
return;
}
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
if (value >= 10)
console_y += (VIDEO_FONT_WIDTH >> 1);
#else
if (value < 10)
console_x -= VIDEO_FONT_WIDTH;
else
console_x -= VIDEO_FONT_HEIGHT + (VIDEO_FONT_WIDTH >> 1);
#endif
snprintf(str, sizeof(str), "%d%%", value);
aicfb_console_put_string(&info, info.width / 2, y + BAR_HEIGHT + 5, str);
aicfb_console_put_string(&info, console_x, console_y, str);
}
static int do_progress_bar(int argc, char *argv[])

View File

@@ -105,6 +105,7 @@ static int do_xip_boot(int argc, char *argv[])
info.bl_len = 1;
info.priv = (void *)((unsigned long)mtd->start + FLASH_XIP_BASE);
entry_point = 0;
ret = spl_load_simple_fit(&info, &entry_point);
if (ret < 0)
goto out;