Friday, October 16, 2015

GCC ARM porting

ARM Cortex-A Processors and GCC Command Lines




Debugging on bare-metal targets using DS-5 and GCC compiler
http://ds.arm.com/debugging-on-bare-metal-targets-using-ds-5-and-gcc-compiler/




Renesas – GNURX Migration Guide
http://www.kpitgnutools.com/manuals/Renesas-GNURX-Migration-Guide.html




ARMv7A - Thumb 2
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344b/CACCICED.html






arm-none-eabi-gcc --target-help
arm-none-eabi-as --target-help






https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html


Four Important properties:
Byte order = little
Floating-point ABI = Default
Instruction set = Arm
Interworking = Checked




$(TCINSTALL)\arm-none-eabi\arm-none-eabi\lib\gcc\arm-none-eabi\ 4.8-GNUARM-NONE_v14.01\interwork




Cerating archive file using GCC
http://www.cs.dartmouth.edu/~campbell/cs50/buildlib.html


Different single line comment for each platform
https://en.wikipedia.org/wiki/GNU_Assembler
Single-Line comments[edit]
Single line comments have a few different formats varying on which architecture is being assembled for.
•Hash symbols (#) are used for the platforms: i386, x86-64, i960, 68HC11, 68HC12, VAX, V850, M32R, PowerPC, MIPS and M880x0.
•Semicolons (;) are used on: AMD 29k family, ARC, H8/300 family, HPPA, PDP-11, picoJava, Motorola, and M32C.
•The at sign (@) is used on the ARM platform.
•A vertical bar (|) is used to signify comments when assembling on 680x0.
•An exclamation mark (!) on the Renesas SH platform.
Preprocess source file GCC
http://www.linuxtopia.org/online_books/an_introduction_to_gcc/gccintro_36.html




NEON:
#define __ARM_NEON__ 1
#define __ARM_NEON 1


NEON_D16:




Very good assembly
http://shervinemami.info/armAssembly.html




Check:


1) in Thumb mode, functions addresses are in thumb and CPU is in thumb mode














d




VFPv3 and VFPv4 has D32 only in  case of having NEON. Otherwise they have only 16 64-bit registers.
http://dench.flatlib.jp/opengl/fpu_vfp

























Re: ARM: VFPv3-D16 vs. VFPv3-D32
https://gcc.gnu.org/ml/gcc/2013-10/msg00183.html

SWI Call:

<>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* vi: set sw=4 ts=4: */
/* syscall for arm/uClibc
 *
 * Copyright (C) 2002 by Erik Andersen 
 *
 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 */

#include 
#include 
#include 
#include 


long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
{
#if !defined(__thumb__)
 register long _r0 __asm__("r0")=(long)(sysnum);
 register long _r6 __asm__("r6")=(long)(f);
 register long _r5 __asm__("r5")=(long)(e);
 register long _r4 __asm__("r4")=(long)(d);
 register long _r3 __asm__("r3")=(long)(c);
 register long _r2 __asm__("r2")=(long)(b);
 register long _r1 __asm__("r1")=(long)(a);
 __asm__ __volatile__(
   "swi %1"
   : "=r"(_r0)
   : "i"(__NR_syscall), "r"(_r0), "r"(_r1),
   "r"(_r2), "r"(_r3), "r"(_r4), "r"(_r5),
   "r"(_r6)
   : "memory");
#else
 register long _r7 __asm__("r7")=(long)(sysnum);
 register long _r5 __asm__("r5")=(long)(f);
 register long _r4 __asm__("r4")=(long)(e);
 register long _r3 __asm__("r3")=(long)(d);
 register long _r2 __asm__("r2")=(long)(c);
 register long _r1 __asm__("r1")=(long)(b);
 register long _r0 __asm__("r0")=(long)(a);
 __asm__ __volatile__(
   "swi 0"
   : "=r"(_r0)
   : "r"(_r0), "r"(_r1), "r"(_r2), "r"(_r3),
   "r"(_r4), "r"(_r5), "r"(_r7)
   : "memory");
#endif
 if(_r0 >=(unsigned long) -4095) {
  long err = _r0;
  (*__errno_location())=(-err);
  _r0=(unsigned long) -1;
 }
 return (long) _r0;
}



http://embdev.net/topic/129714
static inline int Do_SWI_9 (int arg1, struct something *arg2)
{
  register long __res asm("r0");
  asm volatile ("mov r0,%2\n\tmov r1,%3" : \
      "=X" (*(char *)(long)arg1), "=X" (*(char *)(long)arg2) : \
      "r" ((long)arg1), "r" ((long)arg2) : \
      "r0", "r1");
  asm volatile ("swi 9 @ %0" : "=r" (__res) : :
      "r12", "r14", "cc");
  return((int)__res);
}

What's different?
(1) The __res variable is now explicitly placed in r0.
(2) The swi call is marked as returning a value in __res.
(3) The "@%0" comment after swi FOOLS asm() into thinking swi really
does affect r0.
(4) The "mov %0,r0" after the swi is omitted as it's no longer
necessary.

Is this voodoo or what?  But it appears to work great under level 2
optimization.


http://embdev.net/topic/184418

In this case, the parameres are transmitted through the stack, but I do 
not need. When used inline it fits into the function.

How do I type this, an unspecified number of parameters?

_inline_ void sm(int i, int l)

{
   register int p0 asm("r0") = i;
   register int p1 asm("r1") = l;

   asm ("swi 0x148"::"r"(p0),"r"(p1));

}


_inline_ void sm(int i,...)

-------------------------------------------------------------


http://venkateshabbarapu.blogspot.jp/2012/09/interrupt-handling-in-arm.html




それでは、L1 命令キャッシュ、L1 データキャッシュ、L2 統一キャッシュをどのような手順で有効化するかというと、

・L1 命令キャッシュをすべて invalidate する
・L1 データキャッシュをすべて invalidate する
・L2 統一キャッシュをすべて invalidate する
・Control Register の I ビットを立てて L1 命令キャッシュを有効化する
・MMU を有効化する
   - ページテーブルを構成する
   - Translation Table Base Register にページテーブル先頭アドレスを設定する
   - Control Register の M ビットを立てて MMU を有効化する
・Auxiliary Control Register の L2EN ビットを立てる
・Control Register の C ビットを立てて、L1 データキャッシュ、L2 統一キャッシュを有効化する

という方法でいいと思います。

分岐予測を有効にする場合は、更に以下を行います:

・分岐予測器を invalidate する
・Control Register の Z ビットを立てて分岐予測を有効化する























No comments: