Files
rpi_b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c
2016-03-12 19:26:26 +01:00

121 lines
2.5 KiB
C

#include "kernel/kernel.h"
#include "kernel/clock.h"
#include <sys/types.h>
#include <machine/cpu.h>
#include <minix/board.h>
#include <minix/mmio.h>
#include <assert.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include "arch_proto.h"
#include "bsp_timer.h"
#include "rpi_timer_registers.h"
#include "rpi_intr_registers.h"
#include "bsp_intr.h"
/* interrupt handler hook */
static irq_hook_t rpi_timer_hook;
static u32_t counts_per_hz = ~0;
static u64_t high_frc;
static int rpi_timer_init_ok = 0;
struct rpi_timer_registers;
struct bcm2835_timer
{
vir_bytes base;
int irq_nr;
struct rpi_timer_registers *regs;
};
struct rpi_timer_registers
{
vir_bytes STCS;
vir_bytes STCLO;
vir_bytes STCHI;
vir_bytes STC3;
};
static struct rpi_timer_registers regs_v1 =
{
.STCS = BCM2835_STIMER_CS,
.STCLO = BCM2835_STIMER_CLO,
.STCHI = BCM2835_STIMER_CHI,
.STC3 = BCM2835_STIMER_C3
};
static struct bcm2835_timer rpi_timer = {
.base = BCM2835_STIMER_BASE,
.irq_nr = BCM2835_INT_TIMER3,
.regs = &regs_v1
};
static struct bcm2835_timer *timer;
int
bsp_register_timer_handler(const irq_handler_t handler)
{
/* Initialize the CLOCK's interrupt hook. */
rpi_timer_hook.proc_nr_e = NONE;
rpi_timer_hook.irq = timer->irq_nr;
put_irq_handler(&rpi_timer_hook, timer->irq_nr, handler);
/* only unmask interrupts after registering */
bsp_irq_unmask(timer->irq_nr);
return 0;
}
/* meta data for remapping */
static kern_phys_map timer_phys_map;
void
bsp_timer_init(unsigned freq)
{
if ( BOARD_IS_RPI(machine.board_id))
{
u32_t stclo;
timer = &rpi_timer;
counts_per_hz = BCM2835_STIMER_HZ / freq;
kern_phys_map_ptr(timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_WRITE,
&timer_phys_map, (vir_bytes) & timer->base);
mmio_write( timer->base + timer->regs->STCS, BCM2835_STIMER_M3 );
stclo = mmio_read( timer->base + timer->regs->STCLO );
stclo += counts_per_hz;
mmio_write( timer->base + timer->regs->STC3, stclo );
frclock_init();
rpi_timer_init_ok = 1;
}
}
void
bsp_timer_stop()
{
}
void
bsp_timer_int_handler()
{
u32_t stclo;
mmio_write( timer->base + timer->regs->STCS , BCM2835_STIMER_M3 );
stclo = mmio_read( timer->base + timer->regs->STCLO );
stclo += counts_per_hz;
mmio_write( timer->base + timer->regs->STC3, stclo );
}
void
read_tsc_64(u64_t* t)
{
u32_t stclo, stchi;
if (rpi_timer_init_ok) {
stclo = mmio_read( timer->base + timer->regs->STCLO );
stchi = mmio_read( timer->base + timer->regs->STCHI );
*t = ((u64_t)stchi << 32) | (u64_t)stclo;
} else {
*t = (u64_t) 0;
}
}