Re: ARMv7 Cortex-A port for Xilinx Zynq7000

Carlo Caione

On 11/02/2020 15:33, Cufi, Carles wrote:
Hi Immo,
Hi everyone,

+CC Stephanos Ioannidis (Cortex-R guru)

Please comment on the existing Pull Requests and Issues and feel free to open your own Pull Requests to extend the Cortex-A support in Zephyr. I have copied Carlo Caione on this email, since he has been driving this effort so far.
This please. Just a quick note that being the ARMv7/Cortex-A still a 32bit arch, that is probably closer to the current ARMv7/Cortex-R work than to my ARMv8/Cortex-A work.

The only catch is that one of our target hardware platforms is not yet supported, not only at the board/SoC level, but at the architecture level. We'd very much like to see Zephyr run on the dual core (SMP isn't a requirement, though) Cortex-A9 contained in the Xilinx Zynq7000 SoC, despite the lacking support for ARMv7 Cortex-A CPUs.
Cortex-R architecture is supposed to be the arch closer to the ARMv8/Cortex-A if you want a starting point.

I'm now at a point at which I'd call the progress I've made up to now a working proof of concept. Here's what I've done so far:

It looks like you have done a lot already and you can definitely start pushing things upstream if they are ready for review and are self-contained / self-testable.

The problem I encountered when working on the ARMv8 port was that upstream wants to have a fully working port before considering the work ready for merging. This means that you must be able to pass as many tests as possible (in theory all of them). The "push early push often" philosophy seems to not apply very well to the Zephyr project when dealing with new architectures.

- The MMU is set up in the simplest possible way, with a page table consisting of nothing but 1 MB page entries. The part of the system's memory map where the RAM is located is configured as cacheable/bufferable, which is a requirement for any unaligned accesses (which can for example be found in the IP stack) to work. If the MMU isn't set up this way, the result is an illegal instruction exception. The rest of the memory map is set up as strongly ordered, covering areas such as the SLCR, the peripherial register space and the OCM.
MMU work for ARMv8 is ongoing at

- Added a corresponding QEMU target using the Zynq7000 template.
Still, the to-do-list has a quite a few points on it:
- CMSIS for Cortex-A is not yet integrated, e.g. SLCR or FPU register accesses are hand-coded.
Not a problem. That could be added later.

- Caches not activated yet, as my own driver implementations don't contain any barriers yet where they probably should have some.
Not a problem.

- Only compiled with the GNU ARM Embedded Toolchain so far.
Did you try to use the Zephyr SDK?

- QEMU only tested to the point where the hello world and philosophers demos are apparently working with a basic IRQ/Timer/UART setup.
- No tests from the testsuite have run so far.
What's the issue with the remaining tests?

- SMP not addressed at all, but this feature isn't that important to me personally. A single 666 MHz core is quite capable by itself...
SMP not required for an initial submission.

- None of the security features are addressed, it's all secure mode-only for now.
Not a problem.

- The interrupt controller uses the same workaround as the GIC PL-400 in the Cortex-R port: store a pointer to the driver attached to vector [0] as there is no well-defined interrupt controller such as the Cortex-M's NVIC. Therefore, currently all interrupt vectors are offset by one.
Currently worked out at

- No high-level/scripted configuration of the MMU possible for now.
Not required.

- I'm currently forcing the ARM instruction set, there's currently no Thumb code being generated.
Not a problem.

- I haven't yet looked into whether any other FP ABIs can be supported or not, and there are currently no configuration options for the FPU such as on how to handle denormals.
Not a problem.

- Last but not least, the Zynq has some more peripherials generally supported by Zephyr but for which no drivers exist for now. As the processor system in the Zynq usually relies on *some* content in the programmable logic part (e.g. the AXI GPIO IP core), a driver for the Xilinx devcfg interface might be an integral part of the SoC support (although u-boot can handle this just as well), but there's also things like CAN, ADC, SPI, and the Zedboard features an OLED display...
Are you able to use QEMU to emulate a working hardware?

I'd like to contribute my work to the project, is this of any interest to all of you? Are there any must-have items I should tackle beforehand, probably most likely regaring testing? If so, I'd probably have to start merging my modifications into the current code base, as I'm still working on a code base acquired shortly before the arch/arm path was split up into AARCH32 and AARCH64. What would be the next steps in providing this to the community, considering that this is a bit more than just a stand-alone device driver?
IMO the next step is making sure you are able to pass as many tests as possible in a QEMU environment when using the Zephyr SDK. If for some reason some tests are not passable just specify why is that when pushing the PR. This should be enough to convince people to review your code.

Cheers and good luck :)

Carlo Caione

Join to automatically receive all group messages.