ARM: make cycle counter available to userspace
This commit is contained in:
parent
ea8ff9284a
commit
aa3623d873
@ -17,6 +17,7 @@
|
|||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "kernel/proc.h"
|
#include "kernel/proc.h"
|
||||||
#include "kernel/debug.h"
|
#include "kernel/debug.h"
|
||||||
|
#include "omap_ccnt.h"
|
||||||
|
|
||||||
#include "glo.h"
|
#include "glo.h"
|
||||||
|
|
||||||
@ -80,6 +81,8 @@ void cpu_identify(void)
|
|||||||
|
|
||||||
void arch_init(void)
|
void arch_init(void)
|
||||||
{
|
{
|
||||||
|
u32_t value;
|
||||||
|
|
||||||
k_stacks = (void*) &k_stacks_start;
|
k_stacks = (void*) &k_stacks_start;
|
||||||
assert(!((vir_bytes) k_stacks % K_STACK_SIZE));
|
assert(!((vir_bytes) k_stacks % K_STACK_SIZE));
|
||||||
|
|
||||||
@ -92,6 +95,21 @@ void arch_init(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ser_init();
|
ser_init();
|
||||||
|
|
||||||
|
/* enable user space access to cycle counter */
|
||||||
|
/* set cycle counter to 0: ARM ARM B4.1.113 and B4.1.117 */
|
||||||
|
asm volatile ("MRC p15, 0, %0, c9, c12, 0\t\n": "=r" (value));
|
||||||
|
value |= OMAP_PMCR_C; /* Reset counter */
|
||||||
|
value |= OMAP_PMCR_E; /* Enable counter hardware */
|
||||||
|
asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n": : "r" (value));
|
||||||
|
|
||||||
|
/* enable CCNT counting: ARM ARM B4.1.116 */
|
||||||
|
value = OMAP_PMCNTENSET_C; /* Enable PMCCNTR cycle counter */
|
||||||
|
asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n": : "r" (value));
|
||||||
|
|
||||||
|
/* enable cycle counter in user mode: ARM ARM B4.1.124 */
|
||||||
|
value = OMAP_PMUSERENR_EN;
|
||||||
|
asm volatile ("MCR p15, 0, %0, c9, c14, 0\t\n": : "r" (value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
21
kernel/arch/arm/omap_ccnt.h
Normal file
21
kernel/arch/arm/omap_ccnt.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _OMAP_CCNT_H
|
||||||
|
#define _OMAP_CCNT_H
|
||||||
|
|
||||||
|
/* ARM ARM B4.1.116 */
|
||||||
|
#define OMAP_PMCNTENSET_C (1 << 31) /* Enable PMCCNTR cycle counter */
|
||||||
|
|
||||||
|
/* ARM ARM B4.1.117 PMCR */
|
||||||
|
#define OMAP_PMCR_DP (1 << 5) /* Disable when ev. cnt. prohibited */
|
||||||
|
#define OMAP_PMCR_X (1 << 4) /* Export enable */
|
||||||
|
#define OMAP_PMCR_D (1 << 3) /* Clock divider */
|
||||||
|
#define OMAP_PMCR_C (1 << 2) /* Cycle counter reset */
|
||||||
|
#define OMAP_PMCR_P (1 << 1) /* Event counter reset */
|
||||||
|
#define OMAP_PMCR_E (1 << 0) /* Enable event counters */
|
||||||
|
|
||||||
|
/* ARM ARM B4.1.119 PMINTENSET */
|
||||||
|
#define OMAP_PMINTENSET_C (1 << 31) /* PMCCNTR overflow int req. enable*/
|
||||||
|
|
||||||
|
/* ARM ARM B4.1.124 PMUSERENR */
|
||||||
|
#define OMAP_PMUSERENR_EN (1 << 0) /* User mode access enable bit */
|
||||||
|
|
||||||
|
#endif /* _OMAP_CCNT_H */
|
@ -8,6 +8,7 @@
|
|||||||
#include "omap_intr.h"
|
#include "omap_intr.h"
|
||||||
|
|
||||||
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
|
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
|
||||||
|
static u64_t tsc;
|
||||||
|
|
||||||
int omap3_register_timer_handler(const irq_handler_t handler)
|
int omap3_register_timer_handler(const irq_handler_t handler)
|
||||||
{
|
{
|
||||||
@ -52,7 +53,6 @@ void omap3_timer_stop()
|
|||||||
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST);
|
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64_t tsc;
|
|
||||||
void omap3_timer_int_handler()
|
void omap3_timer_int_handler()
|
||||||
{
|
{
|
||||||
/* Clear the interrupt */
|
/* Clear the interrupt */
|
||||||
@ -60,6 +60,10 @@ void omap3_timer_int_handler()
|
|||||||
tsc++;
|
tsc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't use libminlib's read_tsc_64, but our own version instead. We emulate
|
||||||
|
* the ARM Cycle Counter (CCNT) with 1 cycle per ms. We can't rely on the
|
||||||
|
* actual counter hardware to be working (i.e., qemu doesn't emulate it at all)
|
||||||
|
*/
|
||||||
void read_tsc_64(u64_t *t)
|
void read_tsc_64(u64_t *t)
|
||||||
{
|
{
|
||||||
*t = tsc;
|
*t = tsc;
|
||||||
|
@ -19,7 +19,7 @@ SRCS+= dhcp_gettag.c dhcp_settag.c
|
|||||||
SRCS+= gcov.c gcov_flush.c
|
SRCS+= gcov.c gcov_flush.c
|
||||||
|
|
||||||
# Various utils
|
# Various utils
|
||||||
SRCS+= itoa.c u64util.c
|
SRCS+= itoa.c u64util.c read_tsc_64.c
|
||||||
|
|
||||||
# svrctl
|
# svrctl
|
||||||
SRCS+= svrctl.c
|
SRCS+= svrctl.c
|
||||||
|
@ -1 +1 @@
|
|||||||
SRCS+= get_bp.S
|
SRCS+= get_bp.S read_tsc.c
|
||||||
|
20
lib/libminlib/arm/read_tsc.c
Normal file
20
lib/libminlib/arm/read_tsc.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
read_tsc(u32_t *hi, u32_t *lo)
|
||||||
|
{
|
||||||
|
/* Read Clock Cycle Counter (CCNT). Intel calls it Time Stamp Counter (TSC) */
|
||||||
|
u32_t ccnt;
|
||||||
|
|
||||||
|
/* Get value from the Performance Monitors Cycle Counter Register.
|
||||||
|
* See ARM Architecture Reference Manual B5.1.113.
|
||||||
|
*/
|
||||||
|
asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n" : "=r" (ccnt) : : "%0");
|
||||||
|
|
||||||
|
/* The ARMv7-A clock cycle counter is only 32-bits, but read_tsc is
|
||||||
|
* expected to return a 64-bit value. hi is therefore always 0.
|
||||||
|
*/
|
||||||
|
*hi = 0;
|
||||||
|
*lo = ccnt;
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,2 @@
|
|||||||
SRCS+= _cpufeature.c _cpuid.S get_bp.S getprocessor.S \
|
SRCS+= _cpufeature.c _cpuid.S get_bp.S getprocessor.S \
|
||||||
read_tsc.S read_tsc_64.c
|
read_tsc.S
|
||||||
|
Loading…
x
Reference in New Issue
Block a user