blob: deae3239805edef31545de3e6da55e1989464897 [file] [log] [blame]
#include "string.h"
#include "debug.h"
#include "util.h"
#include "flash_adaptor.h"
#include "load_gih.h"
#include "apb_watchdog.h"
#include "img_layout.h"
#include "image_chunk.h"
#define BOOT_PARTITION_SIZE (512 * 1024) // 512KB
void dump_chunk_param(struct chunk_param chunk)
{
INFO("%c%c%c%c: offset = 0x%08x, size = 0x%08x, dest_start = 0x%016llx, \
dest_size = 0x%08x, attr0 = 0x%08x, attr1 = 0x%08x\n", (char)chunk.id,
(char)(chunk.id >> 8), (char)(chunk.id >> 16), (char)(chunk.id >> 24), chunk.offset,
chunk.size, chunk.dest_start, chunk.dest_size, chunk.attr0, chunk.attr1);
}
//the whole GIH image size = the offset of the last chunk + the size of the last chunk
unsigned int get_image_size_from_GIH(struct image_header * buff)
{
int num = buff->chunk_num;
unsigned int size = 0;
size = buff->chunk[num - 1].offset + buff->chunk[num - 1].size;
return size;
}
// only for the images in bootloader.subimg which the GIH header and images list are separated.
int read_image_from_GIH(int part, struct image_header * gih, unsigned int id, unsigned char* buff)
{
long long ret = 0;
int chunk_id = 0;
int part_addr = 0;
unsigned int offset = 0, size = 0;
DBG("flash: read image from boot partition %d.\n", part);
chunk_id = find_chunk(id, gih);
if(chunk_id >= 0) {
offset = gih->chunk[chunk_id].offset + IMG_HEADER_ADDR;
size = gih->chunk[chunk_id].size;
} else {
ERR("Didn't find %c%c%c%c.\n", (char)id,
(char)(id >> 8), (char)(id >> 16), (char)(id >> 24));
//FIXME:
//reset_soc();
while(1);;
}
//switch to specific part
part_addr = switch_flash_part(part);
if(part_addr < 0) {
ERR("flash: error when switch to boot partion %d(err = %d).\n", part, part_addr);
return FLASH_OP_ERR;
}
// the image should be in the range of boot partition
// for u-boot, there should no this limitation
#ifndef CONFIG_UBOOT
if((offset + size) > BOOT_PARTITION_SIZE) {
ERR("flash: the image is exceed the boot partition\n");
//FIXME:
//reset_soc();
while(1);
}
#endif
ret = read_flash((part_addr + offset), size, buff);
if(ret){
ERR("flash: read image %c%c%c%c error.\n",
(char)id, (char)(id >> 8), (char)(id >> 16), (char)(id >> 24));
dump_chunk_param(gih->chunk[chunk_id]);
return FLASH_OP_ERR;
}
//switch back to user area
part_addr = switch_flash_part(0);
if(part_addr < 0) {
ERR("flash: error when switch to boot partion %d(err = %d).\n", part, part_addr);
return FLASH_OP_ERR;
}
return 0;
}
int find_chunk(unsigned int id, struct image_header * buff)
{
int num = buff->chunk_num;
int i = 0;
for(i = 0; i < num; i++) {
if(id == buff->chunk[i].id) {
//dump_chunk_param((buff->chunk[i]));
return i;
}
}
return CHUNK_NON_EXIST;
}