Move console/*.c into lib/ in order to simplify the directory structure.

Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>
Acked-by: Stefan Reinauer <stepan@coresystems.de>



git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@315 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Stefan Reinauer 2007-05-06 09:35:25 +00:00
commit 9caaf62dd5
9 changed files with 168 additions and 197 deletions

View file

@ -61,3 +61,168 @@ endchoice
endmenu
menu "Console"
config CONSOLE
bool "Console support"
default y
help
Support for various types of (debugging) consoles.
choice
prompt "Console log level"
default CONSOLE_LOGLEVEL_8
depends CONSOLE
config CONSOLE_LOGLEVEL_8
bool "BIOS_SPEW"
help
Way too many details.
config CONSOLE_LOGLEVEL_7
bool "BIOS_DEBUG"
help
Debug-level messages.
config CONSOLE_LOGLEVEL_6
bool "BIOS_INFO"
help
Informational messages.
config CONSOLE_LOGLEVEL_5
bool "BIOS_NOTICE"
help
Normal but significant conditions.
config CONSOLE_LOGLEVEL_4
bool "BIOS_WARNING"
help
Warning conditions.
config CONSOLE_LOGLEVEL_3
bool "BIOS_ERR"
help
Error conditions.
config CONSOLE_LOGLEVEL_2
bool "BIOS_CRIT"
help
Critical conditions.
config CONSOLE_LOGLEVEL_1
bool "BIOS_ALERT"
help
Action must be taken immediately.
config CONSOLE_LOGLEVEL_0
bool "BIOS_EMERG"
help
System is unusable.
endchoice
config DEFAULT_CONSOLE_LOGLEVEL
int
default 0 if CONSOLE_LOGLEVEL_0
default 1 if CONSOLE_LOGLEVEL_1
default 2 if CONSOLE_LOGLEVEL_2
default 3 if CONSOLE_LOGLEVEL_3
default 4 if CONSOLE_LOGLEVEL_4
default 5 if CONSOLE_LOGLEVEL_5
default 6 if CONSOLE_LOGLEVEL_6
default 7 if CONSOLE_LOGLEVEL_7
default 8 if CONSOLE_LOGLEVEL_8
help
Map the log level config names to an integer.
config CONSOLE_SERIAL
boolean "Serial console support"
default y
depends CONSOLE
help
Send LinuxBIOS output to serial console.
choice
prompt "Serial console COM port"
default CONSOLE_SERIAL_COM1
depends CONSOLE_SERIAL
config CONSOLE_SERIAL_COM1
bool "COM1/ttyS0"
help
Serial console on COM1/ttyS0.
config CONSOLE_SERIAL_COM2
bool "COM2/ttyS1"
help
Serial console on COM2/ttyS1.
endchoice
choice
prompt "Serial console speed"
default CONSOLE_SERIAL_115200
depends CONSOLE_SERIAL
config CONSOLE_SERIAL_115200
bool "115200 bps"
help
Set serial console speed to 115200 bps.
config CONSOLE_SERIAL_57600
bool "57600 bps"
help
Set serial console speed to 57600 bps.
config CONSOLE_SERIAL_38400
bool "38400 bps"
help
Set serial console speed to 38400 bps.
config CONSOLE_SERIAL_19200
bool "19200 bps"
help
Set serial console speed to 19200 bps.
config CONSOLE_SERIAL_9600
bool "9600 bps"
help
Set serial console speed to 9600 bps.
endchoice
config CONSOLE_USB
boolean "USB2 console support (EXPERIMENTAL)"
depends CONSOLE && EXPERIMENTAL
help
Send LinuxBIOS output to USB2 (EHCI) console.
Note: This requires a USB2 controller which supports the EHCI
Debug Port capability. Controllers which are known to work:
* 10b9:5239 ALi Corporation USB 2.0 (USB PCI card)
* 10de:0088 NVIDIA MCP2A
* 10de:005b NVIDIA CK804
* 10de:036d NVIDIA MCP55
* 8086:24dd Intel ICH5
* 8086:265c Intel ICH6
* 8086:268c Intel 631xESB/632xESB/3100
* 8086:27cc Intel ICH7
* 8086:2836 Intel ICH8
* 8086:283a Intel ICH8
See http://linuxbios.org/EHCI_Debug_Port for an up-to-date list.
comment "Cosmetic console options"
depends EXPERT && (CONSOLE_SERIAL || CONSOLE_USB)
config CONSOLE_PREFIX
bool "Prefix all console output with '(LB)'"
depends EXPERT && (CONSOLE_SERIAL || CONSOLE_USB)
default n
help
When you enable this option, LinuxBIOS will prefix each line of
console output with '(LB)'.
endmenu

70
lib/console.c Normal file
View file

@ -0,0 +1,70 @@
#include <types.h>
#include <hlt.h>
#include <console.h>
#include <uart8250.h>
// FIXME: we need this for varargs
#include <stdarg.h>
int vtxprintf(void (*)(unsigned char, void *arg),
void *arg, const char *, va_list);
static int console_loglevel(void)
{
return CONFIG_DEFAULT_CONSOLE_LOGLEVEL;
}
void console_tx_byte(unsigned char byte, void *arg)
{
if (byte == '\n') {
uart8250_tx_byte(TTYSx_BASE, '\r');
#if defined(CONFIG_CONSOLE_PREFIX) && (CONFIG_CONSOLE_PREFIX == 1)
uart8250_tx_byte(TTYSx_BASE, '\n');
uart8250_tx_byte(TTYSx_BASE, '(');
uart8250_tx_byte(TTYSx_BASE, 'L');
uart8250_tx_byte(TTYSx_BASE, 'B');
uart8250_tx_byte(TTYSx_BASE, ')');
uart8250_tx_byte(TTYSx_BASE, ' ');
return;
#endif
}
uart8250_tx_byte(TTYSx_BASE, byte);
}
int printk(int msg_level, const char *fmt, ...)
{
va_list args;
int i;
if (msg_level >= console_loglevel()) {
return 0;
}
va_start(args, fmt);
i = vtxprintf(console_tx_byte, (void *)0, fmt, args);
va_end(args);
return i;
}
void console_init(void)
{
static const char console_test[] =
"\n\nLinuxBIOS-"
LINUXBIOS_VERSION
LINUXBIOS_EXTRA_VERSION
" "
LINUXBIOS_BUILD
" starting...\n";
printk(BIOS_INFO, console_test);
}
void die(const char *str)
{
printk(BIOS_EMERG, str);
do {
hlt();
} while (1);
}

58
lib/vsprintf.c Normal file
View file

@ -0,0 +1,58 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
#include <stdarg.h>
#include <string.h>
#include <console.h>
int vtxprintf(void (*tx_byte) (unsigned char byte, void *arg), void *arg, const char *fmt,
va_list args);
/* the arg is the char ** for the buffer */
static void str_tx_byte(unsigned char byte, void *arg)
{
unsigned char *cp = *(unsigned char **) arg;
*cp = byte;
cp++;
/* paranoia, make sure it will be null terminated. The cost for this is small,
* the benefit large.
*/
*cp = 0;
*(unsigned char **) arg = cp;
}
int sprintf(char *buf, const char *fmt, ...)
{
va_list args;
int i;
unsigned char *cp = (unsigned char *)buf;
unsigned char **cpp = &cp;
va_start(args, fmt);
i = vtxprintf(str_tx_byte, cpp, fmt, args);
va_end(args);
return i;
}

289
lib/vtxprintf.c Normal file
View file

@ -0,0 +1,289 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* vtxprintf.c, from
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <stdarg.h>
#include <string.h>
#include <div64.h>
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define is_digit isdigit
#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
static int skip_atoi(const char **s)
{
int i=0;
while (is_digit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static int number(void (*tx_byte)(unsigned char byte, void *arg), void *arg,
unsigned long long num, int base, int size, int precision, int type)
{
char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
int i;
int count = 0;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if ((signed long long)num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0)
tmp[i++] = digits[do_div(num,base)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
tx_byte(' ', arg), count++;
if (sign)
tx_byte(sign, arg), count++;
if (type & SPECIAL) {
if (base==8)
tx_byte('0', arg), count++;
else if (base==16) {
tx_byte('0', arg), count++;
tx_byte(digits[33], arg), count++;
}
}
if (!(type & LEFT))
while (size-- > 0)
tx_byte(c, arg), count++;
while (i < precision--)
tx_byte('0', arg), count++;
while (i-- > 0)
tx_byte(tmp[i], arg), count++;
while (size-- > 0)
tx_byte(' ', arg), count++;
return count;
}
int vtxprintf(void (*tx_byte)(unsigned char byte, void *arg), void *arg, const char *fmt, va_list args)
{
int len;
unsigned long long num;
int i, base;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
int count;
for (count=0; *fmt ; ++fmt) {
if (*fmt != '%') {
tx_byte(*fmt, arg), count++;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (is_digit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (is_digit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
qualifier = *fmt;
++fmt;
if (*fmt == 'l') {
qualifier = 'L';
++fmt;
}
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
tx_byte(' ', arg), count++;
tx_byte((unsigned char) va_arg(args, int), arg), count++;
while (--field_width > 0)
tx_byte(' ', arg), count++;
continue;
case 's':
s = va_arg(args, char *);
if (!s)
s = "<NULL>";
len = strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
tx_byte(' ', arg), count++;
for (i = 0; i < len; ++i)
tx_byte(*s++, arg), count++;
while (len < field_width--)
tx_byte(' ', arg), count++;
continue;
case 'p':
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
count += number(tx_byte, arg,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
continue;
case 'n':
if (qualifier == 'L') {
long long *ip = va_arg(args, long long *);
*ip = count;
} else if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = count;
} else {
int * ip = va_arg(args, int *);
*ip = count;
}
continue;
case '%':
tx_byte('%', arg), count++;
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
tx_byte('%', arg), count++;
if (*fmt)
tx_byte(*fmt, arg), count++;
else
--fmt;
continue;
}
if (qualifier == 'L') {
num = va_arg(args, unsigned long long);
} else if (qualifier == 'l') {
num = va_arg(args, unsigned long);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (short) num;
} else if (flags & SIGN) {
num = va_arg(args, int);
} else {
num = va_arg(args, unsigned int);
}
count += number(tx_byte, arg, num, base, field_width, precision, flags);
}
return count;
}