Core 1 Fails to Execute from QSPI Flash with Incorrect Program Counter Jump
When attempting to run bare-metal code on both cores of an ARM Cortex-A9 dual-core processor within an Intel Cyclone V SoC, Core 0 executes successfully from QSPI flash, while Core 1 fails to start correctly. Instead of jumping to its designated entry point at 0x9FFF0, Core 1’s program counter jumps to an unexpected address, 0xFEBAF5E8. This issue does not occur when debugging via JTAG, where both cores can be brought up sequentially. The problem manifests specifically when booting from QSPI flash, suggesting a misconfiguration in the boot process, memory mapping, or core synchronization.
The Cyclone V SoC’s ARM Cortex-A9 dual-core architecture requires careful handling of the boot sequence, memory initialization, and core synchronization to ensure both cores start executing their respective code. The discrepancy between JTAG and QSPI boot modes indicates a potential issue with the bootloader, memory mapping, or core initialization logic. Specifically, the unexpected program counter jump on Core 1 suggests that the secondary core is not being properly taken out of reset or is not receiving the correct start address.
Misconfigured Bootloader, Memory Mapping, or Core Synchronization
The root cause of Core 1 failing to execute from QSPI flash likely stems from one or more of the following issues: misconfigured bootloader settings, incorrect memory mapping, improper core synchronization, or insufficient cache and memory barrier handling. Each of these factors plays a critical role in ensuring that both cores start executing their respective code correctly.
The bootloader is responsible for initializing the system, loading the application code into memory, and starting the cores. In this case, the bootloader appears to be correctly loading the code for both cores into QSPI flash, as evidenced by Core 0 executing successfully. However, Core 1’s failure to jump to its designated entry point suggests that the bootloader may not be correctly passing the start address to Core 1 or that Core 1 is not being properly taken out of reset.
Memory mapping is another critical factor. The Cyclone V SoC uses a complex memory hierarchy, including QSPI flash, DDR3 memory, and on-chip RAM. The linker/scat file specifies the entry points for Core 0 and Core 1 as 0x60000 and 0x9FFF0, respectively. However, if the memory mapping is not correctly configured, Core 1 may not be able to access its code in QSPI flash or DDR3 memory. This could result in the program counter jumping to an unexpected address.
Core synchronization is also essential in a multi-core system. The ARM Cortex-A9 architecture includes mechanisms for core synchronization, such as the smp
and fw
bits in the auxiliary control register. These bits must be set correctly to ensure that both cores start executing in a coordinated manner. If these bits are not set correctly, Core 1 may not start executing its code, or it may start executing from an incorrect address.
Finally, cache and memory barrier handling can also impact the boot process. The ARM Cortex-A9 includes a cache coherency mechanism that ensures both cores see a consistent view of memory. If the cache is not properly invalidated or if memory barriers are not used correctly, Core 1 may not see the correct code in memory, leading to the program counter jumping to an unexpected address.
Verifying Bootloader Configuration, Memory Mapping, and Core Initialization
To resolve the issue of Core 1 failing to execute from QSPI flash, the following troubleshooting steps should be taken:
-
Verify Bootloader Configuration: Ensure that the bootloader is correctly configured to load the code for both cores into QSPI flash and pass the correct start addresses to each core. The bootloader should also take Core 1 out of reset and set the
cpu1startaddress
register to the correct value (0x100000 in this case). Check the bootloader logs to confirm that both cores are being initialized correctly. -
Check Memory Mapping: Verify that the memory mapping is correctly configured to allow both cores to access their respective code in QSPI flash and DDR3 memory. The linker/scat file should specify the correct entry points for Core 0 and Core 1, and the memory map should be consistent with the hardware configuration. Use a memory map tool or debugger to inspect the memory map and ensure that Core 1’s code is located at the correct address.
-
Inspect Core Synchronization Settings: Ensure that the
smp
andfw
bits in the auxiliary control register are set correctly to enable symmetric multiprocessing and firmware-controlled core startup. These bits should be set before Core 1 is taken out of reset. Use a debugger to inspect the auxiliary control register and confirm that these bits are set correctly. -
Validate Cache and Memory Barrier Handling: Ensure that the cache is properly invalidated and that memory barriers are used correctly to ensure that both cores see a consistent view of memory. The ARM Cortex-A9 architecture includes cache coherency mechanisms that must be properly configured to ensure that Core 1 sees the correct code in memory. Use cache management instructions such as
DCISW
(Data Cache Invalidate by Set/Way) and memory barrier instructions such asDSB
(Data Synchronization Barrier) to ensure cache coherency. -
Debug Core 1 Startup: Use a debugger to step through the Core 1 startup sequence and identify where the program counter jumps to the unexpected address. Inspect the registers, memory, and stack to identify any discrepancies. Pay particular attention to the reset vector, the start address passed to Core 1, and the state of the auxiliary control register.
-
Compare JTAG and QSPI Boot Modes: Compare the behavior of the system when booting via JTAG and QSPI flash to identify any differences in the boot process. Use a debugger to inspect the state of the system in both boot modes and identify any discrepancies in the bootloader, memory mapping, or core synchronization settings.
-
Review Cyclone V SoC Documentation: Review the Cyclone V SoC technical reference manual and ARM Cortex-A9 documentation to ensure that all configuration settings are correct. Pay particular attention to the sections on bootloader configuration, memory mapping, core synchronization, and cache coherency.
By following these troubleshooting steps, the issue of Core 1 failing to execute from QSPI flash can be resolved, ensuring that both cores start executing their respective code correctly in bare-metal mode.