2020#include <fsl_flexspi_nor_boot.h>
2121#endif
2222#include <zephyr/dt-bindings/clock/imx_ccm_rev2.h>
23+ #if defined(CONFIG_SECOND_CORE_MCUX ) && defined(CONFIG_CPU_CORTEX_M7 )
24+ #include <zephyr_image_info.h>
25+ /* Memcpy macro to copy segments from secondary core image stored in flash
26+ * to RAM section that secondary core boots from.
27+ * n is the segment number, as defined in zephyr_image_info.h
28+ */
29+ #define MEMCPY_SEGMENT (n , _ ) \
30+ memcpy((uint32_t *)((SEGMENT_LMA_ADDRESS_ ## n) - ADJUSTED_LMA), \
31+ (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \
32+ (SEGMENT_SIZE_ ## n))
33+ #endif
2334#if CONFIG_USB_DC_NXP_EHCI
2435#include "usb_phy.h"
2536#include "usb.h"
@@ -596,6 +607,7 @@ void imxrt_post_init_display_interface(void)
596607 *
597608 * Initialize the interrupt controller device drivers.
598609 * Also initialize the timer device driver, if required.
610+ * If dual core operation is enabled, the second core image will be loaded to RAM
599611 *
600612 * @return 0
601613 */
@@ -614,6 +626,24 @@ static int imxrt_init(const struct device *arg)
614626 SysTick -> CTRL &= ~SysTick_CTRL_ENABLE_Msk ;
615627 }
616628
629+ #if defined(CONFIG_SECOND_CORE_MCUX ) && defined(CONFIG_CPU_CORTEX_M7 )
630+ /**
631+ * Copy CM4 core from flash to memory. Note that depending on where the
632+ * user decided to store CM4 code, this is likely going to read from the
633+ * flexspi while using XIP. Provided we DO NOT WRITE TO THE FLEXSPI,
634+ * this operation is safe.
635+ *
636+ * Note that this copy MUST occur before enabling the M7 caching to
637+ * ensure the data is written directly to RAM (since the M4 core will use it)
638+ */
639+ LISTIFY (SEGMENT_NUM , MEMCPY_SEGMENT , (;));
640+ /* Set the boot address for the second core */
641+ uint32_t boot_address = (uint32_t )(DT_REG_ADDR (DT_CHOSEN (zephyr_cpu1_region )));
642+ /* Set VTOR for the CM4 core */
643+ IOMUXC_LPSR_GPR -> GPR0 = IOMUXC_LPSR_GPR_GPR0_CM4_INIT_VTOR_LOW (boot_address >> 3u );
644+ IOMUXC_LPSR_GPR -> GPR1 = IOMUXC_LPSR_GPR_GPR1_CM4_INIT_VTOR_HIGH (boot_address >> 16u );
645+ #endif
646+
617647#if defined(CONFIG_SOC_MIMXRT1176_CM7 ) || defined(CONFIG_SOC_MIMXRT1166_CM7 )
618648 if (SCB_CCR_IC_Msk != (SCB_CCR_IC_Msk & SCB -> CCR )) {
619649 SCB_EnableICache ();
@@ -687,3 +717,24 @@ void z_arm_platform_init(void)
687717#endif
688718
689719SYS_INIT (imxrt_init , PRE_KERNEL_1 , 0 );
720+
721+ #if defined(CONFIG_SECOND_CORE_MCUX ) && defined(CONFIG_CPU_CORTEX_M7 )
722+ /**
723+ * @brief Kickoff secondary core.
724+ *
725+ * Kick the secondary core out of reset. The
726+ * core image was already copied to RAM (and the boot address was set) in
727+ * imxrt_init()
728+ *
729+ * @return 0
730+ */
731+ static int second_core_boot (const struct device * arg )
732+ {
733+ /* Kick CM4 core out of reset */
734+ SRC -> CTRL_M4CORE = SRC_CTRL_M4CORE_SW_RESET_MASK ;
735+ SRC -> SCR |= SRC_SCR_BT_RELEASE_M4_MASK ;
736+ return 0 ;
737+ }
738+
739+ SYS_INIT (second_core_boot , PRE_KERNEL_2 , CONFIG_KERNEL_INIT_PRIORITY_DEFAULT );
740+ #endif
0 commit comments