09-27-2012 08:53 PM
Hi,
Has anyone tried to use both cpu cores of zynq?
I did not find any example from Xilinx, only related information
in "Zynq-7000 EPP Technical Reference Manual UG585 (v1.2)".
It says that cpu0 must do these two things:
1. Write the address of the application for CPU1 to 0xFFFFFFF0.
2. Execute the SEV instruction to cause CPU1 to wake up and
jump to the application.
Found a "dual cpu demo" example on ARM web-site:
http://www.arm.com/files/pdf/ZC702_DS5_2.pdf
However, the attached source code doesn't do any of the
above two actions. How can the second cpu start then?
Regards,
Pramod Ranade
08-19-2014 11:54 AM
Thanks again, great gehar. This is useful.
1. I am using Vivado 2014.1 (or tried 2014.2 once). I had tried to build BSP for CPU1 by using the standalone_cpu1_v3_11_a/ that comes inside src/sdk_repo/bsp/ of XAPP1078. But Vivado SDK didn't like it. It said:
"Failed to create Board Support Package
Reason:
Error generating bsp sources. Please check the SDK.log for further details."
Of course, the SDK.log had no useful details to figure out why the BSP couldn't be generated. For my development, I used standalong_v4_9 from the XAPP_1079 updates that I got from wiki.xilinx.com.
2. Are you using Linux to start CPU1 or using JTAG to start CPU1?
3. Do you ever try with Vivado also?
4. Do you have a program to convert .ELF file to 32-bit binary writes for Linux to load CPU1 code directly to DDR? I don't need this now but will eventually want to have it, if possible. Rather than creating new BOOT.BIN file, copying to SD card and rebooting Linux.
08-20-2014 07:11 AM
I did get something working today by taking the standalone_v4_9 from XAPP1079 but changing the boot.S and asm_vectors.S to the one from standalone_amp_v3_09_a/.
I couldn't use the sdk_repo/bsp/ from XAPP1078 with Vivado but could use the one from XAPP1079_updates_for_vivado. This one however had "bad" boot and vector table. I eventually got some success.
My earlier questions to Great Gehar are still open but one more new question:
- when I start CPU1 with $ rwmem.elf 0xfffffff0 0x30000000, the CPU0 with Linux stalls for a few seconds. It comes back to life and after that all is normal and I can see heart beat incrementing every second but for the first 30-40 seconds it appears that Linux is hung.
Does anyone experience this? That starting CPU1 hangs/stalls CPU0 for close to a minute?
Best regards!
08-20-2014 08:46 AM
1. ...
2. I use Linux to start cpu1.
3. There are no. Today I install Vivado 2014.1. Tomorrow I will try compile cpu1 application.
4. In order to convert elf to bin image I use bootgen with -split option. Also it maybe use for prepare FPGA firmware before configure FPGA from Linux. When you have bin-image cpu1 application, you may copy it to memory from the Linux atphysical address specified in ps7_ddr_0_S_AXI_BASEADDR of lscript.ld.
My Linux don't hangs/stalls after start cpu1. CPU1 should not affect to Linux work
08-20-2014 10:56 AM
OK. This is useful information. I will try bootgen to get a binary image from ELF file so that I can download to DRAM directly from Linux.
I see that every time CPU1 starts via a write to 0xffffff0 the stall in CPU0 is for 106 seconds. Weird indeed. I am using Linux from Xilinx github. Kernel is 3.14.0-xilinx-dirty. I do have a Linaro desktop rootfs (not initram disk).
What Linux flavor do you use for CPU0? Kernel revision and with root filesystem or busybox? Thanks again.
08-29-2014 11:48 AM
I've posted an early access design using vivado and petalinux 2014.2. The current instructions ans scripts support zc702 and zc706
The download is available at http://www.wiki.xilinx.com/XAPP1078+Latest+Informa
08-29-2014 12:12 PM
hi johnmcd
thank you for the link, but i followed XAPP1078 and XAPP1079, in order to combine my application with another os on CPU1, but i can't found an instruction ?
also, there is the problem of using reposity , it change my project !!!
any idea
thank you
08-29-2014 02:09 PM
I'm unclear of what you are asking.
If you are refering to the BSP within sdk repository of the updated xapp1078 or the updated xapp1079?
There are a few differences between the two BSPs.
The BSP for xapp1078 has some adjustments for stdio and protection against re-initializing the global timer. The wfe loop is used for linux to start cpu1.
The only modification in the BSP for xapp1079 is to alter how the cpus startup after a reset. Therefore, cpu0 resets cpu1 in order to start it instead of using the wfe loop.
09-02-2014 01:52 PM
Thanks John.
I had a related question - for AMP usage with Linux + baremetal, do you have suggestions or pointers on enabling UART for CPU1 baremetal? I am thinking that softUART is a good initial step but not for application development.
1. Can we enable UART-0 for CPU1 (leave UART-1 with CPU0 Linux) via EMIO setup in PS? I was able to route the UART out to EMIO but I don't know where those lines go on the Zynq board and how to connect the Tx/Rx lines to a host RS-232.
2. Can we just mangle the two CPU to use the same UART and potentially get garbled output? I would then use ssh into CPU0 Linux and leave the UART for CPU1 baremetal exclusive use.
3. Can we have CPU0 not use UART and give it to CPU1 baremetal and use ssh exclusively for Linux?
Any pointers greatly appreciated. Thanks again
09-02-2014 03:18 PM
I also wanted to say that I tried to use the latest XAPP1078 with Vivado 2014.2 but the create_proj_706 failed for me towards the Export of project for SDK. The error reported is captured in JPG file attached. Any ideas what could be wrong? The bitstream was created.
The above issue isn't super important as I was able to take the modified sdk standalone_v4_199/ and shove it into an old project that I had and build a new BSP and app. This worked for me and CPU1 booted immediately without the long wait. It was indeed the change to the xtime_l.c where the timer was initialized by both CPU. Thanks a lot.
Now, I just want to understand the UART usage as per my previous post. How can I make use of "STDOUT_REDIR"? Basically, if I don't define it to 1, then what?
09-02-2014 03:44 PM
hi agaurav,
i suggest to return to 2013.4, i tested both 2014.1 and 2014.2 , but a lot of bug appear, so the only solution is to back to stable version, same thing with SDK
regard
09-03-2014 11:38 AM
It looks like this is a known issue and will be fixed in 2014.3 as per: http://forums.xilinx.com/xlnx/board/crawl_message?board.id=zaps&message.id=2878
So once the script finishes, close SDK, regenerate the output product of the IPI block. Next, select file->export to sdk (include bitstream) and finally select file->launch SDK.
09-03-2014 11:41 AM
Thanks John. I will try the 2014.3 as well as the workaround to launch XSDK separately after closing it once.
In the meantime - if you get a chance, can you look at my previous query in this thread about two UARTs and/or utilizing the STDOUT_REDIR that you added in the modified BSP? How can I enable a UART for CPU1 standalone/baremetal app?
09-03-2014 11:49 AM
09-03-2014 11:50 AM
gma-87: can you elaborate on the bugs you ran into?
09-04-2014 11:41 AM
Great Gehar and ehopkins,
I am trying to start CPU1 baremetal from CPU0 Linux. I can put CPU1 code in BOOT.BIN SD card and then do:
rwmem 0xfffffff0 0x30000000
and the CPU1 app starts. Good. Next, as a baby step, I try the following but it doesn't work for me. I reboot the Linux and then try to do the following
rwmem 0xF8000244 0x00000002
rwmem 0xF8000244 0x00000022
#/ will eventually add loading CPU1 code here but for now code is loaded at FSBL, u-boot time
rwmem 0xF8000244 0x00000020 <--- this is where the Linux becomes unstable and everything takes forever
rwmem 0xF8000244 0x00000000
rwmem 0xfffffff0 0x30000000
I basically wanted this as a test. Do I need to do something different for Zynq ZC706 board? Is the address of register wrong?
09-04-2014 05:34 PM
Umm. This is getting dangerous. It looks like you are trying to reset cpu1. That works for xapp1079 but will not work here because linux owns the reset vector.
In order to stay in the bounds of the wfe control, you would be better off sending a soft IRQ from cpu0 to cpu1. Then cpu1 would respond by jumping back to the wfe loop.
But, the best way to do this is use remoteproc. It is already available in the kernel. I've been told it is easy to use but I haven't had the time to dig into it. Take a look at ug978 (petalinux/freeRtos amp). Remoteproc allows you to run SMP, then remove cpu1 from linux and send it to your baremetal app. The wiki for 1078 updates touches on some of the code within Linux. What linux remoteproc does is temporarily replace the contents of the reset vector and then apply reset to cpu1.
09-05-2014 02:15 PM
Thanks John. These are good pointers and I will take a look and investigate. Best,
09-18-2014 02:53 AM
HI everybody,
can I issue a CPU0 reset (I successfully execute CPU1 reset) without rerunning FSBL?
09-18-2014 05:46 AM
hi,
if we don't use FSBL, no problem just sent program via JTAG or other serial interface
but to reset the CPU1, there is reset push bouton , the problem is the reset of secon CPU is managed by the first,
other solution is to use software code, when the watchdog timer can be set to reset the CPU1, but i doubt about reset of CPU1 without passig by CPU0 !!
thanks
09-18-2014 02:26 PM
Take a look at xapp1079. The latest 'earlyaccess' version issues a cpu1 reset from cpu0 and FSBL is used to load the app for both cpu0 and cpu1.
The earlyaccess version is available at the bottom of the page here: http://www.wiki.xilinx.com/XAPP1079+Latest+Information
There is a doc/instructions.txt that walk through building and running the design.
03-05-2015 08:52 AM
You can see xapp1079. Explanation of interwork of both cores showed in details.
03-05-2015 09:04 AM
hi nagand,
yes, it's a good support, but is still search why Xilinx, provide this solution, where reposity is an obligation, i remember when i tryied to ue this solution, it's create problem on my project, whitch mean, we need to follow some instruction, ever re-write our code
thanks
05-14-2015 09:53 AM
Hi. I try to setup my system with HDMI and CPU1 for baremetal app on ZedBoard. I try example from wiki and its worked smoothly. Then I took Analog Devices video subsystem and 1078 example and compile it together. I can see that application on CPU1 worked fine exept it cannot receive interrupt. I double checked BlockDesign and I can not find any mistake. Do I need to configure linux kernel to enable private interrupts or I should do something else for it?
//Vivado 2014.4
07-30-2015 07:25 PM
1079 is broken in Vivado 2015.*
Also appears to be broken in versions of 2014 later than 2014.2.
Has anyone had any success getting baremetal AMP support going in these versions of the tools?
07-31-2015 01:50 PM
You can find a version for 2015.2 at the bottom of http://www.wiki.xilinx.com/XAPP1079+Latest+Information
02-07-2016 12:38 AM
Hi,
I'm having te same issue. did you fina a solution?
thanks,
Danna
02-07-2016 04:53 AM
Hello,
you can check the following projects :
xapp1079-amp-bare-metal-cortex-a9.pdf
application_notes/xapp1078-amp-linux-bare-metal.pdf
02-07-2016 05:31 PM
03-23-2017 01:11 AM
Hello,
i use the xapp1078 running petalinux on core0 and baremetal on core1, and it works. I changed the design like in the picture. I added a irq_gen1 on addr 0x78700000 which is connected to core1_nFIQ. irq_gen0 on addr 0x78600000 which is still connected to core1_nIRQ.
Therefore, my SetupIntrSystem() routine is the following:
static int SetupIntrSystem( INTC *IntcInstancePtr, XPlIrq *PeriphInstancePtr, u16 IntrId, XPlIrq *PeriphInstancePtr2, u16 IntrId2) { int Status; XScuGic_Config *IntcConfig; /* * Initialize the interrupt controller driver so that it is ready to * use. */ IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); if (NULL == IntcConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the interrupt handler that will be called when an * interrupt occurs for the device. */ Status = XScuGic_Connect(IntcInstancePtr, IntrId, (Xil_ExceptionHandler)PlIntrHandler, PeriphInstancePtr); if (Status != XST_SUCCESS) { xil_printf("ERROR1"); return Status; } Status = XScuGic_Connect(IntcInstancePtr, IntrId2, (Xil_ExceptionHandler)PlIntrHandler2, PeriphInstancePtr2); if (Status != XST_SUCCESS) { xil_printf("ERROR2"); return Status; } /* * Enable the interrupt for the PL device. */ XScuGic_Enable(IntcInstancePtr, IntrId); XScuGic_Enable(IntcInstancePtr, IntrId2); /* * Initialize the exception table */ Xil_ExceptionInit(); /* * Register the interrupt controller handler with the exception table */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstancePtr); /* * Register the interrupt controller handler with the exception table */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_FIQ_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstancePtr); /* * Enable non-critical exceptions */ //Xil_ExceptionEnable(); Xil_ExceptionEnableMask(XIL_EXCEPTION_ALL); return XST_SUCCESS; }
when I start this application, i need to set BOTH irq_gen with this command (the order is unimportant):
poke 0x78600000 0x00000001
poke 0x78700000 0x00000001
the ISR of core1_nIRQ will be executed. Never core1_nFIQ! At addr 0x78600000 there is a 0x00000000 and at 0x78700000 still 0x00000001.
what is my problem? i can't find it....
Thanks!
03-27-2017 08:27 PM
Hellow, julian.bauer.
Try delete:
Status = XScuGic_Connect(IntcInstancePtr, IntrId2, (Xil_ExceptionHandler)PlIntrHandler2, PeriphInstancePtr2); if (Status != XST_SUCCESS) { xil_printf("ERROR2"); return Status; } XScuGic_Enable(IntcInstancePtr, IntrId2);
and use:
/* * Register the interrupt controller handler with the exception table */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_FIQ_INT, (Xil_ExceptionHandler)PlIntrHandler2, IntcInstancePtr);