minix/kernel/arch/earm/arch_clock.c
Lionel Sambuc b1c4ba4ab6 ARM updates
Due to the ABI we are using we have to use the earm architecture
moniker for the build system to behave correctly. This involves
then some headers to move around.

There is also a few related Makefile updates as well as minor
source code corrections.
2013-01-17 10:03:58 +01:00

142 lines
2.6 KiB
C

/* ARM-specific clock functions. */
#include "kernel/kernel.h"
#include "kernel/clock.h"
#include "kernel/proc.h"
#include "kernel/interrupt.h"
#include <minix/u64.h>
#include "kernel/glo.h"
#include "kernel/profile.h"
#include "kernel/spinlock.h"
#ifdef CONFIG_SMP
#include "kernel/smp.h"
#endif
#include "omap_timer.h"
#include "omap_intr.h"
static unsigned tsc_per_ms[CONFIG_MAX_CPUS];
int init_local_timer(unsigned freq)
{
omap3_timer_init(freq);
/* always only 1 cpu in the system */
tsc_per_ms[0] = 1;
return 0;
}
void stop_local_timer(void)
{
omap3_timer_stop();
}
void arch_timer_int_handler(void)
{
omap3_timer_int_handler();
}
void cycles_accounting_init(void)
{
read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch));
make_zero64(get_cpu_var(cpu, cpu_last_tsc));
make_zero64(get_cpu_var(cpu, cpu_last_idle));
}
void context_stop(struct proc * p)
{
u64_t tsc, tsc_delta;
u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
read_tsc_64(&tsc);
p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
tsc_delta = sub64(tsc, *__tsc_ctr_switch);
if(kbill_ipc) {
kbill_ipc->p_kipc_cycles =
add64(kbill_ipc->p_kipc_cycles, tsc_delta);
kbill_ipc = NULL;
}
if(kbill_kcall) {
kbill_kcall->p_kcall_cycles =
add64(kbill_kcall->p_kcall_cycles, tsc_delta);
kbill_kcall = NULL;
}
/*
* deduct the just consumed cpu cycles from the cpu time left for this
* process during its current quantum. Skip IDLE and other pseudo kernel
* tasks
*/
if (p->p_endpoint >= 0) {
#if DEBUG_RACE
make_zero64(p->p_cpu_time_left);
#else
/* if (tsc_delta < p->p_cpu_time_left) in 64bit */
if (ex64hi(tsc_delta) < ex64hi(p->p_cpu_time_left) ||
(ex64hi(tsc_delta) == ex64hi(p->p_cpu_time_left) &&
ex64lo(tsc_delta) < ex64lo(p->p_cpu_time_left)))
{
p->p_cpu_time_left = sub64(p->p_cpu_time_left, tsc_delta);
}
else {
make_zero64(p->p_cpu_time_left);
}
#endif
}
*__tsc_ctr_switch = tsc;
}
void context_stop_idle(void)
{
int is_idle;
#ifdef CONFIG_SMP
unsigned cpu = cpuid;
#endif
is_idle = get_cpu_var(cpu, cpu_is_idle);
get_cpu_var(cpu, cpu_is_idle) = 0;
context_stop(get_cpulocal_var_ptr(idle_proc));
if (is_idle)
restart_local_timer();
#if SPROFILE
if (sprofiling)
get_cpulocal_var(idle_interrupted) = 1;
#endif
}
void restart_local_timer(void)
{
}
int register_local_timer_handler(const irq_handler_t handler)
{
return omap3_register_timer_handler(handler);
}
u64_t ms_2_cpu_time(unsigned ms)
{
return mul64u(tsc_per_ms[cpuid], ms);
}
unsigned cpu_time_2_ms(u64_t cpu_time)
{
return div64u(cpu_time, tsc_per_ms[cpuid]);
}
short cpu_load(void)
{
return 0;
}