diff -Nur a/arch/arm/mach-sunxi/power/brom/Makefile b/arch/arm/mach-sunxi/power/brom/Makefile --- a/arch/arm/mach-sunxi/power/brom/Makefile 2016-03-07 23:43:50.629142681 +0100 +++ b/arch/arm/mach-sunxi/power/brom/Makefile 2016-03-07 23:52:43.092375154 +0100 @@ -3,6 +3,8 @@ always := resumes.code targets := resumes.elf +hostprogs-y := mksunxichecksum + #use "-Os" flags. #Don't use "-O2" flags. KBUILD_CFLAGS := -g -c -nostdlib -march=armv7-a -marm -fno-unwind-tables -fno-asynchronous-unwind-tables -mlittle-endian -O2 @@ -22,8 +24,8 @@ resumes-y := $(addprefix $(obj)/,$(resumes-y)) -$(obj)/resumes.code: $(src)/gen_check_code $(obj)/resumes.bin - $(Q)$< $(obj)/resumes.bin $(obj)/resumes.code +$(obj)/resumes.code: $(obj)/resumes.bin $(obj)/mksunxichecksum + $(obj)/mksunxichecksum $(obj)/resumes.bin $(obj)/resumes.code $(obj)/resumes.bin: $(obj)/resumes.elf FORCE $(Q)$(CROSS_COMPILE)objcopy -O binary $(obj)/resumes.elf $(obj)/resumes.bin diff -Nur a/arch/arm/mach-sunxi/power/brom/mksunxichecksum.c b/arch/arm/mach-sunxi/power/brom/mksunxichecksum.c --- a/arch/arm/mach-sunxi/power/brom/mksunxichecksum.c 1970-01-01 01:00:00.000000000 +0100 +++ b/arch/arm/mach-sunxi/power/brom/mksunxichecksum.c 2016-01-05 19:45:42.000000000 +0100 @@ -0,0 +1,98 @@ +/* + * (C) Copyright 2015 Jean-Francois Moine + * (C) Copyright 2014 Henrik Nordstrom + * + * Based on mksunxiboot + * + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include + +/* boot head definition from sun4i boot code */ +struct boot_file_head { + uint32_t b_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ + uint32_t check_sum; /* generated by PC */ + uint32_t length; /* generated by PC */ + /* + * We use a simplified header, only filling in what is needed + * for checksum calculation. + */ +}; + +#define STAMP_VALUE 0x5F0A6C39 + +/* check sum functon from sun4i boot code */ +static int gen_check_sum(struct boot_file_head *head_p) +{ + uint32_t length; + uint32_t *buf; + uint32_t loop; + uint32_t i; + uint32_t sum; + + length = head_p->length; +// if ((length & 0x3) != 0) /* must 4-byte-aligned */ +// return -1; + buf = (uint32_t *)head_p; + head_p->check_sum = STAMP_VALUE; /* fill stamp */ + loop = length >> 2; + + /* calculate the sum */ + for (i = 0, sum = 0; i < loop; i++) + sum += buf[i]; + + /* write back check sum */ + head_p->check_sum = sum; + + return 0; +} + +int main(int argc, char *argv[]) +{ + struct boot_file_head h, *buf; + unsigned file_size; + FILE *f; + + if (argc != 3) { + printf("Usage: %s file.bin file.code\n" + "calculates BROM checksum in boot header of given .bin file and writes to .code file\n" + "", argv[0]); + exit(1); + } + + f = fopen(argv[1], "rb"); + if (!f) { + perror("Open input file"); + exit(1); + } + + fread(&h, 1, sizeof h, f); + file_size = h.length; // wanted length + + buf = malloc(file_size); + memset(buf, 0xff, file_size); + rewind(f); + + fread(buf, 1, file_size, f); + fclose(f); + + gen_check_sum(buf); + + f = fopen(argv[2], "wb"); + if (!f) { + perror("Open output file"); + exit(1); + } + fwrite(buf, 1, file_size, f); + fclose(f); + + return 0; +}