changeset 2983:790fa8c690f4

* src/timer_tc.c: Implement a profiling timer on TC1. * cdl/hal_arm_at91.cdl: Add CDL option to enable the profiling timer.
author jld
date Sun, 19 Dec 2010 20:49:20 +0000
parents 2155db306734
children cd4e37e75648
files packages/hal/arm/at91/var/current/ChangeLog packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl packages/hal/arm/at91/var/current/src/timer_tc.c
diffstat 3 files changed, 88 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/at91/var/current/ChangeLog
+++ b/packages/hal/arm/at91/var/current/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-17  John Dallaway  <john@dallaway.org.uk>
+
+	* src/timer_tc.c: Implement a profiling timer on TC1.
+	* cdl/hal_arm_at91.cdl: Add CDL option to enable the profiling timer.
+
 2010-05-27 ccoutand <ccoutand@stmi.com>
 	* include/var_io.h: Added ADC defines for AT91_M55800A CPU
 
@@ -477,7 +482,7 @@ 2001-07-16  Gary Thomas  <gthomas@redhat
 // ####GPLCOPYRIGHTBEGIN####                                                
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009, 2010 Free Software Foundation, Inc.
 //
 // This program is free software; you can redistribute it and/or modify     
 // it under the terms of the GNU General Public License as published by     
--- a/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl
+++ b/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl
@@ -8,7 +8,7 @@
 ## ####ECOSGPLCOPYRIGHTBEGIN####                                            
 ## -------------------------------------------                              
 ## This file is part of eCos, the Embedded Configurable Operating System.   
-## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
 ##
 ## 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     
@@ -40,7 +40,7 @@
 ######DESCRIPTIONBEGIN####
 #
 # Author(s):      gthomas
-# Contributors:   gthomas, tkoeller, tdrury, nickg
+# Contributors:   gthomas, tkoeller, tdrury, nickg, jld
 # Date:           2001-07-12
 #
 #####DESCRIPTIONEND####
@@ -135,8 +135,8 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
     cdl_interface CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW {
         display     "Platform has the DBG serial port"
         description "
-            Some varients of the AT91 have a dedicated debug serial
-            port. The HALs of such a varient should implement this interface
+            Some variants of the AT91 have a dedicated debug serial
+            port. The HALs of such a variant should implement this interface
             so allowing the serial driver to the compiled"
     }
 
@@ -154,7 +154,7 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
 
         description   "
             The driver for the dedicated DBG UART will be compiled in the
-            varient HAL when this option is enabled."
+            variant HAL when this option is enabled."
     }
 
     cdl_option CYGBLD_HAL_ARM_AT91_SERIAL_UART {
@@ -165,7 +165,7 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
         requires      !CYGBLD_HAL_ARM_AT91_SERIAL_DBG
         description   "        
             The driver for using the UARTS will be compiled in the
-            varient HAL when this option is enabled."
+            variant HAL when this option is enabled."
     }
 
     cdl_component CYGBLD_HAL_ARM_AT91_DCC {
@@ -190,4 +190,20 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
                 the first serial port. "
         }
     }
+
+    cdl_option CYGFUN_HAL_ARM_AT91_PROFILE_TIMER {
+        display       "Use TC1 for gprof profiling"
+        active_if     CYGPKG_PROFILE_GPROF
+        flavor        bool
+        default_value 1
+        requires      !CYGPKG_HAL_ARM_AT91_JTST
+        implements    CYGINT_PROFILE_HAL_TIMER
+        description   "
+            The AT91 variant HAL can provide support for gprof-based
+            profiling. This uses timer TC1 to generate regular interrupts,
+            and the interrupt handler records the PC at the time of the
+            interrupt. However, TC1 is unavailable for this purpose on
+            the JTST platform. Disable this option if you wish to provide
+            an alternative profiling timer implementation."
+    }
 }
--- a/packages/hal/arm/at91/var/current/src/timer_tc.c
+++ b/packages/hal/arm/at91/var/current/src/timer_tc.c
@@ -8,7 +8,7 @@
 // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
 //
 // 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     
@@ -40,7 +40,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas, jskov, nickg, tkoeller
+// Contributors: gthomas, jskov, nickg, tkoeller, jld
 // Date:         2001-07-12
 // Purpose:      HAL board support
 // Description:  Implementations of HAL board interfaces
@@ -58,6 +58,11 @@
 #include <cyg/hal/hal_arch.h>           // Register state info
 #include <cyg/hal/hal_intr.h>           // necessary?
 
+#ifdef CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/profile/profile.h>        // __profile_hit()
+#endif
+
 // -------------------------------------------------------------------------
 // Clock support
 
@@ -158,4 +163,57 @@ void hal_delay_us(cyg_int32 usecs)
     } while ((stat & AT91_TC_SR_CPC) == 0);
 }
 
+#ifdef CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
+
+// Use TC1 for profiling
+#define AT91_TC_PROFILE AT91_TC_TC1
+#define HAL_INTERRUPT_PROFILE CYGNUM_HAL_INTERRUPT_TIMER1
+
+// Profiling timer ISR
+static cyg_uint32 profile_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data, HAL_SavedRegisters *regs)
+{
+    cyg_uint32 status;
+
+    HAL_READ_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_SR, status); // Clear interrupt
+    HAL_INTERRUPT_ACKNOWLEDGE(HAL_INTERRUPT_PROFILE);
+    __profile_hit(regs->pc);
+    return CYG_ISR_HANDLED;
+}
+
+// Profiling timer setup
+int hal_enable_profile_timer(int resolution)
+{
+    cyg_uint32 period;
+
+    // Calculate how many timer ticks the requested resolution in
+    // microseconds equates to. We do this calculation in 64 bit
+    // arithmetic to avoid overflow.
+    period = (cyg_uint32)((((cyg_uint64)resolution) *
+        ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL);
+
+    CYG_ASSERT(period < 0x10000, "Invalid profile timer resolution"); // 16 bits only
+
+    // Attach ISR
+    HAL_INTERRUPT_ATTACH(HAL_INTERRUPT_PROFILE, &profile_isr, 0x1111, 0);
+    HAL_INTERRUPT_UNMASK(HAL_INTERRUPT_PROFILE);
+
+    // Disable counter
+    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    // Set registers
+    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC
+                                                          AT91_TC_CMR_CLKS_MCK32); // Use MCLK/32
+    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_RC, period);
+
+    // Start timer
+    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+    // Enable timer interrupt
+    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_IER, AT91_TC_IER_CPC);
+
+    return resolution;
+}
+
+#endif // CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
+
 // timer_tc.c