mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-16 17:18:56 +00:00
V1.0.5
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user