This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

synthetic target implementation of HAL_DELAY_US()


This adds an implementation of HAL_DELAY_US() to the synthetic target.
The bogomips rating is extracted from /proc/cpuinfo in the startup
code, and is then used by a bit of inline assembler. The results are
not quite as accurate as I would have liked. On four different
systems, with bogomips ratings of 2375, 1730, 398 and 1376
respectively, 60 seconds worth of HAL_DELAY_US() gives me 58.13,
63.98, 64.56 and 65.60 seconds. However it should be close enough -
synthetic target timing is never going to be particularly accurate
anyway.

Bart

Index: hal/synth/arch/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/ChangeLog,v
retrieving revision 1.28
diff -u -r1.28 ChangeLog
--- hal/synth/arch/current/ChangeLog	11 Mar 2005 19:04:07 -0000	1.28
+++ hal/synth/arch/current/ChangeLog	26 Jun 2005 12:49:58 -0000
@@ -1,3 +1,11 @@
+2005-06-26  Bart Veer  <bartv@ecoscentric.com>
+
+	* src/synth_intr.c (synth_hardware_init): extract bogomips rating
+	for use by HAL_DELAY_US()
+
+	* include/hal_intr.h: add #include of <cyg/hal/var_intr.h> for
+	HAL_DELAY_US().
+
 2005-03-11  Bart Veer  <bartv@ecoscentric.com>
 
 	* src/synth_intr.c (synth_hardware_init): allow the platform to
Index: hal/synth/arch/current/include/hal_intr.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/include/hal_intr.h,v
retrieving revision 1.6
diff -u -r1.6 hal_intr.h
--- hal/synth/arch/current/include/hal_intr.h	9 Aug 2004 17:53:59 -0000	1.6
+++ hal/synth/arch/current/include/hal_intr.h	26 Jun 2005 12:50:02 -0000
@@ -240,6 +239,12 @@
     CYG_MACRO_END
 
 // ----------------------------------------------------------------------------
+// HAL_DELAY_US() support. The macro is provided by the processor-specific
+// HAL, but the bogomips rating is provided by the architectural code.
+extern int hal_bogomips;
+#include <cyg/hal/var_intr.h>
+
+// ----------------------------------------------------------------------------
 // Resetting the Synth target is not possible, but existing the process is.
 externC void            cyg_hal_sys_exit(int); 
 #define HAL_PLATFORM_RESET()                                    \
Index: hal/synth/arch/current/src/synth_intr.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/src/synth_intr.c,v
retrieving revision 1.7
diff -u -r1.7 synth_intr.c
--- hal/synth/arch/current/src/synth_intr.c	11 Mar 2005 19:04:06 -0000	1.7
+++ hal/synth/arch/current/src/synth_intr.c	26 Jun 2005 12:50:07 -0000
@@ -129,6 +129,9 @@
 // ----------------------------------------------------------------------------
 // Statics.
 
+// The bogomips rating, used by HAL_DELAY_US()
+int hal_bogomips;
+
 // Are interrupts currently enabled?
 volatile cyg_bool_t hal_interrupts_enabled = false;
 
@@ -1325,6 +1328,42 @@
         CYG_FAIL("Failed to install signal handler for SIGCHLD");
     }
 
+    // Determine the processor's bogomips rating. This adds some
+    // start-up overhead to all applications, even if HAL_DELAY_US()
+    // is not used. However doing it on demand in the first call
+    // to HAL_DELAY_US() would risk running out of file descriptors.
+    {
+        int     fd;
+        char    buf[4096];      // much larger than current /proc/cpuinfo, but still small enough for synthetic target stacks
+        int     read;
+        int     i;
+
+        fd  = cyg_hal_sys_open("/proc/cpuinfo", CYG_HAL_SYS_O_RDONLY, 0);
+        if (fd < 0) {
+            CYG_FAIL("Failed to open /proc/cpuinfo, needed for BogoMips rating");
+        }
+        read    = cyg_hal_sys_read(fd, buf, 4096);
+        cyg_hal_sys_close(fd);
+
+        for (i = 0; i < read; i++) {
+            if ((buf[i  ] == 'b') && (buf[i+1] == 'o') && (buf[i+2] == 'g') && (buf[i+3] == 'o') &&
+                (buf[i+4] == 'm') && (buf[i+5] == 'i') && (buf[i+6] == 'p') && (buf[i+7] == 's')) {
+
+                for ( i += 8; (i < read) && ((buf[i] < '1') || (buf[i] > '9')); i++) {
+                    ;
+                }
+                // Only bother with the integer part of the rating
+                for ( ; (i < read) && (buf[i] >= '0') && (buf[i] <= '9'); i++) {
+                    hal_bogomips = (10 * hal_bogomips) + (buf[i] - '0');
+                }
+                break;
+            }
+        }
+        if (0 == hal_bogomips) {
+            CYG_FAIL("Failed to find bogomips entry in /proc/cpuinfo");
+        }
+    }
+    
     // Start up the auxiliary process.
     synth_start_auxiliary();
     
Index: hal/synth/i386linux/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/i386linux/current/ChangeLog,v
retrieving revision 1.14
diff -u -r1.14 ChangeLog
--- hal/synth/i386linux/current/ChangeLog	21 Mar 2005 14:37:03 -0000	1.14
+++ hal/synth/i386linux/current/ChangeLog	26 Jun 2005 12:50:44 -0000
@@ -1,3 +1,8 @@
+2005-06-26  Bart Veer  <bartv@ecoscentric.com>
+
+	* include/var_intr.h (HAL_DELAY_US): new header to supply
+	processor-specific HAL_DELAY_US() macro
+
 2005-03-21  Bart Veer  <bartv@ecoscentric.com>
 
 	* cdl/hal_synth_i386.cdl, src/profile.c: add profiling support.
Index: hal/synth/i386linux/current/include/var_intr.h
===================================================================
RCS file: hal/synth/i386linux/current/include/var_intr.h
diff -N hal/synth/i386linux/current/include/var_intr.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ hal/synth/i386linux/current/include/var_intr.h	26 Jun 2005 12:50:45 -0000
@@ -0,0 +1,76 @@
+#ifndef CYGONCE_HAL_VAR_INTR_H
+#define CYGONCE_HAL_VAR_INTR_H
+
+//=============================================================================
+//
+//      var_intr.h
+//
+//      Processor-specific interrupt support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   bartv
+// Date:        2005-06-26
+// Usage:       #include <cyg/hal/hal_intr.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// The architectural HAL provides the bogomips rating. This is an
+// outer loop for the number of us and an inner loop for 1us. The
+// alignment of the inner loop can greatly affect performance. The
+// *16 of the bogomips rating seems to give about the right results
+// on a range of hardware.
+#define HAL_DELAY_US(_us_)                                              \
+    CYG_MACRO_START                                                     \
+    asm volatile (                                                      \
+                   "1:\n"                                               \
+                   "movl %2,%1\n"                                       \
+                   "sal $0x4,%1\n"                                      \
+                   ".align 16\n"                                        \
+                   "2:\n"                                               \
+                   "decl %1\n"                                          \
+                   "jns 2b\n"                                           \
+                   "decl %0\n"                                          \
+                   "jns 1b\n"                                           \
+                   :                                                    \
+                   : "r" (_us_), "r" (0), "g" (hal_bogomips+1)          \
+                   : "cc");                                             \
+    CYG_MACRO_END
+    
+ 
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_INTR_H
+// End of var_intr.h



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]