mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 02:18:54 +00:00
V1.0.5
This commit is contained in:
@@ -149,6 +149,12 @@ if LPKG_USING_LVGL
|
||||
int "Display refresh period (ms)"
|
||||
default 5 # official suggestion
|
||||
|
||||
config LPKG_USING_LVGL_VSCODE
|
||||
bool "Support Vscode simulator import"
|
||||
default n
|
||||
help
|
||||
"assets in packages/artinchip/lvgl-ui/aic_demo/vscode_simulator/hello_demo/lvgl_src"
|
||||
|
||||
config LPKG_USING_LVGL_SQUARELINE
|
||||
bool "Support SquareLine Studio"
|
||||
default n
|
||||
@@ -186,6 +192,18 @@ config AIC_LVGL_LAUNCHER_DEMO
|
||||
config AIC_LVGL_DASHBOARD_DEMO
|
||||
bool "LVGL dashboard demo"
|
||||
|
||||
config AIC_LVGL_SHOWCASE_DEMO
|
||||
bool "LVGL showcase demo"
|
||||
|
||||
config AIC_LVGL_ELEVATOR_DEMO
|
||||
bool "LVGL elevator demo"
|
||||
|
||||
config AIC_LVGL_SLIDE_DEMO
|
||||
bool "LVGL sliding demo"
|
||||
|
||||
config AIC_LVGL_SIMPLE_PLAYER_DEMO
|
||||
bool "LVGL simple player demo"
|
||||
|
||||
if KERNEL_BAREMETAL
|
||||
config AIC_LVGL_GIF_DEMO
|
||||
bool "LVGL gif demo"
|
||||
@@ -207,7 +225,14 @@ if AIC_LVGL_METER_DEMO
|
||||
bool "LVGL meter demo use simple point"
|
||||
default n
|
||||
endif
|
||||
|
||||
# Parameters for LVGL elevator demo
|
||||
if AIC_LVGL_ELEVATOR_DEMO
|
||||
config LV_ELEVATOR_UART_COMMAND
|
||||
bool "LVGL elevator demo use uart send command"
|
||||
default n
|
||||
endif
|
||||
endif # AIC_LVGL_DEMO
|
||||
|
||||
config LVGL_STORAGE_PATH
|
||||
string "LVGL Resource Directory"
|
||||
|
||||
@@ -121,6 +121,21 @@ menu "Upgrading"
|
||||
bool "Write to NOR support"
|
||||
default y
|
||||
depends on AIC_BOOTLOADER_SPINOR_SUPPORT
|
||||
config AICUPG_LOG_BUFFER_SUPPORT
|
||||
bool "Support to get log buffer from device"
|
||||
default y
|
||||
if AICUPG_LOG_BUFFER_SUPPORT
|
||||
config AICUPG_LOG_BUFFER_ADDR
|
||||
hex "Log buffer start address"
|
||||
default 0x100000 if AIC_CHIP_D21X
|
||||
default 0x30040000 if AIC_CHIP_D12X
|
||||
default 0x30040000 if AIC_CHIP_D13X
|
||||
config AICUPG_LOG_BUFFER_SIZE
|
||||
hex "Log buffer size"
|
||||
default 0x3000 if AIC_CHIP_D21X
|
||||
default 0x3000 if AIC_CHIP_D12X
|
||||
default 0x3000 if AIC_CHIP_D13X
|
||||
endif
|
||||
endmenu # "Upgrading settings"
|
||||
|
||||
menu "Commands"
|
||||
@@ -171,6 +186,11 @@ menu "Commands"
|
||||
bool "boot progress bar"
|
||||
default n
|
||||
|
||||
config AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE
|
||||
int "progress bar rotate degress (0/90/270)"
|
||||
default 0
|
||||
depends on AIC_BOOTLOADER_CMD_PROGRESS_BAR
|
||||
|
||||
config AIC_BOOTLOADER_CMD_FB_CONSOLE
|
||||
bool "fb console support"
|
||||
default y
|
||||
|
||||
@@ -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'):
|
||||
|
||||
@@ -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:
|
||||
|
||||
301
application/baremetal/bootloader/cmd/aicupg_erase.c
Normal file
301
application/baremetal/bootloader/cmd/aicupg_erase.c
Normal 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.");
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[])
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -23,6 +23,8 @@ extern "C" {
|
||||
#define UPG_PROTO_CMD_FREE_MEM_BUF 0x09
|
||||
#define UPG_PROTO_CMD_SET_UPG_CFG 0x0A
|
||||
#define UPG_PROTO_CMD_SET_UPG_END 0x0B
|
||||
#define UPG_PROTO_CMD_GET_LOG_SIZE 0x0C
|
||||
#define UPG_PROTO_CMD_GET_LOG_DATA 0x0D
|
||||
#define UPG_PROTO_CMD_SET_FWC_META 0x10
|
||||
#define UPG_PROTO_CMD_GET_BLOCK_SIZE 0x11
|
||||
#define UPG_PROTO_CMD_SEND_FWC_DATA 0x12
|
||||
@@ -43,11 +45,9 @@ extern "C" {
|
||||
/* "UPGR" */
|
||||
#define UPG_CMD_RESP_MAGIC (0x52475055)
|
||||
|
||||
#ifdef AIC_BOOTLOADER_PSRAM_EN
|
||||
#define DATA_WRITE_ONCE_SIZE (1024 * 1024)
|
||||
#else
|
||||
#define DATA_WRITE_ONCE_SIZE (20 * 1024)
|
||||
#endif
|
||||
#define DATA_WRITE_ONCE_MAX_SIZE (1024 * 1024)
|
||||
#define DATA_WRITE_ONCE_MID_SIZE (64 * 1024)
|
||||
#define DATA_WRITE_ONCE_MIN_SIZE (20 * 1024)
|
||||
|
||||
struct cmd_header {
|
||||
u32 magic; /* "UPGC" */
|
||||
@@ -115,11 +115,6 @@ s32 aicupg_get_upg_mode(void);
|
||||
s32 aicupg_data_packet_write(u8 *data, s32 len);
|
||||
s32 aicupg_data_packet_read(u8 *data, s32 len);
|
||||
|
||||
/*SD card upgrade function*/
|
||||
//s32 aicupg_sd_write(struct image_header_upgrade *header, struct mmc *mmc,
|
||||
// struct disk_partition part_info);
|
||||
//s32 aicupg_mmc_create_gpt_part(u32 mmc_id, bool is_sdupg);
|
||||
|
||||
/*fat upgrade function*/
|
||||
s32 aicupg_fat_write(char *image_name, char *protection,
|
||||
struct image_header_upgrade *header);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,7 @@ MEMORY
|
||||
{
|
||||
/* The last 256KB for bootloader */
|
||||
SRAM_SW : ORIGIN = 0x30040000, LENGTH = 0x8000
|
||||
PSRAM_BOOT_SW : ORIGIN = 0x40200100, LENGTH = 0x200000
|
||||
PSRAM_BOOT_SW : ORIGIN = 0x40200100, LENGTH = AIC_PSRAM_SIZE - 0x200000
|
||||
}
|
||||
|
||||
PROVIDE (__sram_start = 0x30040000);
|
||||
@@ -57,7 +57,7 @@ PROVIDE (__sram_end = 0x30040000 + AIC_SRAM_SIZE);
|
||||
|
||||
PROVIDE (__min_heap_size = 0x200);
|
||||
PROVIDE (__heap_start = __psram_sw_heap_start);
|
||||
PROVIDE (__heap_end = 0x40400000);
|
||||
PROVIDE (__heap_end = 0x40000000 + AIC_PSRAM_SIZE);
|
||||
|
||||
REGION_ALIAS("REGION_TEXT" , PSRAM_BOOT_SW);
|
||||
REGION_ALIAS("REGION_RODATA" , PSRAM_BOOT_SW);
|
||||
|
||||
@@ -74,12 +74,12 @@ PROVIDE (__sram_end = 0x30040000 + AIC_SRAM_TOTAL_SIZE);
|
||||
PROVIDE (__min_heap_size = 0x200);
|
||||
#ifdef AIC_BOOTLOADER_PSRAM_EN
|
||||
PROVIDE (__heap_start = 0x40000000);
|
||||
/* Limit bootloader's heap to 8MB */
|
||||
PROVIDE (__heap_end = 0x40000000 + 0x800000);
|
||||
PROVIDE (__heap_end = 0x40000000 + AIC_PSRAM_SIZE);
|
||||
#else
|
||||
PROVIDE (__heap_start = 0x300E0000);
|
||||
PROVIDE (__heap_end = 0x30100000);
|
||||
PROVIDE (__heap_end = 0x300FF000);
|
||||
#endif
|
||||
|
||||
REGION_ALIAS("REGION_TEXT" , SRAM_SW);
|
||||
REGION_ALIAS("REGION_RODATA" , SRAM_SW);
|
||||
REGION_ALIAS("REGION_DATA" , SRAM_SW);
|
||||
|
||||
@@ -134,14 +134,25 @@ int aic_get_os_to_startup(char *target_os)
|
||||
#endif
|
||||
if (strncmp(next, "A", 2) == 0) {
|
||||
memcpy(target_os, APPLICATION_PART, strlen(APPLICATION_PART));
|
||||
ret = fw_env_write("osAB_now", "A");
|
||||
} else if (strncmp(next, "B", 2) == 0) {
|
||||
memcpy(target_os, APPLICATION_PART_REDUNDAND,
|
||||
strlen(APPLICATION_PART_REDUNDAND));
|
||||
ret = fw_env_write("osAB_now", "B");
|
||||
} else {
|
||||
ret = -1;
|
||||
pr_err("Invalid osAB_next\n");
|
||||
goto err_write_next_os;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
pr_err("osAB_now write fail\n");
|
||||
goto err_write_next_os;
|
||||
}
|
||||
fw_env_flush();
|
||||
|
||||
err_write_next_os:
|
||||
fw_env_close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ if GetDepend('AIC_BOOTLOADER_FATFS_SUPPORT'):
|
||||
src += Glob('upg_fat_direct_mmc.c')
|
||||
src += Glob('upg_fat_direct_nor.c')
|
||||
src += Glob('upg_fat_direct_nand.c')
|
||||
if GetDepend('AICUPG_LOG_BUFFER_SUPPORT'):
|
||||
src += Glob('log_buf.c')
|
||||
CPPPATH = [cwd]
|
||||
ASFLAGS = ''
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
#include <console.h>
|
||||
#include <aic_common.h>
|
||||
#include "upg_internal.h"
|
||||
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
#include <log_buf.h>
|
||||
#endif
|
||||
#define BOOT_STAGE_UBOOT 1
|
||||
/*
|
||||
* UPG_PROTO_CMD_GET_HWINFO at BROM stage is use to provide hardware data
|
||||
@@ -482,8 +484,8 @@ static s32 CMD_RUN_SHELL_STR_write_input_data(struct upg_cmd *cmd, u8 *buf,
|
||||
|
||||
if (cmd->state == CMD_STATE_ARG) {
|
||||
/*
|
||||
* Enter recv argument state
|
||||
*/
|
||||
* Enter recv argument state
|
||||
*/
|
||||
if (len < 4)
|
||||
return 0;
|
||||
memcpy(&shinfo->cmdlen, buf, 4);
|
||||
@@ -496,9 +498,9 @@ static s32 CMD_RUN_SHELL_STR_write_input_data(struct upg_cmd *cmd, u8 *buf,
|
||||
|
||||
if (cmd->state == CMD_STATE_DATA_IN) {
|
||||
/*
|
||||
* Enter recv data state, all command string should be sent in
|
||||
* one packet.
|
||||
*/
|
||||
* Enter recv data state, all command string should be sent in
|
||||
* one packet.
|
||||
*/
|
||||
|
||||
if (((len - clen) != shinfo->cmdlen) ||
|
||||
(shinfo->cmdlen >= MAX_SHELL_CMD_STR_LEN)) {
|
||||
@@ -531,9 +533,9 @@ static s32 CMD_RUN_SHELL_STR_read_output_data(struct upg_cmd *cmd, u8 *buf,
|
||||
|
||||
if (cmd->state == CMD_STATE_RESP) {
|
||||
/*
|
||||
* Enter read RESP state, to make it simple, HOST should read
|
||||
* RESP in one read operation.
|
||||
*/
|
||||
* Enter read RESP state, to make it simple, HOST should read
|
||||
* RESP in one read operation.
|
||||
*/
|
||||
aicupg_gen_resp(&resp, cmd->cmd, shinfo->result, 0);
|
||||
siz = sizeof(struct resp_header);
|
||||
memcpy(buf, &resp, siz);
|
||||
@@ -859,6 +861,157 @@ static void CMD_SET_UPG_END_end(struct upg_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
static void CMD_GET_LOG_SIZE_start(struct upg_cmd *cmd, s32 cmd_data_len)
|
||||
{
|
||||
cmd_state_init(cmd, CMD_STATE_START);
|
||||
}
|
||||
|
||||
static s32 CMD_GET_LOG_SIZE_write_input_data(struct upg_cmd *cmd, u8 *buf,
|
||||
s32 len)
|
||||
{
|
||||
/* No input data for this command */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 CMD_GET_LOG_SIZE_read_output_data(struct upg_cmd *cmd, u8 *buf,
|
||||
s32 len)
|
||||
{
|
||||
struct resp_header resp;
|
||||
u32 siz = 0, val = 0;
|
||||
|
||||
if (cmd->state == CMD_STATE_START)
|
||||
cmd_state_set_next(cmd, CMD_STATE_RESP);
|
||||
|
||||
if (cmd->state == CMD_STATE_RESP) {
|
||||
/*
|
||||
* Enter read RESP state, to make it simple, HOST should read
|
||||
* RESP in one read operation.
|
||||
*/
|
||||
aicupg_gen_resp(&resp, cmd->cmd, 0, 4);
|
||||
siz = sizeof(struct resp_header);
|
||||
memcpy(buf, &resp, siz);
|
||||
cmd_state_set_next(cmd, CMD_STATE_DATA_OUT);
|
||||
}
|
||||
if (siz == len)
|
||||
return siz;
|
||||
|
||||
if (cmd->state == CMD_STATE_DATA_OUT) {
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
val = log_buf_get_len();
|
||||
#else
|
||||
val = 0;
|
||||
#endif
|
||||
memcpy(buf, &val, 4);
|
||||
siz += 4;
|
||||
cmd_state_set_next(cmd, CMD_STATE_END);
|
||||
}
|
||||
return siz;
|
||||
}
|
||||
|
||||
static void CMD_GET_LOG_SIZE_end(struct upg_cmd *cmd)
|
||||
{
|
||||
cmd_state_set_next(cmd, CMD_STATE_IDLE);
|
||||
}
|
||||
|
||||
static void CMD_GET_LOG_DATA_start(struct upg_cmd *cmd, s32 cmd_data_len)
|
||||
{
|
||||
static struct cmd_rw_priv read_log;
|
||||
|
||||
read_log.addr = 0;
|
||||
read_log.len = 0;
|
||||
read_log.index = 0;
|
||||
cmd->priv = &read_log;
|
||||
cmd_state_init(cmd, CMD_STATE_START);
|
||||
}
|
||||
|
||||
static s32 CMD_GET_LOG_DATA_write_input_data(struct upg_cmd *cmd, u8 *buf,
|
||||
s32 len)
|
||||
{
|
||||
struct cmd_rw_priv *priv;
|
||||
u32 val, clen = 0;
|
||||
|
||||
priv = (struct cmd_rw_priv *)cmd->priv;
|
||||
if (!priv)
|
||||
return 0;
|
||||
|
||||
if (cmd->state == CMD_STATE_START)
|
||||
cmd_state_set_next(cmd, CMD_STATE_ARG);
|
||||
|
||||
if (cmd->state == CMD_STATE_ARG) {
|
||||
/*
|
||||
* Enter recv argument state
|
||||
*/
|
||||
if (len < 4)
|
||||
return 0;
|
||||
memcpy(&val, buf, 4);
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
if (val > log_buf_get_len())
|
||||
val = log_buf_get_len();
|
||||
#endif
|
||||
priv->len = val;
|
||||
clen += 4;
|
||||
cmd_state_set_next(cmd, CMD_STATE_RESP);
|
||||
}
|
||||
return clen;
|
||||
}
|
||||
|
||||
static s32 CMD_GET_LOG_DATA_read_output_data(struct upg_cmd *cmd, u8 *buf,
|
||||
s32 len)
|
||||
{
|
||||
struct cmd_rw_priv *priv;
|
||||
struct resp_header resp;
|
||||
u32 siz = 0;
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
priv = (struct cmd_rw_priv *)cmd->priv;
|
||||
if (!priv)
|
||||
return 0;
|
||||
if (cmd->state == CMD_STATE_RESP) {
|
||||
/*
|
||||
* Enter read RESP state, to make it simple, HOST should read
|
||||
* RESP in one read operation.
|
||||
*/
|
||||
siz = priv->len;
|
||||
aicupg_gen_resp(&resp, cmd->cmd, 0, siz);
|
||||
siz = sizeof(struct resp_header);
|
||||
memcpy(buf, &resp, siz);
|
||||
cmd_state_set_next(cmd, CMD_STATE_DATA_OUT);
|
||||
}
|
||||
if (siz == len)
|
||||
return siz;
|
||||
if (cmd->state == CMD_STATE_DATA_OUT) {
|
||||
/* Enter read DATA state */
|
||||
p = (char *)buf;
|
||||
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
log_buf_read(p, len - siz);
|
||||
#endif
|
||||
priv->index += (len - siz);
|
||||
siz += (len - siz);
|
||||
if (priv->index >= priv->len)
|
||||
cmd_state_set_next(cmd, CMD_STATE_END);
|
||||
}
|
||||
return siz;
|
||||
}
|
||||
|
||||
static void CMD_GET_LOG_DATA_end(struct upg_cmd *cmd)
|
||||
{
|
||||
struct cmd_rw_priv *priv;
|
||||
|
||||
priv = (struct cmd_rw_priv *)cmd->priv;
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
if (cmd->state == CMD_STATE_END) {
|
||||
priv->addr = 0;
|
||||
priv->len = 0;
|
||||
priv->index = 0;
|
||||
cmd->priv = 0;
|
||||
cmd_state_set_next(cmd, CMD_STATE_IDLE);
|
||||
}
|
||||
}
|
||||
static struct upg_cmd basic_cmd_list[] = {
|
||||
{
|
||||
UPG_PROTO_CMD_GET_HWINFO,
|
||||
@@ -930,6 +1083,20 @@ static struct upg_cmd basic_cmd_list[] = {
|
||||
CMD_FREE_MEM_BUF_read_output_data,
|
||||
CMD_FREE_MEM_BUF_end,
|
||||
},
|
||||
{
|
||||
UPG_PROTO_CMD_GET_LOG_SIZE,
|
||||
CMD_GET_LOG_SIZE_start,
|
||||
CMD_GET_LOG_SIZE_write_input_data,
|
||||
CMD_GET_LOG_SIZE_read_output_data,
|
||||
CMD_GET_LOG_SIZE_end,
|
||||
},
|
||||
{
|
||||
UPG_PROTO_CMD_GET_LOG_DATA,
|
||||
CMD_GET_LOG_DATA_start,
|
||||
CMD_GET_LOG_DATA_write_input_data,
|
||||
CMD_GET_LOG_DATA_read_output_data,
|
||||
CMD_GET_LOG_DATA_end,
|
||||
},
|
||||
};
|
||||
|
||||
struct upg_cmd *find_basic_command(struct cmd_header *h)
|
||||
|
||||
131
application/baremetal/bootloader/lib/aicupg/log_buf.c
Normal file
131
application/baremetal/bootloader/lib/aicupg/log_buf.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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 <aic_core.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_errno.h>
|
||||
#include <log_buf.h>
|
||||
|
||||
#define AIC_LOG_MAGIC 0x4C434941
|
||||
|
||||
struct log_buffer {
|
||||
int magic;
|
||||
int istart;
|
||||
int icurr;
|
||||
int buf_size;
|
||||
char buf[];
|
||||
};
|
||||
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
#define LOG_BUF_ADDR AICUPG_LOG_BUFFER_ADDR
|
||||
#define LOG_BUF_SIZE AICUPG_LOG_BUFFER_SIZE
|
||||
#else
|
||||
#define LOG_BUF_ADDR 0
|
||||
#define LOG_BUF_SIZE 0
|
||||
#endif
|
||||
int log_buf_init(void)
|
||||
{
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
struct log_buffer *log;
|
||||
void *buff;
|
||||
int size;
|
||||
|
||||
buff = (void *)LOG_BUF_ADDR;
|
||||
size = (int)LOG_BUF_SIZE;
|
||||
|
||||
if (!buff || (size < sizeof(*log)))
|
||||
return -1;
|
||||
|
||||
log = buff;
|
||||
if (log->magic == AIC_LOG_MAGIC)
|
||||
return 0;
|
||||
|
||||
log->istart = 0;
|
||||
log->icurr = 0;
|
||||
log->buf_size = size - sizeof(*log);
|
||||
log->magic = AIC_LOG_MAGIC;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_buf_get_len(void)
|
||||
{
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
struct log_buffer *log = (void *)LOG_BUF_ADDR;
|
||||
|
||||
if (!log)
|
||||
return 0;
|
||||
|
||||
return (log->icurr + log->buf_size - log->istart) % log->buf_size;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_buf_write(char *in, int len)
|
||||
{
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
struct log_buffer *log = (void *)LOG_BUF_ADDR;
|
||||
int dolen, freelen;
|
||||
char *ps;
|
||||
|
||||
if (!log)
|
||||
return 0;
|
||||
if (log->magic != AIC_LOG_MAGIC)
|
||||
return 0;
|
||||
|
||||
dolen = len;
|
||||
freelen = log->buf_size - 1 - log_buf_get_len();
|
||||
if (freelen == 0)
|
||||
return 0;
|
||||
|
||||
if (dolen > freelen)
|
||||
dolen = freelen;
|
||||
len = dolen;
|
||||
ps = in;
|
||||
while (dolen) {
|
||||
log->buf[log->icurr % log->buf_size] = *ps;
|
||||
log->icurr = (log->icurr + 1) % log->buf_size;
|
||||
dolen--;
|
||||
ps++;
|
||||
}
|
||||
return len;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_buf_read(char *out, int len)
|
||||
{
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
struct log_buffer *log = (void *)LOG_BUF_ADDR;
|
||||
int dolen, loglen;
|
||||
char *pd;
|
||||
|
||||
if (!log)
|
||||
return 0;
|
||||
if (log->magic != AIC_LOG_MAGIC)
|
||||
return 0;
|
||||
|
||||
dolen = len;
|
||||
loglen = log_buf_get_len();
|
||||
if (dolen > loglen)
|
||||
dolen = loglen;
|
||||
len = dolen;
|
||||
pd = out;
|
||||
while (dolen) {
|
||||
*pd = log->buf[log->istart % log->buf_size];
|
||||
log->istart = (log->istart + 1) % log->buf_size;
|
||||
dolen--;
|
||||
pd++;
|
||||
}
|
||||
return len;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
17
application/baremetal/bootloader/lib/aicupg/log_buf.h
Normal file
17
application/baremetal/bootloader/lib/aicupg/log_buf.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Wu Dehuang <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#ifndef _LOG_BUF_H_
|
||||
#define _LOG_BUF_H_
|
||||
|
||||
int log_buf_init(void);
|
||||
int log_buf_get_len(void);
|
||||
int log_buf_write(char *in, int len);
|
||||
int log_buf_read(char *out, int len);
|
||||
|
||||
#endif
|
||||
@@ -50,6 +50,23 @@ s32 mmc_fwc_prepare(struct fwc_info *fwc, u32 mmc_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct aic_partition *mmc_fwc_get_part_by_name(struct fwc_info *fwc, char *name)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
struct aic_partition *parts = NULL;
|
||||
|
||||
priv = (struct aicupg_mmc_priv *)fwc->priv;
|
||||
parts = priv->parts;
|
||||
while (parts) {
|
||||
if (!strcmp(parts->name, name))
|
||||
return parts;
|
||||
|
||||
parts = parts->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned long mmc_write(struct blk_desc *block_dev, u64 start,
|
||||
u64 blkcnt, void *buffer)
|
||||
{
|
||||
@@ -115,6 +132,71 @@ out:
|
||||
free(priv);
|
||||
}
|
||||
|
||||
s32 mmc_fwc_sparse_fill(struct aicupg_mmc_priv *priv, struct aic_partition *parts, u64 chunk_blkcnt, uint32_t fill_val)
|
||||
{
|
||||
u32 blks, remain_blks, redund_blks, erase_group;
|
||||
u32 *fill_buf, fill_buf_num_blks, fill_blks = 0;
|
||||
int i, j;
|
||||
|
||||
fill_buf = (u32 *)aicos_malloc_align(0, ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE), CACHE_LINE_SIZE);
|
||||
if (!fill_buf) {
|
||||
pr_err("Malloc failed for: CHUNK_TYPE_FILL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (SPARSE_FILLBUF_SIZE / sizeof(fill_val)); i++)
|
||||
fill_buf[i] = fill_val;
|
||||
|
||||
// When using 0 fill, it is faster to use erase than write
|
||||
if (chunk_blkcnt >= 0x400 && fill_val == 0x0) { // 512K
|
||||
// 1. Fill part start blocks to align by group. 1 group = 1024 blocks
|
||||
remain_blks = ROUNDUP((parts->start / MMC_BLOCK_SIZE) + priv->blkstart, 0x400) - ((parts->start / MMC_BLOCK_SIZE) + priv->blkstart);
|
||||
blks = mmc_bwrite(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, remain_blks, (u8 *)fill_buf);
|
||||
if (blks < remain_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, remain_blks);
|
||||
goto out;
|
||||
}
|
||||
fill_blks += blks;
|
||||
|
||||
// 2. Erase by group for faster speed,
|
||||
erase_group = (chunk_blkcnt - remain_blks) / 0x400;
|
||||
blks = mmc_berase(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, erase_group * 0x400);
|
||||
if (blks != (erase_group * 0x400)) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Erase failed, block %llu[%d]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, erase_group * 0x400);
|
||||
goto out;
|
||||
}
|
||||
fill_blks += blks;
|
||||
|
||||
// 3. Fill of remaining blocks
|
||||
redund_blks = chunk_blkcnt - remain_blks - (erase_group * 0x400);
|
||||
blks = mmc_bwrite(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, redund_blks, (u8 *)fill_buf);
|
||||
if (blks < redund_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, redund_blks);
|
||||
goto out;
|
||||
}
|
||||
fill_blks += blks;
|
||||
} else {
|
||||
fill_buf_num_blks = SPARSE_FILLBUF_SIZE / MMC_BLOCK_SIZE;
|
||||
for (i = 0; i < chunk_blkcnt;) {
|
||||
j = chunk_blkcnt - i;
|
||||
if (j > fill_buf_num_blks)
|
||||
j = fill_buf_num_blks;
|
||||
|
||||
blks = mmc_bwrite(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, j, (u8 *)fill_buf);
|
||||
if (blks < j) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, j);
|
||||
goto out;
|
||||
}
|
||||
fill_blks += blks;
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
aicos_free_align(0, fill_buf);
|
||||
return fill_blks;
|
||||
}
|
||||
|
||||
s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
@@ -126,9 +208,7 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
u32 chunk;
|
||||
u64 chunk_data_sz, chunk_blkcnt, remain_blkcnt;
|
||||
u32 total_blocks = 0, blks;
|
||||
u32 remain_blks, redund_blks, erase_group;
|
||||
u32 *fill_buf, fill_val, fill_buf_num_blks;
|
||||
int i, j, break_flag = 0;
|
||||
u32 fill_val;
|
||||
|
||||
wbuf = malloc(ROUNDUP(len + MMC_BLOCK_SIZE, fwc->block_size));
|
||||
if (!wbuf) {
|
||||
@@ -153,16 +233,11 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
total_len = (priv->remain_len + len);
|
||||
remain = total_len;
|
||||
|
||||
parts = priv->parts;
|
||||
while (parts) {
|
||||
if (!strcmp(parts->name, fwc->meta.partition))
|
||||
break;
|
||||
|
||||
parts = parts->next;
|
||||
}
|
||||
|
||||
if (!parts)
|
||||
parts = mmc_fwc_get_part_by_name(fwc, fwc->meta.partition);
|
||||
if (!parts) {
|
||||
pr_err("not find %s part info.\n", fwc->meta.partition);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sheader = &(priv->sparse_header);
|
||||
if (is_sparse_image(wbuf)) {
|
||||
@@ -171,11 +246,6 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
wbuf += sheader->file_hdr_sz;
|
||||
clen += sheader->file_hdr_sz;
|
||||
remain -= sheader->file_hdr_sz;
|
||||
if (sheader->file_hdr_sz > sizeof(sparse_header_t)) {
|
||||
wbuf += (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
clen += (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
remain -= (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
}
|
||||
pr_info("=== Sparse Image Header ===\n");
|
||||
pr_info("magic: 0x%x\n", sheader->magic);
|
||||
pr_info("major_version: 0x%x\n", sheader->major_version);
|
||||
@@ -194,17 +264,11 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
/* Read and skip over chunk header */
|
||||
cheader = (chunk_header_t *)wbuf;
|
||||
|
||||
if (cheader->chunk_type != CHUNK_TYPE_RAW) {
|
||||
pr_debug("=== Chunk Header ===\n");
|
||||
pr_debug("chunk_type: 0x%x\n", cheader->chunk_type);
|
||||
pr_debug("chunk_data_sz: 0x%x\n", cheader->chunk_sz);
|
||||
pr_debug("total_size: 0x%x\n", cheader->total_sz);
|
||||
}
|
||||
|
||||
if (cheader->chunk_type != CHUNK_TYPE_RAW &&
|
||||
cheader->chunk_type != CHUNK_TYPE_FILL &&
|
||||
cheader->chunk_type != CHUNK_TYPE_DONT_CARE &&
|
||||
cheader->chunk_type != CHUNK_TYPE_CRC32) {
|
||||
cheader->chunk_type != CHUNK_TYPE_CRC32 &&
|
||||
priv->cur_chunk_remain_data_sz) {
|
||||
cheader = &(priv->chunk_header);
|
||||
chunk_data_sz = priv->cur_chunk_remain_data_sz;
|
||||
} else {
|
||||
@@ -212,69 +276,50 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
clen += sheader->chunk_hdr_sz;
|
||||
remain -= sheader->chunk_hdr_sz;
|
||||
memcpy(&(priv->chunk_header), cheader, sizeof(chunk_header_t));
|
||||
if (sheader->chunk_hdr_sz > sizeof(chunk_header_t)) {
|
||||
/*
|
||||
* Skip the remaining bytes in a header that is longer
|
||||
* than we expected.
|
||||
*/
|
||||
wbuf += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
clen += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
remain -= (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
}
|
||||
chunk_data_sz = ((u64)sheader->blk_sz) * cheader->chunk_sz;
|
||||
priv->cur_chunk_remain_data_sz = chunk_data_sz;
|
||||
priv->cur_chunk_burned_data_sz = 0;
|
||||
pr_debug("=== Chunk Header ===\n");
|
||||
pr_debug("chunk_type: 0x%x\n", cheader->chunk_type);
|
||||
pr_debug("chunk_size: 0x%x\n", cheader->chunk_sz);
|
||||
pr_debug("total_size: 0x%x\n", cheader->total_sz);
|
||||
pr_debug("=== Chunk DEBUG ===\n");
|
||||
pr_debug("chunk_id: %u\t", chunk);
|
||||
pr_debug("chunk_offset: %u\t", fwc->trans_size + clen);
|
||||
pr_debug("chunk_number: %u\n", cheader->total_sz - sheader->chunk_hdr_sz);
|
||||
}
|
||||
|
||||
chunk_blkcnt = DIV_ROUND_UP(chunk_data_sz, MMC_BLOCK_SIZE);
|
||||
if (priv->blkstart + chunk_blkcnt > (parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Request would exceed partition size!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
remain_blkcnt = remain / MMC_BLOCK_SIZE;
|
||||
switch (cheader->chunk_type) {
|
||||
case CHUNK_TYPE_RAW:
|
||||
if (cheader->total_sz !=
|
||||
(sheader->chunk_hdr_sz + chunk_data_sz +
|
||||
priv->cur_chunk_burned_data_sz)) {
|
||||
if (cheader->total_sz != (sheader->chunk_hdr_sz + chunk_data_sz + priv->cur_chunk_burned_data_sz)) {
|
||||
pr_err("Bogus chunk size for chunk type Raw\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (priv->blkstart + chunk_blkcnt >
|
||||
(parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Request would exceed partition size!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (remain_blkcnt > chunk_blkcnt &&
|
||||
(remain - chunk_data_sz) >= 16) {
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
chunk_blkcnt, wbuf);
|
||||
if (blks <
|
||||
chunk_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
blks);
|
||||
if (remain_blkcnt > chunk_blkcnt && (remain - chunk_data_sz) >= 16) {
|
||||
blks = mmc_bwrite(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, chunk_blkcnt, wbuf);
|
||||
if (blks < chunk_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, blks);
|
||||
goto out;
|
||||
}
|
||||
remain = remain - chunk_data_sz;
|
||||
priv->cur_chunk_remain_data_sz = 0;
|
||||
priv->cur_chunk_burned_data_sz += chunk_data_sz;
|
||||
} else {
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
remain_blkcnt, wbuf);
|
||||
if (blks <
|
||||
remain_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
blks);
|
||||
blks = mmc_bwrite(priv->host, (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, remain_blkcnt, wbuf);
|
||||
if (blks < remain_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n", (parts->start / MMC_BLOCK_SIZE) + priv->blkstart, blks);
|
||||
goto out;
|
||||
}
|
||||
priv->cur_chunk_remain_data_sz -=
|
||||
remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
priv->cur_chunk_burned_data_sz +=
|
||||
remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
priv->cur_chunk_remain_data_sz -= remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
priv->cur_chunk_burned_data_sz += remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
remain = remain % MMC_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
@@ -282,122 +327,31 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
total_blocks += blks;
|
||||
wbuf += blks * MMC_BLOCK_SIZE;
|
||||
clen += blks * MMC_BLOCK_SIZE;
|
||||
if ((priv->cur_chunk_remain_data_sz > 0 &&
|
||||
(remain > 0 && remain < MMC_BLOCK_SIZE)) ||
|
||||
remain < sizeof(chunk_header_t))
|
||||
break_flag = 1;
|
||||
|
||||
break;
|
||||
|
||||
case CHUNK_TYPE_FILL:
|
||||
if (cheader->total_sz !=
|
||||
(sheader->chunk_hdr_sz + sizeof(uint32_t))) {
|
||||
if (cheader->total_sz != (sheader->chunk_hdr_sz + sizeof(uint32_t))) {
|
||||
pr_err("Bogus chunk size for chunk type FILL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_buf = (u32 *)aicos_malloc_align(
|
||||
0, ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE),
|
||||
CACHE_LINE_SIZE);
|
||||
if (!fill_buf) {
|
||||
pr_err("Malloc failed for: CHUNK_TYPE_FILL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_val = *(uint32_t *)wbuf;
|
||||
wbuf = (u8 *)wbuf + sizeof(u32);
|
||||
clen += sizeof(uint32_t);
|
||||
remain -= sizeof(uint32_t);
|
||||
if (remain < sizeof(chunk_header_t))
|
||||
break_flag = 1;
|
||||
|
||||
if (priv->blkstart + chunk_blkcnt >
|
||||
(parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Request would exceed partition size!\n");
|
||||
pr_debug("FILL with \t 0x%08x\n", fill_val);
|
||||
|
||||
blks = mmc_fwc_sparse_fill(priv, parts, chunk_blkcnt, fill_val);
|
||||
if (blks != chunk_blkcnt) {
|
||||
pr_err("CHUNK_TYPE_FILL FILL failed.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < (SPARSE_FILLBUF_SIZE / sizeof(fill_val)); i++)
|
||||
fill_buf[i] = fill_val;
|
||||
|
||||
remain_blks =
|
||||
ROUNDUP((parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
0x400) -
|
||||
((parts->start / MMC_BLOCK_SIZE) + priv->blkstart);
|
||||
if (chunk_blkcnt >= (remain_blks + 0x400) &&
|
||||
fill_val == 0x0) { // 512K
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
remain_blks, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
remain_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
remain_blks);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
|
||||
erase_group = (chunk_blkcnt - remain_blks) / 0x400;
|
||||
blks = mmc_berase(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
erase_group * 0x400);
|
||||
if (blks !=
|
||||
(erase_group *
|
||||
0x400)) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Erase failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
erase_group * 0x400);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
|
||||
redund_blks =
|
||||
chunk_blkcnt - remain_blks - (erase_group * 0x400);
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
redund_blks, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
redund_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
redund_blks);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
} else {
|
||||
fill_buf_num_blks = SPARSE_FILLBUF_SIZE / MMC_BLOCK_SIZE;
|
||||
for (i = 0; i < chunk_blkcnt;) {
|
||||
j = chunk_blkcnt - i;
|
||||
if (j > fill_buf_num_blks)
|
||||
j = fill_buf_num_blks;
|
||||
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
j, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
j) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
j);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
total_blocks += DIV_ROUND_UP(chunk_data_sz, sheader->blk_sz);
|
||||
|
||||
free(fill_buf);
|
||||
break;
|
||||
|
||||
case CHUNK_TYPE_DONT_CARE:
|
||||
@@ -421,13 +375,13 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
cheader = &(priv->chunk_header);
|
||||
}
|
||||
|
||||
if (break_flag)
|
||||
if ((priv->cur_chunk_remain_data_sz > 0 && (remain > 0 && remain < MMC_BLOCK_SIZE)) || remain < sizeof(chunk_header_t))
|
||||
break;
|
||||
}
|
||||
|
||||
priv->remain_len = remain;
|
||||
priv->cur_chunk = chunk;
|
||||
if (priv->remain_len) {
|
||||
priv->cur_chunk = chunk;
|
||||
memcpy(priv->remain_data, wbuf, priv->remain_len);
|
||||
}
|
||||
|
||||
@@ -436,8 +390,7 @@ s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
|
||||
|
||||
out:
|
||||
if (p)
|
||||
free(p);
|
||||
free(p);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -455,14 +408,7 @@ s32 mmc_fwc_raw_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
goto out;
|
||||
}
|
||||
|
||||
parts = priv->parts;
|
||||
while (parts) {
|
||||
if (!strcmp(parts->name, fwc->meta.partition))
|
||||
break;
|
||||
|
||||
parts = parts->next;
|
||||
}
|
||||
|
||||
parts = mmc_fwc_get_part_by_name(fwc, fwc->meta.partition);
|
||||
if (!parts)
|
||||
pr_err("not find %s part info.\n", fwc->meta.partition);
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
int total_len = 0, remain_offset = 0;
|
||||
u8 *wbuf = NULL, *pbuf = NULL;
|
||||
|
||||
wbuf = malloc(ROUNDUP(len, fwc->block_size));
|
||||
wbuf = aicos_malloc_align(0, ROUNDUP(len, fwc->block_size), CACHE_LINE_SIZE);
|
||||
if (!wbuf) {
|
||||
pr_err("malloc failed.\n");
|
||||
return 0;
|
||||
@@ -291,13 +291,13 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
|
||||
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
|
||||
|
||||
free(wbuf);
|
||||
aicos_free_align(0, wbuf);
|
||||
|
||||
return len;
|
||||
|
||||
out:
|
||||
if (wbuf)
|
||||
free(wbuf);
|
||||
aicos_free_align(0, wbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -256,9 +256,7 @@ static s32 spl_build_page_table(struct aicupg_nand_spl *spl,
|
||||
|
||||
pr_debug("%s, going to generate page table.\n", __func__);
|
||||
slice_size = spl->mtd->writesize;
|
||||
pt->head.page_size = PAGE_SIZE_2KB;
|
||||
if (spl->mtd->writesize == 4096)
|
||||
pt->head.page_size = PAGE_SIZE_4KB;
|
||||
pt->head.page_size = spl->mtd->writesize;
|
||||
|
||||
page_per_blk = spl->mtd->erasesize / spl->mtd->writesize;
|
||||
page_data = malloc(PAGE_MAX_SIZE);
|
||||
@@ -455,7 +453,7 @@ out:
|
||||
static s32 verify_page_table(struct aicupg_nand_spl *spl, u32 blkidx,
|
||||
struct nand_page_table *pt, u32 len)
|
||||
{
|
||||
u8 page_data[PAGE_TABLE_USE_SIZE] = { 0 };
|
||||
u8 page_data[PAGE_MAX_SIZE] = { 0 };
|
||||
ulong offset;
|
||||
u32 sumval;
|
||||
s32 ret;
|
||||
@@ -639,3 +637,15 @@ s32 nand_fwc_spl_write(u32 totalsiz, u8 *buf, s32 len)
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int nand_spl_get_candidate_blocks(u32 *blks, u32 size)
|
||||
{
|
||||
if (!blks || size < SPL_CANDIDATE_BLOCK_NUM) {
|
||||
pr_err("Invalid parameter.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(blks, spl_candidate_block_table,
|
||||
sizeof(u32) * SPL_CANDIDATE_BLOCK_NUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,10 +27,6 @@ extern "C" {
|
||||
|
||||
#define ROUNDUP(a, b) ((((a)-1) / (b) + 1) * (b))
|
||||
|
||||
#define PAGE_SIZE_1KB 1
|
||||
#define PAGE_SIZE_2KB 2
|
||||
#define PAGE_SIZE_4KB 4
|
||||
|
||||
#define MAX_DUPLICATED_PART 4
|
||||
|
||||
#ifdef AIC_NFTL_SUPPORT
|
||||
@@ -51,8 +47,8 @@ struct aicupg_nand_priv {
|
||||
struct nand_page_table_head {
|
||||
char magic[4]; /* AICP: AIC Page table */
|
||||
u32 entry_cnt;
|
||||
u8 page_size; /* 0: No page size info; 1: 1KB; 2: 2KB; 4: 4KB */
|
||||
u8 pad[11]; /* Padding it to fit size 20 bytes */
|
||||
u16 page_size;
|
||||
u8 pad[10]; /* Padding it to fit size 20 bytes */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -90,6 +86,7 @@ s32 nand_fwc_spl_reserve_blocks(struct aicupg_nand_priv *priv);
|
||||
s32 nand_fwc_spl_prepare(struct aicupg_nand_priv *priv, u32 datasiz,
|
||||
u32 blksiz);
|
||||
s32 nand_fwc_spl_write(u32 totalsiz, u8 *buf, s32 len);
|
||||
int nand_spl_get_candidate_blocks(u32 *blks, u32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
#endif
|
||||
|
||||
#define RECV_SIZE_USE_DMA 512
|
||||
#define TRANS_DATA_BUFF_SIZE (64 * 1024)
|
||||
#define TRANS_DATA_BUFF_MAX_SIZE (64 * 1024)
|
||||
#define TRANS_DATA_BUFF_MIN_SIZE (20 * 1024)
|
||||
static u8 *trans_pkt_buf = NULL;
|
||||
static u32 trans_pkt_siz = 0;
|
||||
|
||||
static void trans_send_csw(struct phy_data_rw *rw, u32 tag, u8 status, u32 rest)
|
||||
{
|
||||
@@ -56,10 +58,15 @@ s32 trans_layer_rw_proc(struct phy_data_rw *rw, u8 *buffer, u32 len)
|
||||
}
|
||||
|
||||
if (!trans_pkt_buf) {
|
||||
trans_pkt_buf = aicos_malloc_align(0, TRANS_DATA_BUFF_SIZE, CACHE_LINE_SIZE);
|
||||
trans_pkt_siz = TRANS_DATA_BUFF_MAX_SIZE;
|
||||
trans_pkt_buf = aicos_malloc_align(0, trans_pkt_siz, CACHE_LINE_SIZE);
|
||||
if (!trans_pkt_buf) {
|
||||
pr_err("malloc trans pkt buf failed.\n");
|
||||
return -1;
|
||||
trans_pkt_siz = TRANS_DATA_BUFF_MIN_SIZE;
|
||||
trans_pkt_buf = aicos_malloc_align(0, trans_pkt_siz, CACHE_LINE_SIZE);
|
||||
if (!trans_pkt_buf) {
|
||||
pr_err("malloc trans pkt buf(%u) failed.\n", trans_pkt_siz);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +94,8 @@ s32 trans_layer_rw_proc(struct phy_data_rw *rw, u8 *buffer, u32 len)
|
||||
rest = data_len;
|
||||
total = 0;
|
||||
while (rest > 0) {
|
||||
if (rest >= TRANS_DATA_BUFF_SIZE)
|
||||
slice = TRANS_DATA_BUFF_SIZE;
|
||||
if (rest >= trans_pkt_siz)
|
||||
slice = trans_pkt_siz;
|
||||
else
|
||||
slice = rest;
|
||||
|
||||
@@ -121,8 +128,8 @@ s32 trans_layer_rw_proc(struct phy_data_rw *rw, u8 *buffer, u32 len)
|
||||
rest = data_len;
|
||||
total = 0;
|
||||
while (rest > 0) {
|
||||
if (rest >= TRANS_DATA_BUFF_SIZE)
|
||||
slice = TRANS_DATA_BUFF_SIZE;
|
||||
if (rest >= trans_pkt_siz)
|
||||
slice = trans_pkt_siz;
|
||||
else
|
||||
slice = rest;
|
||||
|
||||
|
||||
@@ -19,11 +19,45 @@
|
||||
static u32 image_size = 0;
|
||||
static u64 write_size = 0;
|
||||
|
||||
static void *upg_fat_malloc_align(struct fwc_info *fwc, u32 *size, size_t align)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
switch (*size) {
|
||||
case DATA_WRITE_ONCE_MAX_SIZE:
|
||||
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MAX_SIZE, fwc->block_size);
|
||||
ptr = aicos_malloc_align(0, *size, align);
|
||||
if (ptr)
|
||||
break;
|
||||
case DATA_WRITE_ONCE_MID_SIZE:
|
||||
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MID_SIZE, fwc->block_size);
|
||||
ptr = aicos_malloc_align(0, *size, align);
|
||||
if (ptr)
|
||||
break;
|
||||
case DATA_WRITE_ONCE_MIN_SIZE:
|
||||
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MIN_SIZE, fwc->block_size);
|
||||
ptr = aicos_malloc_align(0, *size, align);
|
||||
if (ptr)
|
||||
break;
|
||||
default:
|
||||
ptr = aicos_malloc_align(0, *size, align);
|
||||
if (ptr)
|
||||
break;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void upg_fat_free_align(void *mem)
|
||||
{
|
||||
aicos_free_align(0, mem);
|
||||
}
|
||||
|
||||
#define FRAME_LIST_SIZE 4096
|
||||
static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
|
||||
{
|
||||
struct fwc_info *fwc;
|
||||
int offset, write_once_size, len, remaining_size;
|
||||
u32 offset, write_once_size, len, remaining_size;
|
||||
u8 *buf;
|
||||
s32 ret;
|
||||
ulong actread, total_len = 0;
|
||||
@@ -48,18 +82,18 @@ static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
|
||||
/*start write data*/
|
||||
start_us = aic_get_time_us();
|
||||
media_data_write_start(fwc);
|
||||
|
||||
/*config write size once*/
|
||||
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;
|
||||
write_once_size = DATA_WRITE_ONCE_MAX_SIZE;
|
||||
|
||||
/*malloc buf memory*/
|
||||
buf = aicos_malloc_align(0, write_once_size, FRAME_LIST_SIZE);
|
||||
buf = upg_fat_malloc_align(fwc, &write_once_size, FRAME_LIST_SIZE);
|
||||
if (!buf) {
|
||||
pr_err("Error: malloc buf failed.\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset((void *)buf, 0, write_once_size);
|
||||
|
||||
offset = 0;
|
||||
@@ -99,13 +133,13 @@ static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
|
||||
(total_len * 1000000 / start_us) / 1024 / 1024,
|
||||
(total_len * 1000000 / start_us) / 1024 % 1024);
|
||||
|
||||
aicos_free_align(0, buf);
|
||||
upg_fat_free_align(buf);
|
||||
aicos_free_align(0, fwc);
|
||||
|
||||
return total_len;
|
||||
err:
|
||||
if (buf)
|
||||
aicos_free_align(0, buf);
|
||||
upg_fat_free_align(buf);
|
||||
if (fwc)
|
||||
aicos_free_align(0, fwc);
|
||||
return 0;
|
||||
|
||||
@@ -29,14 +29,13 @@ void boot_app(void *app)
|
||||
return;
|
||||
#ifndef LPKG_USING_FDTLIB
|
||||
ep = image_get_entry_point(app);
|
||||
if (!ep) {
|
||||
printf("Entry point is null.\n");
|
||||
while(1)
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
ep = app;
|
||||
#endif
|
||||
if (!ep) {
|
||||
printf("Entry point is null, Run APP failure.\n");
|
||||
return;
|
||||
}
|
||||
boot_time_trace("Run APP");
|
||||
boot_time_show();
|
||||
dev = aic_get_boot_device();
|
||||
|
||||
@@ -30,7 +30,11 @@
|
||||
#include <usbhost.h>
|
||||
#include <usbdevice.h>
|
||||
#include <boot_rom.h>
|
||||
#include <ram_param.h>
|
||||
#include <hal_axicfg.h>
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
#include <log_buf.h>
|
||||
#endif
|
||||
|
||||
extern size_t __heap_start;
|
||||
extern size_t __heap_end;
|
||||
@@ -54,9 +58,33 @@ struct hal_axicfg_table axi_cfg_table[HAL_AXICFG_PORT_MAX] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static void aic_board_heap_init(enum boot_device bd)
|
||||
{
|
||||
size_t heap_size, heap_start, real_ram_size = 0, config_ram_size = 0;
|
||||
|
||||
#ifdef AIC_PSRAM_SIZE
|
||||
config_ram_size = AIC_PSRAM_SIZE;
|
||||
#elif AIC_DRAM_TOTAL_SIZE
|
||||
config_ram_size = AIC_DRAM_TOTAL_SIZE;
|
||||
#endif
|
||||
|
||||
real_ram_size = aic_get_ram_size();
|
||||
if (config_ram_size != real_ram_size)
|
||||
pr_warn("config ram size(0x%x) is not equal real ram size(0x%x)\n", (u32)config_ram_size, (u32)real_ram_size);
|
||||
|
||||
heap_size = ((size_t)&__heap_end) - ((size_t)&__heap_start);
|
||||
|
||||
/* Limit bootloader's heap to 2MB */
|
||||
if (bd != BD_UDISK && bd != BD_SDFAT32 && bd != BD_USB && heap_size > 0x200000)
|
||||
heap_size = 0x200000;
|
||||
|
||||
heap_start = (size_t)&__heap_end - heap_size;
|
||||
|
||||
heap_init((void *)heap_start, heap_size);
|
||||
}
|
||||
|
||||
static int board_init(enum boot_device bd)
|
||||
{
|
||||
size_t heap_size, heap_start;
|
||||
int cons_uart;
|
||||
|
||||
/* target/<chip>/<board>/board.c */
|
||||
@@ -73,21 +101,14 @@ static int board_init(enum boot_device bd)
|
||||
}
|
||||
#endif
|
||||
|
||||
heap_size = ((size_t)&__heap_end) - ((size_t)&__heap_start);
|
||||
|
||||
if (bd != BD_UDISK && bd != BD_SDFAT32 && heap_size > 0x200000)
|
||||
heap_size = 0x200000;
|
||||
|
||||
heap_start = (size_t)&__heap_end - heap_size;
|
||||
|
||||
heap_init((void *)heap_start, heap_size);
|
||||
boot_time_trace("Heap init done");
|
||||
|
||||
cons_uart = AIC_BOOTLOADER_CONSOLE_UART;
|
||||
uart_init(cons_uart);
|
||||
stdio_set_uart(cons_uart);
|
||||
boot_time_trace("Console UART ready");
|
||||
|
||||
aic_board_heap_init(bd);
|
||||
boot_time_trace("Heap init done");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -96,6 +117,17 @@ void show_banner(void)
|
||||
printf("\ntinySPL [Built on %s %s]\n", __DATE__, __TIME__);
|
||||
}
|
||||
|
||||
int bl_upgmode_detect(void)
|
||||
{
|
||||
enum aic_reboot_reason r;
|
||||
|
||||
r = aic_get_reboot_reason();
|
||||
if (r == REBOOT_REASON_BL_UPGRADE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
enum boot_device bd;
|
||||
@@ -113,6 +145,13 @@ int main(void)
|
||||
#endif
|
||||
|
||||
bd = aic_get_boot_device();
|
||||
if (bl_upgmode_detect())
|
||||
bd = BD_USB;
|
||||
|
||||
#ifdef AICUPG_LOG_BUFFER_SUPPORT
|
||||
log_buf_init();
|
||||
#endif
|
||||
|
||||
board_init(bd);
|
||||
#ifdef AIC_DMA_DRV
|
||||
drv_dma_init();
|
||||
|
||||
@@ -22,7 +22,7 @@ static int do_reset_boot(int argc, char *argv[])
|
||||
{
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_init();
|
||||
printf("Going to reboot ...\n");
|
||||
printf("Restarting system ...\n");
|
||||
#endif
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_CMD_REBOOT);
|
||||
@@ -40,7 +40,10 @@ CONSOLE_CMD(reboot, do_reset_boot, "Reboot device.");
|
||||
static int cmd_aicupg(int argc, char **argv)
|
||||
{
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
if ((argc == 2) && !strcmp(argv[1], "gotobl"))
|
||||
aic_set_reboot_reason(REBOOT_REASON_BL_UPGRADE);
|
||||
else
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
#endif
|
||||
do_reset_boot(0, NULL);
|
||||
return 0;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <board.h>
|
||||
#include <hal_syscfg.h>
|
||||
#include <aic_core.h>
|
||||
@@ -22,6 +23,10 @@
|
||||
#include "drv_dma.h"
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_SID
|
||||
#include "efuse.h"
|
||||
#endif
|
||||
|
||||
#ifdef AIC_OSR_CE_DRV
|
||||
#include <osrce.h>
|
||||
#endif
|
||||
@@ -55,11 +60,11 @@ extern void lv_port_indev_init(void);
|
||||
extern void lv_user_gui_init(void);
|
||||
#endif
|
||||
|
||||
extern void show_version(void);
|
||||
|
||||
void show_banner(void)
|
||||
{
|
||||
printf("%s\n", BANNER);
|
||||
printf("Welcome to ArtInChip Luban-Lite %d.%d [Baremetal - Built on %s %s]\n",
|
||||
LL_VERSION, LL_SUBVERSION, __DATE__, __TIME__);
|
||||
}
|
||||
|
||||
static int board_init(void)
|
||||
@@ -76,7 +81,11 @@ static int board_init(void)
|
||||
uart_init(cons_uart);
|
||||
stdio_set_uart(cons_uart);
|
||||
|
||||
#ifdef AIC_USING_SID
|
||||
efuse_init();
|
||||
#endif
|
||||
show_banner();
|
||||
show_version();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -125,8 +134,10 @@ int main(void)
|
||||
#endif
|
||||
#ifdef AIC_USING_SDMC1
|
||||
mmc_init(1);
|
||||
#ifdef AIC_SD_USING_HOTPLUG
|
||||
sdcard_hotplug_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_USING_SDMC0)
|
||||
if (dfs_mount("mmc0p2", "/rodata", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
@@ -231,6 +242,10 @@ int main(void)
|
||||
extern void msc_storage_init(char *path);
|
||||
msc_storage_init(MSC_STORAGE_PATH);
|
||||
#endif
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE_MTP_TEMPLATE
|
||||
extern void mtp_init(char *path);
|
||||
mtp_init(ROOT_PATH);
|
||||
#endif
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE_MIDI_TEMPLATE
|
||||
extern void midi_init(void);
|
||||
midi_init();
|
||||
@@ -241,6 +256,12 @@ int main(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SD_USING_HOTPLUG
|
||||
while (1) {
|
||||
sdcard_hotplug_act();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
/* Console shell loop */
|
||||
console_init();
|
||||
|
||||
@@ -40,7 +40,10 @@ CONSOLE_CMD(reboot, do_reset_boot, "Reboot device.");
|
||||
static int cmd_aicupg(int argc, char **argv)
|
||||
{
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
if ((argc == 2) && !strcmp(argv[1], "gotobl"))
|
||||
aic_set_reboot_reason(REBOOT_REASON_BL_UPGRADE);
|
||||
else
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
#endif
|
||||
do_reset_boot(0, NULL);
|
||||
return 0;
|
||||
|
||||
@@ -133,8 +133,10 @@ int main(void)
|
||||
|
||||
#ifdef AIC_SDMC_DRV
|
||||
mmc_init(1);
|
||||
#ifdef AIC_SD_USING_HOTPLUG
|
||||
sdcard_hotplug_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_SDMC_DRV)
|
||||
if (dfs_mount("sd1", "/sdcard", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
@@ -213,6 +215,12 @@ int main(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SD_USING_HOTPLUG
|
||||
while (1) {
|
||||
sdcard_hotplug_act();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FreeRTOS Task exit */
|
||||
aicos_thread_delete(NULL);
|
||||
return 0;
|
||||
|
||||
@@ -17,19 +17,32 @@
|
||||
#include <stdio.h>
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <boot_param.h>
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#ifdef AIC_AB_SYSTEM_INTERFACE
|
||||
char target[32] = { 0 };
|
||||
enum boot_device boot_dev = aic_get_boot_device();
|
||||
|
||||
aic_ota_status_update();
|
||||
aic_get_rodata_to_mount(target);
|
||||
printf("Mount APP in blk %s\n", target);
|
||||
if (boot_dev != BD_SDMC0) {
|
||||
|
||||
if (dfs_mount(target, "/rodata", "elm", 0, 0) < 0)
|
||||
printf("Failed to mount elm\n");
|
||||
aic_ota_status_update();
|
||||
aic_get_rodata_to_mount(target);
|
||||
printf("Mount APP in blk %s\n", target);
|
||||
|
||||
if (dfs_mount(target, "/rodata", "elm", 0, 0) < 0)
|
||||
printf("Failed to mount elm\n");
|
||||
|
||||
memset(target, 0, sizeof(target));
|
||||
|
||||
aic_get_data_to_mount(target);
|
||||
printf("Mount APP in blk %s\n", target);
|
||||
|
||||
if (dfs_mount(target, "/data", "elm", 0, 0) < 0)
|
||||
printf("Failed to mount elm\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ULOG_USING_FILTER
|
||||
|
||||
Reference in New Issue
Block a user