Posts: 4267
Joined: Tue Mar 18, 2014 11:47 am

DSB instruction and ARMv6

Fri Apr 10, 2015 5:06 pm

I'm working on a port of the MIT/Intel Cilk runtime for ARM


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.

Posts: 4267
Joined: Tue Mar 18, 2014 11:47 am

Re: DSB instruction and ARMv6

Mon Apr 13, 2015 6:11 pm

tufty wrote: viewtopic.php?f=72&t=13959
may be of use.
Thanks for the reply. I found similar inline memory barrier instructions in the Linux kernel.

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");
The resulting build seems to work fine on both versions of the Raspberry Pi. I'm uncertain about using a deprecated instruction for ARMv7, but it seems the best solution for creating a binary package that runs on both processors.

Posts: 58
Joined: Wed Jan 09, 2013 6:50 pm

Re: DSB instruction and ARMv6

Sun Apr 19, 2015 11:49 am

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.

Return to “Bare metal, Assembly language”