ARM: make cycle counter available to userspace
This commit is contained in:
parent
ea8ff9284a
commit
aa3623d873
8 changed files with 67 additions and 4 deletions
|
@ -17,6 +17,7 @@
|
|||
#include "serial.h"
|
||||
#include "kernel/proc.h"
|
||||
#include "kernel/debug.h"
|
||||
#include "omap_ccnt.h"
|
||||
|
||||
#include "glo.h"
|
||||
|
||||
|
@ -80,6 +81,8 @@ void cpu_identify(void)
|
|||
|
||||
void arch_init(void)
|
||||
{
|
||||
u32_t value;
|
||||
|
||||
k_stacks = (void*) &k_stacks_start;
|
||||
assert(!((vir_bytes) k_stacks % K_STACK_SIZE));
|
||||
|
||||
|
@ -92,6 +95,21 @@ void arch_init(void)
|
|||
#endif
|
||||
|
||||
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"
|
||||
|
||||
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
|
||||
static u64_t tsc;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static u64_t tsc;
|
||||
void omap3_timer_int_handler()
|
||||
{
|
||||
/* Clear the interrupt */
|
||||
|
@ -60,6 +60,10 @@ void omap3_timer_int_handler()
|
|||
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)
|
||||
{
|
||||
*t = tsc;
|
||||
|
|
|
@ -19,7 +19,7 @@ SRCS+= dhcp_gettag.c dhcp_settag.c
|
|||
SRCS+= gcov.c gcov_flush.c
|
||||
|
||||
# Various utils
|
||||
SRCS+= itoa.c u64util.c
|
||||
SRCS+= itoa.c u64util.c read_tsc_64.c
|
||||
|
||||
# svrctl
|
||||
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 \
|
||||
read_tsc.S read_tsc_64.c
|
||||
read_tsc.S
|
||||
|
|
Loading…
Reference in a new issue