I'm working on a port of the MIT/Intel Cilk runtime for ARM
viewtopic.php?f=33&t=102743
and am trying to put together a binary package that runs on both the original Raspberry Pi and new Pi 2B. The difficulty is that the Pi 2B needs a DSB Data Synchronization Barrier instruction to manage the multi-core hardware whereas the original PI doesn't have this instruction. Currently I make the definition
#define __cilkrts_fence() __asm__ volatile ("DSB")
in the runtime source and everything works fine on the Pi 2B. This is binary equivalent to
#define __cilkrts_fence() __asm__ volatile (".word 0xf57ff04f")
which again works fine on the Pi 2B and has the advantage that it can be compiled by the assembler in ARMv6 mode. Not surprisingly the resulting binary gives an "Illegal instruction" trap when run on the original Pi. Therefore, I need to insert code that tests the cpuid register and makes a relative branch to skip past the DSB instruction if the cpuid is ARMv6. Logically the code should function as
if cpuid != ARMv6 then DSB
and be written in inline assembler. While I expect this is simple enough, I'm a complete noob at ARM assembler and would appreciate any help offered.
Re: DSB instruction and ARMv6
Thanks for the reply. I found similar inline memory barrier instructions in the Linux kernel.tufty wrote: viewtopic.php?f=72&t=13959
may be of use.
http://lxr.free-electrons.com/source/ar ... /barrier.h
According to official ARM documentation these instructions are deprecated on ARMv7 cores.
http://infocenter.arm.com/help/index.js ... 06s01.html
This is why I used the newer "DSB" instruction in my initial build of the MIT/Intel Cilk runtime for gcc-5.0. I have now rebuilt using the deprecated instruction by commenting out my previous define and replacing it with the p15 memory barrier instruction in os-fence.h as follows:
Code: Select all
//# define __cilkrts_fence() __asm__ volatile ("DSB")
# define __cilkrts_fence() __asm__ __volatile__ ("mcr p15,0,%[t],c7,c10,4\n" :: [t] "r" (0) : "memory");
Re: DSB instruction and ARMv6
Luckily deprecated only means they will go away in some future version. Not that you can't use them. Using the old style barriers works on both RPi and RPi2.
For extra bonus points you could use boot time patching like linux does for SMP and XEN. Define a macro for each barrier type that will insert the old style MCR instruction but also recod the address of that instruction in some array. Then at boot your code will work on RPi or RPi2 just fine. But you can use the array and replace all the MCR opcodes with DMB/DSB/ISB instructions.
For extra bonus points you could use boot time patching like linux does for SMP and XEN. Define a macro for each barrier type that will insert the old style MCR instruction but also recod the address of that instruction in some array. Then at boot your code will work on RPi or RPi2 just fine. But you can use the array and replace all the MCR opcodes with DMB/DSB/ISB instructions.