mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
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 */
|
||||
ENTRY_T * e = _entries.head();
|
||||
if (!e) {
|
||||
t = _idle->Entry::_time;
|
||||
t = _lap_time;
|
||||
return _idle;
|
||||
}
|
||||
e->Entry::_consume(t);
|
||||
@ -1422,7 +1422,7 @@ namespace Kernel
|
||||
void add_pending_context(Signal_context * const c)
|
||||
{
|
||||
assert(c->_receiver == this);
|
||||
_pending_contexts.enqueue(c);
|
||||
if(!c->is_enqueued()) _pending_contexts.enqueue(c);
|
||||
_listen();
|
||||
}
|
||||
};
|
||||
|
@ -47,7 +47,9 @@ namespace Genode
|
||||
EMIF1_EMIF2_CS0_SDRAM_BASE = 0x80000000,
|
||||
EMIF1_EMIF2_CS0_SDRAM_SIZE = 0x40000000,
|
||||
|
||||
/* misc */
|
||||
SECURITY_EXTENSION = 0,
|
||||
SYS_CLK = 38400000,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -5,12 +5,13 @@
|
||||
#
|
||||
|
||||
# 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
|
||||
REP_INC_DIR += include/platform/panda_a2
|
||||
|
||||
# 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-tl16c750.mk)
|
||||
|
||||
|
@ -169,8 +169,8 @@ namespace Genode
|
||||
/**
|
||||
* Translate microseconds to a native timer value
|
||||
*/
|
||||
static unsigned long us_to_tics(unsigned long const tics) {
|
||||
return tics / TICS_PER_US; }
|
||||
static unsigned long us_to_tics(unsigned long const us) {
|
||||
return us * TICS_PER_US; }
|
||||
|
||||
/**
|
||||
* 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