score: Add CPU counter support

Add a CPU counter interface to allow access to a free-running counter.
It is useful to measure short time intervals.  This can be used for
example to enable profiling of critical low-level functions.

Add two busy wait functions rtems_counter_delay_ticks() and
rtems_counter_delay_nanoseconds() implemented via the CPU counter.
This commit is contained in:
Sebastian Huber
2014-02-12 10:31:38 +01:00
parent 382ea27b6a
commit 24bf11eca1
97 changed files with 985 additions and 5 deletions

View File

@@ -38,6 +38,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
../../sparc/shared/startup/bspgetworkarea.c ../../shared/sbrk.c startup/setvec.c \
startup/spurious.c startup/bspidle.S startup/bspdelay.c \
../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.c
libbsp_a_SOURCES += startup/cpucounter.c
# ISR Handler
libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S

View File

@@ -209,6 +209,10 @@ extern void BSP_shared_interrupt_unmask(int irq);
*/
extern void BSP_shared_interrupt_mask(int irq);
typedef enum {
LEON3_FATAL_CPU_COUNTER_INIT
} leon3_fatal_code;
#ifdef __cplusplus
}
#endif

View File

@@ -317,6 +317,8 @@ int apbuart_inbyte_nonblocking(struct apbuart_regs *regs);
*/
void leon3_secondary_cpu_initialize(uint32_t cpu);
void leon3_cpu_counter_initialize(void);
void bsp_debug_uart_init(void);
#endif /* !ASM */

View File

@@ -79,6 +79,7 @@ void bsp_start( void )
* interrupt support
*/
amba_initialize();
leon3_cpu_counter_initialize();
/* find debug UART for printk() */
bsp_debug_uart_init();

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <bsp.h>
#include <leon.h>
#include <rtems/counter.h>
static volatile struct gptimer_regs *leon3_cpu_counter_gpt;
void leon3_cpu_counter_initialize(void)
{
struct ambapp_dev *adev;
int idx = 1;
volatile struct gptimer_regs *gpt;
unsigned new_prescaler = 8;
unsigned prescaler;
uint32_t frequency;
adev = (void *) ambapp_for_each(
&ambapp_plb,
OPTIONS_ALL | OPTIONS_APB_SLVS,
VENDOR_GAISLER,
GAISLER_GPTIMER,
ambapp_find_by_idx,
&idx
);
if (adev == NULL) {
rtems_fatal(RTEMS_FATAL_SOURCE_BSP_SPECIFIC, LEON3_FATAL_CPU_COUNTER_INIT);
}
gpt = (volatile struct gptimer_regs *) DEV_TO_APB(adev)->start;
prescaler = gpt->scaler_reload + 1;
gpt->scaler_reload = new_prescaler - 1;
gpt->timer[0].reload = 0xffffffff;
gpt->timer[0].ctrl = LEON3_GPTIMER_EN | LEON3_GPTIMER_RL
| LEON3_GPTIMER_LD;
leon3_cpu_counter_gpt = gpt;
/* Assume that GRMON initialized the timer to 1MHz */
frequency = UINT32_C(1000000) * (prescaler / new_prescaler);
rtems_counter_initialize_converter(frequency);
}
CPU_Counter_ticks _CPU_Counter_read(void)
{
volatile struct gptimer_regs *gpt = leon3_cpu_counter_gpt;
return 0U - gpt->timer[0].value;
}