[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/boot/common/src/loader/drivers/image.c b/boot/common/src/loader/drivers/image.c
new file mode 100755
index 0000000..8903e14
--- /dev/null
+++ b/boot/common/src/loader/drivers/image.c
@@ -0,0 +1,351 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include <image.h>
+#include <linux/byteorder/generic.h>
+#include <secure_verify.h>
+
+#include "flash.h"
+#include <bbt.h>
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+uint32_t page_align(uint32_t offset)
+{
+ uint32_t page_size = flash.page_size;
+ if(offset & (page_size - 1))
+ {
+ offset &= (~(page_size - 1));
+ offset += page_size;
+ }
+ return offset;
+}
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+uint32_t find_partition_para(partition_entry_t *entry,
+ uint32_t entrys,
+ uint8_t *name)
+{
+ partition_entry_t *p_entry = entry;
+ uint32_t entry_nums = entrys;
+ while(entry_nums--)
+ {
+ if(memcmp( p_entry->part_name, name, strlen(name)) == 0)
+ return p_entry->part_offset;
+ p_entry++;
+ }
+ return -1;
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int read_image_part_offset(uint8_t *name, uint32_t *offset)
+{
+ int ret = 0;
+ uint32_t part_size = 0;
+
+ if(flash.flash_type == NOR_BOOT)
+ {
+ part_size = 8*flash.page_size;
+ }
+ else
+ {
+ part_size = flash.page_size;
+ }
+
+ ret = flash.read(0x2000, part_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ partition_table_t *part = (partition_table_t *)CFG_TEMP_ADDR;
+ partition_entry_t *entry = &part->table[0];
+ uint32_t entrys = part->entrys;
+
+ if(part->magic != CFG_PARTITION_MAGIC)
+ {
+ return -1;
+ }
+
+ *offset = find_partition_para(entry, entrys, name);
+ if(*offset == -1 )
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+int read_flags_image(uint8_t *name)
+{
+ T_BOOT_FOTA_FLAG *fotaFlag;
+ uint32_t uiPageSize = 0;
+ uint32_t flags_offset = 0;
+ uint32_t off = 0;
+ uint32_t flags_size = 0x4E0000;/*flags·ÖÇø*/
+ uint32_t blockNum = 0;
+ int32_t flag_one = 0;
+ uint32_t work_area_offset = 0;
+ uint32_t backup_area_offset = 0;
+ int32_t ret = 0;
+ int32_t fota_size = sizeof(T_BOOT_FOTA_FLAG);
+ int32_t block_size = flash.block_size;
+
+ fota_size = page_align(fota_size);
+
+ ret = read_image_part_offset(name, &flags_offset);
+ if(ret != 0)
+ {
+ printf("flags partition offset fail.\n");
+ return -1;
+ }
+
+ /*È·¶¨¹¤×÷ÇøºÍ±¸·ÝÇøÆ«ÒÆµØÖ·*/
+ for (off = flags_offset; off < flags_offset+flags_size; off += flash.block_size)
+ {
+ if (!(nand_block_isbad(off)))
+ {
+ blockNum += 1;
+ }
+
+ if((blockNum == 1) && (flag_one == 0))
+ {
+ work_area_offset = off;
+ flag_one = 1;
+ }
+
+ else if(blockNum == 2)
+ {
+ backup_area_offset = off;
+ break;
+ }
+ }
+
+ if(blockNum < 2)
+ {
+ printf("flags partition have not enough space!\n");
+
+ return -1;
+ }
+
+ ret = flash.read(work_area_offset, fota_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("read flags work partition err.\n");
+
+ return -1;
+ }
+
+ fotaFlag = (T_BOOT_FOTA_FLAG *)(CFG_TEMP_ADDR);
+
+ if(fotaFlag->magic != FLAGS_MAGIC)
+ {
+ ret = flash.read(backup_area_offset, fota_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("read flags backup partition err.\n");
+
+ return -1;
+ }
+ fotaFlag = (T_BOOT_FOTA_FLAG *)(CFG_TEMP_ADDR);
+ if(fotaFlag->magic != FLAGS_MAGIC)
+ {
+ printf("flags magic err.\n");
+ return -1;
+ }
+ }
+
+ return 0;
+
+}
+#endif
+/*
+ ****************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *****************************************************************************
+ */
+int read_uboot_image(uint8_t *name, uint32_t *uboot_entry_point)
+{
+ /*
+ * +----------------------------------------------------------------+
+ * | sImageHeader | image_header_t | u-boot.bin |
+ * +----------------------------------------------------------------+
+ * | 384 Bytes | 64 Bytes | xxx Bytes |
+ *
+ */
+
+ image_header_t *psImgHdrOld = NULL;
+
+ uint32_t uiPageSize = 0;
+
+ uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
+ uint32_t uiImgHdrSizeNew = sizeof(sImageHeader);
+
+ uint32_t uiUBootSize = 0;
+ uint32_t uiUBootLoadAddr = 0;
+ uint32_t uiUBootIsReadSize = 0;
+
+ int32_t ret = 0;
+ uint32_t uboot_offset = 0;
+
+
+
+ if(flash.flash_type == NOR_BOOT)
+ {
+ uiPageSize = 8*flash.page_size;
+ }
+ else
+ {
+ uiPageSize = flash.page_size;
+ }
+
+ ret = read_image_part_offset(name, &uboot_offset);
+ if(ret != 0)
+ {
+ printf("offset fail.\n");
+ return -1;
+ }
+
+ ret = flash.read(uboot_offset, uiPageSize, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("image header err.\n");
+ return -1;
+ }
+
+ psImgHdrOld = (image_header_t *)(CFG_TEMP_ADDR + uiImgHdrSizeNew);
+ uiUBootSize = ___htonl(psImgHdrOld->ih_size);
+ uiUBootLoadAddr = ___htonl(psImgHdrOld->ih_load);
+ *uboot_entry_point = ___htonl(psImgHdrOld->ih_ep);
+
+ if(___htonl(psImgHdrOld->ih_magic) != IH_MAGIC)
+ {
+ printf("magic err.\n");
+ return -1;
+ }
+
+ uiUBootIsReadSize = uiPageSize - uiImgHdrSizeOld - uiImgHdrSizeNew;
+ uiUBootSize -= uiUBootIsReadSize;
+ uiUBootSize = page_align(uiUBootSize);
+
+ memcpy(uiUBootLoadAddr - uiImgHdrSizeOld,
+ CFG_TEMP_ADDR + uiImgHdrSizeNew,
+ uiUBootIsReadSize + uiImgHdrSizeOld);
+
+ ret = flash.read(uboot_offset + uiPageSize,
+ uiUBootSize,
+ uiUBootLoadAddr + uiUBootIsReadSize);
+ if(ret != 0)
+ {
+ printf("image err.\n");
+ return -1;
+ }
+
+ ret = SecureVerify(CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("Secure verify fail!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ int nand_read_m0(uint32_t *m0_entry_point)
+{
+ int remap = 0;
+ image_header_t *header = NULL;
+ uint32_t image_header_size = sizeof(image_header_t);
+ uint32_t m0_size = 0;
+ uint32_t m0_load_addr = 0;
+ /*
+ * +---------------------------------------------------------+
+ * | image_header_t | m0 |
+ * +---------------------------------------------------------+
+ m0.bin
+ */
+
+ /*1¡¢µÈ´ýBOOT°áÔËM0°æ±¾µ½CONFIG_SYS_SDRAM_TEMP_BASEÖÐ*/
+ writel(0, M0_IMAGE_READY_FLAG_ADDR);
+ while(!readl(M0_IMAGE_READY_FLAG_ADDR));
+
+ /*2¡¢M0µÄ0µØÖ·ÖØÓ³Éä*/
+ remap = readl(0x140000);
+ remap |= 0x800000;
+ writel(remap,0x140000);
+
+ /*3¡¢½âÎöM0µÄ°æ±¾Í·£¬»ñÈ¡ÔËÐеØÖ·ÒÔ¼°´óС*/
+ header = (image_header_t *)CONFIG_SYS_SDRAM_TEMP_BASE;
+ m0_size = ___htonl(header->ih_size); /* m0.bin */
+ m0_load_addr = ___htonl(header->ih_load);
+ *m0_entry_point = ___htonl(header->ih_ep);
+
+ if(___htonl(header->ih_magic) != IH_MAGIC)
+ {
+ return -1;
+ }
+
+ /*4¡¢½«M0µÄ°æ±¾´ÓIRAM0¿½±´µ½load_addr*/
+ memcpy(m0_load_addr, CONFIG_SYS_SDRAM_TEMP_BASE + image_header_size, m0_size);
+
+ /*5¡¢ÐÞ¸ÄIRAM±ê¼Ç£¬Ê¹BOOT¼ÌÐøÍùÏÂÖ´ÐÐ*/
+ writel(0, M0_IMAGE_READY_FLAG_ADDR);
+
+ return 0;
+}
+
+