base_hw & omap4: Timer driver.
Fix bug regarding idle thread in thread scheduling in 'base-hw/src/core/kernel.cc'. Fix regarding signal submit in signal framework in 'base-hw/src/core/kernel.cc'.
This commit is contained in:
parent
31d57a6257
commit
612735732a
|
@ -895,7 +895,7 @@ namespace Kernel
|
||||||
/* update current entry */
|
/* update current entry */
|
||||||
ENTRY_T * e = _entries.head();
|
ENTRY_T * e = _entries.head();
|
||||||
if (!e) {
|
if (!e) {
|
||||||
t = _idle->Entry::_time;
|
t = _lap_time;
|
||||||
return _idle;
|
return _idle;
|
||||||
}
|
}
|
||||||
e->Entry::_consume(t);
|
e->Entry::_consume(t);
|
||||||
|
@ -1422,7 +1422,7 @@ namespace Kernel
|
||||||
void add_pending_context(Signal_context * const c)
|
void add_pending_context(Signal_context * const c)
|
||||||
{
|
{
|
||||||
assert(c->_receiver == this);
|
assert(c->_receiver == this);
|
||||||
_pending_contexts.enqueue(c);
|
if(!c->is_enqueued()) _pending_contexts.enqueue(c);
|
||||||
_listen();
|
_listen();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,9 @@ namespace Genode
|
||||||
EMIF1_EMIF2_CS0_SDRAM_BASE = 0x80000000,
|
EMIF1_EMIF2_CS0_SDRAM_BASE = 0x80000000,
|
||||||
EMIF1_EMIF2_CS0_SDRAM_SIZE = 0x40000000,
|
EMIF1_EMIF2_CS0_SDRAM_SIZE = 0x40000000,
|
||||||
|
|
||||||
|
/* misc */
|
||||||
SECURITY_EXTENSION = 0,
|
SECURITY_EXTENSION = 0,
|
||||||
|
SYS_CLK = 38400000,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# denote wich specs are also fullfilled by this spec
|
# denote wich specs are also fullfilled by this spec
|
||||||
SPECS += cortex_a9 tl16c750 omap44xx
|
SPECS += cortex_a9 tl16c750 omap4 platform_panda
|
||||||
|
|
||||||
# add repository relative include paths
|
# add repository relative include paths
|
||||||
REP_INC_DIR += include/platform/panda_a2
|
REP_INC_DIR += include/platform/panda_a2
|
||||||
|
|
||||||
# include implied specs
|
# include implied specs
|
||||||
|
include $(call select_from_repositories,mk/spec-platform_panda.mk)
|
||||||
include $(call select_from_repositories,mk/spec-cortex_a9.mk)
|
include $(call select_from_repositories,mk/spec-cortex_a9.mk)
|
||||||
include $(call select_from_repositories,mk/spec-tl16c750.mk)
|
include $(call select_from_repositories,mk/spec-tl16c750.mk)
|
||||||
|
|
||||||
|
|
|
@ -169,8 +169,8 @@ namespace Genode
|
||||||
/**
|
/**
|
||||||
* Translate microseconds to a native timer value
|
* Translate microseconds to a native timer value
|
||||||
*/
|
*/
|
||||||
static unsigned long us_to_tics(unsigned long const tics) {
|
static unsigned long us_to_tics(unsigned long const us) {
|
||||||
return tics / TICS_PER_US; }
|
return us * TICS_PER_US; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate native timer value to microseconds
|
* Translate native timer value to microseconds
|
||||||
|
|
270
os/src/drivers/timer/hw/omap4/platform_timer_base.h
Normal file
270
os/src/drivers/timer/hw/omap4/platform_timer_base.h
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
* \brief Basic driver behind platform timer
|
||||||
|
* \author Martin Stein
|
||||||
|
* \date 2012-05-03
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HW__OMAP4__PLATFORM_TIMER_BASE_H_
|
||||||
|
#define _HW__OMAP4__PLATFORM_TIMER_BASE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <io_mem_session/connection.h>
|
||||||
|
#include <util/mmio.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
|
#include <drivers/board.h>
|
||||||
|
|
||||||
|
namespace Genode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Omap4 general purpose timer 3 through 9 and 11
|
||||||
|
*/
|
||||||
|
class Omap4_gp_timer_1 : public Mmio
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Timer tics per microsecond
|
||||||
|
*/
|
||||||
|
static float tics_per_us() {
|
||||||
|
return (float)Board::SYS_CLK / 1000000; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Microsecodns per timer tic
|
||||||
|
*/
|
||||||
|
static float us_per_tic() { return 1 / tics_per_us(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L4 interface control
|
||||||
|
*/
|
||||||
|
struct Tiocp_cfg : Register<0x10, 32>
|
||||||
|
{
|
||||||
|
struct Softreset : Bitfield<0, 1> { }; /* SW reset active */
|
||||||
|
struct Idlemode : Bitfield<2, 2> /* action on IDLE request */
|
||||||
|
{
|
||||||
|
enum { FORCE_IDLE = 0 };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer wake-up enable register
|
||||||
|
*/
|
||||||
|
struct Twer : Register<0x20, 32>
|
||||||
|
{
|
||||||
|
struct Mat_wup_ena : Bitfield<0, 1> { }; /* wakeup on match */
|
||||||
|
struct Ovf_wup_ena : Bitfield<1, 1> { }; /* wakeup on overflow */
|
||||||
|
struct Tcar_wup_ena : Bitfield<2, 1> { }; /* wakeup on capture */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer initialization value
|
||||||
|
*/
|
||||||
|
static access_t init_timer()
|
||||||
|
{
|
||||||
|
return Mat_wup_ena::bits(0) |
|
||||||
|
Ovf_wup_ena::bits(0) |
|
||||||
|
Tcar_wup_ena::bits(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer synchronous interface control register
|
||||||
|
*/
|
||||||
|
struct Tsicr : Register<0x54, 32>
|
||||||
|
{
|
||||||
|
struct Posted : Bitfield<2, 1> { }; /* enable posted mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control timer-functionality dependent features
|
||||||
|
*/
|
||||||
|
struct Tclr : Register<0x38, 32>
|
||||||
|
{
|
||||||
|
struct St : Bitfield<0, 1> { }; /* start/stop timer */
|
||||||
|
struct Ar : Bitfield<1, 1> { }; /* enable eutoreload */
|
||||||
|
struct Pre : Bitfield<5, 1> { }; /* enable prescaler */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run-and-wrap configuration
|
||||||
|
*/
|
||||||
|
static access_t init_run_and_wrap()
|
||||||
|
{
|
||||||
|
return St::bits(0) |
|
||||||
|
Ar::bits(1) |
|
||||||
|
Pre::bits(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set IRQ enables
|
||||||
|
*/
|
||||||
|
struct Irqenable_set : Register<0x2c, 32>
|
||||||
|
{
|
||||||
|
struct Ovf_en_flag : Bitfield<1, 1> { }; /* enable overflow IRQ */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IRQ status
|
||||||
|
*/
|
||||||
|
struct Irqstatus : Register<0x28, 32>
|
||||||
|
{
|
||||||
|
struct Ovf_it_flag : Bitfield<1, 1> { }; /* clear overflow IRQ */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer counter register
|
||||||
|
*/
|
||||||
|
struct Tcrr : Register<0x3c, 32>
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* maximum counter value
|
||||||
|
*/
|
||||||
|
static access_t max_value() { return ~0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer load value register
|
||||||
|
*/
|
||||||
|
struct Tldr : Register<0x40, 32> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Freeze timer counter
|
||||||
|
*/
|
||||||
|
void _freeze() { write<Tclr::St>(0); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unfreeze timer counter
|
||||||
|
*/
|
||||||
|
void _unfreeze() { write<Tclr::St>(1); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get remaining counting amount
|
||||||
|
*/
|
||||||
|
unsigned long _value() { return max_value() - read<Tcrr>(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply counting amount
|
||||||
|
*/
|
||||||
|
void _value(unsigned long const v) { write<Tcrr>(max_value() - v); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param base MMIO base
|
||||||
|
*/
|
||||||
|
Omap4_gp_timer_1(addr_t const base) : Mmio(base)
|
||||||
|
{
|
||||||
|
_freeze();
|
||||||
|
|
||||||
|
/* do a software reset */
|
||||||
|
write<Tiocp_cfg::Softreset>(1);
|
||||||
|
while (read<Tiocp_cfg::Softreset>()) ;
|
||||||
|
|
||||||
|
/* configure Idle mode */
|
||||||
|
write<Tiocp_cfg::Idlemode>(Tiocp_cfg::Idlemode::FORCE_IDLE);
|
||||||
|
|
||||||
|
/* enable wake-up interrupt events */
|
||||||
|
write<Twer>(Twer::init_timer());
|
||||||
|
|
||||||
|
/* select posted mode */
|
||||||
|
write<Tsicr::Posted>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count down 'value', raise IRQ output, wrap counter and continue
|
||||||
|
*/
|
||||||
|
void run_and_wrap(unsigned long value)
|
||||||
|
{
|
||||||
|
enum { MIN_VALUE = 1 };
|
||||||
|
|
||||||
|
/* stop timer */
|
||||||
|
_freeze();
|
||||||
|
clear_interrupt();
|
||||||
|
value = value ? value : MIN_VALUE;
|
||||||
|
|
||||||
|
/* configure for a run and wrap */
|
||||||
|
write<Tclr>(Tclr::init_run_and_wrap());
|
||||||
|
write<Irqenable_set::Ovf_en_flag>(1);
|
||||||
|
|
||||||
|
/* install value */
|
||||||
|
_value(value);
|
||||||
|
write<Tldr>(0);
|
||||||
|
|
||||||
|
/* start timer */
|
||||||
|
_unfreeze();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear interrupt output
|
||||||
|
*/
|
||||||
|
void clear_interrupt() {
|
||||||
|
write<Irqstatus::Ovf_it_flag>(1); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum timeout value
|
||||||
|
*/
|
||||||
|
unsigned long max_value() { return Tcrr::max_value(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate timer tics to microseconds
|
||||||
|
*/
|
||||||
|
unsigned long tics_to_us(unsigned long const tics)
|
||||||
|
{
|
||||||
|
float const us = tics * us_per_tic();
|
||||||
|
return (unsigned long)us;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate microseconds to timer tics
|
||||||
|
*/
|
||||||
|
unsigned long us_to_tics(unsigned long const us)
|
||||||
|
{
|
||||||
|
float const tics = us * tics_per_us();
|
||||||
|
return (unsigned long)tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sample the timer counter and according wrapped status
|
||||||
|
*/
|
||||||
|
unsigned long value(bool & wrapped)
|
||||||
|
{
|
||||||
|
Tcrr::access_t const v = _value();
|
||||||
|
wrapped = (bool)read<Irqstatus::Ovf_it_flag>();
|
||||||
|
return wrapped ? _value() : v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic driver behind platform timer
|
||||||
|
*/
|
||||||
|
class Platform_timer_base : public Genode::Io_mem_connection,
|
||||||
|
public Genode::Omap4_gp_timer_1
|
||||||
|
{
|
||||||
|
/* FIXME these should be located in a omap4-defs file */
|
||||||
|
enum {
|
||||||
|
GP_TIMER_3_IRQ = 71,
|
||||||
|
GP_TIMER_3_MMIO_BASE = 0x48034000,
|
||||||
|
GP_TIMER_3_MMIO_SIZE = 0x00001000,
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum { IRQ = GP_TIMER_3_IRQ };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Platform_timer_base() :
|
||||||
|
Io_mem_connection(GP_TIMER_3_MMIO_BASE, GP_TIMER_3_MMIO_SIZE),
|
||||||
|
Genode::Omap4_gp_timer_1((Genode::addr_t)Genode::env()->rm_session()->attach(dataspace()))
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _HW__OMAP4__PLATFORM_TIMER_BASE_H_ */
|
||||||
|
|
23
os/src/drivers/timer/hw/omap4/target.mk
Executable file
23
os/src/drivers/timer/hw/omap4/target.mk
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
# \brief Timer session server
|
||||||
|
# \author Martin Stein
|
||||||
|
# \date 2012-05-03
|
||||||
|
#
|
||||||
|
|
||||||
|
# Set program name
|
||||||
|
TARGET = timer
|
||||||
|
|
||||||
|
# Add C++ sources
|
||||||
|
SRC_CC += main.cc
|
||||||
|
|
||||||
|
# Skip build if required specs not fullfilled
|
||||||
|
REQUIRES += hw omap4
|
||||||
|
|
||||||
|
# Add libraries
|
||||||
|
LIBS += cxx server env alarm
|
||||||
|
|
||||||
|
# Add include paths
|
||||||
|
INC_DIR += $(PRG_DIR) $(PRG_DIR)/../ $(PRG_DIR)/../../nova/
|
||||||
|
|
||||||
|
# Declare source paths
|
||||||
|
vpath main.cc $(PRG_DIR)/../..
|
Loading…
Reference in New Issue
Block a user