mirror of
https://github.com/gnuton/asuswrt-merlin.ng.git
synced 2025-05-19 16:02:36 +02:00
341 lines
12 KiB
C
Executable file
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;
|
|
}
|
|
|