~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFerass El Hafidi <vitali64pmemail@protonmail.com>2023-05-08 19:03:10 +0200
committerFerass El Hafidi <vitali64pmemail@protonmail.com>2023-05-08 19:03:10 +0200
commitf9ed707f171c8069e99e24e24c3da73d8b6f5716 (patch)
tree4da9838d387c8bc260e83f3f51f5dfa83e0b48ae /common/fip.c
downloadamlogic-bl2-master.tar.gz
Push old Amlogic BL2 sourcesHEADmaster
Diffstat (limited to 'common/fip.c')
-rw-r--r--common/fip.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/common/fip.c b/common/fip.c
new file mode 100644
index 0000000..cdc579a
--- /dev/null
+++ b/common/fip.c
@@ -0,0 +1,248 @@
+
+/*
+ * arch/arm/cpu/armv8/common/firmware/common/fip.c
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <fip.h>
+#include <storage.h>
+#include <string.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stdio.h>
+#include <asm/arch/cpu_config.h>
+#include <storage.h>
+#include <sha2.h>
+#include <mailbox.h>
+#include <asm/arch/romboot.h>
+#include <cache.h>
+#include <fip.h>
+#include <asm/arch/watchdog.h>
+#include <timer.h>
+#include <io.h>
+
+static int aml_check(unsigned long pBufferSRC,unsigned long pBufferDST,unsigned int nLength,unsigned int nAESFlag);
+
+void bl2_load_image(void){
+ /* dump ddr data when function enabled and flag set */
+ dump_ddr_data();
+
+ //meminfo_t *bl2_tzram_layout;
+ bl31_params_t *bl2_to_bl31_params;
+ entry_point_info_t *bl31_ep_info;
+ //meminfo_t bl33_mem_info;
+ unsigned int * pCHK = (unsigned int *)FM_FIP_HEADER_LOAD_ADDR;
+ unsigned int nAESFlag = 1;
+ unsigned int nBL3XLoadAddr = readl(0xc8100228);
+ nBL3XLoadAddr = readl(0xc8100228);
+ int nSecFlag = nBL3XLoadAddr & (1<<4);
+ /*load fip header*/
+ aml_fip_header_t *fip_header;
+ fip_header = (aml_fip_header_t *)(uint64_t)FM_FIP_HEADER_LOAD_ADDR;
+#if defined(CONFIG_AML_SECURE_UBOOT)
+ extern void platform_stack_set_bl2 (unsigned long);
+ platform_stack_set_bl2(BL2_SEC_BOOT_SP_BASE);
+#endif
+ storage_load(BL2_SIZE, (uint64_t)fip_header, sizeof(aml_fip_header_t), "fip header");
+ memcpy((void*)FM_FIP_BL3X_TEMP_LOAD_ADDR,(void*)FM_FIP_HEADER_LOAD_ADDR,sizeof(aml_fip_header_t));
+ if (TOC_HEADER_NAME == *pCHK && TOC_HEADER_SERIAL_NUMBER == *(pCHK+1))
+ {
+ nAESFlag = 0;
+ }
+
+ aml_check(FM_FIP_BL3X_TEMP_LOAD_ADDR,FM_FIP_HEADER_LOAD_ADDR,sizeof(aml_fip_header_t),nAESFlag);
+
+ /*load and process bl30*/
+ image_info_t bl30_image_info;
+ entry_point_info_t bl30_ep_info;
+ nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL30_LOAD_ADDR;
+ storage_load(BL2_SIZE + (fip_header->bl30_entry.offset),nBL3XLoadAddr, (fip_header->bl30_entry.size), "bl30");
+ parse_blx(&bl30_image_info, &bl30_ep_info,nBL3XLoadAddr, FM_BL30_LOAD_ADDR, (fip_header->bl30_entry.size),nAESFlag);
+ /*process bl30*/
+ process_bl30x(&bl30_image_info, &bl30_ep_info, "bl30");
+
+#if (NEED_BL301)
+ /*load and process bl301*/
+ image_info_t bl301_image_info;
+ entry_point_info_t bl301_ep_info;
+ nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL301_LOAD_ADDR;
+ storage_load(BL2_SIZE + (fip_header->bl301_entry.offset),nBL3XLoadAddr, (fip_header->bl301_entry.size), "bl301");
+ parse_blx(&bl301_image_info, &bl301_ep_info, nBL3XLoadAddr ,FM_BL301_LOAD_ADDR, (fip_header->bl301_entry.size),nAESFlag);
+ /*process bl301*/
+ process_bl30x(&bl301_image_info, &bl301_ep_info, "bl301");
+#endif
+
+ /*load and process bl31*/
+ bl2_to_bl31_params = bl2_plat_get_bl31_params();
+ bl31_ep_info = bl2_plat_get_bl31_ep_info();
+ /* Set the X0 parameter to bl31 */
+ bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
+ nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL31_LOAD_ADDR;
+ storage_load(BL2_SIZE + (fip_header->bl31_entry.offset), nBL3XLoadAddr, (fip_header->bl31_entry.size), "bl31");
+ parse_blx(bl2_to_bl31_params->bl31_image_info, bl31_ep_info,nBL3XLoadAddr, FM_BL31_LOAD_ADDR, (fip_header->bl31_entry.size),nAESFlag);
+ bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, bl31_ep_info);
+
+#if (NEED_BL32)
+ /*
+ * Load the BL32 image if there's one. It is upto to platform
+ * to specify where BL32 should be loaded if it exists. It
+ * could create space in the secure sram or point to a
+ * completely different memory.
+ *
+ * If a platform does not want to attempt to load BL3-2 image
+ * it must leave NEED_BL32=0
+ */
+ meminfo_t bl32_mem_info;
+ bl2_plat_get_bl32_meminfo(&bl32_mem_info);
+ nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL32_LOAD_ADDR;
+ storage_load(BL2_SIZE + fip_header->bl32_entry.offset, nBL3XLoadAddr , fip_header->bl32_entry.size, "bl32");
+ parse_blx(bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info,
+ nBL3XLoadAddr, FM_BL32_LOAD_ADDR, fip_header->bl32_entry.size,nAESFlag);
+ bl2_plat_set_bl32_ep_info(bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info);
+#endif /* NEED_BL32 */
+
+ /*load and process bl33*/
+ nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL33_LOAD_ADDR;
+ storage_load(BL2_SIZE + fip_header->bl33_entry.offset,nBL3XLoadAddr, fip_header->bl33_entry.size, "bl33");
+ parse_blx(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info,
+ nBL3XLoadAddr, FM_BL33_LOAD_ADDR, fip_header->bl33_entry.size,nAESFlag);
+ //bl2_plat_get_bl33_meminfo(&bl33_mem_info);
+ bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info);
+
+ /* Flush the params to be passed to memory */
+ bl2_plat_flush_bl31_params();
+
+ /*disable mmu and dcache, flush dcache, then enter next firmware*/
+ disable_mmu_el1();
+ watchdog_disable();
+ /*
+ * Run BL31 via an SMC to BL1. Information on how to pass control to
+ * the BL32 (if present) and BL33 software images will be passed to
+ * BL31 as an argument.
+ */
+
+ smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
+
+/*
+ typedef unsigned long (*FUNC_TPL)(void );
+ unsigned long bl33_entry = FM_BL33_LOAD_ADDR;
+ serial_puts("bl33 entry: 0x");
+ serial_put_hex(bl33_entry, 32);
+ serial_puts("\n");
+ FUNC_TPL func_tpl=(FUNC_TPL)bl33_entry;
+ func_tpl();
+*/
+}
+
+static int aml_check(unsigned long pBufferSRC,unsigned long pBufferDST,unsigned int nLength,unsigned int nAESFlag)
+{
+ int nReturn = aml_data_check(pBufferSRC,pBufferDST,nLength,nAESFlag);
+ if (nReturn)
+ {
+ //printf("aml log : SIG CHK : %d for address 0x%08X\n",nReturn,pBufferSRC);
+ serial_puts("aml log : SIG CHK : ");
+ serial_put_dec(nReturn);
+ serial_puts(" for address 0x");
+ serial_put_hex(pBufferSRC, 32);
+ serial_puts("\n");
+ //while(1);
+ check_handler();
+ }
+
+ return nReturn;
+}
+
+/*blx header parse function*/
+void parse_blx(image_info_t *image_data,
+ entry_point_info_t *entry_point_info,
+ unsigned int src,
+ unsigned int dst,
+ unsigned int length,
+ unsigned int nAESFlag)
+{
+ image_data->image_base = dst;
+ image_data->image_size = length;
+ if (entry_point_info != NULL)
+ entry_point_info->pc = dst;
+
+ aml_check(src,dst,length,nAESFlag);
+}
+
+/*process bl30x, transfer to m3, etc..*/
+void process_bl30x(image_info_t *image_data,
+ entry_point_info_t *entry_point_info, const char * name)
+{
+ //serial_puts("start sha2\n");
+ uint8_t _sha2[32] = {0};
+ sha2((const uint8_t *)image_data->image_base,
+ image_data->image_size,
+ _sha2,
+ 0); /*0 means sha256, else means sha224*/
+
+#if 0
+ serial_puts(name);
+ serial_puts(" sha2:");
+ int print_loop = 0;
+ for (print_loop=0; print_loop<32; print_loop++) {
+ if (0 == (print_loop % 16))
+ serial_puts("\n");
+ serial_put_hex(_sha2[print_loop], 8);
+ serial_puts(" ");
+ }
+ serial_puts("\n");
+#endif
+
+ send_bl30x(image_data->image_base, image_data->image_size, \
+ _sha2, sizeof(_sha2), name);
+ return;
+}
+
+void bl2_to_romcode(uintptr_t entry)
+{
+ bl31_params_t *bl2_to_bl31_params;
+ entry_point_info_t *bl31_ep_info;
+
+ bl2_to_bl31_params = bl2_plat_get_bl31_params();
+ bl31_ep_info = bl2_plat_get_bl31_ep_info();
+ /* Set the X0 parameter to bl31 */
+ bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
+
+ bl31_ep_info->pc = entry;
+ SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+ bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_DBG_BIT));
+
+ watchdog_disable();
+ disable_mmu_el1();
+
+ bl31_ep_info->args.arg0 = 0;
+ smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
+}
+
+void check_handler(void) {
+ if (BOOT_DEVICE_USB == get_boot_device()) {
+ serial_puts("USB mode!\n");
+ bl2_to_romcode(USB_BL2_RETURN_ROM_ADDR);
+ }
+ else{
+ serial_puts("reset...\n");
+ reset_system();
+ }
+}