← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] - Fix for compiling on ARM CPUs

 

On 11/25/2013 05:21 PM, Robert Yates wrote:
Two problems to fix in order to allow compiling for ARM.

The first was to add the proper "Boost::Context assembly wrapper" files
for ARM, and modify common/system/fcontext.s to include them. The files
'jump_arm_aapcs_elf_gas.S' and 'make_arm_aapcs_elf_gas.S' I acquired
from the boost_1_55_0.tar.bz2 download from http://www.boost.org/

The second parch is for a fake rdtsc() function in include/profile.h to
make the compiler happy.  I'm not a c++ programmer so I don't actually
know what the right thing to do is, but I'm sure returning the number
'42' isn't it. ;-)  There seems to be a cycle counter register built
into ARM CPUs similar to the TSC register in x86 CPUs, but reading it is
not trivial just google 'arm cycle counter' to see what I mean.

But with these two patches I'm able to compile under Arch linux ARM on
my Chromebook
(http://archlinuxarm.org/platforms/armv7/samsung/samsung-chromebook) and
it seems to be running well.

Both patches are against revision 4499 of the lp:kicad branch.

On 11/25/13 11:54, Maciej Sumiński wrote:
Thank you for sharing the solution. I have to admit that the ARM build
happened faster than I thought it will. Regarding rdtsc() - in fact, you
may return 42, but the proper function would be great. As the header
name says - it is only for execution time measurements and it is not
critical for the application operation. By the way - did not you have
any problems with OpenGL?

Kind regards,
Orson



I've done some more digging and this is what I've found.

Although there is a cycle counter built into ARM devices, you have to have kernel level access to enable it and to enable permission for the user-mode code to read the register. Apparently the Linux kernel does not do this by default so in order to use it you would have to write some init code into a kernel module or hack it directly into the kernel to make cycle level profiling work in Kicad. That seems a bit too much effort to go to for a little profiling.
References here:
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0211h/Bihcgfcf.html
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344b/Bgbjjhaj.html
http://stackoverflow.com/questions/3247373/how-to-measure-program-execution-time-in-arm-cortex-a8-processor

Then sniffing around with grep I learned that rdtsc() is only being called by prof_start() and prof_end() in profile.h, and depending on how you call prof_start() determines whether the timing source rdtsc() or get_tics() is used for profiling. (Also as an interesting aside it would seem right now all instances of prof_start() are being called "prof_start( &totalTime, false );" which means rdtsc() is never actually being called at all.) All that being said it would seem that the functions rdtsc() and get_tics() are at least somewhat interchangeable. If you still want a working timing function when rdtsc() is called on an ARM processor I would suggest just copying the get_tics() function's code to the __arm__ version of the rdtsc() function. I'll go ahead and attach a patch that does just that since it's at least a much less ugly hack then the first patch I sent in, and it's just about within my abilities as a person who doesn't really know much about programming in C++.

Also I noticed there's another profile.h at common/profile.h that is an exact duplicate of the one I've been working with at include/profile.h Is there any chance that common/profile.h would ever be included instead of include/profile.h, or is it just an oversight and should be removed?

Oh and as far as problems with OpenGL. The 3D display in pcbnew does not work, when I try to use it I get a delay where the program does not respond for a short time and then the 3D display window finally comes up but there is no 3D image, just black where the image should be. Also in pcbnew the default display canvas works fine, the Cairo canvas also works but is much slower, and the OpenGL canvas does not work, there is just black where the board should be displayed. I'm really not sure if the accelerated graphics drivers are installed properly glxgears runs but with a distorted image at about 90fps. I can send you the output from glxinfo or glewinfo or whatever else if you're interested.

=== modified file 'include/profile.h'
--- include/profile.h	2013-09-18 17:56:37 +0000
+++ include/profile.h	2013-11-25 23:17:35 +0000
@@ -59,6 +59,17 @@
 }
 
 
+// ARM version, no easy access to cycle counter on ARM so just use gettimeofday()
+#elif defined(__arm__)
+static inline uint64_t rdtsc()
+{
+    struct timeval tv;
+    gettimeofday( &tv, NULL );
+
+    return (uint64_t) tv.tv_sec * 1000000ULL + (uint64_t) tv.tv_usec;
+}
+
+
 #elif defined(__powerpc__)
 static __inline__ unsigned long long rdtsc()
 {


=== modified file 'common/system/fcontext.s'
--- common/system/fcontext.s	2013-10-14 11:43:57 +0000
+++ common/system/fcontext.s	2013-11-25 13:02:52 +0000
@@ -33,6 +33,10 @@
         #include "jump_x86_64_sysv_elf_gas.S"
         #include "make_x86_64_sysv_elf_gas.S"
 
+    #elif __arm__
+        #include "jump_arm_aapcs_elf_gas.S"
+        #include "make_arm_aapcs_elf_gas.S"
+
     #else
          #error "Missing make_fcontext & jump_fcontext routines for this architecture"
     #endif

=== added file 'common/system/jump_arm_aapcs_elf_gas.S'
--- common/system/jump_arm_aapcs_elf_gas.S	1970-01-01 00:00:00 +0000
+++ common/system/jump_arm_aapcs_elf_gas.S	2013-11-25 13:01:07 +0000
@@ -0,0 +1,76 @@
+/*
+            Copyright Oliver Kowalke 2009.
+   Distributed under the Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt or copy at
+          http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ *                                                                 *
+ *  -------------------------------------------------------------  *
+ *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| 0x20| 0x24|  *
+ *  -------------------------------------------------------------  *
+ *  |  v1 |  v2 |  v3 |  v4 |  v5 |  v6 |  v7 |  v8 |  sp |  lr |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  10 |                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x28|                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  |  pc |                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  11 |  12 |                                               |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x2c| 0x30|                                               |  *
+ *  -------------------------------------------------------------  *
+ *  |  sp | size|                                               |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  13 |  14 | 15 |  16 |  17 |  18 |  19 |  20 |  21 |  22  |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x34| 0x38|0x3c| 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58 |  *
+ *  -------------------------------------------------------------  *
+ *  | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | s24 | s25 |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  23 |  24 |  25 |  26 |  27 |  28 |                       |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x5c| 0x60| 0x64| 0x68| 0x6c| 0x70|                       |  *
+ *  -------------------------------------------------------------  *
+ *  | s26 | s27 | s28 | s29 | s30 | s31 |                       |  *
+ *  -------------------------------------------------------------  *
+ *                                                                 *
+ * *****************************************************************/
+
+.text
+.globl jump_fcontext
+.align 2
+.type jump_fcontext,%function
+jump_fcontext:
+    stmia   a1, {v1-v8,sp-lr}       @ save V1-V8,SP-LR
+    str     lr, [a1,#40]            @ save LR as PC
+
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
+    cmp     a4, #0                  @ test if fpu env should be preserved
+    beq     1f
+
+    mov     a4, a1
+    add     a4, #52
+    vstmia  a4, {d8-d15}            @ save S16-S31
+
+    mov     a4, a2
+    add     a4, #52
+    vldmia  a4, {d8-d15}            @ restore S16-S31
+1:
+#endif
+
+    mov     a1, a3                  @ use third arg as return value after jump
+                                    @ and as first arg in context function
+    ldmia   a2, {v1-v8,sp-pc}       @ restore v1-V8,SP-PC
+.size jump_fcontext,.-jump_fcontext
+
+/* Mark that we don't need executable stack.  */
+.section .note.GNU-stack,"",%progbits

=== added file 'common/system/make_arm_aapcs_elf_gas.S'
--- common/system/make_arm_aapcs_elf_gas.S	1970-01-01 00:00:00 +0000
+++ common/system/make_arm_aapcs_elf_gas.S	2013-11-25 13:01:07 +0000
@@ -0,0 +1,79 @@
+/*
+            Copyright Oliver Kowalke 2009.
+   Distributed under the Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt or copy at
+          http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ *                                                                 *
+ *  -------------------------------------------------------------  *
+ *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| 0x20| 0x24|  *
+ *  -------------------------------------------------------------  *
+ *  |  v1 |  v2 |  v3 |  v4 |  v5 |  v6 |  v7 |  v8 |  sp |  lr |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  10 |                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x28|                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  |  pc |                                                     |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  11 |  12 |                                               |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x2c| 0x30|                                               |  *
+ *  -------------------------------------------------------------  *
+ *  |  sp | size|                                               |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  13 |  14 | 15 |  16 |  17 |  18 |  19 |  20 |  21 |  22  |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x34| 0x38|0x3c| 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58 |  *
+ *  -------------------------------------------------------------  *
+ *  | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | s24 | s25 |  *
+ *  -------------------------------------------------------------  *
+ *  -------------------------------------------------------------  *
+ *  |  23 |  24 |  25 |  26 |  27 |  28 |                       |  *
+ *  -------------------------------------------------------------  *
+ *  | 0x5c| 0x60| 0x64| 0x68| 0x6c| 0x70|                       |  *
+ *  -------------------------------------------------------------  *
+ *  | s26 | s27 | s28 | s29 | s30 | s31 |                       |  *
+ *  -------------------------------------------------------------  *
+ *                                                                 *
+ * *****************************************************************/
+
+.text
+.globl make_fcontext
+.align 2
+.type make_fcontext,%function
+make_fcontext:
+    mov     a4, a1          @ save address of context stack (base) A4
+    sub     a1, a1, #116    @ reserve space for fcontext_t at top of context stack
+
+    @ shift address in A1 to lower 16 byte boundary
+    @ == pointer to fcontext_t and address of context stack
+    bic     a1, a1, #15
+
+    str     a4, [a1,#44]    @ save address of context stack (base) in fcontext_t
+    str     a2, [a1,#48]    @ save context stack size in fcontext_t
+    str     a3, [a1,#40]    @ save address of context function in fcontext_t
+
+    str     a1, [a1,#32]    @ save address in A4 as stack pointer for context function
+
+    adr     a2, finish      @ compute abs address of label finish
+    str     a2, [a1,#36]    @ save address of finish as return address for context function
+                            @ entered after context function returns
+
+    bx      lr
+
+finish:
+    @ SP points to same addras SP on entry of context function
+    mov     a1, #0          @ exit code is zero
+    bl      _exit@PLT       @ exit application
+.size make_fcontext,.-make_fcontext
+
+/* Mark that we don't need executable stack.  */
+.section .note.GNU-stack,"",%progbits


Follow ups

References