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