EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Question about inline asm for ARM

Started by Unknown January 17, 2014
Hi,
I want to use ARM A8 performance counter. I find a post on line, but I do not understand its grammar. ARM inforcenter does not help much. I especially do not understand the '::'. Could you explain it to me? Or point to some links for it.

Thanks,



.................
Accessing the performance counters isn't difficult, but you have to enable them from kernel-mode. By default the counters are disabled.

In a nutshell you have to execute the following two lines inside the kernel. Either as a loadable module or just adding the two lines somewhere in the board-init will do:

  /* enable user-mode access to the performance counter*/
  asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));

  /* disable counter overflow interrupts (just in case)*/
  asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));

Once you did this the cycle counter will start incrementing for each cycle. Overflows of the register will go unnoticed and don't cause any problems (except they might mess up your measurements).

Now you want to access the cycle-counter from the user-mode:

We start with a function that reads the register:

static inline unsigned int get_cyclecount (void)
{
  unsigned int value;
  // Read CCNT Register
  asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));  
  return value;
}
rxjwg98@gmail.com wrote:

> Hi, > I want to use ARM A8 performance counter. I find a post on line, but I do > not understand its grammar. ARM inforcenter does not help much. I > especially do not understand the '::'. Could you explain it to me? Or > point to some links for it.
This is a gcc feature, not specifically an ARM feature. One page of documentation is at <http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Extended-Asm.html#Extended-Asm> The overall gcc documents start at <http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/> Mel.
On Fri, 17 Jan 2014 09:30:19 -0800, rxjwg98 wrote:

> Hi, > I want to use ARM A8 performance counter. I find a post on line, but I > do not understand its grammar. ARM inforcenter does not help much. I > especially do not understand the '::'. Could you explain it to me? Or > point to some links for it. >
>> snip <<
> /* enable user-mode access to the performance counter*/ > asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));
Assuming that you're doing this in C or C++ in the first place, know that inline assembly is not a standard feature of C. Every compiler vendor will approach this from a different perspective. It appears that your example is for the gnu compiler (which, IMHO, has the best damned inline assembler interface ever). If so, then you need to hit the gnu compiler books to understand. If I recall correctly, the fields of the asm statement in gnu are delimited by colons. So '::' just means that there's an empty field in there. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
On Fri, 17 Jan 2014 09:30:19 -0800, rxjwg98 wrote:

> I want to use ARM A8 performance counter. I find a post on line, but I > do not understand its grammar. ARM inforcenter does not help much. I > especially do not understand the '::'. Could you explain it to me? Or > point to some links for it.
..
> /* enable user-mode access to the performance counter*/ > asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1)); >
The GCC inline assembly language statement is a strange beast because the general form is architecture-independent but of course the details are very specific to ARM. In general, the form is asm(<inline code> : <output> : <input> : <clobber>) Your example uses instruction MCR p15,0,rX,c9,c14,0 , no outputs, and one register input that the compiler is being asked to contain a constant 1 (one). Apparenlty MCR requires a value of 1 in a register, and the asm() allows the compiler to reuse a register that already contains this value---and if there isn't one it'll generate a mov r3, #1 just before the MCR. More information on GCC ARM asm() is e.g. at http://www.ethernut.de/en/documents/arm-inline-asm.html By the way, you can check all this for yourself by running code fragments like the above through GCC -c and observing the output with objdump -D: cat > x.c main() { asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1)); } ^D arm-gp2x-linux-gcc -c x.c arm-gp2x-linux-objdump -D x.o

The 2024 Embedded Online Conference