OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [platform/] [beagle/] [perfmon.c] - Rev 2

Compare with Previous | Blame | View Log

/*
 * Platform specific perfmon initialization
 *
 * Copyright (C) 2010 B Labs Ltd.
 *
 * Author: Bahadir Balban
 */
#include INC_PLAT(timer.h)
#include <l4/lib/printk.h>
#include INC_PLAT(offsets.h)
#include INC_SUBARCH(perfmon.h)
#include INC_SUBARCH(mmu_ops.h)
#include INC_GLUE(memlayout.h)
/*
 * Current findings by these tests:
 *
 * Cpu cycle count and timer ticks are consistently showing 400Mhz
 * with a reference timer tick of 1Mhz. So cycle counts are fixed
 * with regard to the timer.
 *
 * Instruction execute count on the busy_loop however, is varying
 * between x1, x2 combinations when compared to timer and cycle
 * count values. This is happening by trivial changes in code such
 * as adding a function call. (Other variables are ruled out, e.g.
 * no concurrent memory accesses, caches are off)
 *
 * There may be two causes to this:
 * - Due to missing dmb/dsb/isb instructions.
 * - Due to BTC (busy_loop has one branch) which may describe
 * the doubling in IPC, since out of the 2 instructions in the
 * busy loop one is a branch.
 *
 * Disabling the BTC increased cycle counts per instruction
 * significantly, advising us not to expect any accuracy in counting
 * instructions in cycles. Hence instruction-based tests are
 * commented out. It is wise to only rely upon timer and cycle counts.
 */
void platform_test_tick_cycles()
{
	/* Initialize the timer */
	const unsigned int load_value = 0xffffffff - 100000;
	int mhz_top, mhz_bot, temp;
	unsigned long timer_base = PLATFORM_TIMER1_VBASE;
	int cyccnt;
 
	/* Make sure timer is disabled */
	timer_stop(timer_base);
 
	/* One shot, 32 bits, no irqs */
	timer_init_oneshot(timer_base);
 
	/* Load the timer with ticks value */
        timer_load(timer_base, load_value);
 
	/* Start the timer */
	timer_start(timer_base);
 
	/* Start counter */
	perfmon_reset_start_cyccnt();
 
	/* Wait until 0 */
	while (timer_read(timer_base) != 0)
		;
 
	cyccnt = perfmon_read_cyccnt();
 
	/* Fixed-point accuracy on bottom digit */
	temp = cyccnt * 64 * 10 * 13 / 100000;
	mhz_top = temp / 10;
	mhz_bot = temp - mhz_top * 10;
 
	printk("Perfmon: 0x%x cycle count \n", cyccnt);
	printk("%s: %d.%d MHz CPU speed measured by timer REFCLK at 13MHz\n",
	       __KERNELNAME__, mhz_top, mhz_bot);
}
 
void platform_test_cpucycles(void)
{
	/*
	 * Variable results:
	 *
	 * platform_test_loop_cycles();
	 * platform_test_loop_ticks();
	 */
 
	/* Fixed result */
	platform_test_tick_cycles();
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.