genode/base-hw/include/kernel/log.h
2014-02-25 14:58:02 +01:00

119 lines
2.3 KiB
C++

/*
* \brief Print to the standard output of the kernel
* \author Martin stein
* \date 2012-04-05
*/
/*
* Copyright (C) 2012-2013 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 _KERNEL__LOG_H_
#define _KERNEL__LOG_H_
/* Genode includes */
#include <kernel/interface.h>
namespace Kernel
{
/**
* Prints incoming streams to the standard output of the kernel
*/
class Log
{
private:
/**
* Print an unsigned 4 bit integer x as hexadecimal value
*/
void _print_4bit_hex(unsigned char x) const
{
/* decode to ASCII char */
x &= 0x0f;
if (x > 9) x += 39;
x += 48;
/* print ASCII char */
print_char(x);
}
public:
/**
* Print a zero-terminated string s
*/
Log & operator << (char const * s)
{
while (*s) print_char(*s++);
if (*--s != '\n') { print_char(' '); }
return *this;
}
/**
* Print an unsigned integer x as hexadecimal value
*/
Log & operator << (unsigned int const x)
{
enum {
BYTE_WIDTH = 8,
CW = sizeof(unsigned char)*BYTE_WIDTH,
IW = sizeof(unsigned int)*BYTE_WIDTH
};
/*
* Walk from most significant to least significant bit and
* process 2 hex digits per step.
*/
bool leading = true;
for (int i = IW - CW; i >= 0; i = i - CW)
{
/* fetch the 2 current digits */
unsigned char c = (char)((x >> i) & 0xff);
/* has the payload part of the value already begun? */
if (leading)
{
/* ignore leading zeros ... */
if (!c)
{
/* ... expect they are the only digits */
if (i == 0) _print_4bit_hex(c);
continue;
}
/* transit from leading to payload part */
leading = false;
if (c < 0x10) {
_print_4bit_hex(c);
continue;
}
}
/* print both digits */
_print_4bit_hex(c >> 4);
_print_4bit_hex(c);
}
print_char(' ');
return *this;
}
/**
* Print a pointer p as hexadecimal value
*/
Log & operator << (void * const p) { return *this << (unsigned)p; }
};
/**
* Return singleton kernel-log
*/
inline Log & log()
{
static Log s;
return s;
}
}
#endif /* _KERNEL__LOG_H_ */