SmartAudio/lichee/brandy/u-boot-2014.07/sprite/sprite_verify.c

379 lines
9.0 KiB
C
Raw Normal View History

2018-07-13 01:31:50 +00:00
/*
* (C) Copyright 2007-2013
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
* Jerry Wang <wangflord@allwinnertech.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <common.h>
#include <malloc.h>
#include "sparse/sparse.h"
#include <sunxi_mbr.h>
#include <sunxi_board.h>
#if defined (CONFIG_SUNXI_SPINOR)
#define VERIFY_ONCE_BYTES (2 * 1024 * 1024)
#else
#define VERIFY_ONCE_BYTES (16 * 1024 * 1024)
#endif
#define VERIFY_ONCE_SECTORS (VERIFY_ONCE_BYTES/512)
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
uint add_sum(void *buffer, uint length)
{
#ifndef CONFIG_USE_NEON_SIMD
unsigned int *buf;
unsigned int count;
unsigned int sum;
count = length >> 2; // 以 字4bytes为单位计数
sum = 0;
buf = (unsigned int *)buffer;
while(count--)
{
sum += *buf++; // 依次累加,求得校验和
};
switch(length & 0x03)
{
case 0:
return sum;
case 1:
sum += (*buf & 0x000000ff);
break;
case 2:
sum += (*buf & 0x0000ffff);
break;
case 3:
sum += (*buf & 0x00ffffff);
break;
}
#else
uint sum;
sum = add_sum_neon(buffer, length);
#endif
return sum;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
uint sunxi_sprite_part_rawdata_verify(uint base_start, long long base_bytes)
{
uint checksum = 0;
uint unaligned_bytes, last_time_bytes;
uint rest_sectors;
uint crt_start;
char *tmp_buf = NULL;
tmp_buf = (char *)malloc(VERIFY_ONCE_BYTES);
if(!tmp_buf)
{
printf("sunxi sprite err: unable to malloc memory for verify\n");
return 0;
}
crt_start = base_start;
rest_sectors = (uint)((base_bytes + 511)>>9);
unaligned_bytes = (uint)base_bytes & 0x1ff;
debug("read total sectors %d\n", rest_sectors);
debug("read part start %d\n", crt_start);
while(rest_sectors >= VERIFY_ONCE_SECTORS)
{
if(sunxi_sprite_read(crt_start, VERIFY_ONCE_SECTORS, tmp_buf) != VERIFY_ONCE_SECTORS)
{
printf("sunxi sprite: read flash error when verify\n");
checksum = 0;
goto __rawdata_verify_err;
}
crt_start += VERIFY_ONCE_SECTORS;
rest_sectors -= VERIFY_ONCE_SECTORS;
checksum += add_sum(tmp_buf, VERIFY_ONCE_BYTES);
debug("check sum = 0x%x\n", checksum);
}
if(rest_sectors)
{
if(sunxi_sprite_read(crt_start, rest_sectors, tmp_buf) != rest_sectors)
{
printf("sunxi sprite: read flash error when verify\n");
checksum = 0;
goto __rawdata_verify_err;
}
if(unaligned_bytes)
{
last_time_bytes = (rest_sectors - 1) * 512 + unaligned_bytes;
}
else
{
last_time_bytes = rest_sectors * 512;
}
checksum += add_sum(tmp_buf, last_time_bytes);
debug("check sum = 0x%x\n", checksum);
}
__rawdata_verify_err:
if(tmp_buf)
{
free(tmp_buf);
}
return checksum;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
uint sunxi_sprite_part_sparsedata_verify(void)
{
return unsparse_checksum();
}
uint sunxi_sprite_generate_checksum(void *buffer, uint length, uint src_sum)
{
return sunxi_generate_checksum(buffer, length, src_sum);
}
int sunxi_sprite_verify_checksum(void *buffer, uint length, uint src_sum)
{
return sunxi_verify_checksum(buffer, length, src_sum);
}
/*
***************************************************************
* __mbr_map_dump
*
* Description:
* check the input para
* Parameters:
*
* Return value:
*
* History:
*
***************************************************************
*/
static void __mbr_map_dump(u8 *buf)
{
sunxi_mbr_t *mbr_info = (sunxi_mbr_t *)buf;
sunxi_partition *part_info;
u32 i;
char buffer[32];
printf("*************MBR DUMP***************\n");
printf("total mbr part %d\n", mbr_info->PartCount);
printf("\n");
for(part_info = mbr_info->array, i=0;i<mbr_info->PartCount;i++, part_info++)
{
memset(buffer, 0, 32);
memcpy(buffer, part_info->name, 16);
printf("part[%d] name :%s\n", i, buffer);
memset(buffer, 0, 32);
memcpy(buffer, part_info->classname, 16);
printf("part[%d] classname :%s\n", i, buffer);
printf("part[%d] addrlo :0x%x\n", i, part_info->addrlo);
printf("part[%d] lenlo :0x%x\n", i, part_info->lenlo);
printf("part[%d] user_type :%d\n", i, part_info->user_type);
printf("part[%d] keydata :%d\n", i, part_info->keydata);
printf("part[%d] ro :%d\n", i, part_info->ro);
printf("\n");
}
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_sprite_verify_mbr(void *buffer)
{
sunxi_mbr_t *local_mbr;
char *tmp_buf = (char *)buffer;
int i;
int mbr_num = SUNXI_MBR_COPY_NUM;
tmp_buf = buffer;
if (get_boot_storage_type() == STORAGE_NOR)
{
mbr_num = 1;
}
for(i=0;i<mbr_num;i++)
{
local_mbr = (sunxi_mbr_t *)tmp_buf;
if(crc32(0, (const unsigned char *)(tmp_buf + 4), SUNXI_MBR_SIZE - 4) != local_mbr->crc32)
{
printf("the %d mbr table is bad\n", i);
return -1;
}
else
{
printf("the %d mbr table is ok\n", i);
tmp_buf += SUNXI_MBR_SIZE;
}
}
#if 1
__mbr_map_dump(buffer);
#endif
return 0;
}
int sunxi_sprite_get_one_valid_mbr(void *valid_mbr_buffer, void *source_mbr_buffer)
{
sunxi_mbr_t *local_mbr;
char *tmp_buf;
int i;
int mbr_num = SUNXI_MBR_COPY_NUM;
tmp_buf = source_mbr_buffer;
if (get_boot_storage_type() == STORAGE_NOR)
mbr_num = 1;
for (i = 0; i < mbr_num; i++) {
local_mbr = (sunxi_mbr_t *)tmp_buf;
if (crc32(0, (const unsigned char *)(tmp_buf + 4), SUNXI_MBR_SIZE - 4) != local_mbr->crc32) {
printf("the %d mbr table is bad\n", i);
tmp_buf += SUNXI_MBR_SIZE;
} else {
printf("the %d mbr table is ok\n", i);
memmove(valid_mbr_buffer, tmp_buf, SUNXI_MBR_SIZE);
#if 1
__mbr_map_dump(valid_mbr_buffer);
#endif
return 0;
}
}
return -1;
}
int sunxi_sprite_read_mbr(void *buffer, uint mbr_copy)
{
uint sectors;
sectors = mbr_copy*SUNXI_MBR_SIZE/512;
if (sectors != sunxi_sprite_read(0, sectors, buffer))
return -1;
#ifdef CONFIG_GPT_SUPPORT
char *p = buffer;
char *p_sunxi_mbr = p + 3*SUNXI_MBR_SIZE;
/* 00K~48K ->GPT entry */
/* 48K~64K ->sunxi mbr */
/* for sunxi_sprite_verify_mbr get success result */
memcpy(p + 0*SUNXI_MBR_SIZE, p_sunxi_mbr, SUNXI_MBR_SIZE);
memcpy(p + 1*SUNXI_MBR_SIZE, p_sunxi_mbr, SUNXI_MBR_SIZE);
memcpy(p + 2*SUNXI_MBR_SIZE, p_sunxi_mbr, SUNXI_MBR_SIZE);
#endif
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_sprite_verify_dlmap(void *buffer)
{
sunxi_download_info *local_dlmap;
char *tmp_buf = (char *)buffer;
tmp_buf = buffer;
local_dlmap = (sunxi_download_info *)tmp_buf;
if(crc32(0, (const unsigned char *)(tmp_buf + 4), SUNXI_MBR_SIZE - 4) != local_dlmap->crc32)
{
printf("downlaod map is bad\n");
return -1;
}
return 0;
}