changeset 1999:21e6e977e7c2

Implement HAL_DELAY_US() for the synthetic target
author bartv
date Sun, 26 Jun 2005 13:02:04 +0000
parents 7237127655fc
children 418f67f643d5
files packages/hal/synth/arch/current/ChangeLog packages/hal/synth/arch/current/include/hal_intr.h packages/hal/synth/arch/current/src/synth_intr.c packages/hal/synth/i386linux/current/ChangeLog packages/hal/synth/i386linux/current/include/var_intr.h
diffstat 5 files changed, 134 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/synth/arch/current/ChangeLog
+++ b/packages/hal/synth/arch/current/ChangeLog
@@ -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
--- a/packages/hal/synth/arch/current/include/hal_intr.h
+++ b/packages/hal/synth/arch/current/include/hal_intr.h
@@ -106,7 +106,6 @@
 // cyg_vector_t etc., supplied either by the kernel or the common HAL
 #include <cyg/hal/drv_api.h>
 
-
 // Nearly all interrupt state control happens via functions. This
 // facilitates debugging, for example it is easier to set breakpoints
 // that way, at the cost of performance. However performance is not a
@@ -240,6 +239,12 @@ externC cyg_uint32      hal_clock_read(v
     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()                                    \
--- a/packages/hal/synth/arch/current/src/synth_intr.c
+++ b/packages/hal/synth/arch/current/src/synth_intr.c
@@ -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 @@ synth_hardware_init(void)
         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();
     
--- a/packages/hal/synth/i386linux/current/ChangeLog
+++ b/packages/hal/synth/i386linux/current/ChangeLog
@@ -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.
new file mode 100644
--- /dev/null
+++ b/packages/hal/synth/i386linux/current/include/var_intr.h
@@ -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