Support for AXI interconnect targetting the XILINX ZC706

Chris Johns chrisj at rtems.org
Tue Nov 5 23:32:22 UTC 2019


On 5/11/19 11:43 pm, Tiago Manuel Da Silva Jorge wrote:
> We are working on an interesting project where we are developing applications
> that should run with RTEMS on ARM and additionally communicate with Programmable
> Logic (FPGA). We are using the Xilinx Zynq-7000 SoC ZC706 Evaluation Kit, and
> for communication between its PS (Processing System: ARM Cortex-A9) and PL
> (Programmable Logic: Artix-7 FPGA) we are planning to use its AXI Interconnect.

Welcome to RTEMS and thank for the introduction. It sounds like an interesting
project.

> Hence, the question is: Is there any support (e.g. driver or the like) for this
> AXI on RTEMS/ARM (to communicate with PL side)?

RTEMS provides all the primitives you need:

1. MMU and cache support
2. Interrupts

After this there is no specific support for the AXI bus and that is mostly due
to the wide range of ways you can implement the transfer of data across the AXI
bus to and from the PL. The factors that effect the design are the amount of
data and the performance needed. An other factor is the experience of the PL
design team, if they are new to the Zynq or Xilinx there may be a learning curve
here.

For each part of the PL logic you interact with over the AXI bus you will need a
set of registers assigned to one of the AXI bus ports. The PL team will do this
and set the base address of the port. You need to configure the MMU so you can
access that address space and so the PL. To set up the MMU and cache create a
file in your application, say mmu.c, and add a table similar to:

---- 8< -----
#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION

#include <bsp.h>
#include <bsp/start.h>
#include <bsp/arm-gic-irq.h>
#include <bsp/arm-cp15-start.h>
#include <bsp/arm-a9mpcore-start.h>

#ifdef ARMV7_CP15_START_DEFAULT_SECTIONS

BSP_START_DATA_SECTION static const arm_cp15_start_section_config
zynq_mmu_config_table[] = {
  ARMV7_CP15_START_DEFAULT_SECTIONS,
  {
    .begin = 0xe0000000U,
    .end   = 0xe0200000U,
    .flags = ARMV7_MMU_DEVICE
  }, {
    .begin = 0xf8000000U,
    .end   = 0xf9000000U,
    .flags = ARMV7_MMU_DEVICE
  }, {
    .begin = 0x40000000U,
    .end   = 0xc0000000U,
    .flags = ARMV7_MMU_DEVICE
  }, {
    .begin = 0x00100000U,
    .end   = 0x00400000U,
    .flags = ARMV7_MMU_DEVICE
  }, {
    .begin = 0xfffc0000u,
    .end   = 0xffffffffu,
    .flags = ARMV7_MMU_DEVICE
  }
};

BSP_START_TEXT_SECTION void zynq_setup_mmu_and_cache(void)
{
  uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
    ARM_CP15_CTRL_A,
    ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
  );

  arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
    ctrl,
    (uint32_t *) bsp_translation_table_base,
    ARM_MMU_DEFAULT_CLIENT_DOMAIN,
    &zynq_mmu_config_table[0],
    RTEMS_ARRAY_SIZE(zynq_mmu_config_table)
  );
}

#endif
---- 8< -----

The function `zynq_setup_mmu_and_cache()` is weak in the BSP and so this
function overrides the default.

You can now access the PL over the AXI bus. From here you can use CDMA as a
simple but slow method to transfer blocks of data, or the PL designers can bus
master the AXI bus and write directly into the main DDR (fast but more complex).
The software would configure the DDR target address via the PL registers. DMA
and bus master writes and reads require you manage the cache invalidates and
flushes. There are calls in RTEMS to handle this for you.

I hope this helps.

Chris


More information about the devel mailing list