UPGRADE YOUR BROWSER

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!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
5,754 Views
Registered: ‎05-12-2011

How To - Zynq SMP Bare Metal

Jump to solution

Hiya.  So I've seen the thread on using both cores and the tidbit in UG585 about firing off core 1, and I'm still not sure about the best way to proceed.

 

I have a ZC702 and a Zedboard, and have created a single core bare metal application for learning purposes at this point.  What I'd like to do, is fire up the second core after I'm done with whatever application setup I want done in main() running on core 0, and have core 1 run a dedicated function that's part of the one application.  Ultimately I'd like to end up with something like StartCore1( MyFuncPtr, MyVoidArgPtr ),  Rather similar to firing off a second thread with pthreads, the hard way.

 

The other folks I've seen reference this topic appear to be looking to have one elf file loaded for core 0 and a separate elf file loaded for core 1, whereas I want a more SMP approach where everything is one combined application and I serialize access to critical sections as part of the application design.  I'm looking for some guidance on the best way to accomplish this without going completely against the grain of the "standard" development flow.

 

I'm thinking about cannibalizing boot.S into boot1.S and launching the second core at it, eventually transferring control to the desired target function instead of _start.  However since the whole Zynq thing is still relatively new, if there's a more standardized way of doing something like that coming down the pipe some time in the near future, I don't want to put a bunch of effort into something that's decidedly against the grain so to speak.  I'm familiar with bringing up multiple cores from the overly large corporation that begins with an 'I' complete with the multiple different stacks required and the page tables and so on.  Am I best off diving into the ARM architecture and doing something similar on my own?  I realize there's no substitute for in-depth knowledge, but I was kind of hoping for a point-and-click solution after seeing the considerable effort put into the Xilinx development tools.

 

If I'm best off winging it on my own, any suggestions on things to do or things not to do would be appreciated.  For the record I'm not concerned about officially supported methodolgies, so if someone has already come up with a way to do this that they're willing to share I promise not to pretend that whatever I wreck from there on out is anything but my own fault.  If I end up having to change things around later to better fit the official design flows it's not the end of the world.

 

Thanks for listening.

 

-Doug

0 Kudos
1 Solution

Accepted Solutions
Explorer
Explorer
7,535 Views
Registered: ‎05-12-2011

Re: How To - Zynq SMP Bare Metal

Jump to solution

I did eventually run across the errata which mentions the broken JTAG / CPU1 thing, but I disagree with whomever decided it was trivial and had no impact on anyone.  Having to write the app to FLASH to test out each and every code change when using both cores would be a huge pain in the butt, and with no wear leveling or bad block management on the QSPI I'd be concerned about burning holes in the storage.  Putzing around with XMD to manually poke the PC into CPU1 is a bit klunky, I'd think there would be a way to patch in the necessary code in an automated way as part of the whole loading the image and starting CPU0 thing.  But that would require changes that are probably not on the development schedule, so consider it a suggestion but I won't wait around for it to appear.

 

I was able to reset CPU1, the reset vector is at 0x00000000 by the way, and accomplish what I wanted to do.  Now all I have to do is learn everything else.

 

Cheers,

-Doug

0 Kudos
3 Replies
Explorer
Explorer
5,723 Views
Registered: ‎05-12-2011

Re: How To - Zynq SMP Bare Metal

Jump to solution

Okay then, how about this.

 

Is there a difference in behavior when using the JTAG boot mode on a Zynq board as far as the second processor is concerned as compared to booting from say QSPI?

 

Empirically I would have to say there is.  After wrestling with how to modify the default BSP so it doesn't go away every time you clean the project and silently toss all of your changes (I resorted to adding a folder and manually copying the filesystem structure for the standalone stuff from the main Xilinx directory and then added that copy as a local suppository), I created a minimalist BSP that simply configured the EMIO signals for the LEDs on the Zedboard and then turned on the LED (0 or 1) of whichever core showed up (default is all LEDs OFF).  After setting the appropriate LED to ON, when core 0 showed up, I performed the core 1 startup procedure write to 0xFFFFFFF0 followed by the SEV to kick off core 1.  When core 1 showed up I just stuffed it into a loop (after setting LED1 ON of course).  No transferring control to anything, just setting an LED based on core number and looping forever.

 

When using the JTAG load and boot from SDK, because I figured it would be convenient for software development, I could not get LED1 to light after 2+ days of trying everything I could think of.

 

So I made a separate FSBL project, not related to the test project with the super tiny and not suitable for handing off control BSP thing in it, built a boot image with the test project (and associated bastardized BSP), the "normal" FSBL and the simple bit file that ties 8 of the EMIO signals to the Zedboard LEDs.  I programmed it into the QSPI FLASH, set the jumpers, and power cycled the Zedboard.  Lo and behold, LED0 and LED1 both lit up where no matter what I did with the JTAG setup from SDK I could not get that to happen and was only ever rewarded with LED0.

 

It looks to me like the boot ROM is bailing out too early when the JTAG boot is selected, and is not stuffing the WFE loop into OCM as it does when booting from non-volatile storage.  Either that, or it was intentional in the boot ROM but someone forgot or hasn't yet gotten around to adding that part to the JTAG programming logic in SDK.  Either way, when using the JTAG load thing built into SDK the second core is not available for launching as it is stated in the documentation (UG585 specifically) but is available when booting from at least QSPI.  I did not try the other NVM boot media options.

 

I'm wondering if a workaround in order to use the somewhat handier than burning the FLASH for every code JTAG thing might be to use the A9_CPU_RST_CTRL register, specifically the A9_RST1 bit (even though it says "CPU 0 software reset control " on page1468 of UG585 where I believe it should be CPU 1), to reset core 1 wherever it might be hanging out.  The catch would seem to be that I don't know what the VBAR setting is for core 1 in the JTAG boot scenario, and in fact I can't find anything definitive on what the default value of VBAR might be, which would make it a guessing game as far as where to stuff the reset vector.  Can someone tell me what VBAR is for core 1 in the JTAG boot mode?  Or of course if I'm going about this all wrong (a distinct possibility) I'm open to suggestions.

 

Cheers,

-Doug

0 Kudos
Explorer
Explorer
7,536 Views
Registered: ‎05-12-2011

Re: How To - Zynq SMP Bare Metal

Jump to solution

I did eventually run across the errata which mentions the broken JTAG / CPU1 thing, but I disagree with whomever decided it was trivial and had no impact on anyone.  Having to write the app to FLASH to test out each and every code change when using both cores would be a huge pain in the butt, and with no wear leveling or bad block management on the QSPI I'd be concerned about burning holes in the storage.  Putzing around with XMD to manually poke the PC into CPU1 is a bit klunky, I'd think there would be a way to patch in the necessary code in an automated way as part of the whole loading the image and starting CPU0 thing.  But that would require changes that are probably not on the development schedule, so consider it a suggestion but I won't wait around for it to appear.

 

I was able to reset CPU1, the reset vector is at 0x00000000 by the way, and accomplish what I wanted to do.  Now all I have to do is learn everything else.

 

Cheers,

-Doug

0 Kudos
Newbie nicanor5
Newbie
2,652 Views
Registered: ‎01-02-2016

Re: How To - Zynq SMP Bare Metal

Jump to solution

 

 

Hello,

 

I'm trying to use both processors of my Zynq (I have a ZYBO) to make an audio application this semester. One of the cores will be in charge of reading an audio buffer and the other in charge of analysing the buffer. The application runs fine sequentially, but I want to reduce the latency.

 

However the problem I face now is to share the buffer.

 

Did you manage to use both cores in a SMP fashion?

 

Thank you very much.

0 Kudos