255 lines
4.4 KiB
C
255 lines
4.4 KiB
C
/*
|
|
* (C) Copyright 2018-2020
|
|
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
|
* wangwei <wangwei@allwinnertech.com>
|
|
*
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <spare_head.h>
|
|
#include <nand_boot0.h>
|
|
#include <private_toc.h>
|
|
#include <private_boot0.h>
|
|
#include <private_uboot.h>
|
|
#include <arch/uart.h>
|
|
|
|
#ifdef CFG_SUNXI_USE_NEON
|
|
/*stdint.h included by arm_neon.h has conflict on uintptr_t with linux/types.h, undef it here*/
|
|
#undef __UINTPTR_TYPE__
|
|
#include <arm_neon.h>
|
|
|
|
int verify_addsum(void *mem_base, u32 size)
|
|
{
|
|
uint32x4_t sum_vec;
|
|
uint32x4_t adding;
|
|
u32 neon_sum = 0;
|
|
u32 src_sum;
|
|
u32 *buf = (u32 *)mem_base;
|
|
u32 count = size >> 2;
|
|
sbrom_toc1_head_info_t *bfh;
|
|
bfh = (sbrom_toc1_head_info_t *)mem_base;
|
|
|
|
neon_enable();
|
|
|
|
src_sum = bfh->add_sum;
|
|
bfh->add_sum = STAMP_VALUE;
|
|
|
|
sum_vec = vdupq_n_u32(0);
|
|
while (count >= 4) {
|
|
adding = vld1q_u32(buf);
|
|
sum_vec = vaddq_u32(sum_vec, adding);
|
|
buf += 4;
|
|
count -= 4;
|
|
}
|
|
neon_sum += vgetq_lane_u32(sum_vec, 0);
|
|
neon_sum += vgetq_lane_u32(sum_vec, 1);
|
|
neon_sum += vgetq_lane_u32(sum_vec, 2);
|
|
neon_sum += vgetq_lane_u32(sum_vec, 3);
|
|
|
|
while (count-- > 0)
|
|
neon_sum += *buf++;
|
|
|
|
//printf("sum=%x\n", neon_sum);
|
|
//printf("src_sum=%x\n", src_sum);
|
|
|
|
bfh->add_sum = src_sum;
|
|
if (neon_sum == src_sum)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
#else
|
|
/* check: 0-success -1:fail */
|
|
int verify_addsum(void *mem_base, u32 size)
|
|
{
|
|
u32 *buf;
|
|
u32 count;
|
|
u32 src_sum;
|
|
u32 sum;
|
|
sbrom_toc1_head_info_t *bfh;
|
|
|
|
bfh = (sbrom_toc1_head_info_t *)mem_base;
|
|
/*generate checksum*/
|
|
src_sum = bfh->add_sum;
|
|
bfh->add_sum = STAMP_VALUE;
|
|
count = size >> 2;
|
|
sum = 0;
|
|
buf = (u32 *)mem_base;
|
|
do
|
|
{
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
}while( ( count -= 4 ) > (4-1) );
|
|
|
|
while( count-- > 0 )
|
|
sum += *buf++;
|
|
|
|
bfh->add_sum = src_sum;
|
|
|
|
// printf("sum=%x\n", sum);
|
|
// printf("src_sum=%x\n", src_sum);
|
|
if( sum == src_sum )
|
|
return 0;
|
|
else
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CFG_KERNEL_CHECKSUM
|
|
/* check: 0-success -1:fail */
|
|
int verify_addsum_for_kernel(void *mem_base, u32 size, u32 src_sum)
|
|
{
|
|
#ifdef CFG_USE_DCACHE
|
|
dcache_enable();
|
|
#endif
|
|
u32 *buf;
|
|
u32 count;
|
|
u32 sum;
|
|
|
|
/*generate checksum*/
|
|
count = size >> 2;
|
|
sum = 0;
|
|
buf = (u32 *)mem_base;
|
|
do {
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
} while ((count -= 4) > (4 - 1));
|
|
|
|
while (count-- > 0)
|
|
sum += *buf++;
|
|
|
|
#ifdef CFG_USE_DCACHE
|
|
dcache_disable();
|
|
#endif
|
|
if (sum == src_sum) {
|
|
return 0;
|
|
} else {
|
|
printf("boot image checksum error sum=%x src_sum=%x\n", sum,
|
|
src_sum);
|
|
return -1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
u32 sunxi_generate_checksum(void *buffer, uint length, uint div, uint src_sum)
|
|
{
|
|
uint *buf;
|
|
int count;
|
|
uint sum;
|
|
|
|
count = length >> 2;
|
|
sum = 0;
|
|
buf = (__u32 *)buffer;
|
|
do {
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
sum += *buf++;
|
|
} while ((count -= (4*div)) > (4 - 1));
|
|
|
|
while (count-- > 0)
|
|
sum += *buf++;
|
|
|
|
sum = sum - src_sum + STAMP_VALUE;
|
|
|
|
return sum;
|
|
}
|
|
|
|
int sunxi_verify_checksum(void *buffer, uint length, uint src_sum)
|
|
{
|
|
uint sum;
|
|
sum = sunxi_generate_checksum(buffer, length, 1, src_sum);
|
|
|
|
boot_info("src sum=%x, check sum=%x\n", src_sum, sum);
|
|
if (sum == src_sum)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
u32 g_mod( u32 dividend, u32 divisor, u32 *quot_p)
|
|
{
|
|
if (divisor == 0) {
|
|
*quot_p = 0;
|
|
return 0;
|
|
}
|
|
if (divisor == 1) {
|
|
*quot_p = dividend;
|
|
return 0;
|
|
}
|
|
|
|
for (*quot_p = 0; dividend >= divisor; ++(*quot_p))
|
|
dividend -= divisor;
|
|
return dividend;
|
|
}
|
|
|
|
u8 *get_page_buf( void )
|
|
{
|
|
|
|
return (u8 *)(CONFIG_SYS_DRAM_BASE + 1024 * 1024);
|
|
}
|
|
|
|
char get_uart_input(void)
|
|
{
|
|
|
|
char c = 0;
|
|
if (sunxi_serial_tstc()) {
|
|
c = sunxi_serial_getc();
|
|
printf("key press : %c\n", c);
|
|
/* test time: 30 ms */
|
|
/*
|
|
if (get_sys_ticks() - start > 30)
|
|
break;
|
|
*/
|
|
}
|
|
return c;
|
|
}
|
|
|
|
static uint8_t uboot_func_mask;
|
|
void set_uboot_func_mask(uint8_t mask)
|
|
{
|
|
uboot_func_mask |= mask;
|
|
}
|
|
|
|
uint8_t get_uboot_func_mask(uint8_t mask)
|
|
{
|
|
return uboot_func_mask & mask;
|
|
}
|
|
|
|
__weak int sunxi_board_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
__weak uint8_t sunxi_board_late_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
__weak int sunxi_board_init_early(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
__weak uint32_t *sunxi_bootparam_get_dram_buf(void)
|
|
{
|
|
return
|
|
#if CFG_SUNXI_SBOOT
|
|
(uint32_t *)toc0_config->dram_para;
|
|
#elif CFG_SUNXI_FES
|
|
(uint32_t *)fes1_head.prvt_head.dram_para;
|
|
#else
|
|
(uint32_t *)BT0_head.prvt_head.dram_para;
|
|
#endif
|
|
}
|
|
|
|
__weak int sunxi_bootparam_load(void)
|
|
{
|
|
return 0;
|
|
}
|