app/rom_logger: base API transition, hexdump output

Ref #1987
This commit is contained in:
Emery Hemingway 2016-11-17 02:21:38 +01:00 committed by Christian Helmuth
parent c0f1d99d7a
commit f1fc94cfbd
3 changed files with 54 additions and 39 deletions

View File

@ -3,3 +3,6 @@ ROM dataspace to the LOG. It responds to configuration and ROM-module updates.
The name of the ROM module must be specified via the 'rom' attribute of the The name of the ROM module must be specified via the 'rom' attribute of the
components '<config>' node. For example: '<config rom="pointer"/>'. components '<config>' node. For example: '<config rom="pointer"/>'.
The output format may be also be specified via a 'format' attribute. The options are
'text'and 'hexdump', with the former as a default.

View File

@ -12,12 +12,10 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <rom_session/connection.h>
#include <base/signal.h> #include <base/signal.h>
#include <os/config.h> #include <base/attached_rom_dataspace.h>
#include <os/attached_rom_dataspace.h>
#include <util/print_lines.h> #include <util/print_lines.h>
#include <os/server.h> #include <base/component.h>
#include <util/volatile_object.h> #include <util/volatile_object.h>
namespace Rom_logger { struct Main; } namespace Rom_logger { struct Main; }
@ -25,7 +23,9 @@ namespace Rom_logger { struct Main; }
struct Rom_logger::Main struct Rom_logger::Main
{ {
Server::Entrypoint &_ep; Genode::Env &_env;
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
Genode::Lazy_volatile_object<Genode::Attached_rom_dataspace> _rom_ds; Genode::Lazy_volatile_object<Genode::Attached_rom_dataspace> _rom_ds;
@ -42,72 +42,84 @@ struct Rom_logger::Main
* Signal handler that is invoked when the configuration or the ROM module * Signal handler that is invoked when the configuration or the ROM module
* changes. * changes.
*/ */
void _handle_update(unsigned); void _handle_update();
Genode::Signal_rpc_member<Main> _update_dispatcher = Genode::Signal_handler<Main> _update_handler {
{ _ep, *this, &Main::_handle_update }; _env.ep(), *this, &Main::_handle_update };
Main(Server::Entrypoint &ep) : _ep(ep) Main(Genode::Env &env) : _env(env)
{ {
Genode::config()->sigh(_update_dispatcher); _config_rom.sigh(_update_handler);
_handle_update(0); _handle_update();
} }
}; };
void Rom_logger::Main::_handle_update(unsigned) template <typename T>
{ inline Genode::Hex mkhex(T value) {
using Genode::config; return Genode::Hex(value, Genode::Hex::OMIT_PREFIX, Genode::Hex::PAD); }
config()->reload();
void Rom_logger::Main::_handle_update()
{
_config_rom.update();
/* /*
* Query name of ROM module from config * Query name of ROM module from config
*/ */
Rom_name rom_name; Rom_name rom_name;
try { try {
rom_name = config()->xml_node().attribute_value("rom", rom_name); _config_rom.xml().attribute("rom").value(&rom_name);
} catch (...) { } catch (...) {
Genode::warning("could not determine ROM name from config"); Genode::warning("could not determine ROM name from config");
return; return;
} }
typedef Genode::String<8> Format_string;
Format_string format =
_config_rom.xml().attribute_value("format", Format_string("text"));
/* /*
* If ROM name changed, reconstruct '_rom_ds' * If ROM name changed, reconstruct '_rom_ds'
*/ */
if (rom_name != _rom_name) { if (rom_name != _rom_name) {
_rom_ds.construct(rom_name.string()); _rom_ds.construct(rom_name.string());
_rom_ds->sigh(_update_dispatcher); _rom_ds->sigh(_update_handler);
_rom_name = rom_name; _rom_name = rom_name;
} }
if (!_rom_ds.constructed())
return;
/* /*
* Update ROM module and print content to LOG * Update ROM module and print content to LOG
*/ */
if (_rom_ds.constructed()) { _rom_ds->update();
_rom_ds->update();
if (_rom_ds->valid()) { if (!_rom_ds->valid()) {
log("ROM '", _rom_name, "':"); Genode::log("ROM '", _rom_name, "' is invalid");
return;
}
Genode::print_lines<200>(_rom_ds->local_addr<char>(), _rom_ds->size(), log("ROM '", _rom_name, "':");
[&] (char const *line) { Genode::log(" ", line); });
} else { if (format == "text") {
Genode::log("ROM '", _rom_name, "' is invalid"); Genode::print_lines<200>(_rom_ds->local_addr<char>(), _rom_ds->size(),
} [&] (char const *line) { Genode::log(" ", line); });
} else if (format == "hexdump") {
short const *data = _rom_ds->local_addr<short const>();
/* dataspaces are always page aligned, therefore multiples of 2*8 bytes */
Genode::uint32_t const data_len = _rom_ds->size() / sizeof(short);
for (Genode::uint32_t i = 0; i < data_len; i += 8)
log(mkhex(i)," ",mkhex(data[i+0])," ",mkhex(data[i+1]),
" ",mkhex(data[i+2])," ",mkhex(data[i+3]),
" ",mkhex(data[i+4])," ",mkhex(data[i+5]),
" ",mkhex(data[i+6])," ",mkhex(data[i+7]));
} else {
error("unknown format specified by '", _config_rom.xml(),"'");
} }
} }
namespace Server { Genode::size_t Component::stack_size() { return 4*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Rom_logger::Main main(env); }
char const *name() { return "ep"; }
size_t stack_size() { return 4*1024*sizeof(long); }
void construct(Entrypoint &ep)
{
static Rom_logger::Main main(ep);
}
}

View File

@ -1,3 +1,3 @@
TARGET = rom_logger TARGET = rom_logger
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base config server LIBS = base