dde_bsd: update audio driver to OpenBSD 5.9

In addition to updating the contrib sources the driver now uses the
new Component API and will report the internal mixer state.

Reporting of the mixer state is enabled by adding the 'report_mixer'
attribute to the drivers configuration and setting its value to 'yes'.

The following snippets illustrates the format of the report:

!<mixer_state>
!  <mixer field="inputs.beep" value="108"/>
!  <mixer field="outputs.hp_sense" value="plugged"/>
!  <mixer field="outputs.master" value="128,128"/>
!  <mixer field="outputs.mic_sense" value="unplugged"/>
!  <mixer field="outputs.spkr_muters" value="hp,mic"/>
!</mixer_state>

The mixer state may expose other mixer fields as well, depending on the
used sound card. The naming scheme of the attributes intentionally
matches the naming scheme of OpenBSD's mixerctl(1) program.

Each 'mixer' node can be used to configure the audio driver by using it
in its configuration, e.g.:

!<config report_mixer="yes">
!  <mixer field="outputs.master" value="255,255"/>
!</config>

This configuration will set the output volume to the highest possible
value. Although it is now also possible to update the configuration
at run-time it should not be done while the driver is currently playing
or recording because it may provoke the generation of artefacts.

Fixes #1973.
This commit is contained in:
Josef Söntgen 2016-04-24 10:56:31 +02:00 committed by Christian Helmuth
parent 44648bb5c7
commit 47990f37d7
25 changed files with 395 additions and 386 deletions

View File

@ -7,8 +7,6 @@
./sys/dev/pci/eapreg.h
./sys/dev/pci/pcidevs.h
./sys/dev/pci/pcidevs_data.h
./sys/dev/auconv.c
./sys/dev/auconv.h
./sys/dev/mulaw.c
./sys/dev/mulaw.h
./sys/dev/ic/ac97.c

View File

@ -9,7 +9,7 @@
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
* Copyright (C) 2016 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.
@ -18,7 +18,10 @@
#ifndef _AUDIO__AUDIO_H_
#define _AUDIO__AUDIO_H_
#include <os/server.h>
/* Genode includes */
#include <base/env.h>
#include <util/xml_node.h>
/*****************************
** private Audio namespace **
@ -38,7 +41,9 @@ namespace Audio_in {
namespace Audio {
void init_driver(Server::Entrypoint &ep);
void update_config(Genode::Xml_node);
void init_driver(Genode::Env &, Genode::Allocator &, Genode::Xml_node);
bool driver_active();

View File

@ -0,0 +1 @@
INC_DIR += $(LIB_CACHE_DIR)/dde_bsd_audio_include/include

View File

@ -3,10 +3,16 @@ LIB_INC_DIR = $(LIB_DIR)/include
AUDIO_CONTRIB_DIR := $(call select_from_ports,dde_bsd)/src/lib/audio
#
# Set include paths up before adding the dde_bsd_audio_include library
# because it will use INC_DIR += and must be at the end
#
INC_DIR += $(LIB_DIR)
INC_DIR += $(LIB_INC_DIR)
INC_DIR += $(AUDIO_CONTRIB_DIR)
LIBS += dde_bsd_audio_include
SRC_CC += bus.cc dummies.cc driver.cc irq.cc mem.cc misc.cc scheduler.cc timer.cc
SRC_C += bsd_emul.c
SRC_S += setjmp.S
@ -19,13 +25,16 @@ CC_OPT += -fno-builtin-printf -fno-builtin-snprintf -fno-builtin-vsnprintf \
CC_OPT += -D_KERNEL
# disable false warning in audio.c:786
CC_C_OPT += -Wno-maybe-uninitialized
# enable when debugging
# CC_OPT += -DAUDIO_DEBUG
# CC_OPT += -DAZALIA_DEBUG
# CC_OPT += -DDIAGNOSTIC
# audio interface
SRC_C += dev/audio.c dev/auconv.c
SRC_C += dev/audio.c
# AC97 codec
SRC_C += dev/ic/ac97.c
@ -38,38 +47,6 @@ SRC_C += dev/pci/eap.c
SRC_C += dev/mulaw.c
#
# Determine the header files included by the contrib code. For each
# of these header files we create a symlink to 'bsd_emul.h'.
#
GEN_INCLUDES := $(shell grep -rh "^\#include .*" $(AUDIO_CONTRIB_DIR) |\
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
#
# Filter out original BSD headers that exist in the contrib directory
#
NO_GEN_INCLUDES := $(shell cd $(AUDIO_CONTRIB_DIR); find -name "*.h" | sed "s/.\///" | sed "s/.*include\///")
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
#
# Put BSD headers in 'GEN_INC' dir
#
GEN_INC := $(shell pwd)/include
$(shell mkdir -p $(GEN_INC))
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
INC_DIR += $(GEN_INC)
#
# Make sure to create the header symlinks prior building
#
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(GEN_INCLUDES)
$(GEN_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -s $(LIB_INC_DIR)/bsd_emul.h $@
vpath %.c $(AUDIO_CONTRIB_DIR)
vpath %.c $(LIB_DIR)
vpath %.cc $(LIB_DIR)

View File

@ -0,0 +1,24 @@
#
# Pseudo library to generate a symlink for each header file included by the
# contrib code. Each symlink points to the same 'bsd_emul.h' file, which
# provides our emulation of the OpenBSD kernel API.
#
ifeq ($(called_from_lib_mk),yes)
BSD_CONTRIB_DIR := $(call select_from_ports,dde_bsd)/src/lib/audio
BSD_EMUL_H := $(REP_DIR)/src/lib/audio/include/bsd_emul.h
GEN_INCLUDES := $(shell grep -rh "^\#include .*" $(BSD_CONTRIB_DIR) |\
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
GEN_INC := $(shell pwd)/include
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
all: $(GEN_INCLUDES)
$(GEN_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -sf $(BSD_EMUL_H) $@
endif

View File

@ -1,17 +1,19 @@
diff --git a/dev/audio.c b/dev/audio.c
index 1271bc7..6535d10 100644
--- a/dev/audio.c
+++ b/dev/audio.c
@@ -2293,6 +2293,8 @@
sc->sc_pqui = 1;
audio_wake(&sc->sc_wchan);
@@ -411,6 +411,8 @@ audio_pintr(void *addr)
}
selwakeup(&sc->play.sel);
}
+
+ notify_play();
}
/*
@@ -2400,6 +2402,8 @@
sc->sc_rqui = 1;
audio_wake(&sc->sc_rchan);
@@ -486,6 +488,8 @@ audio_rintr(void *addr)
}
selwakeup(&sc->rec.sel);
}
+
+ notify_record();

View File

@ -1 +1 @@
7efb09a93f78f7896e1a73264145e188afa3e80f
9d32d78a9e2488f993723b6d1d353dec2bc55e24

View File

@ -3,12 +3,12 @@ VERSION := 1
DOWNLOADS := audio.archive
#
# Audio drivers from OpenBSD 5.7
# Audio drivers from OpenBSD 5.9
#
SRC_DIR_AUDIO := src/lib/audio
VERSION_AUDIO := 5.7
VERSION_AUDIO := 5.9
URL(audio) := http://mirror.switch.ch/ftp/pub/OpenBSD/$(VERSION_AUDIO)/sys.tar.gz
SHA(audio) := 1a60125a7fce6524b0d62643db47acca0b11506a
SHA(audio) := 65080ae5524ffed903dac7ecb49c1c4955afbc7f
DIR(audio) := $(SRC_DIR_AUDIO)
TAR_OPT(audio) := --strip-components=2 --files-from $(REP_DIR)/audio.list
HASH_INPUT += $(REP_DIR)/audio.list

View File

@ -72,9 +72,7 @@ append_if $use_mixer config {
append config {
<start name="audio_drv">
<resource name="RAM" quantum="8M"/>
<provides>
<service name="Audio_out"/>
</provides>
<provides> <service name="Audio_out"/> </provides>
</start>
<start name="test-audio_out">
<resource name="RAM" quantum="4M"/>

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
@ -15,21 +15,16 @@
/* Genode includes */
#include <audio_in_session/rpc_object.h>
#include <audio_out_session/rpc_object.h>
#include <base/env.h>
#include <base/sleep.h>
#include <cap_session/connection.h>
#include <os/config.h>
#include <os/server.h>
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/log.h>
#include <root/component.h>
#include <util/misc_math.h>
#include <trace/timestamp.h>
/* local includes */
#include <audio/audio.h>
using namespace Genode;
using namespace Audio;
@ -72,9 +67,9 @@ class Audio_out::Out
{
private:
Server::Entrypoint &_ep;
Genode::Signal_rpc_member<Audio_out::Out> _data_avail_dispatcher;
Genode::Signal_rpc_member<Audio_out::Out> _notify_dispatcher;
Genode::Entrypoint &_ep;
Genode::Signal_handler<Audio_out::Out> _data_avail_dispatcher;
Genode::Signal_handler<Audio_out::Out> _notify_dispatcher;
bool _active() {
return channel_acquired[LEFT] && channel_acquired[RIGHT] &&
@ -110,8 +105,9 @@ class Audio_out::Out
static short silence[Audio_out::PERIOD * Audio_out::MAX_CHANNELS] = { 0 };
int err = Audio::play(silence, sizeof(silence));
if (err && err != 35)
PWRN("Error %d during silence playback", err);
if (err && err != 35) {
Genode::warning("Error ", err, " during silence playback");
}
}
void _play_packet()
@ -132,8 +128,9 @@ class Audio_out::Out
}
/* send to driver */
if (int err = Audio::play(data, sizeof(data)))
PWRN("Error %d during playback", err);
if (int err = Audio::play(data, sizeof(data))) {
Genode::warning("Error ", err, " during playback");
}
p_left->invalidate();
p_right->invalidate();
@ -161,12 +158,12 @@ class Audio_out::Out
* started to play and we will keep doing it, even if it is
* silence.
*/
void _handle_data_avail(unsigned) { }
void _handle_data_avail() { }
/*
* DMA block played
*/
void _handle_notify(unsigned)
void _handle_notify()
{
if (_active())
_play_packet();
@ -174,7 +171,7 @@ class Audio_out::Out
public:
Out(Server::Entrypoint &ep)
Out(Genode::Entrypoint &ep)
:
_ep(ep),
_data_avail_dispatcher(ep, *this, &Audio_out::Out::_handle_data_avail),
@ -225,8 +222,8 @@ struct Audio_out::Root_policy
if ((ram_quota < session_size) ||
(sizeof(Stream) > ram_quota - session_size)) {
PERR("insufficient 'ram_quota', got %zd, need %zd",
ram_quota, sizeof(Stream) + session_size);
Genode::error("insufficient 'ram_quota', got ", ram_quota,
" need ", sizeof(Stream) + session_size);
throw ::Root::Quota_exceeded();
}
@ -257,7 +254,7 @@ class Audio_out::Root : public Audio_out::Root_component
{
private:
Server::Entrypoint &_ep;
Genode::Entrypoint &_ep;
Signal_context_capability _cap;
@ -278,7 +275,7 @@ class Audio_out::Root : public Audio_out::Root_component
public:
Root(Server::Entrypoint &ep, Allocator &md_alloc,
Root(Genode::Entrypoint &ep, Allocator &md_alloc,
Signal_context_capability cap)
:
Root_component(&ep.rpc_ep(), &md_alloc),
@ -323,8 +320,8 @@ class Audio_in::In
{
private:
Server::Entrypoint &_ep;
Genode::Signal_rpc_member<Audio_in::In> _notify_dispatcher;
Genode::Entrypoint &_ep;
Genode::Signal_handler<Audio_in::In> _notify_dispatcher;
bool _active() { return channel_acquired && channel_acquired->active(); }
@ -334,8 +331,9 @@ class Audio_in::In
{
static short data[2 * Audio_in::PERIOD];
if (int err = Audio::record(data, sizeof(data))) {
if (err && err != 35)
PWRN("Error %d during recording", err);
if (err && err != 35) {
Genode::warning("Error ", err, " during recording");
}
return;
}
@ -361,7 +359,7 @@ class Audio_in::In
if (overrun) channel_acquired->overrun_submit();
}
void _handle_notify(unsigned)
void _handle_notify()
{
if (_active())
_record_packet();
@ -369,7 +367,7 @@ class Audio_in::In
public:
In(Server::Entrypoint &ep)
In(Genode::Entrypoint &ep)
:
_ep(ep),
_notify_dispatcher(ep, *this, &Audio_in::In::_handle_notify)
@ -408,8 +406,8 @@ struct Audio_in::Root_policy
if ((ram_quota < session_size) ||
(sizeof(Stream) > (ram_quota - session_size))) {
PERR("insufficient 'ram_quota', got %zu, need %zu",
ram_quota, sizeof(Stream) + session_size);
Genode::error("insufficient 'ram_quota', got ", ram_quota,
" need ", sizeof(Stream) + session_size);
throw Genode::Root::Quota_exceeded();
}
@ -440,7 +438,7 @@ class Audio_in::Root : public Audio_in::Root_component
{
private:
Server::Entrypoint &_ep;
Genode::Entrypoint &_ep;
Signal_context_capability _cap;
protected:
@ -458,7 +456,7 @@ class Audio_in::Root : public Audio_in::Root_component
public:
Root(Server::Entrypoint &ep, Allocator &md_alloc,
Root(Genode::Entrypoint &ep, Allocator &md_alloc,
Signal_context_capability cap)
: Root_component(&ep.rpc_ep(), &md_alloc), _ep(ep), _cap(cap) { }
};
@ -468,67 +466,73 @@ class Audio_in::Root : public Audio_in::Root_component
** Main **
**********/
static bool disable_playback()
static bool check(Genode::Xml_node config,
char const * const attr,
char const * const value)
{
using namespace Genode;
try {
return config()->xml_node().attribute("playback").has_value("no");
} catch (...) { }
return false;
}
static bool enable_recording()
{
using namespace Genode;
try {
return config()->xml_node().attribute("recording").has_value("yes");
} catch (...) { }
return false;
try { return config.attribute(attr).has_value(value); }
catch (...) { return false; }
}
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Entrypoint &ep;
Genode::Heap heap { &env.ram(), &env.rm() };
Main(Server::Entrypoint &ep) : ep(ep)
Genode::Attached_rom_dataspace config { env, "config" };
Genode::Signal_handler<Main> config_update_dispatcher {
ep, *this, &Main::handle_config_update };
void handle_config_update()
{
Audio::init_driver(ep);
config.update();
if (!config.is_valid()) { return; }
Audio::update_config(config.xml());
}
if (Audio::driver_active()) {
Main(Genode::Env &env) : env(env), ep(env.ep())
{
Audio::init_driver(env, heap, config.xml());
/* playback */
if (!disable_playback()) {
static Audio_out::Out out(ep);
Audio::play_sigh(out.sigh());
static Audio_out::Root out_root(ep, *env()->heap(), out.data_avail());
env()->parent()->announce(ep.manage(out_root));
PINF("--- BSD Audio driver enable playback ---");
}
/* recording */
if (enable_recording()) {
static Audio_in::In in(ep);
Audio::record_sigh(in.sigh());
static Audio_in::Root in_root(ep, *env()->heap(),
Genode::Signal_context_capability());
env()->parent()->announce(ep.manage(in_root));
PINF("--- BSD Audio driver enable recording ---");
}
if (!Audio::driver_active()) {
return;
}
/* playback */
if (!check(config.xml(), "playback", "no")) {
static Audio_out::Out out(ep);
Audio::play_sigh(out.sigh());
static Audio_out::Root out_root(ep, heap, out.data_avail());
env.parent().announce(ep.manage(out_root));
Genode::log("--- BSD Audio driver enable playback ---");
}
/* recording */
if (check(config.xml(), "recording", "yes")) {
static Audio_in::In in(ep);
Audio::record_sigh(in.sigh());
static Audio_in::Root in_root(ep, heap,
Genode::Signal_context_capability());
env.parent().announce(ep.manage(in_root));
Genode::log("--- BSD Audio driver enable recording ---");
}
config.sigh(config_update_dispatcher);
}
};
/************
** Server **
************/
/***************
** Component **
***************/
namespace Server {
char const *name() { return "audio_drv_ep"; }
size_t stack_size() { return 8*1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
namespace Component {
char const *name() { return "audio_drv_ep"; }
size_t stack_size() { return 8*1024*sizeof(long); }
void construct(Genode::Env &env) { static Main server(env); }
}

View File

@ -1,5 +1,5 @@
REQUIRES = x86 pci
TARGET = audio_drv
SRC_CC = main.cc
LIBS = dde_bsd_audio base config server
LIBS = dde_bsd_audio base config
INC_DIR += $(REP_DIR)/include

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
@ -16,19 +16,19 @@
/* Genode includes */
#include <base/cache.h>
#include <base/env.h>
#include <irq_session/capability.h>
#include <os/server.h>
/* local includes */
#include <scheduler.h>
namespace Bsd {
int probe_drivers();
int probe_drivers(Genode::Env&, Genode::Allocator&);
void irq_init(Server::Entrypoint &ep);
void timer_init(Server::Entrypoint &ep);
void mem_init(Genode::Env&, Genode::Allocator &);
void irq_init(Genode::Entrypoint&, Genode::Allocator&);
void timer_init(Genode::Entrypoint&);
void update_time();

View File

@ -60,10 +60,10 @@ struct cdevsw cdevsw[] = {
(int (*)(struct tty*, int)) enodev,
0,
audiopoll,
audiommap,
0,
0,
audiokqfilter,
0,
0,
},
};
@ -139,3 +139,12 @@ struct device *config_found_sm(struct device *parent, void *aux, cfprint_t print
return 0;
}
struct device *device_lookup(struct cfdriver *cd, int unit)
{
if (unit >= audio_cd.cd_ndevs || audio_cd.cd_devs[unit] == NULL)
return NULL;
return audio_cd.cd_devs[unit];
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
@ -13,6 +13,7 @@
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/log.h>
#include <base/object_pool.h>
#include <dataspace/client.h>
#include <io_port_session/connection.h>
@ -22,9 +23,10 @@
#include <util/retry.h>
/* local includes */
#include "bsd.h"
#include <bsd.h>
#include <bsd_emul.h>
#include <extern_c_begin.h>
# include <bsd_emul.h>
# include <dev/pci/pcidevs.h>
#include <extern_c_end.h>
@ -42,6 +44,9 @@ class Pci_driver : public Bsd::Bus_driver
private:
Genode::Env &_env;
Genode::Allocator &_alloc;
struct pci_attach_args _pa { 0, 0, 0, 0, 0 };
Platform::Connection _pci;
@ -55,6 +60,8 @@ class Pci_driver : public Bsd::Bus_driver
*/
struct Dma_region_manager : public Genode::Allocator_avl
{
Genode::Env &env;
enum { BACKING_STORE_SIZE = 1024 * 1024 };
Genode::addr_t base;
@ -64,8 +71,10 @@ class Pci_driver : public Bsd::Bus_driver
Pci_driver &_drv;
Dma_region_manager(Genode::Allocator &alloc, Pci_driver &drv)
: Genode::Allocator_avl(&alloc), _drv(drv) { }
Dma_region_manager(Genode::Env &env,
Genode::Allocator &alloc,
Pci_driver &drv)
: Genode::Allocator_avl(&alloc), env(env), _drv(drv) { }
Genode::addr_t alloc(Genode::size_t size, int align)
{
@ -74,12 +83,12 @@ class Pci_driver : public Bsd::Bus_driver
if (!_dma_initialized) {
try {
Ram_dataspace_capability cap = _drv._alloc_dma_memory(BACKING_STORE_SIZE);
mapped_base = (addr_t)env()->rm_session()->attach(cap);
mapped_base = (addr_t)env.rm().attach(cap);
base = Dataspace_client(cap).phys_addr();
Allocator_avl::add_range(mapped_base, BACKING_STORE_SIZE);
} catch (...) {
PERR("alloc DMA memory failed");
Genode::error("alloc DMA memory failed");
return 0;
}
_dma_initialized = true;
@ -129,14 +138,22 @@ class Pci_driver : public Bsd::Bus_driver
char quota[32];
Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd",
donate);
Genode::env()->parent()->upgrade(_pci.cap(), quota);
_env.parent().upgrade(_pci.cap(), quota);
donate = donate * 2 > size ? 4096 : donate * 2;
});
}
public:
Pci_driver() : _dma_region_manager(*Genode::env()->heap(), *this) { }
Pci_driver(Genode::Env &env, Genode::Allocator &alloc)
:
_env(env), _alloc(alloc),
_dma_region_manager(_env, _alloc, *this)
{ }
Genode::Env &env() { return _env; }
Genode::Allocator &alloc() { return _alloc; }
Platform::Device_capability cap() { return _cap; }
@ -146,7 +163,7 @@ class Pci_driver : public Bsd::Bus_driver
{
char buf[32];
Genode::snprintf(buf, sizeof(buf), "ram_quota=%u", 8192U);
Genode::env()->parent()->upgrade(_pci.cap(), buf);
_env.parent().upgrade(_pci.cap(), buf);
/*
* We hide ourself in the bus_dma_tag_t as well as
@ -166,8 +183,8 @@ class Pci_driver : public Bsd::Bus_driver
if ((device.device_id() == PCI_PRODUCT_INTEL_CORE4G_HDA_2) ||
(bus == 0 && dev == 3 && func == 0)) {
PWRN("ignore %u:%u:%u not supported HDMI/DP HDA device",
bus, dev, func);
Genode::warning("ignore ", (unsigned)bus, ":", (unsigned)dev, ":",
(unsigned)func, "not supported HDMI/DP HDA device");
continue;
}
@ -264,7 +281,9 @@ struct Io_memory : public Bus_space
Genode::Io_mem_dataspace_capability _mem_ds;
Genode::addr_t _vaddr;
Io_memory(Genode::addr_t base, Genode::Io_mem_session_capability cap)
Io_memory(Genode::Region_map &rm,
Genode::addr_t base,
Genode::Io_mem_session_capability cap)
:
_mem(cap),
_mem_ds(_mem.dataspace())
@ -272,7 +291,7 @@ struct Io_memory : public Bus_space
if (!_mem_ds.valid())
throw Genode::Exception();
_vaddr = Genode::env()->rm_session()->attach(_mem_ds);
_vaddr = rm.attach(_mem_ds);
_vaddr |= base & 0xfff;
}
@ -298,10 +317,10 @@ struct Io_memory : public Bus_space
} /* anonymous namespace */
int Bsd::probe_drivers()
int Bsd::probe_drivers(Genode::Env &env, Genode::Allocator &alloc)
{
PINF("--- probe drivers ---");
static Pci_driver drv;
static Pci_driver drv(env, alloc);
return drv.probe();
}
@ -342,21 +361,21 @@ extern "C" int pci_mapreg_map(struct pci_attach_args *pa,
switch (res.type()) {
case Platform::Device::Resource::IO:
{
Io_port *iop = new (Genode::env()->heap())
Io_port *iop = new (&drv->alloc())
Io_port(res.base(), device.io_port(r));
*tagp = (Genode::addr_t) iop;
break;
}
case Platform::Device::Resource::MEMORY:
{
Io_memory *iom = new (Genode::env()->heap())
Io_memory(res.base(), device.io_mem(r));
Io_memory *iom = new (&drv->alloc())
Io_memory(drv->env().rm(), res.base(), device.io_mem(r));
*tagp = (Genode::addr_t) iom;
break;
}
case Platform::Device::Resource::INVALID:
{
PERR("PCI resource type invalid");
Genode::error("PCI resource type invalid");
return -1;
}
}
@ -388,7 +407,7 @@ extern "C" int pci_mapreg_map(struct pci_attach_args *pa,
char quota[32];
Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd",
donate);
Genode::env()->parent()->upgrade(drv->pci().cap(), quota);
drv->env().parent().upgrade(drv->pci().cap(), quota);
donate *= 2;
});
@ -510,7 +529,8 @@ extern "C" int bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t dmam, void *buf,
extern "C" void bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t)
{
PDBG("not implemented, called from %p", __builtin_return_address(0));
Genode::log("not implemented, called from ",
__builtin_return_address(0));
}
@ -549,7 +569,7 @@ extern "C" int bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, int ns
size_t size, caddr_t *kvap, int flags)
{
if (nsegs > 1) {
PERR("%s: cannot map more than 1 segment", __func__);
Genode::error(__func__, ": cannot map more than 1 segment");
return -1;
}
@ -570,6 +590,7 @@ extern "C" void bus_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t) { }
extern "C" paddr_t bus_dmamem_mmap(bus_dma_tag_t, bus_dma_segment_t *,
int, off_t, int, int)
{
PDBG("not implemented, called from %p", __builtin_return_address(0));
Genode::log("not implemented, called from ",
__builtin_return_address(0));
return 0;
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
@ -14,23 +14,22 @@
/* Genode includes */
#include <audio_out_session/audio_out_session.h>
#include <audio_in_session/audio_in_session.h>
#include <os/config.h>
#include <os/server.h>
#include <base/env.h>
#include <base/log.h>
#include <os/reporter.h>
#include <util/xml_node.h>
/* local includes */
#include <audio/audio.h>
#include <bsd.h>
#include <bsd_emul.h>
#include <extern_c_begin.h>
# include <bsd_emul.h>
# include <sys/device.h>
# include <sys/audioio.h>
#include <extern_c_end.h>
static bool verbose = false;
extern struct cfdriver audio_cd;
static dev_t const adev = 0x80; /* audio0 (minor nr 128) */
@ -55,33 +54,24 @@ static bool drv_loaded()
******************************/
#define DUMP_INFO(field) \
PLOG("--- " #field " information ---"); \
PLOG("sample_rate: %u", ai.field.sample_rate); \
PLOG("channels: %u", ai.field.channels); \
PLOG("precision: %u", ai.field.precision); \
PLOG("bps: %u", ai.field.bps); \
PLOG("encoding: %u", ai.field.encoding); \
PLOG("gain: %u", ai.field.gain); \
PLOG("port: %u", ai.field.port); \
PLOG("seek: %u", ai.field.seek); \
PLOG("avail_ports: %u", ai.field.avail_ports); \
PLOG("buffer_size: %u", ai.field.buffer_size); \
PLOG("block_size: %u", ai.field.block_size); \
PLOG("samples: %u", ai.field.samples); \
PLOG("eof: %u", ai.field.eof); \
PLOG("pause: %u", ai.field.pause); \
PLOG("error: %u", ai.field.error); \
PLOG("waiting: %u", ai.field.waiting); \
PLOG("balance: %u", ai.field.balance); \
PLOG("open: %u", ai.field.open); \
PLOG("active: %u", ai.field.active)
Genode::log("--- " #field " information ---"); \
Genode::log("sample_rate: ", (unsigned)ai.field.sample_rate); \
Genode::log("channels: ", (unsigned)ai.field.channels); \
Genode::log("precision: ", (unsigned)ai.field.precision); \
Genode::log("bps: ", (unsigned)ai.field.bps); \
Genode::log("encoding: ", (unsigned)ai.field.encoding); \
Genode::log("buffer_size: ", (unsigned)ai.field.buffer_size); \
Genode::log("block_size: ", (unsigned)ai.field.block_size); \
Genode::log("samples: ", (unsigned)ai.field.samples); \
Genode::log("pause: ", (unsigned)ai.field.pause); \
Genode::log("active: ", (unsigned)ai.field.active)
static void dump_pinfo()
{
struct audio_info ai;
if (audioioctl(adev, AUDIO_GETINFO, (char*)&ai, 0, 0)) {
PERR("could not gather play information");
Genode::error("could not gather play information");
return;
}
@ -93,7 +83,7 @@ static void dump_rinfo()
{
struct audio_info ai;
if (audioioctl(adev, AUDIO_GETINFO, (char*)&ai, 0, 0)) {
PERR("could not gather play information");
Genode::error("could not gather play information");
return;
}
@ -182,7 +172,7 @@ static bool set_mixer_value(Mixer &mixer, char const * const field,
if (audioioctl(mdev, AUDIO_MIXER_READ, (char*)&ctrl, 0, 0)) {
ctrl.un.value.num_channels = 1;
if (audioioctl(mdev, AUDIO_MIXER_READ, (char*)&ctrl, 0, 0)) {
PERR("could not read mixer %d'", ctrl.dev);
Genode::error("could not read mixer ", ctrl.dev);
return 0;
}
}
@ -232,11 +222,10 @@ static bool set_mixer_value(Mixer &mixer, char const * const field,
break;
if (audioioctl(mdev, AUDIO_MIXER_WRITE, (char*)&ctrl, FWRITE, 0)) {
PERR("could not set '%s' from %d to %d", field, oldv, newv);
Genode::error("could not set ", field, " from ", oldv, " to ", newv);
break;
}
PLOG("%s: %d -> %d", field, oldv, newv);
return true;
}
@ -256,7 +245,7 @@ static char const *get_mixer_value(mixer_devinfo_t *info)
if (audioioctl(mdev, AUDIO_MIXER_READ, (char*)&ctrl, 0, 0)) {
ctrl.un.value.num_channels = 1;
if (audioioctl(mdev, AUDIO_MIXER_READ, (char*)&ctrl, 0, 0)) {
PERR("could not read mixer %d'", ctrl.dev);
Genode::error("could not read mixer ", ctrl.dev);
return 0;
}
}
@ -302,7 +291,7 @@ static char const *get_mixer_value(mixer_devinfo_t *info)
static void dump_mixer(Mixer const &mixer)
{
PLOG("--- mixer information ---");
Genode::log("--- mixer information ---");
for (unsigned i = 0; i < mixer.num; i++) {
if (mixer.info[i].type == AUDIO_MIXER_CLASS)
continue;
@ -313,11 +302,47 @@ static void dump_mixer(Mixer const &mixer)
char const * const value = get_mixer_value(&mixer.info[i]);
if (value)
PLOG("%s.%s=%s", class_name, name, value);
Genode::log(class_name, ".", name, "=", value);
}
}
static Genode::Reporter mixer_reporter = { "mixer_state" };
static void report_mixer(Mixer const &mixer)
{
if (!mixer_reporter.is_enabled()) { return; }
try {
Genode::Reporter::Xml_generator xml(mixer_reporter, [&]() {
for (unsigned i = 0; i < mixer.num; i++) {
if (mixer.info[i].type == AUDIO_MIXER_CLASS)
continue;
unsigned mixer_class = mixer.info[i].mixer_class;
char const * const class_name = mixer.info[mixer_class].label.name;
char const * const name = mixer.info[i].label.name;
char const * const value = get_mixer_value(&mixer.info[i]);
if (value) {
xml.node("mixer", [&]() {
char tmp[64];
Genode::snprintf(tmp, sizeof(tmp), "%s.%s",
class_name, name);
xml.attribute("field", tmp);
xml.attribute("value", value);
});
}
}
});
} catch (...) { Genode::warning("Could not report mixer state"); }
}
/******************
** Audio device **
******************/
@ -335,26 +360,14 @@ static bool open_audio_device(dev_t dev)
}
static bool config_verbose()
static void parse_config(Mixer &mixer, Genode::Xml_node config)
{
using namespace Genode;
try {
return config()->xml_node().attribute("verbose").has_value("yes");
} catch (...) { }
bool const v = config.attribute_value<bool>("report_mixer", false);
mixer_reporter.enabled(v);
return false;
}
static void parse_config(Mixer &mixer)
{
using namespace Genode;
PLOG("--- parse config ---");
Xml_node config_node = config()->xml_node();
config_node.for_each_sub_node("mixer", [&] (Xml_node node) {
config.for_each_sub_node("mixer", [&] (Xml_node node) {
char field[32];
char value[16];
try {
@ -367,7 +380,7 @@ static void parse_config(Mixer &mixer)
}
static bool configure_audio_device(dev_t dev)
static bool configure_audio_device(dev_t dev, Genode::Xml_node config)
{
struct audio_info ai;
@ -408,31 +421,49 @@ static bool configure_audio_device(dev_t dev)
if (!mixer.info || !query_mixer(mixer))
return false;
if (config_verbose()) verbose = true;
bool const verbose = config.attribute_value<bool>("verbose", false);
if (verbose) dump_pinfo();
if (verbose) dump_rinfo();
if (verbose) dump_mixer(mixer);
parse_config(mixer);
parse_config(mixer, config);
report_mixer(mixer);
return true;
}
static void run_bsd(void *)
namespace {
struct Task_args
{
Genode::Env &env;
Genode::Allocator &alloc;
Genode::Xml_node config;
Task_args(Genode::Env &env, Genode::Allocator &alloc,
Genode::Xml_node config)
: env(env), alloc(alloc), config(config) { }
};
}
static void run_bsd(void *p)
{
if (!Bsd::probe_drivers()) {
PERR("no supported sound card found");
Task_args *args = static_cast<Task_args*>(p);
if (!Bsd::probe_drivers(args->env, args->alloc)) {
Genode::error("no supported sound card found");
Genode::sleep_forever();
}
if (!open_audio_device(adev)) {
PERR("could not initialize sound card");
Genode::error("could not initialize sound card");
Genode::sleep_forever();
}
adev_usuable = configure_audio_device(adev);
adev_usuable = configure_audio_device(adev, args->config);
while (true) {
Bsd::scheduler().current()->block_and_schedule();
@ -472,14 +503,27 @@ extern "C" void notify_record()
** private Audio namespace **
*****************************/
void Audio::init_driver(Server::Entrypoint &ep)
void Audio::update_config(Genode::Xml_node config)
{
Bsd::irq_init(ep);
Bsd::timer_init(ep);
if (mixer.info == nullptr) { return; }
static Bsd::Task task_bsd(run_bsd, nullptr, "bsd",
parse_config(mixer, config);
report_mixer(mixer);
}
void Audio::init_driver(Genode::Env &env, Genode::Allocator &alloc,
Genode::Xml_node config)
{
Bsd::mem_init(env, alloc);
Bsd::irq_init(env.ep(), alloc);
Bsd::timer_init(env.ep());
static Task_args args(env, alloc, config);
static Bsd::Task task_bsd(run_bsd, &args, "bsd",
Bsd::Task::PRIORITY_0, Bsd::scheduler(),
2048 * sizeof(long));
2048 * sizeof(Genode::addr_t));
Bsd::scheduler().schedule();
}

View File

@ -11,7 +11,7 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/log.h>
extern "C" {
typedef long DUMMY;
@ -23,23 +23,23 @@ enum {
};
#define DUMMY(retval, name) \
DUMMY name(void) { \
DUMMY name(void) { \
if (SHOW_DUMMY) \
PDBG( #name " called (from %p) not implemented", __builtin_return_address(0)); \
Genode::log( #name " called (from ", __builtin_return_address(0), ") not implemented"); \
return retval; \
}
#define DUMMY_SKIP(retval, name) \
DUMMY name(void) { \
if (SHOW_SKIP) \
PLOG( #name " called (from %p) skipped", __builtin_return_address(0)); \
DUMMY name(void) { \
if (SHOW_SKIP) \
Genode::log( #name " called (from ", __builtin_return_address(0), ") skipped"); \
return retval; \
}
#define DUMMY_RET(retval, name) \
DUMMY name(void) { \
if (SHOW_RET) \
PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \
DUMMY name(void) { \
if (SHOW_RET) \
Genode::warning( #name " called (from ", __builtin_return_address(0), ") return ", retval); \
return retval; \
}
@ -63,5 +63,6 @@ DUMMY(0, timeout_del)
DUMMY(0, timeout_set)
DUMMY(0, tsleep)
DUMMY(0, vdevgone)
DUMMY(0, device_unref)
} /* extern "C" */

View File

@ -17,9 +17,7 @@
#ifndef _BSD_EMUL_H_
#define _BSD_EMUL_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <extern_c_begin.h>
/*
@ -300,7 +298,7 @@ void wakeup(const volatile void*);
int tsleep(const volatile void *, int, const char *, int);
int msleep(const volatile void *, struct mutex *, int, const char*, int);
int uiomovei(void *, int, struct uio *);
int uiomove(void *, int, struct uio *);
/*******************
@ -681,8 +679,6 @@ int timeout_del(struct timeout *);
#define htole32(x) ((uint32_t)(x))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#include <extern_c_end.h>
#endif /* _BSD_EMUL_H_ */

View File

@ -11,6 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#ifdef __cplusplus
#define extern_c_begin
extern "C" {
@ -24,3 +26,5 @@ extern "C" {
#define private private_
#define class class_
#define new new_
#endif /* __cplusplus */

View File

@ -11,6 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#ifdef __cplusplus
#undef new
#undef class
#undef private
@ -18,3 +20,5 @@
#pragma GCC diagnostic pop
} /* extern "C" */
#endif /* __cplusplus */

View File

@ -7,7 +7,7 @@
*/
/*
* Copyright (C) 2012-2015 Genode Labs GmbH
* Copyright (C) 2012-2016 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.
@ -167,13 +167,6 @@ class Bsd::Scheduler
* Returns if no task is runnable.
*/
void schedule();
/**
* Log current state of tasks in present list (debug)
*
* Log lines are prefixed with 'prefix'
*/
void log_state(char const *prefix);
};
#endif /* _SCHEDULER_H_ */

View File

@ -5,13 +5,14 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
*/
/* Genode includes */
#include <base/log.h>
#include <base/thread.h>
#include <base/tslab.h>
#include <timer_session/connection.h>
@ -20,9 +21,7 @@
/* local includes */
#include <audio/audio.h>
#include <bsd.h>
#include <extern_c_begin.h>
# include <bsd_emul.h>
#include <extern_c_end.h>
#include <bsd_emul.h>
namespace Bsd {
@ -49,7 +48,7 @@ class Bsd::Irq
Bsd::Task _task;
Genode::Irq_session_client _irq;
Genode::Signal_rpc_member<Context> _dispatcher;
Genode::Signal_handler<Context> _dispatcher;
intrh_t _intrh;
void *_intarg;
@ -57,7 +56,7 @@ class Bsd::Irq
/**
* Signal handler
*/
void _handle(unsigned)
void _handle()
{
_task.unblock();
Bsd::scheduler().schedule();
@ -68,7 +67,7 @@ class Bsd::Irq
/**
* Constructor
*/
Context(Server::Entrypoint &ep,
Context(Genode::Entrypoint &ep,
Genode::Irq_session_capability cap,
intrh_t intrh, void *intarg)
:
@ -95,7 +94,7 @@ class Bsd::Irq
private:
Genode::Allocator &_alloc;
Server::Entrypoint &_ep;
Genode::Entrypoint &_ep;
Context *_ctx;
public:
@ -103,7 +102,7 @@ class Bsd::Irq
/**
* Constructor
*/
Irq(Genode::Allocator &alloc, Server::Entrypoint &ep)
Irq(Genode::Allocator &alloc, Genode::Entrypoint &ep)
: _alloc(alloc), _ep(ep), _ctx(nullptr) { }
/**
@ -112,7 +111,7 @@ class Bsd::Irq
void establish_intr(Genode::Irq_session_capability cap, intrh_t intrh, void *intarg)
{
if (_ctx) {
PERR("interrupt already established");
Genode::error("interrupt already established");
Genode::sleep_forever();
}
@ -124,9 +123,9 @@ class Bsd::Irq
static Bsd::Irq *_bsd_irq;
void Bsd::irq_init(Server::Entrypoint &ep)
void Bsd::irq_init(Genode::Entrypoint &ep, Genode::Allocator &alloc)
{
static Bsd::Irq irq_context(*Genode::env()->heap(), ep);
static Bsd::Irq irq_context(alloc, ep);
_bsd_irq = &irq_context;
}

View File

@ -5,26 +5,24 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
*/
/* Genode includes */
#include <base/env.h>
#include <base/allocator_avl.h>
#include <base/printf.h>
#include <base/env.h>
#include <base/log.h>
#include <dataspace/client.h>
#include <rm_session/connection.h>
#include <region_map/client.h>
#include <util/string.h>
/* local includes */
#include "bsd.h"
#include <extern_c_begin.h>
# include <bsd_emul.h>
#include <extern_c_end.h>
#include <bsd.h>
#include <bsd_emul.h>
static bool const verbose = false;
@ -64,7 +62,7 @@ class Bsd::Slab_backend_alloc : public Genode::Allocator,
bool _alloc_block()
{
if (_index == ELEMENTS) {
PERR("Slab-backend exhausted!");
Genode::error("Slab-backend exhausted!");
return false;
}
@ -83,13 +81,14 @@ class Bsd::Slab_backend_alloc : public Genode::Allocator,
public:
Slab_backend_alloc(Genode::Ram_session &ram)
Slab_backend_alloc(Genode::Ram_session &ram, Genode::Region_map &rm,
Genode::Allocator &md_alloc)
:
Region_map_client(Rm_connection::create(VM_SIZE)),
_index(0), _range(Genode::env()->heap()), _ram(ram)
_index(0), _range(&md_alloc), _ram(ram)
{
/* reserver attach us, anywere */
_base = Genode::env()->rm_session()->attach(dataspace());
_base = rm.attach(dataspace());
}
addr_t start() const { return _base; }
@ -109,7 +108,7 @@ class Bsd::Slab_backend_alloc : public Genode::Allocator,
done = _alloc_block();
if (!done) {
PERR("Backend allocator exhausted\n");
Genode::error("Backend allocator exhausted\n");
return false;
}
@ -220,15 +219,16 @@ class Bsd::Malloc
public:
Malloc(Slab_backend_alloc &alloc)
Malloc(Slab_backend_alloc &alloc, Genode::Allocator &md_alloc)
:
_back_allocator(alloc), _start(alloc.start()),
_end(alloc.end())
{
/* init slab allocators */
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
_allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
Slab_alloc(1U << i, _back_allocator);
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) {
_allocator[i - SLAB_START_LOG2] =
new (&md_alloc) Slab_alloc(1U << i, _back_allocator);
}
}
/**
@ -254,13 +254,13 @@ class Bsd::Malloc
msb = SLAB_STOP_LOG2;
if (msb > SLAB_STOP_LOG2) {
PERR("Slab too large %u reqested %zu", 1U << msb, size);
Genode::error("Slab too large ", 1U << msb, " reqested ", size);
return 0;
}
addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc();
if (!addr) {
PERR("Failed to get slab for %u", 1U << msb);
Genode::error("Failed to get slab for ", 1U << msb);
return 0;
}
@ -306,14 +306,20 @@ class Bsd::Malloc
};
static Bsd::Malloc& malloc_backend()
static Bsd::Malloc *_malloc;
void Bsd::mem_init(Genode::Env &env, Genode::Allocator &alloc)
{
static Bsd::Slab_backend_alloc sb(*Genode::env()->ram_session());
static Bsd::Malloc m(sb);
return m;
static Bsd::Slab_backend_alloc sb(env.ram(), env.rm(), alloc);
static Bsd::Malloc m(sb, alloc);
_malloc = &m;
}
static Bsd::Malloc& malloc_backend() { return *_malloc; }
/**********************
** Memory allocation *
**********************/
@ -343,17 +349,18 @@ extern "C" void free(void *addr, int type, size_t size)
if (!addr) return;
if (!malloc_backend().inside((Genode::addr_t)addr)) {
PERR("cannot free unknown memory at %p, called from %p",
addr, __builtin_return_address(0));
Genode::error("cannot free unknown memory at ", __builtin_return_address(0),
" called from ", addr);
return;
}
if (size) {
size_t ssize = malloc_backend().size(addr);
if (ssize != size)
PWRN("size: %zu for %p does not match stored size: %zu",
size, addr, ssize);
if (ssize != size) {
Genode::warning("size: ", size, "for ", addr,
" does not match stored size: ", ssize);
}
}
malloc_backend().free(addr);
@ -379,7 +386,7 @@ extern "C" void bcopy(const void *src, void *dst, size_t len)
}
extern "C" int uiomovei(void *buf, int n, struct uio *uio)
extern "C" int uiomove(void *buf, int n, struct uio *uio)
{
void *dst = nullptr;
void *src = nullptr;

View File

@ -18,9 +18,7 @@
#include <util/string.h>
/* local includes */
#include <extern_c_begin.h>
#include <bsd_emul.h>
#include <extern_c_end.h>
/* compiler includes */
#include <stdarg.h>

View File

@ -9,13 +9,14 @@
*/
/*
* Copyright (C) 2012-2015 Genode Labs GmbH
* Copyright (C) 2012-2016 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.
*/
/* Genode includes */
#include <base/log.h>
#include <base/sleep.h>
/* local includes */
@ -23,11 +24,6 @@
#include <scheduler.h>
static bool const debugging = false;
static bool const verbose = false;
#define PDBGV(...) do { if (verbose) PDBG(__VA_ARGS__); } while (0)
/**********
** Task **
**********/
@ -40,7 +36,7 @@ bool Bsd::Task::_runnable() const
case STATE_BLOCKED: return false;
}
PERR("state %d not handled by switch", _state);
Genode::error("state ", (unsigned)_state, " not handled by switch");
Genode::sleep_forever();
}
@ -72,7 +68,7 @@ bool Bsd::Task::run()
}
/* never reached */
PERR("Unexpected return of Task");
Genode::error("Unexpected return of Task");
Genode::sleep_forever();
}
@ -99,8 +95,6 @@ Bsd::Task::Task(void (*func)(void*), void *arg, char const *name,
_func(func), _arg(arg), _name(name), _stack_size(stack_size)
{
scheduler.add(this);
PDBGV("name: '%s' func: %p arg: %p prio: %u t: %p", name, func, arg, priority, this);
}
@ -125,7 +119,7 @@ Bsd::Scheduler & Bsd::scheduler()
Bsd::Task *Bsd::Scheduler::current()
{
if (!_current) {
PERR("BUG: _current is zero!");
Genode::error("BUG: _current is zero!");
Genode::sleep_forever();
}
@ -179,8 +173,7 @@ void Bsd::Scheduler::schedule()
}
if (!at_least_one) {
PWRN("schedule() called without runnable tasks");
log_state("SCHEDULE");
Genode::warning("schedule() called without runnable tasks");
}
/* clear current as no task is running */
@ -188,69 +181,7 @@ void Bsd::Scheduler::schedule()
}
#include <timer_session/connection.h>
namespace {
struct Logger : Genode::Thread_deprecated<0x4000>
{
Timer::Connection _timer;
Bsd::Scheduler &_scheduler;
unsigned const _interval;
Logger(Bsd::Scheduler &scheduler, unsigned interval_seconds)
:
Genode::Thread_deprecated<0x4000>("logger"),
_scheduler(scheduler), _interval(interval_seconds)
{
start();
}
void entry()
{
PWRN("Scheduler::Logger is up");
_timer.msleep(1000 * _interval);
while (true) {
_scheduler.log_state("LOGGER");
_timer.msleep(2000);
}
}
};
}
#define ANSI_ESC_RESET "\033[00m"
#define ANSI_ESC_BLACK "\033[30m"
#define ANSI_ESC_RED "\033[31m"
#define ANSI_ESC_YELLOW "\033[33m"
static char const *state_color(Bsd::Task::State state)
{
switch (state) {
case Bsd::Task::STATE_INIT: return ANSI_ESC_RESET;
case Bsd::Task::STATE_RUNNING: return ANSI_ESC_RED;
case Bsd::Task::STATE_BLOCKED: return ANSI_ESC_YELLOW;
}
return ANSI_ESC_BLACK;
}
void Bsd::Scheduler::log_state(char const *prefix)
{
unsigned i;
Bsd::Task *t;
for (i = 0, t = _present_list.first(); t; t = t->next(), ++i) {
Genode::printf("%s [%u] prio: %u state: %s%u" ANSI_ESC_RESET " %s\n",
prefix, i, t->priority(), state_color(t->state()),
t->state(), t->name());
}
}
Bsd::Scheduler::Scheduler()
{
if (debugging)
new (Genode::env()->heap()) Logger(*this, 10);
}
Bsd::Scheduler::Scheduler() { }
Bsd::Scheduler::~Scheduler() { }

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014-2015 Genode Labs GmbH
* Copyright (C) 2014-2016 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.
@ -14,7 +14,7 @@
/* Genode includes */
#include <base/env.h>
#include <base/heap.h>
#include <base/printf.h>
#include <base/log.h>
#include <base/sleep.h>
#include <base/tslab.h>
#include <timer_session/connection.h>
@ -22,10 +22,7 @@
/* local includes */
#include <list.h>
#include <bsd.h>
#include <extern_c_begin.h>
# include <bsd_emul.h>
#include <extern_c_end.h>
#include <bsd_emul.h>
static unsigned long millisecs;
@ -42,13 +39,13 @@ class Bsd::Timer
{
private:
::Timer::Connection _timer_conn;
Genode::Signal_rpc_member<Bsd::Timer> _dispatcher;
::Timer::Connection _timer_conn;
Genode::Signal_handler<Bsd::Timer> _dispatcher;
/**
* Handle trigger_once signal
*/
void _handle(unsigned)
void _handle()
{
Bsd::scheduler().schedule();
}
@ -58,7 +55,7 @@ class Bsd::Timer
/**
* Constructor
*/
Timer(Server::Entrypoint &ep)
Timer(Genode::Entrypoint &ep)
:
_dispatcher(ep, *this, &Bsd::Timer::_handle)
{
@ -78,7 +75,7 @@ class Bsd::Timer
static Bsd::Timer *_bsd_timer;
void Bsd::timer_init(Server::Entrypoint &ep)
void Bsd::timer_init(Genode::Entrypoint &ep)
{
/* XXX safer way preventing possible nullptr access? */
static Bsd::Timer bsd_timer(ep);
@ -106,16 +103,13 @@ static Bsd::Task *_sleep_task;
extern "C" int msleep(const volatile void *ident, struct mutex *mtx,
int priority, const char *wmesg, int timo)
{
// PDBG("ident: %p mtx: %p priority: %d wmesg: '%s' timo: %d",
// ident, mtx, priority, wmesg, timo);
if (_sleep_task) {
PERR("_sleep_task is not null, current task: '%s'", Bsd::scheduler().current()->name());
Genode::error("_sleep_task is not null, current task: ",
Bsd::scheduler().current()->name());
Genode::sleep_forever();
}
_sleep_task = Bsd::scheduler().current();
// PERR("msleep: '%s' %p", _sleep_task->name(), ident);
_sleep_task->block_and_schedule();
return 0;
@ -123,7 +117,6 @@ extern "C" int msleep(const volatile void *ident, struct mutex *mtx,
extern "C" void wakeup(const volatile void *ident)
{
// PERR("wakeup: '%s' %p", _sleep_task->name(), ident);
_sleep_task->unblock();
_sleep_task = nullptr;
}