We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Showing results for 
Search instead for 
Did you mean: 
Registered: ‎08-09-2018

Zynq AMP example do not start CPU1 applicataion when linker script modified

Hello everyone,


I am trying to design AMP system in which CPU0 application will use the most of the 1 GB DDR and CPU1 application will use approximately 128 MB. 


I am working with Vivado 2014.4  using a dedicated board with Zynq, with dual parallel flash. What I want to do is, creating a boot.mcs file and program QSPI, which my project will boot from QSPI. My both applications will be baremetal.


So, I followed the XAPP1079 instructions with the updated files for Vivado 14.2. 


Here is the interesting error that I faced.


When I use default settings of lscript.ld for CPU0 and CPU1 application ( For CPU0; Base Address: 0x01000000, Length:0x01000000, For CPU1; Base Address: 0x02000000, Length 0x01000000) example design works well. 


But when I changed the lscript.ld as CPU0 Base Address: 0x00100000, Length: 0x38000000 and CPU1 Base Address : 0x38100000 and Length: 0x01000000, (I also modified the app_cpu0.c file for CPU1 start address as 0x38100000) only CPU0 application is started and CPU1 application won't start.


Please also note that I try two starting sequence of CPU1 from CPU0 application which is as belows;



print("CPU0: writing startaddress for cpu1\n\r");

* Reset and start CPU1
* - Application for cpu1 exists at 0x00000000 per cpu1 linkerscript
#include "xil_misc_psreset_api.h"
#include "xil_io.h"

#define A9_CPU_RST_CTRL (XSLCR_BASEADDR + 0x244)
#define A9_RST1_MASK 0x00000002
#define A9_CLKSTOP1_MASK 0x00000020
#define CPU1_CATCH 0x00000024

#define XSLCR_LOCK_CODE 0x0000767B

u32 RegVal;

* Setup cpu1 catch address with starting address of app_cpu1. The FSBL initialized the vector table at 0x00000000
* using a boot.S that checks for cpu number and jumps to the address stored at the
* end of the vector table in cpu0_catch and cpu1_catch entries.
* Note: Cache has been disabled at the beginning of main(). Otherwise
* a cache flush would have to be issued after this write

/* Unlock the slcr register access lock */

// the user must stop the associated clock, de-assert the reset, and then restart the clock. During a
// system or POR reset, hardware automatically takes care of this. Therefore, a CPU cannot run the code
// that applies the software reset to itself. This reset needs to be applied by the other CPU or through
// JTAG or PL. Assuming the user wants to reset CPU1, the user must to set the following fields in the
// slcr.A9_CPU_RST_CTRL (address 0xF8000244) register in the order listed:
// 1. A9_RST1 = 1 to assert reset to CPU0
// 2. A9_CLKSTOP1 = 1 to stop clock to CPU0
// 3. A9_RST1 = 0 to release reset to CPU0
// 4. A9_CLKSTOP1 = 0 to restart clock to CPU0

/* Assert and deassert cpu1 reset and clkstop using above sequence*/
RegVal = Xil_In32(A9_CPU_RST_CTRL);
RegVal |= A9_RST1_MASK;
Xil_Out32(A9_CPU_RST_CTRL, RegVal);
Xil_Out32(A9_CPU_RST_CTRL, RegVal);
RegVal &= ~A9_RST1_MASK;
Xil_Out32(A9_CPU_RST_CTRL, RegVal);
RegVal &= ~A9_CLKSTOP1_MASK;
Xil_Out32(A9_CPU_RST_CTRL, RegVal);

/* lock the slcr register access */



xil_printf("CPU0: writing startaddress for cpu1\n\r");
Xil_Out32(CPU1STARTADR, 0x38100000);
dmb(); //waits until write has finished

xil_printf("CPU0: sending the SEV to wake up CPU1\n\r");


These starting sequences both start the CPU1 application when I use default lscripts.ld files but won't start CPU1 application when I modify lscript.ld files.


Why this problem is occured and how I get rid of this? Intuitively I guess I should change the boot.S or vector table but I could not find a solution.


Thank you,


0 Kudos
1 Reply
Xilinx Employee
Xilinx Employee
Registered: ‎02-01-2008

Re: Zynq AMP example do not start CPU1 applicataion when linker script modified

There should be no requirement for cpu0 to send sev at the end of sequence 2. But that shouldn't matter.


As soon as the clk is started for cpu1, cpu1 should start executing code at 0x00000000. This address should jump to the entry of boot.s from the FSBL, and this code should detect what cpu it is running on, then jump to the address that is stored at the end of the vector table of FSBL, address 0x00000024. You initialize that address with APP_CPU1_ADDR which I don't see defined but presume it is 0x38100000.


And at 0x38100000 you should see your vector table with a branch to _boot: in your app's boot.S.


I don't know where you are writing in sequence 2 this line:

Xil_Out32(CPU1STARTADR, 0x38100000);


Since your are using 2014.4, check your cpu1 BSP boot.s contents. There use to be a time when USE_AMP would enable a virtual address map of some ddr address range to 0x00000000 as non-cached. I just don't recall if this virtual map was still in 2014.4 boot.S.

0 Kudos