summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mvme2307/console/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme2307/console/printk.c')
-rw-r--r--c/src/lib/libbsp/powerpc/mvme2307/console/printk.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme2307/console/printk.c b/c/src/lib/libbsp/powerpc/mvme2307/console/printk.c
new file mode 100644
index 0000000000..0058f03d74
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mvme2307/console/printk.c
@@ -0,0 +1,199 @@
+#include <bsp.h>
+
+#if 1
+
+static void outbyte(char c) {
+ volatile char * const pc16550 = (char *) IO_TO_LOCAL(0x03f8);
+# define THR 0
+# define LSR 5
+# define THRE 0x20
+ while ((pc16550[LSR] & THRE) == 0) {
+ ;
+ }
+ pc16550[THR] = c;
+}
+
+#else
+
+/* printk to memory for debugging */
+static void outbyte(char c) {
+ static char *memory_log = (char *) 0x01F00000;
+
+ *memory_log++ = c;
+ if (memory_log >= (char *) 0x01F80000) {
+ memory_log--;
+ }
+}
+
+#endif
+
+/*-------------------------------------------------------------------------+
+| printk.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on code by: Jose Rufino - IST
+|
+| $Id$
++--------------------------------------------------------------------------*/
+
+
+#include <stdarg.h>
+
+/*-------------------------------------------------------------------------+
+| Function: printNum
+| Description: print number in a given base.
+| Global Variables: None.
+| Arguments: num - number to print, base - base used to print the number.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void printNum(long unsigned int num, int base, int sign, int width,
+ int zerofill) {
+ long unsigned int n;
+ int count, negative = 0;
+ char toPrint[80];
+ char *digits = "0123456789ABCDEF";
+
+ if (width > sizeof(toPrint)) {
+ width = sizeof(toPrint);
+ }
+ if ((sign == 1) && ((long) num < 0)) {
+ negative = 1;
+ num = -num;
+ }
+
+ count = 0;
+ while ((n = num / base) > 0) {
+ toPrint[count++] = digits[num - (n * base)];
+ num = n;
+ }
+ toPrint[count++] = digits[num];
+ if (count + negative < width) {
+ /* this needs to be padded out to width */
+ if (zerofill) {
+ while (count + negative < width) {
+ toPrint[count++] = '0';
+ }
+ if (negative) {
+ toPrint[count++] = '-';
+ }
+ } else {
+ if (negative) {
+ toPrint[count++] = '-';
+ }
+ while (count < width) {
+ toPrint[count++] = ' ';
+ }
+ }
+ } else if (negative) {
+ toPrint[count++] = '-';
+ }
+
+ for (n = 0; n < count; n++) {
+ outbyte(toPrint[count - (n + 1)]);
+ }
+}
+
+
+/*-------------------------------------------------------------------------+
+| Function: printk
+| Description: a simplified version of printf intended for use when the
+ console is not yet initialized or in ISR's.
+| Global Variables: None.
+| Arguments: as in printf: fmt - format string, ... - unnamed arguments.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+int printk_enabled = 1;
+
+void printk(char *fmt, ...) {
+ va_list ap; /* points to each unnamed argument in turn */
+ char c, *str;
+ int lflag, base, sign, width, zero;
+
+ /* disable interrupts??? */
+
+ if (printk_enabled) {
+ va_start(ap, fmt); /* make ap point to 1st unnamed arg */
+ for (; *fmt != '\0'; fmt++) {
+ lflag = 0;
+ base = 0;
+ sign = 0;
+ width = 0;
+ if (*fmt == '\n') {
+ outbyte('\r');
+ }
+ if (*fmt == '%') {
+ c = *++fmt;
+ if (c == '0') {
+ zero = 1;
+ c = *++fmt;
+ } else {
+ zero = 0;
+ }
+ for (; c >= '0' && c <= '9'; c = *++fmt) {
+ width = width * 10 + (c - '0');
+ }
+ if (c == 'l') {
+ lflag = 1;
+ c = *++fmt;
+ }
+ switch (c) {
+ case 'o':
+ case 'O':
+ base = 8;
+ sign = 0;
+ break;
+ case 'd':
+ case 'D':
+ base = 10;
+ sign = 1;
+ break;
+ case 'u':
+ case 'U':
+ base = 10;
+ sign = 0;
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ sign = 0;
+ break;
+ case 's':
+ for (str = va_arg(ap, char *); *str; str++) {
+ outbyte(*str);
+ width--;
+ }
+ while (width-- > 0) {
+ outbyte(' ');
+ }
+ break;
+ case 'c':
+ outbyte(va_arg(ap, int));
+ break;
+ default:
+ outbyte(c);
+ break;
+ }
+
+ if (base) {
+ printNum(lflag ? va_arg(ap, long int) :
+ (long int) va_arg(ap, int), base, sign, width, zero);
+ }
+ } else {
+ outbyte(*fmt);
+ }
+ }
+ va_end(ap); /* clean up when done */
+ /* enable interrupts??? */
+ }
+}