By Adam Taylor

In my last blog I introduced the concept of bare-metal Asymmetric Multiprocessing using both of the Zynq SoC’s ARM Cortex-A9 MPCore processors to execute bare metal programs. I hope you are sitting very comfortably as this blog may be a little long but by the end of it, we will have our AMP system up and running. While there are a few steps involved to get AMP up and running, it is actually very simple and straightforward process and certainly nothing to be afraid of.

The key aspect to getting AMP running on the Zynq SoC is a boot loader that looks for a second executable file after loading the first into the memory. Unfortunately the Vivado design suite I am using 2014.1 (I recently moved house and have no internet connection so have not been able to download the latest yet) does not support AMP when it generates an FSBL (first-stage boot loader). Therefore to get this example up and running I will be using the modified FSBL and modified standalone OS provided as part of Xilinx Application note XAPP1079. (The source files are available here http://www.xilinx.com/support/documentation/application_notes/xapp1079-amp-bare-metal-cortex-a9.pdf)

Having downloaded the zip file the first step is to extract the zipped files into your desired working directory and to rename the folder called SRC to design. These files contain both a modified FSBL and a modified, standalone OS. We need the SDK to be aware of these files so the next step is to update your SDK repository to make the SDK aware of their existence. Within SDK under the Xilinx tools menu, select repositories and then new, navigating to the directory location <your working directory>\app1079\design\work\sdk_repo as shown below:

Having added in the repositories the next stage is to generate the following :

AMP first-stage boot loader

Core 0 application

Core 1 application

We are going to generate a BSP (board support package) for each of these.

The first thing to do is create a new FSBL. Select file -> new application -> project, which enables us to create an FSBL project that supports AMP. This is no different to what we have done before, however we will be selecting the Zynq FSBL for AMP template in place of the of the Zynq FSBL template.

Following the creation of the AMP FSBL, we need to create the application for the first core. This again is very simple to do. We have done this many times before. Be sure to select Core 0 and the standalone OS and allow it to create its own BSP.

Once we have created this application we need to correctly define the location in DDR memory where the application will execute. To do this, we edit the linker script as below to show the DDR base address and size. This is important. If we do not correctly segment the DDR memory for Core 0 and Core 1 applications, we risk one inadvertently corrupting the other.

We can now write the application we wish to execute on Core 0. This is the core that will be in charge within the AMP system and it starts the execution of code on core 1. We will need to include the following section of code within the application. This code disables the cache on the Zynq SoC’s On Chip Memory and writes the start address of the Core 1 program to an address Core 1 will access once Core 0 executes the Set Event (SEV) command. The SEV command causes Core 1 to start executing its program.

The next step is to create a BSP for Core1. We want to use the modified standalone OS (standalone_amp), which prevents re-initialization of the PS Snoop Control Unit (SCU). Consequently, we cannot allow automatic generation of the BSP as we create the project like we did for Core 0. Be sure to select Core 1 in the CPU selection options.

Now that we have created the BSP for Core 1, we need to modify the settings of the BSP before we can progress to creating the application program we want to run on Core 1. This is very simple and requires the addition of an extra complier flag of –DUSE_AMP=1 to the configuration for drivers section of the BSP:

With this completed we are free to create the application for Core 1. Be sure to select Core 1 as the processor and use the BSP we just created:

Again, having created the new application, we need to again define the correct memory locations within the DDR memory from which the Core 1 program will execute. This is achieved by editing the linker script for the Core 1 application:

As with the first core within this application, we must also disable the cache on the On Chip Memory because we will be using this memory in later blogs to communicate between the two processors.

Once we have completed our applications and built the projects we should now be in possession of the following:

AMP FSBL ELF

Core 0 ELF

CORE 1 ELF

Bit file defining the configuration of the device.

We now need a .bin file to enable the Zynq SoC to boot from your selected configuration memory. We also need a bif file, which defines the files to be used to create the bin file, and we need to define the order in which the files go.

Rather than use the created Zynq boot image within SDK we will be using an ISE command prompt and bat file provided as part of XAPP 1079 under directory\design\work\bootgen. This directory contains a bif file and a cpu1_bootvec.bin which is used as part of the modified FSBL to stop it from looking for more applications to load.

To generate the bin file, we copy the three generated ELF files to the bootgen directory and edit the BIF file to ensure the elf names within the bif file are correct.

We can now open an ISE command prompt, navigate to the bootgen directory, and run the createboot.bat, which will create the boot.bin file:

This file can then be downloaded into the non-volatile memory on your Zynq SoC. Booting the device will result in both cores starting and executing their respective programs.

In my next blog we will look a little more in detail into the software applications we just got running on the Zynq SoC’s two ARM Cortex-A9 MPCore processors.

Please see the previous entries in this MicroZed series by Adam Taylor:

Adam Taylor’s MicroZed Chronicles Part 46: Using both of the Zynq SoC’s ARM Cortex-A9 Cores

Adam Taylor’s MicroZed Chronicles Part 44: MicroZed Operating Systems—FreeRTOS

Adam Taylor’s MicroZed Chronicles Part 43: XADC Alarms and Interrupts

Adam Taylor’s MicroZed Chronicles MicroZed Part 42: MicroZed Operating Systems Part 4

Adam Taylor’s MicroZed Chronicles MicroZed Part 41: MicroZed Operating Systems Part 3

Adam Taylor’s MicroZed Chronicles MicroZed Part 40: MicroZed Operating Systems Part Two

Adam Taylor’s MicroZed Chronicles MicroZed Part 39: MicroZed Operating Systems Part One

Adam Taylor’s MicroZed Chronicles MicroZed Part 38 – Answering a question on Interrupts

Adam Taylor’s MicroZed Chronicles Part 37: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 8

Adam Taylor’s MicroZed Chronicles Part 36: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 7

Adam Taylor’s MicroZed Chronicles Part 35: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 6

Adam Taylor’s MicroZed Chronicles Part 34: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 5

Adam Taylor’s MicroZed Chronicles Part 33: Driving Adafruit RGB NeoPixel LED arrays with the Zynq SoC

Adam Taylor’s MicroZed Chronicles Part 32: Driving Adafruit RGB NeoPixel LED arrays

Adam Taylor’s MicroZed Chronicles Part 31: Systems of Modules, Driving RGB NeoPixel LED arrays

Adam Taylor’s MicroZed Chronicles Part 30: The MicroZed I/O Carrier Card

Zynq DMA Part Two – Adam Taylor’s MicroZed Chronicles Part 29

The Zynq PS/PL, Part Eight: Zynq DMA – Adam Taylor’s MicroZed Chronicles Part 28

The Zynq PS/PL, Part Seven: Adam Taylor’s MicroZed Chronicles Part 27

The Zynq PS/PL, Part Six: Adam Taylor’s MicroZed Chronicles Part 26

The Zynq PS/PL, Part Five: Adam Taylor’s MicroZed Chronicles Part 25

The Zynq PS/PL, Part Four: Adam Taylor’s MicroZed Chronicles Part 24

The Zynq PS/PL, Part Three: Adam Taylor’s MicroZed Chronicles Part 23

The Zynq PS/PL, Part Two: Adam Taylor’s MicroZed Chronicles Part 22

The Zynq PS/PL, Part One: Adam Taylor’s MicroZed Chronicles Part 21

Introduction to the Zynq Triple Timer Counter Part Four: Adam Taylor’s MicroZed Chronicles Part 20

Introduction to the Zynq Triple Timer Counter Part Three: Adam Taylor’s MicroZed Chronicles Part 19

Introduction to the Zynq Triple Timer Counter Part Two: Adam Taylor’s MicroZed Chronicles Part 18

Introduction to the Zynq Triple Timer Counter Part One: Adam Taylor’s MicroZed Chronicles Part 17

The Zynq SoC’s Private Watchdog: Adam Taylor’s MicroZed Chronicles Part 16

Implementing the Zynq SoC’s Private Timer: Adam Taylor’s MicroZed Chronicles Part 15

MicroZed Timers, Clocks and Watchdogs: Adam Taylor’s MicroZed Chronicles Part 14

More About MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 13

MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 12

Using the MicroZed Button for Input: Adam Taylor’s MicroZed Chronicles Part 11

Driving the Zynq SoC's GPIO: Adam Taylor’s MicroZed Chronicles Part 10

Meet the Zynq MIO: Adam Taylor’s MicroZed Chronicles Part 9

MicroZed XADC Software: Adam Taylor’s MicroZed Chronicles Part 8

Getting the XADC Running on the MicroZed: Adam Taylor’s MicroZed Chronicles Part 7

A Boot Loader for MicroZed. Adam Taylor’s MicroZed Chronicles, Part 6

Figuring out the MicroZed Boot Loader – Adam Taylor’s MicroZed Chronicles, Part 5

Running your programs on the MicroZed – Adam Taylor’s MicroZed Chronicles, Part 4

Zynq and MicroZed say “Hello World”-- Adam Taylor’s MicroZed Chronicles, Part 3

Adam Taylor’s MicroZed Chronicles: Setting the SW Scene

Bringing up the Avnet MicroZed with Vivado