Files
foc/kernel/fiasco/src/kern/arm/bsp/exynos5/timer-arm-exynos5.cpp
Sebastian Sumpf dad53fb148 FOC: Enable caches
2013-02-20 12:19:25 +01:00

89 lines
1.8 KiB
C++

INTERFACE [arm & exynos5]:
#include "kmem.h"
#include "processor.h"
EXTENSION class Timer
{
public:
enum {
BASE = Kmem::Timer_map_base,
CFG0 = BASE,
CFG1 = BASE + 0x4,
TCON = BASE + 0x8,
TCNTB0 = BASE + 0xc,
TCMPB0 = BASE + 0x10,
TINT_STAT = BASE + 0x44,
ONE_MS = 33000, /* HZ */
};
static unsigned irq() { return 68 + Proc::cpu_id(); }
};
IMPLEMENTATION [arm && exynos5]:
#include "cpu.h"
#include "io.h"
#include "irq_mgr.h"
#include "mmu.h"
IMPLEMENT inline
void
Timer::update_one_shot(Unsigned64 wakeup)
{
(void)wakeup;
}
static inline
Mword
tcon_to_timer(Mword val, unsigned cpu_id)
{
return cpu_id == 0 ? val : (val << (4 + (4 * cpu_id)));
}
IMPLEMENT
void Timer::init(unsigned)
{
unsigned cpu_id = Proc::cpu_id();
if (Cpu::boot_cpu()->phys_id() == cpu_id)
{
// prescaler to one
Io::write<Mword>(0x101, CFG0);
// divider to 1
Io::write<Mword>(0x0, CFG1);
}
// program 1ms
Mword offset = 0xc * cpu_id;
Io::write<Mword>(ONE_MS, TCNTB0 + offset);
Io::write<Mword>(0x0, TCMPB0 + offset);
// enable IRQ
Io::set<Mword>(0x1 << cpu_id, TINT_STAT);
// load and start timer in invterval mode
Mword tcon = Io::read<Mword>(TCON);
Io::write<Mword>(tcon | tcon_to_timer(0xa, cpu_id), TCON);
Io::write<Mword>(tcon | tcon_to_timer(0x9, cpu_id), TCON);
// route IRQ to this CPU
Irq_mgr::mgr->set_cpu(irq(), cpu_id);
}
IMPLEMENT inline NEEDS["config.h", "kip.h"]
Unsigned64
Timer::system_clock()
{
if (Config::Scheduler_one_shot)
return 0;
else
return Kip::k()->clock;
}
PUBLIC static inline NEEDS["io.h"]
void Timer::acknowledge()
{
Mword stat = Io::read<Mword>(TINT_STAT);
Io::write<Mword>(stat & (0x1f | (0x20 << Proc::cpu_id())), TINT_STAT);
}