diff options
Diffstat (limited to 'c/src/lib/libbsp/sparc')
-rw-r--r-- | c/src/lib/libbsp/sparc/erc32/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/erc32/timer/timer.c | 81 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/Makefile.am | 6 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/timer/timer.c | 83 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/Makefile.am | 10 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/timer/timer.c | 85 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/timer/watchdog.c | 90 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/timer/gptimer.c | 544 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/timer/tlib.c | 77 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c | 453 |
10 files changed, 9 insertions, 1422 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am index 3171e0b697..7668a98610 100644 --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am @@ -50,7 +50,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/console/debugputs.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/erc32/clock/ckinit.c # timer -librtemsbsp_a_SOURCES += timer/timer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/btimer/btimer.c # IRQ librtemsbsp_a_SOURCES += ../shared/irq/irq-shared.c diff --git a/c/src/lib/libbsp/sparc/erc32/timer/timer.c b/c/src/lib/libbsp/sparc/erc32/timer/timer.c deleted file mode 100644 index 05728f8acc..0000000000 --- a/c/src/lib/libbsp/sparc/erc32/timer/timer.c +++ /dev/null @@ -1,81 +0,0 @@ -/* timer.c - * - * This file implements a benchmark timer using the General Purpose Timer on - * the MEC. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Ported to ERC32 implementation of the SPARC by On-Line Applications - * Research Corporation (OAR) under contract to the European Space - * Agency (ESA). - * - * ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995. - * European Space Agency. - */ - -#include <bsp.h> -#include <rtems/btimer.h> - -bool benchmark_timer_find_average_overhead; - -bool benchmark_timer_is_initialized = false; - -void benchmark_timer_initialize(void) -{ - /* - * Timer runs long and accurate enough not to require an interrupt. - */ - - if ( benchmark_timer_is_initialized == false ) { - - /* approximately 1 us per countdown */ - ERC32_MEC.General_Purpose_Timer_Scalar = CLOCK_SPEED - 1; - ERC32_MEC.General_Purpose_Timer_Counter = 0xffffffff; - - } else { - benchmark_timer_is_initialized = true; - } - - ERC32_MEC_Set_General_Purpose_Timer_Control( - ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | - ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER - ); - - ERC32_MEC_Set_General_Purpose_Timer_Control( - ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING - ); - -} - -#define AVG_OVERHEAD 12 /* It typically takes 3.0 microseconds */ - /* to start/stop the timer. */ -#define LEAST_VALID 13 /* Don't trust a value lower than this */ - -benchmark_timer_t benchmark_timer_read(void) -{ - uint32_t total; - - total = ERC32_MEC.General_Purpose_Timer_Counter; - - total = 0xffffffff - total; - - if ( benchmark_timer_find_average_overhead == true ) - return total; /* in one microsecond units */ - - if ( total < LEAST_VALID ) - return 0; /* below timer resolution */ - - return total - AVG_OVERHEAD; -} - -void benchmark_timer_disable_subtracting_average_overhead( - bool find_flag -) -{ - benchmark_timer_find_average_overhead = find_flag; -} diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am index 34cd6fcd12..7e5d8b6363 100644 --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am @@ -66,8 +66,8 @@ librtemsbsp_a_SOURCES += ../shared/amba/ambapp_show.c librtemsbsp_a_SOURCES += ../shared/amba/ahbstat.c # Clock Driver and Timer Library -librtemsbsp_a_SOURCES += ../shared/timer/gptimer.c -librtemsbsp_a_SOURCES += ../shared/timer/tlib.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/gptimer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib.c # PCI librtemsbsp_a_SOURCES += ../shared/pci/grpci2.c @@ -137,7 +137,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/cache.c # griommu librtemsbsp_a_SOURCES += ../shared/iommu/griommu.c # timer -librtemsbsp_a_SOURCES += timer/timer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/btimer/btimer.c # TM/TC librtemsbsp_a_SOURCES += ../shared/tmtc/grtc.c diff --git a/c/src/lib/libbsp/sparc/leon2/timer/timer.c b/c/src/lib/libbsp/sparc/leon2/timer/timer.c deleted file mode 100644 index de115c965a..0000000000 --- a/c/src/lib/libbsp/sparc/leon2/timer/timer.c +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file - * @ingroup sparc_leon2 - * @brief Implement a benchmark timer using timer 2 - */ - -/* timer.c - * - * This file implements a benchmark timer using timer 2. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Ported to LEON implementation of the SPARC by On-Line Applications - * Research Corporation (OAR) under contract to the European Space - * Agency (ESA). - * - * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995. - * European Space Agency. - */ - - -#include <bsp.h> -#include <rtems/btimer.h> - -bool benchmark_timer_find_average_overhead; - -bool benchmark_timer_is_initialized = false; - -void benchmark_timer_initialize(void) -{ - /* - * Timer runs long and accurate enough not to require an interrupt. - */ - - if ( benchmark_timer_is_initialized == false ) { - - /* approximately 1 us per countdown */ - LEON_REG.Timer_Counter_2 = 0xffffff; - LEON_REG.Timer_Reload_2 = 0xffffff; - - } else { - benchmark_timer_is_initialized = true; - } - - LEON_REG.Timer_Control_2 = ( - LEON_REG_TIMER_COUNTER_ENABLE_COUNTING | - LEON_REG_TIMER_COUNTER_LOAD_COUNTER - ); - -} - -#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */ - /* to start/stop the timer. */ -#define LEAST_VALID 2 /* Don't trust a value lower than this */ - -benchmark_timer_t benchmark_timer_read(void) -{ - uint32_t total; - - total = LEON_REG.Timer_Counter_2; - - total = 0xffffff - total; - - if ( benchmark_timer_find_average_overhead == true ) - return total; /* in one microsecond units */ - - if ( total < LEAST_VALID ) - return 0; /* below timer resolution */ - - return total - AVG_OVERHEAD; -} - -void benchmark_timer_disable_subtracting_average_overhead( - bool find_flag -) -{ - benchmark_timer_find_average_overhead = find_flag; -} diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index df75c03552..71a020cd17 100644 --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am @@ -60,9 +60,9 @@ librtemsbsp_a_SOURCES += ../shared/amba/ambapp_show.c librtemsbsp_a_SOURCES += ../shared/amba/ahbstat.c # Clock Driver and Timer Library -librtemsbsp_a_SOURCES += ../shared/timer/gptimer.c -librtemsbsp_a_SOURCES += ../shared/timer/tlib.c -librtemsbsp_a_SOURCES += ../shared/timer/tlib_ckinit.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/gptimer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib_ckinit.c # non-Driver Manager Clock Implementation librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/leon3/clock/ckinit.c @@ -151,8 +151,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/cache.c # griommu librtemsbsp_a_SOURCES += ../shared/iommu/griommu.c # timer -librtemsbsp_a_SOURCES += timer/timer.c -librtemsbsp_a_SOURCES += timer/watchdog.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/btimer/btimer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/btimer/watchdog.c # GR712 librtemsbsp_a_SOURCES += ../shared/ascs/grascs.c diff --git a/c/src/lib/libbsp/sparc/leon3/timer/timer.c b/c/src/lib/libbsp/sparc/leon3/timer/timer.c deleted file mode 100644 index 40bdeb87bb..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/timer/timer.c +++ /dev/null @@ -1,85 +0,0 @@ -/* timer.c - * - * This file implements a benchmark timer using timer 2. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Ported to LEON implementation of the SPARC by On-Line Applications - * Research Corporation (OAR) under contract to the European Space - * Agency (ESA). - * - * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995. - * European Space Agency. - */ - - -#include <bsp.h> -#include <rtems/btimer.h> - -#if defined(RTEMS_MULTIPROCESSING) - #define LEON3_TIMER_INDEX \ - ((rtems_configuration_get_user_multiprocessing_table()) ? \ - (rtems_configuration_get_user_multiprocessing_table()->node) - 1 : 1) -#else - #define LEON3_TIMER_INDEX 0 -#endif - -bool benchmark_timer_find_average_overhead; - -bool benchmark_timer_is_initialized = false; - -extern volatile struct gptimer_regs *LEON3_Timer_Regs; - -void benchmark_timer_initialize(void) -{ - /* - * Timer runs long and accurate enough not to require an interrupt. - */ - if (LEON3_Timer_Regs) { - if ( benchmark_timer_is_initialized == false ) { - /* approximately 1 us per countdown */ - LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].reload = 0xffffff; - LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value = 0xffffff; - } else { - benchmark_timer_is_initialized = true; - } - LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].ctrl = - GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_LD; - } -} - -#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */ - /* to start/stop the timer. */ -#define LEAST_VALID 2 /* Don't trust a value lower than this */ - -benchmark_timer_t benchmark_timer_read(void) -{ - uint32_t total; - - if (LEON3_Timer_Regs) { - total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value; - - total = 0xffffff - total; - - if ( benchmark_timer_find_average_overhead == true ) - return total; /* in one microsecond units */ - - if ( total < LEAST_VALID ) - return 0; /* below timer resolution */ - - return total - AVG_OVERHEAD; - } - return 0; -} - -void benchmark_timer_disable_subtracting_average_overhead( - bool find_flag -) -{ - benchmark_timer_find_average_overhead = find_flag; -} diff --git a/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c b/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c deleted file mode 100644 index 5ce8e32354..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c +++ /dev/null @@ -1,90 +0,0 @@ -/* GPTIMER Watchdog timer routines. On some systems the first GPTIMER - * core's last Timer instance underflow signal is connected to system - * reset. - * - * COPYRIGHT (c) 2012. - * Cobham Gaisler AB. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include <bsp.h> -#include <bsp/watchdog.h> -#include <grlib.h> - -extern volatile struct gptimer_regs *LEON3_Timer_Regs; - -struct gptimer_watchdog_priv { - struct gptimer_regs *regs; - struct gptimer_timer_regs *timer; - int timerno; -}; - -struct gptimer_watchdog_priv bsp_watchdogs[1]; -int bsp_watchdog_count = 0; - -int bsp_watchdog_init(void) -{ - int timercnt; - - if (!LEON3_Timer_Regs) - return 0; - - /* Get Watchdogs in system, this is implemented for one GPTIMER core - * only. - * - * First watchdog is a special case, we can get the first timer core by - * looking at LEON3_Timer_Regs, the watchdog within a timer core is - * always the last timer. Unfortunately we can not know it the watchdog - * functionality is available or not, we assume that it is if we - * reached this function. - */ - bsp_watchdogs[0].regs = (struct gptimer_regs *)LEON3_Timer_Regs; - - /* Find Timer that has watchdog functionality */ - timercnt = bsp_watchdogs[0].regs->cfg & 0x7; - if (timercnt < 2) /* First timer system clock timer */ - return 0; - - bsp_watchdogs[0].timerno = timercnt - 1; - bsp_watchdogs[0].timer = &bsp_watchdogs[0].regs->timer[bsp_watchdogs[0].timerno]; - - bsp_watchdog_count = 1; - return bsp_watchdog_count; -} - -void bsp_watchdog_reload(int watchdog, unsigned int reload_value) -{ - if (bsp_watchdog_count == 0) - bsp_watchdog_init(); - - if (bsp_watchdog_count <= watchdog) - return; - - /* Kick watchdog, and clear interrupt pending bit */ - bsp_watchdogs[watchdog].timer->reload = reload_value; - bsp_watchdogs[watchdog].timer->ctrl = - (GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_EN) | - (bsp_watchdogs[watchdog].timer->ctrl & ~(1<<4)); -} - -void bsp_watchdog_stop(int watchdog) -{ - if (bsp_watchdog_count == 0) - bsp_watchdog_init(); - - if (bsp_watchdog_count <= watchdog) - return; - - /* Stop watchdog timer */ - bsp_watchdogs[watchdog].timer->ctrl = 0; -} - -/* Use watchdog timer to reset system */ -void bsp_watchdog_system_reset(void) -{ - sparc_disable_interrupts(); - bsp_watchdog_reload(0, 1); -} diff --git a/c/src/lib/libbsp/sparc/shared/timer/gptimer.c b/c/src/lib/libbsp/sparc/shared/timer/gptimer.c deleted file mode 100644 index 08e498178e..0000000000 --- a/c/src/lib/libbsp/sparc/shared/timer/gptimer.c +++ /dev/null @@ -1,544 +0,0 @@ -/* This file contains the driver for the GRLIB GPTIMER timers port. The driver - * is implemented by using the tlib.c simple timer layer and the Driver - * Manager. - * - * The Driver can be configured using driver resources: - * - * - timerStart Timer Index if first Timer, this parameters is typically used - * in AMP systems for resource allocation. The Timers before - * timerStart will not be accessed. - * - timerCnt Number of timers that the driver will use, this parameters is - * typically used in AMP systems for resource allocation between - * OS instances. - * - prescaler Base prescaler, normally set by bootloader but can be - * overridden. The default scaler reload value set by bootloader - * is so that Timers operate in 1MHz. Setting the prescaler to a - * lower value increase the accuracy of the timers but shortens - * the time until underflow happens. - * - clockTimer Used to select a particular timer to be the system clock - * timer. This is useful when multiple GPTIMERs cores are - * available, or in AMP systems. By default the TLIB selects the - * first timer registered as system clock timer. - * - * The BSP define APBUART_INFO_AVAIL in order to add the info routine - * used for debugging. - * - * COPYRIGHT (c) 2010. - * Cobham Gaisler AB. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include <rtems.h> -#include <bsp.h> -#include <stdlib.h> -#include <string.h> -#include <drvmgr/drvmgr.h> -#include <drvmgr/ambapp_bus.h> -#include <grlib.h> -#include <bsp/gptimer.h> -#include <bsp/tlib.h> - -#if defined(LEON3) -#include <leon.h> -#endif - -#ifdef GPTIMER_INFO_AVAIL -#include <stdio.h> -#endif - -#ifdef RTEMS_SMP -#include <rtems/score/processormask.h> -#include <rtems/score/smpimpl.h> -#endif - -/* GPTIMER Core Configuration Register (READ-ONLY) */ -#define GPTIMER_CFG_TIMERS_BIT 0 -#define GPTIMER_CFG_IRQ_BIT 3 -#define GPTIMER_CFG_SI_BIT 8 -#define GPTIMER_CFG_DF_BIT 9 - -#define GPTIMER_CFG_TIMERS (0x7<<GPTIMER_CFG_TIMERS_BIT) -#define GPTIMER_CFG_IRQ (0x1f<<GPTIMER_CFG_IRQ_BIT) -#define GPTIMER_CFG_SI (1<<GPTIMER_CFG_SI_BIT) -#define GPTIMER_CFG_DF (1<<GPTIMER_CFG_DF_BIT) - -/* GPTIMER Timer Control Register */ -#define GPTIMER_CTRL_EN_BIT 0 -#define GPTIMER_CTRL_RS_BIT 1 -#define GPTIMER_CTRL_LD_BIT 2 -#define GPTIMER_CTRL_IE_BIT 3 -#define GPTIMER_CTRL_IP_BIT 4 -#define GPTIMER_CTRL_CH_BIT 5 -#define GPTIMER_CTRL_DH_BIT 6 - -#define GPTIMER_CTRL_EN (1<<GPTIMER_CTRL_EN_BIT) -#define GPTIMER_CTRL_RS (1<<GPTIMER_CTRL_RS_BIT) -#define GPTIMER_CTRL_LD (1<<GPTIMER_CTRL_LD_BIT) -#define GPTIMER_CTRL_IE (1<<GPTIMER_CTRL_IE_BIT) -#define GPTIMER_CTRL_IP (1<<GPTIMER_CTRL_IP_BIT) -#define GPTIMER_CTRL_CH (1<<GPTIMER_CTRL_CH_BIT) -#define GPTIMER_CTRL_DH (1<<GPTIMER_CTRL_DH_BIT) - -#define DBG(x...) - -/* GPTIMER timer private */ -struct gptimer_timer { - struct tlib_dev tdev; /* Must be first in struct */ - struct gptimer_timer_regs *tregs; - char index; /* Timer Index in this driver */ - char tindex; /* Timer Index In Hardware */ - unsigned char irq_ack_mask; -}; - -/* GPTIMER Core private */ -struct gptimer_priv { - struct drvmgr_dev *dev; - struct gptimer_regs *regs; - unsigned int base_clk; - unsigned int base_freq; - unsigned int widthmask; - char separate_interrupt; - char isr_installed; - - /* Structure per Timer unit, the core supports up to 8 timers */ - int timer_cnt; - struct gptimer_timer timers[0]; -}; - -void gptimer_isr(void *data); - -#if 0 -void gptimer_tlib_irq_register(struct tlib_drv *tdrv, tlib_isr_t func, void *data) -{ - struct gptimer_priv *priv = (struct gptimer_priv *)tdrv; - - if ( SHARED ...) - - - drvmgr_interrupt_register(); -} -#endif - -/******************* Driver manager interface ***********************/ - -/* Driver prototypes */ -static struct tlib_drv gptimer_tlib_drv; -int gptimer_device_init(struct gptimer_priv *priv); - -int gptimer_init1(struct drvmgr_dev *dev); -#ifdef GPTIMER_INFO_AVAIL -static int gptimer_info( - struct drvmgr_dev *dev, - void (*print_line)(void *p, char *str), - void *p, int, char *argv[]); -#define GTIMER_INFO_FUNC gptimer_info -#else -#define GTIMER_INFO_FUNC NULL -#endif - -struct drvmgr_drv_ops gptimer_ops = -{ - .init = {gptimer_init1, NULL, NULL, NULL}, - .remove = NULL, - .info = GTIMER_INFO_FUNC, -}; - -struct amba_dev_id gptimer_ids[] = -{ - {VENDOR_GAISLER, GAISLER_GPTIMER}, - {VENDOR_GAISLER, GAISLER_GRTIMER}, - {0, 0} /* Mark end of table */ -}; - -struct amba_drv_info gptimer_drv_info = -{ - { - DRVMGR_OBJ_DRV, /* Driver */ - NULL, /* Next driver */ - NULL, /* Device list */ - DRIVER_AMBAPP_GAISLER_GPTIMER_ID,/* Driver ID */ - "GPTIMER_DRV", /* Driver Name */ - DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */ - &gptimer_ops, - NULL, /* Funcs */ - 0, /* No devices yet */ - 0, - }, - &gptimer_ids[0] -}; - -void gptimer_register_drv (void) -{ - DBG("Registering GPTIMER driver\n"); - drvmgr_drv_register(&gptimer_drv_info.general); -} - -int gptimer_init1(struct drvmgr_dev *dev) -{ - struct gptimer_priv *priv; - struct gptimer_regs *regs; - struct amba_dev_info *ambadev; - struct ambapp_core *pnpinfo; - int timer_hw_cnt, timer_cnt, timer_start; - int i, size; - struct gptimer_timer *timer; - union drvmgr_key_value *value; - unsigned char irq_ack_mask; - - /* Get device information from AMBA PnP information */ - ambadev = (struct amba_dev_info *)dev->businfo; - if ( ambadev == NULL ) { - return -1; - } - pnpinfo = &ambadev->info; - regs = (struct gptimer_regs *)pnpinfo->apb_slv->start; - - DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name); - - /* Get number of Timers */ - timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS; - - /* Let user spelect a range of timers to be used. In AMP systems - * it is sometimes neccessary to leave timers for other CPU instances. - * - * The default operation in AMP is to shared the timers within the - * first GPTIMER core as below. This can of course be overrided by - * driver resources. - */ - timer_cnt = timer_hw_cnt; - timer_start = 0; -#if defined(RTEMS_MULTIPROCESSING) && defined(LEON3) - if ((dev->minor_drv == 0) && drvmgr_on_rootbus(dev)) { - timer_cnt = 1; - timer_start = LEON3_Cpu_Index; - } -#endif - value = drvmgr_dev_key_get(dev, "timerStart", DRVMGR_KT_INT); - if ( value) { - timer_start = value->i; - timer_cnt = timer_hw_cnt - timer_start; - } - value = drvmgr_dev_key_get(dev, "timerCnt", DRVMGR_KT_INT); - if ( value && (value->i < timer_cnt) ) { - timer_cnt = value->i; - } - - /* Allocate Common Timer Description, size depends on how many timers - * are present. - */ - size = sizeof(struct gptimer_priv) + - timer_cnt*sizeof(struct gptimer_timer); - priv = dev->priv = (struct gptimer_priv *)malloc(size); - if ( !priv ) - return DRVMGR_NOMEM; - memset(priv, 0, size); - priv->dev = dev; - priv->regs = regs; - - /* The Base Frequency of the GPTIMER core is the same as the - * frequency of the AMBA bus it is situated on. - */ - drvmgr_freq_get(dev, DEV_APB_SLV, &priv->base_clk); - - /* This core will may provide important Timer functionality - * to other drivers and the RTEMS kernel, the Clock driver - * may for example use this device. So the Timer driver must be - * initialized in the first iiitialization stage. - */ - - /*** Initialize Hardware ***/ - - /* If user request to set prescaler, we will do that. However, note - * that doing so for the Root-Bus GPTIMER may affect the RTEMS Clock - * so that Clock frequency is wrong. - */ - value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT); - if ( value ) - regs->scaler_reload = value->i; - - /* Get Frequency that the timers are operating in (after prescaler) */ - priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1); - - /* Stop Timer and probe Pending bit. In newer hardware the - * timer has pending bit is cleared by writing a one to it, - * whereas older versions it is cleared with a zero. - */ - priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP; - if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0) - irq_ack_mask = ~GPTIMER_CTRL_IP; - else - irq_ack_mask = ~0; - - /* Probe timer register width mask */ - priv->regs->timer[timer_start].value = 0xffffffff; - priv->widthmask = priv->regs->timer[timer_start].value; - - priv->timer_cnt = timer_cnt; - for (i=0; i<timer_cnt; i++) { - timer = &priv->timers[i]; - timer->index = i; - timer->tindex = i + timer_start; - timer->tregs = ®s->timer[(int)timer->tindex]; - timer->tdev.drv = &gptimer_tlib_drv; - timer->irq_ack_mask = irq_ack_mask; - - /* Register Timer at Timer Library */ - tlib_dev_reg(&timer->tdev); - } - - /* Check Interrupt support implementation, two cases: - * A. All Timers share one IRQ - * B. Each Timer have an individual IRQ. The number is: - * BASE_IRQ + timer_index - */ - priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0; - - return DRVMGR_OK; -} - -#ifdef GPTIMER_INFO_AVAIL -static int gptimer_info( - struct drvmgr_dev *dev, - void (*print_line)(void *p, char *str), - void *p, int argc, char *argv[]) -{ - struct gptimer_priv *priv = dev->priv; - struct gptimer_timer *timer; - char buf[64]; - int i; - - if (priv == NULL || argc != 0) - return -DRVMGR_EINVAL; - - sprintf(buf, "Timer Count: %d", priv->timer_cnt); - print_line(p, buf); - sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs); - print_line(p, buf); - sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload); - print_line(p, buf); - sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000); - print_line(p, buf); - sprintf(buf, "SeparateIRQ: %s", priv->separate_interrupt ? "YES":"NO"); - print_line(p, buf); - - for (i=0; i<priv->timer_cnt; i++) { - timer = &priv->timers[i]; - sprintf(buf, " - TIMER HW Index %d -", timer->tindex); - print_line(p, buf); - sprintf(buf, " TLIB Index: %d", timer->index); - print_line(p, buf); - sprintf(buf, " RELOAD REG: %d", timer->tregs->reload); - print_line(p, buf); - sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl); - print_line(p, buf); - } - - return DRVMGR_OK; -} -#endif - -static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t) -{ - return (struct gptimer_priv *) - ((unsigned int)t - - sizeof(struct gptimer_priv) - - t->index * sizeof(struct gptimer_timer)); -} - -static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl = timer->tregs->ctrl; - - if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) == - (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) { - /* clear Pending IRQ ? */ - if (ack) - timer->tregs->ctrl = ctrl & timer->irq_ack_mask; - return 1; /* timer generated IRQ */ - } else - return 0; /* was not timer causing IRQ */ -} - -void gptimer_isr(void *data) -{ - struct gptimer_priv *priv = data; - int i; - - /* Check all timers for IRQ */ - for (i=0;i<priv->timer_cnt; i++) { - if (gptimer_tlib_int_pend((void *)&priv->timers[i], 0)) { - /* IRQ Was generated by Timer and Pending flag has *not* - * yet been cleared, this is to allow ISR to look at - * pending bit. Call ISR registered. Clear pending bit. - */ - if (priv->timers[i].tdev.isr_func) { - priv->timers[i].tdev.isr_func( - priv->timers[i].tdev.isr_data); - } - gptimer_tlib_int_pend((void *)&priv->timers[i], 1); - } - } -} - -static void gptimer_tlib_reset(struct tlib_dev *hand) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) & - GPTIMER_CTRL_IP; - timer->tregs->reload = 0xffffffff; - timer->tregs->ctrl = GPTIMER_CTRL_LD; -} - -static void gptimer_tlib_get_freq( - struct tlib_dev *hand, - unsigned int *basefreq, - unsigned int *tickrate) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - struct gptimer_priv *priv = priv_from_timer(timer); - - /* Calculate base frequency from Timer Clock and Prescaler */ - if ( basefreq ) - *basefreq = priv->base_freq; - if ( tickrate ) - *tickrate = timer->tregs->reload + 1; -} - -static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - timer->tregs->reload = tickrate - 1; - - /*Check that value was allowed (Timer may not be as wide as expected)*/ - if ( timer->tregs->reload != (tickrate - 1) ) - return -1; - else - return 0; -} - -static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - struct gptimer_priv *priv = priv_from_timer(timer); - - if ( priv->separate_interrupt ) { - drvmgr_interrupt_register(priv->dev, timer->tindex, - "gptimer", func, data); - } else { - if (priv->isr_installed == 0) { - /* Shared IRQ handler */ - drvmgr_interrupt_register( - priv->dev, - 0, - "gptimer_shared", - gptimer_isr, - priv); - } - priv->isr_installed++; - } - -#if RTEMS_SMP - if (flags & TLIB_FLAGS_BROADCAST) { - int tindex = 0; - - if (priv->separate_interrupt) { - /* Offset interrupt number with HW subtimer index */ - tindex = timer->tindex; - } - drvmgr_interrupt_set_affinity(priv->dev, tindex, - _SMP_Get_online_processors()); - } -#endif - - timer->tregs->ctrl |= GPTIMER_CTRL_IE; -} - -static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - struct gptimer_priv *priv = priv_from_timer(timer); - - /* Turn off IRQ at source, unregister IRQ handler */ - timer->tregs->ctrl &= ~GPTIMER_CTRL_IE; - - if ( priv->separate_interrupt ) { - drvmgr_interrupt_unregister(priv->dev, timer->tindex, - func, data); - } else { - timer->tdev.isr_func = NULL; - priv->isr_installed--; - if (priv->isr_installed == 0) { - drvmgr_interrupt_unregister(priv->dev, 0, - gptimer_isr, priv); - } - } -} - -static void gptimer_tlib_start(struct tlib_dev *hand, int once) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl; - - /* Load the selected frequency before starting Frequency */ - ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; - if ( once == 0 ) - ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */ - timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask & - ~GPTIMER_CTRL_RS); -} - -static void gptimer_tlib_stop(struct tlib_dev *hand) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - /* Load the selected Frequency */ - timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP); -} - -static void gptimer_tlib_restart(struct tlib_dev *hand) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; -} - -static void gptimer_tlib_get_counter( - struct tlib_dev *hand, - unsigned int *counter) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - *counter = timer->tregs->value; -} - -static void gptimer_tlib_get_widthmask( - struct tlib_dev *hand, - unsigned int *widthmask) -{ - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - struct gptimer_priv *priv = priv_from_timer(timer); - - *widthmask = priv->widthmask; -} - -static struct tlib_drv gptimer_tlib_drv = -{ - .reset = gptimer_tlib_reset, - .get_freq = gptimer_tlib_get_freq, - .set_freq = gptimer_tlib_set_freq, - .irq_reg = gptimer_tlib_irq_reg, - .irq_unreg = gptimer_tlib_irq_unreg, - .start = gptimer_tlib_start, - .stop = gptimer_tlib_stop, - .restart = gptimer_tlib_restart, - .get_counter = gptimer_tlib_get_counter, - .custom = NULL, - .int_pend = gptimer_tlib_int_pend, - .get_widthmask = gptimer_tlib_get_widthmask, -}; diff --git a/c/src/lib/libbsp/sparc/shared/timer/tlib.c b/c/src/lib/libbsp/sparc/shared/timer/tlib.c deleted file mode 100644 index a0525d072d..0000000000 --- a/c/src/lib/libbsp/sparc/shared/timer/tlib.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Timer Library (TLIB) - * - * COPYRIGHT (c) 2011. - * Cobham Gaisler AB. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include <rtems.h> -#include <bsp/tlib.h> - -struct tlib_dev *tlib_dev_head = NULL; -struct tlib_dev *tlib_dev_tail = NULL; -static int tlib_dev_cnt = 0; - -/* Register Timer device to Timer Library */ -int tlib_dev_reg(struct tlib_dev *newdev) -{ - /* Reset device */ - newdev->status = 0; - newdev->isr_func = NULL; - newdev->index = tlib_dev_cnt; - - /* Insert last in queue */ - newdev->next = NULL; - if ( tlib_dev_tail == NULL ) { - tlib_dev_head = newdev; - } else { - tlib_dev_tail->next = newdev; - } - tlib_dev_tail = newdev; - - /* Return Index of Registered Timer */ - return tlib_dev_cnt++; -} - -void *tlib_open(int timer_no) -{ - struct tlib_dev *dev; - - if ( timer_no < 0 ) - return NULL; - - dev = tlib_dev_head; - while ( (timer_no > 0) && dev ) { - timer_no--; - dev = dev->next; - } - if ( dev ) { - if ( dev->status ) - return NULL; - dev->status = 1; - /* Reset Timer to initial state */ - tlib_reset(dev); - } - return dev; -} - -void tlib_close(void *hand) -{ - struct tlib_dev *dev = hand; - - /* Stop any ongoing timer operation and unregister IRQ if registered */ - tlib_stop(dev); - tlib_irq_unregister(dev); - - /* Mark not open */ - dev->status = 0; -} - -int tlib_ntimer(void) -{ - return tlib_dev_cnt; -} diff --git a/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c b/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c deleted file mode 100644 index 3f56d725d9..0000000000 --- a/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Clock Tick Device Driver using Timer Library implemented - * by the GRLIB GPTIMER / LEON2 Timer drivers. - * - * COPYRIGHT (c) 2010 - 2017. - * Cobham Gaisler AB. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -/* - * This is an implementation of the RTEMS "clockdrv_shell" interface for - * LEON2/3/4 systems using the Driver Manager. It is clock hardware agnostic - * and compatible with SMP and UP. Availability of free running counters is - * probed and selected as needed. - */ -#include <rtems.h> -#include <rtems/timecounter.h> -#include <rtems/clockdrv.h> -#include <stdlib.h> -#include <bsp.h> -#include <bsp/tlib.h> - -#ifdef RTEMS_DRVMGR_STARTUP - -#if defined(LEON3) -#include <leon.h> -#endif - -struct ops { - /* - * Set up the free running counter using the Timecounter or Simple - * Timecounter interface. - */ - rtems_device_driver (*initialize_counter)(void); - - /* - * Hardware-specific support at tick interrupt which runs early in Clock_isr. - * It can for example be used to check if interrupt was actually caused by - * the timer hardware. If return value is not RTEMS_SUCCESSFUL then Clock_isr - * returns immediately. at_tick can be initialized with NULL. - */ - rtems_device_driver (*at_tick)(void); - - /* - * Typically calls rtems_timecounter_tick(). A specialized clock driver may - * use for example rtems_timecounter_tick_simple() instead. - */ - void (*timecounter_tick)(void); - - /* - * Called when the clock driver exits. It can be used to stop functionality - * started by initialize_counter. The tick timer is stopped by default. - * shutdown_hardware can be initialized with NULL - */ - void (*shutdown_hardware)(void); -}; - -/* - * Different implementation depending on available free running counter for the - * timecounter. - * - * NOTE: The clock interface is not compatible with shared interrupts on the - * clock (tick) timer in SMP configuration. - */ - -/* "simple timecounter" interface. Only for non-SMP. */ -static const struct ops ops_simple; -/* Hardware support up-counter using LEON3 %asr23. */ -static const struct ops ops_timetag; -/* Timestamp counter available in some IRQ(A)MP instantiations. */ -static const struct ops ops_irqamp; -/* Separate GPTIMER subtimer as timecounter */ -static const struct ops ops_subtimer; - -struct clock_priv { - const struct ops *ops; - /* - * Timer number in Timer Library for tick timer used by this interface. - * Defaults to the first Timer in the System. - */ - int tlib_tick_index; - /* Timer number for timecounter timer if separate GPTIMER subtimer is used */ - int tlib_counter_index; - void *tlib_tick; - void *tlib_counter; - rtems_timecounter_simple tc_simple; - struct timecounter tc; -}; -static struct clock_priv priv; - -/** Common interface **/ - -/* Set system clock timer instance */ -void Clock_timer_register(int timer_number) -{ - priv.tlib_tick_index = timer_number; - priv.tlib_counter_index = timer_number + 1; -} - -static rtems_device_driver tlib_clock_find_timer(void) -{ - /* Take Timer that should be used as system timer. */ - priv.tlib_tick = tlib_open(priv.tlib_tick_index); - if (priv.tlib_tick == NULL) { - /* System Clock Timer not found */ - return RTEMS_NOT_DEFINED; - } - - /* Select which operation set to use */ -#ifndef RTEMS_SMP - priv.ops = &ops_simple; -#else - /* When on LEON3 try to use dedicated hardware free running counter. */ - leon3_up_counter_enable(); - if (leon3_up_counter_is_available()) { - priv.ops = &ops_timetag; - return RTEMS_SUCCESSFUL; - } else { - volatile struct irqmp_timestamp_regs *irqmp_ts; - - irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0]; - if (leon3_irqmp_has_timestamp(irqmp_ts)) { - priv.ops = &ops_irqamp; - return RTEMS_SUCCESSFUL; - } - } - - /* Take another subtimer as the final option. */ - priv.ops = &ops_subtimer; -#endif - - return RTEMS_SUCCESSFUL; -} - -static rtems_device_driver tlib_clock_initialize_hardware(void) -{ - /* Set tick rate in number of "Base-Frequency ticks" */ - tlib_set_freq(priv.tlib_tick, rtems_configuration_get_microseconds_per_tick()); - priv.ops->initialize_counter(); - tlib_start(priv.tlib_tick, 0); - - return RTEMS_SUCCESSFUL; -} - -static rtems_device_driver tlib_clock_at_tick(void) -{ - if (priv.ops->at_tick) { - return priv.ops->at_tick(); - } - - return RTEMS_SUCCESSFUL; -} - -static void tlib_clock_timecounter_tick(void) -{ - priv.ops->timecounter_tick(); -} - -/* Return a value not equal to RTEMS_SUCCESFUL to make Clock_initialize fail. */ -static rtems_device_driver tlib_clock_install_isr(rtems_isr *isr) -{ - int flags = 0; - -#ifdef RTEMS_SMP - /* We shall broadcast the clock interrupt to all processors. */ - flags = TLIB_FLAGS_BROADCAST; -#endif - tlib_irq_register(priv.tlib_tick, isr, NULL, flags); - - return RTEMS_SUCCESSFUL; -} - -static void tlib_clock_shutdown_hardware(void) -{ - if (priv.tlib_tick) { - tlib_stop(priv.tlib_tick); - priv.tlib_tick = NULL; - } - if (priv.ops->shutdown_hardware) { - priv.ops->shutdown_hardware(); - } -} - -/** Simple counter **/ -static uint32_t simple_tlib_tc_get(rtems_timecounter_simple *tc) -{ - unsigned int clicks = 0; - - if (priv.tlib_tick != NULL) { - tlib_get_counter(priv.tlib_tick, &clicks); - } - - return clicks; -} - -static bool simple_tlib_tc_is_pending(rtems_timecounter_simple *tc) -{ - bool pending = false; - - if (priv.tlib_tick != NULL) { - pending = tlib_interrupt_pending(priv.tlib_tick, 0) != 0; - } - - return pending; -} - -static uint32_t simple_tlib_tc_get_timecount(struct timecounter *tc) -{ - return rtems_timecounter_simple_downcounter_get( - tc, - simple_tlib_tc_get, - simple_tlib_tc_is_pending - ); -} - -static rtems_device_driver simple_initialize_counter(void) -{ - uint64_t frequency; - unsigned int tick_hz; - - frequency = 1000000; - tick_hz = rtems_configuration_get_microseconds_per_tick(); - - rtems_timecounter_simple_install( - &priv.tc_simple, - frequency, - tick_hz, - simple_tlib_tc_get_timecount - ); - - return RTEMS_NOT_DEFINED; -} - -static void simple_tlib_tc_at_tick(rtems_timecounter_simple *tc) -{ - /* Nothing to do */ -} - -/* - * Support for shared interrupts. Ack IRQ at source, only handle interrupts - * generated from the tick-timer. This is called early in Clock_isr. - */ -static rtems_device_driver simple_at_tick(void) -{ - if (tlib_interrupt_pending(priv.tlib_tick, 1) == 0) { - return RTEMS_NOT_DEFINED; - } - return RTEMS_SUCCESSFUL; -} - -static void simple_timecounter_tick(void) -{ - rtems_timecounter_simple_downcounter_tick( - &priv.tc_simple, - simple_tlib_tc_get, - simple_tlib_tc_at_tick - ); -} - -static const struct ops ops_simple = { - .initialize_counter = simple_initialize_counter, - .at_tick = simple_at_tick, - .timecounter_tick = simple_timecounter_tick, - .shutdown_hardware = NULL, -}; - -/** Subtimer as counter **/ -static uint32_t subtimer_get_timecount(struct timecounter *tc) -{ - unsigned int counter; - - tlib_get_counter(priv.tlib_counter, &counter); - - return 0xffffffff - counter; -} - -static rtems_device_driver subtimer_initialize_counter(void) -{ - unsigned int mask; - unsigned int basefreq; - - if (priv.tlib_counter_index == priv.tlib_tick_index) { - priv.tlib_counter_index = priv.tlib_tick_index + 1; - } - /* Take Timer that should be used as timecounter upcounter timer. */ - priv.tlib_counter = tlib_open(priv.tlib_counter_index); - if (priv.tlib_counter == NULL) { - /* Timecounter timer not found */ - return RTEMS_NOT_DEFINED; - } - - /* Configure free running counter: GPTIMER */ - tlib_get_freq(priv.tlib_counter, &basefreq, NULL); - tlib_get_widthmask(priv.tlib_counter, &mask); - - priv.tc.tc_get_timecount = subtimer_get_timecount; - priv.tc.tc_counter_mask = mask; - priv.tc.tc_frequency = basefreq; - priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; - rtems_timecounter_install(&priv.tc); - /* Start free running counter */ - tlib_start(priv.tlib_counter, 0); - - return RTEMS_SUCCESSFUL; -} - -static void subtimer_timecounter_tick(void) -{ - rtems_timecounter_tick(); -} - -static void subtimer_shutdown_hardware(void) -{ - if (priv.tlib_counter) { - tlib_stop(priv.tlib_counter); - priv.tlib_counter = NULL; - } -} - -static const struct ops ops_subtimer = { - .initialize_counter = subtimer_initialize_counter, - .timecounter_tick = subtimer_timecounter_tick, - .shutdown_hardware = subtimer_shutdown_hardware, -}; - -#if defined(LEON3) -/** DSU timetag as counter **/ -static uint32_t timetag_get_timecount(struct timecounter *tc) -{ - return leon3_up_counter_low(); -} - -static rtems_device_driver timetag_initialize_counter(void) -{ - /* Configure free running counter: timetag */ - priv.tc.tc_get_timecount = timetag_get_timecount; - priv.tc.tc_counter_mask = 0xffffffff; - priv.tc.tc_frequency = leon3_up_counter_frequency(); - priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; - rtems_timecounter_install(&priv.tc); - - return RTEMS_SUCCESSFUL; -} - -static void timetag_timecounter_tick(void) -{ - rtems_timecounter_tick(); -} - -static const struct ops ops_timetag = { - .initialize_counter = timetag_initialize_counter, - .at_tick = NULL, - .timecounter_tick = timetag_timecounter_tick, - .shutdown_hardware = NULL, -}; -#endif - -#if defined(LEON3) -/** IRQ(A)MP timestamp as counter **/ -static uint32_t irqamp_get_timecount(struct timecounter *tc) -{ - return LEON3_IrqCtrl_Regs->timestamp[0].counter; -} - -static rtems_device_driver irqamp_initialize_counter(void) -{ - volatile struct irqmp_timestamp_regs *irqmp_ts; - static const uint32_t A_TSISEL_FIELD = 0xf; - - /* Configure free running counter: timetag */ - priv.tc.tc_get_timecount = irqamp_get_timecount; - priv.tc.tc_counter_mask = 0xffffffff; - priv.tc.tc_frequency = leon3_up_counter_frequency(); - priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; - rtems_timecounter_install(&priv.tc); - - /* - * The counter increments whenever a TSISEL field in a Timestamp Control - * Register is non-zero. - */ - irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0]; - irqmp_ts->control = A_TSISEL_FIELD; - - return RTEMS_SUCCESSFUL; -} - -static void irqamp_timecounter_tick(void) -{ - rtems_timecounter_tick(); -} - -static const struct ops ops_irqamp = { - .initialize_counter = irqamp_initialize_counter, - .at_tick = NULL, - .timecounter_tick = irqamp_timecounter_tick, - .shutdown_hardware = NULL, -}; -#endif - -/** Interface to the Clock Driver Shell (dev/clock/clockimpl.h) **/ -#define Clock_driver_support_find_timer() \ - do { \ - rtems_device_driver ret; \ - ret = tlib_clock_find_timer(); \ - if (RTEMS_SUCCESSFUL != ret) { \ - return ret; \ - } \ - } while (0) - -#define Clock_driver_support_install_isr( isr ) \ - do { \ - rtems_device_driver ret; \ - ret = tlib_clock_install_isr( isr ); \ - if (RTEMS_SUCCESSFUL != ret) { \ - return ret; \ - } \ - } while (0) - -#define Clock_driver_support_set_interrupt_affinity(online_processors) \ - /* Done by tlib_clock_install_isr() */ - -#define Clock_driver_support_initialize_hardware() \ - do { \ - rtems_device_driver ret; \ - ret = tlib_clock_initialize_hardware(); \ - if (RTEMS_SUCCESSFUL != ret) { \ - return ret; \ - } \ - } while (0) - -#define Clock_driver_support_shutdown_hardware() \ - tlib_clock_shutdown_hardware() - -#define Clock_driver_timecounter_tick() \ - tlib_clock_timecounter_tick() - -#define Clock_driver_support_at_tick() \ - do { \ - rtems_device_driver ret; \ - ret = tlib_clock_at_tick(); \ - if (RTEMS_SUCCESSFUL != ret) { \ - return; \ - } \ - } while (0) - -#include "../../../shared/dev/clock/clockimpl.h" - -#endif /* RTEMS_DRVMGR_STARTUP */ - |