diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c index db746bb..438c70c 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c @@ -66,6 +66,26 @@ BUG_ON(ret); } +/* + * Power-on execution flow of start_nxp_imx8mq_evk() might not be + * obvious for a very first read, so here's, hopefully helpful, + * summary: + * + * 1. MaskROM uploads PBL into OCRAM and that's where this function is + * executed for the first time + * + * 2. DDR is initialized and full i.MX image is loaded to the + * beginning of RAM + * + * 3. start_nxp_imx8mq_evk, now in RAM, is executed again + * + * 4. BL31 blob is uploaded to OCRAM and the control is transfer to it + * + * 5. BL31 exits EL3 into EL2 at address MX8MQ_ATF_BL33_BASE_ADDR, + * executing start_nxp_imx8mq_evk() the third time + * + * 6. Standard barebox boot flow continues + */ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) { arm_cpu_lowlevel_init(); @@ -73,9 +93,23 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) + if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) { + /* + * We assume that we were just loaded by MaskROM into + * SRAM if we are not running from DDR. We also assume + * that means DDR needs to be initialized for the + * first time. + */ nxp_imx8mq_evk_sram_setup(); - + } + /* + * Straight from the power-on we are at EL3, so the following + * code _will_ load and jump to ATF. + * + * However when we are re-executed upon exit from ATF's + * initialization routine, it is EL2 which means we'll skip + * loadting ATF blob again + */ if (current_el() == 3) { const u8 *bl31; size_t bl31_size; @@ -84,6 +118,9 @@ imx8mq_atf_load_bl31(bl31, bl31_size); } + /* + * Standard entry we hit once we initialized both DDR and ATF + */ barebox_arm_entry(MX8MQ_DDR_CSD1_BASE_ADDR, SZ_2G + SZ_1G, __dtb_imx8mq_evk_start); }