Skip to content
This repository has been archived by the owner on Jul 6, 2019. It is now read-only.

Zinc on Cortex-A #283

Open
geraldstanje opened this issue Apr 11, 2015 · 40 comments
Open

Zinc on Cortex-A #283

geraldstanje opened this issue Apr 11, 2015 · 40 comments

Comments

@geraldstanje
Copy link

Hi,

is arm cortex a9 bare metal supported?

Thanks,
Gerald

@farcaller
Copy link
Member

Zinc can technically run on anything that is supported by rustc, which includes cortex-a cores. There is no support for any cortex-a9 chips in the works though.

While cortex-a cores can usually run things like linux and require more complex init sequences, I'm not entirely against adding bare metal cortex-a support into zinc in the future.

@farcaller farcaller changed the title arm question Zinc on Cortex-A Apr 12, 2015
@Arnold1
Copy link

Arnold1 commented May 14, 2015

how much effort is it to add those support? a basic support would already be great...many people use arm cortex a9 with xillinx zynq device...
http://www.xilinx.com/products/silicon-devices/soc/zynq-7000.html
http://www.myirtech.com/list.asp?id=502
http://www.open-electronics.org/red-pitaya-the-opensource-electronic-laboratory/

@farcaller
Copy link
Member

There is a very big amount of various Cortex-A cores, so it's a very hard target for zinc. What features would you like to see in Cortex-A code?

@Arnold1
Copy link

Arnold1 commented May 14, 2015

for arm cortex a9: GPIO/s, VFPv3, Timers, shared memory access between the ARM and the FPGA by adding some interrupt logic ... how much effort is it to add those?

@ghost
Copy link

ghost commented May 25, 2015

This would be nice to see. @farcaller, can you quickly outline at a high level what would be needed by zinc to support the Zynq SoC?

@ghost
Copy link

ghost commented May 25, 2015

Just a clarification to my above comment, what I mean is: in general, what does zinc need to support a platform? Given that I can figure out the Zynq specifics...

@bharrisau
Copy link
Contributor

Like most things, zinc has layers:

  • Layer 1 is the toochain. You need for the Rust output to run on the device. This is left to you, but we can help with any changes to the Zinc build system. The tricky part of this layer is the setting the vector table correctly so that your code actually starts.
  • Layer 2 is the processor core. In this case, ARM Cortex-A. This will live in src/hal/cortex_a_xxxx and needs to contain functions for interfacing with the special function registers (SFR) on the core.
  • Layer 3 is the system on chip. In this case the Zync. This will live in src/hal/zync (potentially refactored into specific modules later) and will have the majority of the code - interfacing with the SFRs of all the Xilinx peripherals.
  • Layer 4 is the application board. Undefined in this case. The code lives in src/drivers and will handle talking to all the other devices embedded in the OEM device (LCDs, accelerometers, etc). This will eventually become separate crates when Zinc is stable enough.

I hope that is a sufficient overview. Also, don't forget the initialisation code, there is usually a system initialisation document detailing the order that things need to be activated (and please link to it in your comments wherever you reference it). Forgetting to initialise watchdogs causes lots of debugging grief.

In the future (when I get some more time for Zinc), I'd like to decouple the above a little bit, so that the definition and instantiation of each layer is separate. i.e. ARM_systick_module_1 is implemented once in layer 1, and we map it into Cortex_M1 in a separate layer. Same for layer 2 peripherals, implement the vendor peripheral in one area, but instantiate it for the particular device somewhere else.

@bharrisau
Copy link
Contributor

And for completeness, there is also a layer of Zinc utilities.

@ghost
Copy link

ghost commented May 26, 2015

Thanks Ben, good overview. its nice to give each board a crate. Those could grow as large as they want. Now that I understand the layout a bit, I'll have a better time digging around.

@Arnold1
Copy link

Arnold1 commented May 31, 2015

awesome zinc seems to build with nightly....

Any news about very basic support for arm corex a9? e.g. GPIO + Timer to toggle a LED...

@mcoffin
Copy link
Contributor

mcoffin commented Jun 1, 2015

@Arnold1 I don't think anybody is working on it right now, but as always feel free to start it!

@farcaller
Copy link
Member

Let's clarify terminology once again.

Cortex-A9 is a computing core along with a very little set of peripherals (systick timer and MMU). It is somewhat different from the cores currently supported in zinc (Cortex-M0, M3 and M4), but not very different for adding support to be unbearable.

Different MCU vendors incorporate ARM cores in their products, e.g. Raspberry Pi 2 has a BCM2836 CPU featuring Cortex-A7 core. Broadcomm provides IP for gpios, serial ports, audio, video, etc. on the same die as the ARM core is.

So, speaking of adding Cortex-M9 support, the only core-specific thing we now have is a set of initialisation vectors, and adding that is trivial. Adding support for specific CPU or a family of CPUs is where complexity is. As far as I know xillinx zynq devices, those are FPGAs with ARM cores inside, so, basically, you provide the peripheral IP yourself (including gpio, serial and other things). I don't see how this fits zinc, as the peripheral configuration is defined by user and we just can't provide any kind of generic drivers.

Speaking of Cortex-A profile support, I can consider looking at some easily-available board (RPi, beaglebone?) and giving directions on what is needed to add support for it in zinc.

@ghost
Copy link

ghost commented Jun 1, 2015

Hi Vladimir,
Xilinx's Zynq is actually a full dual core A9 SoC with USB, gpio, Ethernet,
and many other peripherals on die. Also on die is the fpga which you can
have the processor subsystem populate on boot with a custom design (say a
specific HW accel function your app needs). You can then call that function
from C code. It would fit Zinc as far as the processor system is concerned
which is why I found interest in Zinc.

I have started to look at the tool chain layer along with the layout
described by Ben. However, the repo does not appear to be in the state
he described just yet. Still, I have to get to know rust a bit more and I'm
working my way there. This is definitely an interesting project though and
seeing Zynq running zinc would be a cool thing to see.

On Monday, June 1, 2015, Vladimir Pouzanov <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

Let's clarify terminology once again.

Cortex-A9 is a computing core along with a very little set of peripherals
(systick timer and MMU). It is somewhat different from the cores currently
supported in zinc (Cortex-M0, M3 and M4), but not very different for adding
support to be unbearable.

Different MCU vendors incorporate ARM cores in their products, e.g.
Raspberry Pi 2 has a BCM2836 CPU featuring Cortex-A7 core. Broadcomm
provides IP for gpios, serial ports, audio, video, etc. on the same die as
the ARM core is.

So, speaking of adding Cortex-M9 support, the only core-specific thing we
now have is a set of initialisation vectors, and adding that is trivial.
Adding support for specific CPU or a family of CPUs is where complexity is.
As far as I know xillinx zynq devices, those are FPGAs with ARM cores
inside, so, basically, you provide the peripheral IP yourself (including
gpio, serial and other things). I don't see how this fits zinc, as the
peripheral configuration is defined by user and we just can't provide any
kind of generic drivers.

Speaking of Cortex-A profile support, I can consider looking at some
easily-available board (RPi, beaglebone?) and giving directions on what is
needed to add support for it in zinc.


Reply to this email directly or view it on GitHub
#283 (comment).

@farcaller
Copy link
Member

Xilinx's Zynq is actually a full dual core A9 SoC with USB, gpio, Ethernet, and many other peripherals on die.

Ah, makes more sense then. Given that, the support plan would be the same as with other platforms, add support for any boot requirements for CPU, then add peripheral drivers. The issue with latter is that Platform Tree has a big chance to get a redesign, and we don't have good traits defined for peripherals, really.

@Arnold1
Copy link

Arnold1 commented Jun 1, 2015

@farcaller thanks for the reply. could you prepare a basic toolchain e.g. platform tree as a start implementing the support for arm cortex a9? maybe @Bechamp whats to join in some work too...

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

any feedback on this @farcaller @Bechamp ?

@ghost
Copy link

ghost commented Jun 5, 2015

Hi, trying to get hands on a board through work before committing. Also new
to rust so I'm still trying to get my head around the platform trees. This
won't be a one weekend project for me alone but definitely interested. Do
you have a board?

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

any feedback on this @farcaller https://github.com/farcaller @Bechamp
https://github.com/bechamp ?


Reply to this email directly or view it on GitHub
#283 (comment).

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

yes i have a board. i already used rust and mapped the fpga memory to linux using mmap...
it would be great if @farcaller can help us with the initial start as well as platform tree... do you want to constribute?

@ghost
Copy link

ghost commented Jun 5, 2015

Which board?

Also have you gotten vanilla rust to cross compile for it already? because
if not then we don't need the boards right away if we are still figuring
out the tool chain.

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

yes i have a board.


Reply to this email directly or view it on GitHub
#283 (comment).

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

i have this board called redpitaya. but also might get a myirtech Z-turn Board... do you get a myirtech Z-turn Board as well?

i already used rust and mapped the fpga memory to linux using mmap... but not yet bare metal...

what is vanella rust?

@ghost
Copy link

ghost commented Jun 5, 2015

RedPitaya boards are a great application. I saw them when they were
announced. Outside my hobby budget though and we don't have those laying
around at work. You are further along then me then. Would you have any
notes to share on getting rust to build for the device? Bare metal right
(not cross Linux)?

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

i have this board called redpitaya.

i already used rust and mapped the fpga memory to linux using mmap...


Reply to this email directly or view it on GitHub
#283 (comment).

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

i have not yet tried to build rust for bare metal... @farcaller can you jump in?

@posborne
Copy link
Contributor

posborne commented Jun 5, 2015

Having worked on a number of Cortex-A devices (working on U-Boot, Embedded Linux, and also and RTOS project), I'm not sure it makes a lot of sense for Zinc to try to target them in the short term. Although targeting the core itself is and getting some code running in SRAM loaded on through JTAG is probably not terrible, these more powerful cores after often found within the context of more complicated SoCs which require more work to integrate with. Let's say we were to target something like the BeagleBone Black or Freescale i.mx6:

  • Both of these boards are used with DDR SDRAM. This requires a fair amount of additional code to initialize this RAM.
  • In order to boot to code, executables must be programmed into NAND flash (or eMMC/SD Card) in a specific fashion that can be understood by the boot ROM in the SoC. Doable, but work that must be done differently for many different boards.
  • There are many, many IP blocks in modern SoCs. The reference manual for MCUs is maybe 1000 pages. It isn't unusual for the reference manual on SoCs to be upwards of 6000-8000 pages. You don't need to use all of those IP blocks, but you are better off just using Linux if you want to make use of most of that hardware.

Maybe I have only worked with the more complex designs using these cores? I just wonder if it makes sense for Zinc to stay focused on M0, M0+, M3, M4 MCUs rather than targeting more powerful cores that really require an OS for reasonable use.

@farcaller
Copy link
Member

I really agree with @posborne on this one, if your hardware supports u-boot, then there's really very little sense to bring zinc in.

As for guidelines on where to start, I really have little idea how to initialise Cortex-A systems and can hardly advice on that. Maybe starting with barebones helloworld in rust that inits hw enough to blink a led is a reasonable starting point? We can then see how init code can be fit into zinc.

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

why? some people run linux on core0 and bare metal on core1...

hello world + blink a led sounds great... can you provide some infos on how to initialize the cortex a9?

@ghost
Copy link

ghost commented Jun 5, 2015

Hi Paul,
Everything you say is absolutely correct. Fully supporting the A core is
not a small feat. Supporting the on-die ecosystem is approaching
monumental. Then each board support package would be quite a bit of work.

SoCs are getting very complex with nonhomogeneous mutlicore arrangements
that support hypervisors and other such advances. Are those even attainable
by Rust and zinc? Maybe, probably, with enough time. But it's a good
discussion to define the scope and possibilies of a project like zinc.rs.
But, without taking focus away from the current goals. So thanks for the
interjection.

I approached this discussion from the notion that 1) Rust is
(intended) interchangeable with C not just replacement and 2) I
envision the rust code would simply be the application level code operating
in the existing bare metal ecosystem. Maybe that is not the intent of
zinc.rs as it is taking ownership of the system but it was a thought. ( and
well 3) zinc.rs running on Zynq would be cool even if it's a
bit superficial ;) )

(T.b.h. Where I am right now as far as exposure to Rust, had I the time I
would probably try to make a crate for a teensy board running zinc to start
with before seriously considering a full scale SoC)

On Friday, June 5, 2015, Paul Osborne notifications@github.com wrote:

Having worked on a number of Cortex-A devices (working on U-Boot, Embedded
Linux, and also and RTOS project), I'm not sure it makes a lot of sense for
Zinc to try to target them in the short term. Although targeting the core
itself is and getting some code running in SRAM loaded on through JTAG is
probably not terrible, these more powerful cores after often found within
the context of more complicated SoCs which require more work to integrate
with. Let's say we were to target something like the BeagleBone Black or
Freescale i.mx6:

  • Both of these boards are used with DDR SDRAM. This requires a fair
    amount of additional code to initialize this RAM.
  • In order to boot to code, executables must be programmed into NAND
    flash (or eMMC/SD Card) in a specific fashion that can be understood by the
    boot ROM in the SoC. Doable, but work that must be done differently for
    many different boards.
  • There are many, many IP blocks in modern SoCs. The reference manual
    for MCUs is maybe 1000 pages. It isn't unusual for the reference manual on
    SoCs to be upwards of 6000-8000 pages. You don't need to use all of those
    IP blocks, but you are better off just using Linux if you want to make use
    of most of that hardware.

Maybe I have only worked with the more complex designs using these cores?
I just wonder if it makes sense for Zinc to stay focused on M0, M0+, M3, M4
MCUs rather than targeting more powerful cores that really require an OS
for reasonable use.


Reply to this email directly or view it on GitHub
#283 (comment).

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

@Bechamp lets build a hello world in rust targeting the arm cortex a9 as a proof of concept?

@farcaller
Copy link
Member

@Bechamp you can take any existing C-based OS for Cortex-A9 and run rust code on it with reasonably little effort already. I envision zinc.rs as rust-only [RT]OS with no C code, the reasoning is to see what rust is missing to be used like that.

@ghost
Copy link

ghost commented Jun 5, 2015

That is what I felt this project was and support that. Which is why I'm not
too sure about pursuing the SoC yet (myself) now as a lot of foundation is
still to achieved.

But, Arnold,
I think I'll try and look through that app note in the coming days and
cross reference the redpitaya docs to get an idea of what a hello world on
that board would be. I think it will be nontrivial too:

  • compile vanilla rust to compatible code
  • figure out how to get the device to execute that code instead of its own
    boot loader
  • properly initialize a subset of the system, I guess at least the MIO
    enough to touch an LED.

But after getting there, porting of zinc is somewhat within range.

On Friday, June 5, 2015, Vladimir Pouzanov notifications@github.com wrote:

@Bechamp https://github.com/bechamp you can take any existing C-based
OS for Cortex-A9 and run rust code on it with reasonably little effort
already. I envision zinc.rs as rust-only [RT]OS with no C code, the
reasoning is to see what rust is missing to be used like that.


Reply to this email directly or view it on GitHub
#283 (comment).

@Arnold1
Copy link

Arnold1 commented Jun 5, 2015

@geraldstanje
Copy link
Author

hi,

i would like to contribute and started to port some C code to Rust:
https://github.com/geraldstanje/rust-arm-cortex-a9

the original C source is here:
https://github.com/geraldstanje/rust-arm-cortex-a9/tree/master/orig/bare_metal_test.cpu1

Rust project (main.rs will implement a blink app):
https://github.com/geraldstanje/rust-arm-cortex-a9/

...im not sure about the llvm-target for arm cortex a9!?
target.json:

{
    "arch": "arm",
    "cpu": "cortex-a9",
    "data-layout": "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-v128:64:128-a:0:32-n32-S64",
    "disable-redzone": true,
    "executables": true,
    "llvm-target": "arm-unknown-eabi",
    "linker": "arm-xilinx-eabi-gcc",
    "morestack": false,
    "os": "none",
    "linker-is-gnu": true,
    "has-rpath": true,
    "relocation-model": "static",
    "target-endian": "little",
    "target-pointer-width": "32"
}

my c compiler (for linking the object files):

arm-xilinx-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-xilinx-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/Xilinx/SDK/2015.1/gnu/arm/lin/bin/../libexec/gcc/arm-xilinx-eabi/4.9.1/lto-wrapper
Target: arm-xilinx-eabi
Configured with: /scratch/cltang/xilinx/eabi/src/gcc-4.9-2014.11/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-xilinx-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv7-a --with-cpu=cortex-a9 --with-float=softfp --with-fpu=neon-fp16 --disable-multilib --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} -D__CS_SOURCERYGXX_MAJ__=2014 -D__CS_SOURCERYGXX_MIN__=11 -D__CS_SOURCERYGXX_REV__=31' --enable-languages=c,c++ --disable-shared --enable-lto --with-newlib --with-pkgversion='Sourcery CodeBench Lite 2014.11-31' --with-bugurl=https://s...content-available-to-author-only...r.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-xilinx-eabi --with-build-sysroot=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi --with-gmp=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-cloog=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --disable-libgomp --disable-libitm --disable-libatomic --disable-libssp --enable-poison-system-directories --with-build-time-tools=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi/bin --with-build-time-tools=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi/bin SED=sed
Thread model: single
gcc version 4.9.1 (Sourcery CodeBench Lite 2014.11-31)

will libcompiler-rt.a only need boot.S? ...boot.S is part of the board support package (BSP): http://www.xilinx.com/support/documentation/sw_manuals/xilinx12_2/SDK_Doc/concepts/sdk_c_bsp_internal.htm

How can i port offsetof(struct rproc_resource, code_cout) from C to Rust?

@farcaller @posborne @bharrisau can you comment on this?

@geraldstanje
Copy link
Author

can someone comment on this?

@farcaller
Copy link
Member

The safest bet is to dump ti_ipc_remoteproc_ResourceTable in a hex editor and just make a [u8] vec in rust to make you going.

@geraldstanje
Copy link
Author

@farcaller
is arm-unknown-eabi the right llvm target for arm cortex a9?
and what about the startup code, i currently only added boot.S?!

@farcaller
Copy link
Member

arm-unknown-eabi sounds like a reasonable target. as for boot.S, I haven't worked with Cortex-A in a long while so I can't really advice on the proper initialisation sequence.

@geraldstanje
Copy link
Author

@farcaller
i have my working c project here: https://github.com/geraldstanje/rust-arm-cortex-a9/tree/master/orig/bare_metal_test.cpu1

but i cant see how the startup sequence is called. any idea?

@farcaller
Copy link
Member

This is the entry: https://github.com/geraldstanje/rust-arm-cortex-a9/blob/master/orig/bare_metal_test.cpu1/lscript.ld#L33

That calls to the vector table:

.section .vectors
_vector_table:
    B   _boot
    B   Undefined
    B   SVCHandler
    B   PrefetchAbortHandler
    B   DataAbortHandler
    NOP /* Placeholder for address exception vector*/
    B   IRQHandler
    B   FIQHandler

that goes to the boot, that branches to C code.

@geraldstanje
Copy link
Author

@farcaller
so all i need is asm_vectors.S and boot.S, thats it?

@farcaller
Copy link
Member

I think it's a reasonable approximation.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants