asuswrt-merlin.ng/release/src-rt-5.04axhnd.675x/router-sysdep.rt-ax88u_pro/bcm_flashutil/bcm_imgif.c

341 lines
12 KiB
C
Executable file

/*****************************************************************************
* <:copyright-BRCM:2015:DUAL/GPL:standard
*
* Copyright (c) 2015 Broadcom
* All Rights Reserved
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed
* to you under the terms of the GNU General Public License version 2
* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
* with the following added to such license:
*
* As a special exception, the copyright holders of this software give
* you permission to link this software with independent modules, and
* to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent
* module, the terms and conditions of the license of that module.
* An independent module is a module which is not derived from this
* software. The special exception does not apply to any modifications
* of the software.
*
* Not withstanding the above, under no circumstances may you combine
* this software in any way with any other Broadcom software provided
* under a license other than the GPL, without Broadcom's express prior
* written consent.
*
* :>
****************************************************************************/
/*****************************************************************************
* Description:
*
* The BCM CPE software Image Incremental Flashing (imageIf) library
* implementation. This library runs on top of bcm_flashutil. It uses
* the incremental flashing mechanism to avoid holding the entire image
* in RAM, thus reduces RAM usage.
* This library is expected to be platform-independent. The underlying
* bcm_flashutil library handles the platform-specific operations.
* Notes about the library:
* - It supports FLASH format image, with a Whole Flash Image WFI_TAG
* (length TOKEN_LEN) trailer. It supports NAND flash.
* - It assumes CFEROM stays on erase block #0 only.
* - It does not handle BROADCOM format image or NOR flash.
* - It does not handle the configuration file upgrade, and messages
* related to the configuration file validation.
*
*****************************************************************************/
/* ---- Include Files ----------------------------------------------------- */
#include "bcm_flashutil.h"
#include "bcm_flashutil_nand.h"
#include "bcm_flashutil_emmc.h"
#include "bcm_flashutil_nor.h"
#include "bcm_imgif.h"
#include "bcm_imgif_nand.h"
#include "bcm_imgif_emmc.h"
#include "bcm_imgif_pkgtb.h"
/* ---- Constants and Types ----------------------------------------------- */
/* IMGIF context. */
typedef struct
{
IMGIF_HANDLE (*imgif_open_cb)(IMG_FORMAT_PARSER_CB fmtParserCb,
CAL_CRC32_CB calCrc32Cb);
int (*imgif_write_cb)(IMGIF_HANDLE h, UINT8 *dataP, int len);
int (*imgif_close_cb)(IMGIF_HANDLE h, UBOOL8 abortFlag);
int (*imgif_set_image_info_cb)(IMGIF_HANDLE h, imgif_img_info_t *imgInfoP);
int (*imgif_get_flash_info_cb)(imgif_flash_info_t *flashInfoP);
unsigned int flash_type;
} imgif_ctx_t;
/* ---- Private Function Prototypes --------------------------------------- */
/* ---- Public Variables -------------------------------------------------- */
/* ---- Private Variables ------------------------------------------------- */
static imgif_ctx_t imgif_ctx = {NULL, NULL, NULL, NULL, NULL, 0};
/* ---- Functions --------------------------------------------------------- */
/*****************************************************************************
* FUNCTION: imgif_init
* PURPOSE: Initialize imgif callbacks.
* PARAMETERS:
* None.
* RETURNS:
* TRUE - supported and enabled. FALSE - else.
* NOTES:
* None.
*****************************************************************************/
static void imgif_init(void)
{
/* Ignore redundant calls to this function */
if( imgif_ctx.flash_type )
return;
if( getFlashInfo(&imgif_ctx.flash_type) >= 0 )
{
switch( imgif_ctx.flash_type )
{
#ifdef SUPPORT_INCREMENTAL_FLASHING
case FLASH_INFO_FLAG_NAND:
if( nandIsLegacyFlashLayout() )
{
imgif_ctx.imgif_open_cb = imgif_nand_open;
imgif_ctx.imgif_write_cb = imgif_nand_write;
imgif_ctx.imgif_close_cb = imgif_nand_close;
imgif_ctx.imgif_set_image_info_cb = imgif_nand_set_image_info;
imgif_ctx.imgif_get_flash_info_cb = imgif_nand_get_flash_info;
}
else
{
imgif_ctx.imgif_open_cb = imgif_pkgtb_open;
imgif_ctx.imgif_write_cb = imgif_pkgtb_write;
imgif_ctx.imgif_close_cb = imgif_pkgtb_close;
imgif_ctx.imgif_set_image_info_cb = imgif_pkgtb_set_image_info;
imgif_ctx.imgif_get_flash_info_cb = imgif_pkgtb_get_flash_info;
}
printf("imgif: Enabling NAND incremental flashing functions!\n");
break;
case FLASH_INFO_FLAG_EMMC:
if( emmcIsLegacyFlashLayout() )
{
imgif_ctx.imgif_open_cb = imgif_emmc_open;
imgif_ctx.imgif_write_cb = imgif_emmc_write;
imgif_ctx.imgif_close_cb = imgif_emmc_close;
imgif_ctx.imgif_set_image_info_cb = imgif_emmc_set_image_info;
imgif_ctx.imgif_get_flash_info_cb = imgif_emmc_get_flash_info;
}
else
{
imgif_ctx.imgif_open_cb = imgif_pkgtb_open;
imgif_ctx.imgif_write_cb = imgif_pkgtb_write;
imgif_ctx.imgif_close_cb = imgif_pkgtb_close;
imgif_ctx.imgif_set_image_info_cb = imgif_pkgtb_set_image_info;
imgif_ctx.imgif_get_flash_info_cb = imgif_pkgtb_get_flash_info;
}
printf("imgif: Enabling EMMC incremental flashing functions!\n");
break;
#ifndef DESKTOP_LINUX
case FLASH_INFO_FLAG_NOR:
if( norIsNewFlashLayout() )
{
imgif_ctx.imgif_open_cb = imgif_pkgtb_open;
imgif_ctx.imgif_write_cb = imgif_pkgtb_write;
imgif_ctx.imgif_close_cb = imgif_pkgtb_close;
imgif_ctx.imgif_set_image_info_cb = imgif_pkgtb_set_image_info;
imgif_ctx.imgif_get_flash_info_cb = imgif_pkgtb_get_flash_info;
printf("imgif: Enabling SPI NOR incremental flashing functions!\n");
}
else
printf("imgif: Incremental flashing not supported!\n");
break;
#endif
#endif
default:
printf("imgif: Incremental flashing not supported!\n");
break;
}
}
else
{
printf("imgif: Error! Cannot determine flash type!\n");
}
}
/*****************************************************************************
* FUNCTION: imgif_open
* PURPOSE: Initialize IMGIF context.
* PARAMETERS:
* fmtParserCb (IN) Image parser callback function.
calCrc32Cb (IN) Application-specific CRC algorithm callback function.
* RETURNS:
* Pointer to the IMGIF context - successful operation.
* NULL - failed operation, for example, another software upgrade already
* in progress.
* NOTES:
* None.
*****************************************************************************/
IMGIF_HANDLE imgif_open(IMG_FORMAT_PARSER_CB fmtParserCb,
CAL_CRC32_CB calCrc32Cb)
{
if( !imgif_ctx.flash_type )
imgif_init();
if( imgif_ctx.imgif_open_cb )
return (imgif_ctx.imgif_open_cb( fmtParserCb, calCrc32Cb));
else
{
printf("imgif: Error! imgif not initialized!\n");
return(NULL);
}
}
/*****************************************************************************
* FUNCTION: imgif_write
* PURPOSE: Write image block to IMGIF.
* PARAMETERS:
* h (IN) - IMGIF context pointer.
* dataP (IN) - image block data pointer.
* len (IN) - image block size.
* RETURNS:
* >=0 - number of bytes written.
* -1 - failed operation.
* NOTES:
* None.
*****************************************************************************/
int imgif_write(IMGIF_HANDLE h, UINT8 *dataP, int len)
{
if( imgif_ctx.imgif_write_cb )
return (imgif_ctx.imgif_write_cb( h, dataP, len ));
else
{
printf("imgif: Error! imgif not initialized!\n");
return(-1);
}
}
/*****************************************************************************
* FUNCTION: imgif_close
* PURPOSE: Close IMGIF context.
* PARAMETERS:
* h (IN) - IMGIF context pointer.
* abortFlag (IN) - TRUE: user aborts the operation.
* RETURNS:
* 0 - successful operation.
* -1 - failed operation.
* NOTES:
* User may stop an upgrade at any time, when there is an operator,
* command, protocol failure, or unmatched image size and/or CRC values
* between IMGIF and user.
*****************************************************************************/
int imgif_close(IMGIF_HANDLE h, UBOOL8 abortFlag)
{
if( imgif_ctx.imgif_close_cb )
return (imgif_ctx.imgif_close_cb( h, abortFlag ));
else
{
printf("imgif: Error! imgif not initialized!\n");
return(-1);
}
}
/*****************************************************************************
* FUNCTION: imgif_set_image_info
* PURPOSE: Set image info obtained externally.
* PARAMETERS:
h (IN) - IMGIF context pointer.
imgInfoExtP (OUT) - image info pointer.
* RETURNS:
* 0 - successful operation.
* < 0 - failed operation.
* NOTES:
* This function may be invoked at any time. However, it is typically
* invoked at the end of the upgrade, when user has received the whole
* image, and has obtained the image integrity information.
*****************************************************************************/
int imgif_set_image_info(IMGIF_HANDLE h, imgif_img_info_t *imgInfoExtP)
{
if( !imgif_ctx.flash_type )
imgif_init();
if( imgif_ctx.imgif_set_image_info_cb )
return (imgif_ctx.imgif_set_image_info_cb( h, imgInfoExtP ));
else
{
printf("imgif: Error! imgif not initialized!\n");
return(-1);
}
}
/*****************************************************************************
* FUNCTION: imgif_get_flash_info
* PURPOSE: Obtain flash info.
* PARAMETERS:
h (IN) - IMGIF context pointer.
flashInfoP (OUT) - flash info pointer.
* RETURNS:
* 0 - successful operation.
* < 0 - failed operation.
* NOTES:
* This function may be invoked at any time.
*****************************************************************************/
int imgif_get_flash_info(imgif_flash_info_t *flashInfoP)
{
if( !imgif_ctx.flash_type )
imgif_init();
if( imgif_ctx.imgif_get_flash_info_cb )
return (imgif_ctx.imgif_get_flash_info_cb( flashInfoP ));
else
{
printf("imgif: Error! imgif not initialized!\n");
return(-1);
}
}
/*****************************************************************************
* FUNCTION: imgif_get_enable_mode
* PURPOSE: Check whether incremental flashing is supported and enabled.
* PARAMETERS:
* None.
* RETURNS:
* TRUE - supported and enabled. FALSE - else.
* NOTES:
* None.
*****************************************************************************/
UBOOL8 imgif_get_enable_mode(void)
{
UBOOL8 mode = FALSE;
if( !imgif_ctx.flash_type )
imgif_init();
switch( imgif_ctx.flash_type )
{
case FLASH_INFO_FLAG_NAND:
case FLASH_INFO_FLAG_EMMC:
#ifdef SUPPORT_INCREMENTAL_FLASHING
mode = TRUE;
#endif /* SUPPORT_INCREMENTAL_FLASHING */
break;
case FLASH_INFO_FLAG_NOR:
#ifdef SUPPORT_INCREMENTAL_FLASHING
#ifndef DESKTOP_LINUX
if (norIsNewFlashLayout())
mode = TRUE;
#endif
#endif /* SUPPORT_INCREMENTAL_FLASHING */
break;
default:
mode = FALSE;
break;
}
return mode;
}