From: Joshua Wise Date: Fri, 19 Sep 2008 20:56:30 +0000 (-0400) Subject: merge X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/a9d1719cd11f54eaa60e5206f220212b771caf7c?hp=f2da2cd360ec68bd03100e10d5b24daefc97c1ab merge --- diff --git a/aseg/Makefile b/aseg/Makefile index 5806bd1..359759c 100644 --- a/aseg/Makefile +++ b/aseg/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-I../include -I../include/raw -nostdlib -nostdinc -fno-builtin -D__RAW__ -Wall -Werror -pedantic -ansi -std=gnu99 -OBJS=counter.o firstrun.o ../pci/pci-raw.o ../lib/minilib.o ../lib/console.o ../ich2/smram-ich2.o ../ich2/smi.o vga-overlay.o +OBJS=counter.o firstrun.o ../pci/pci-raw.o ../lib/minilib.o ../lib/console.o ../ich2/smram-ich2.o ../ich2/smi.o vga-overlay.o ../lib/sprintf.o ../lib/doprnt.o all: aseg.elf diff --git a/aseg/counter.c b/aseg/counter.c index d523168..104d809 100644 --- a/aseg/counter.c +++ b/aseg/counter.c @@ -25,15 +25,12 @@ void pci_dump() { case 0x20000: { unsigned char b; - strcpy(s, "READxxxxxxxxxxxxxxxx"); - tohex(s+4, cts); b = inb(cts & 0xFFFF); - tohex(s+12, b); + dologf("READ: %08x (%02x)", cts, b); if ((cts & 0xFFFF) == 0x64) curdev = (b & 0x20) ? 1 : 0; if ((curdev == 0) && ((cts & 0xFFFF) == 0x60) && (b == 0x01)) outb(0xCF9, 0x4); - dolog(s); *(unsigned char*)0xAFFD0 /* EAX */ = b; break; } @@ -97,13 +94,7 @@ void __start (void) outl(0x840, 0x0100); } if (inl(0x834) & ~(0x4160)) - { - char s[40]; - strcpy(s, "Unknown: xxxxxxxx"); - tohex(s + 9, inl(0x834) & ~(0x140)); - dolog(s); - } - + dologf("Unknown: %08x", inl(0x834) & ~(0x140)); outlog(); diff --git a/aseg/vga-overlay.c b/aseg/vga-overlay.c index e5414ca..d205656 100644 --- a/aseg/vga-overlay.c +++ b/aseg/vga-overlay.c @@ -2,6 +2,7 @@ #include #include #include +#include static char logents[4][41] = {{0}}; @@ -22,8 +23,8 @@ static char * vga_base() { return (char *) ( TEXT_CONSOLE_BASE - | (((unsigned int) vga_read(CRTC_START_ADDR_LSB_IDX)) << 9) - | (((unsigned int) vga_read(CRTC_START_ADDR_MSB_IDX)) << 1) + + (((unsigned int) vga_read(CRTC_START_ADDR_MSB_IDX)) << 9) + + (((unsigned int) vga_read(CRTC_START_ADDR_LSB_IDX)) << 1) ); } @@ -60,7 +61,7 @@ void outlog() } smram_restore_state(old_state); - + for (y = 0; y < 4; y++) strblit(logents[y], y, 40); } @@ -70,3 +71,13 @@ void dolog(char *s) memmove(logents[0], logents[1], sizeof(logents[0])*3); strcpy(logents[3], s); } + +void dologf(char *fmt, ...) +{ + va_list va; + + memmove(logents[0], logents[1], sizeof(logents[0])*3); + va_start(va, fmt); + vsnprintf(logents[3], 40, fmt, va); + va_end(va); +} diff --git a/aseg/vga-overlay.h b/aseg/vga-overlay.h index f79e6da..890f353 100644 --- a/aseg/vga-overlay.h +++ b/aseg/vga-overlay.h @@ -4,6 +4,7 @@ void strblit(char *src, int row, int col); void dolog(char *s); +void dologf(char *s, ...); void outlog(); #endif diff --git a/ich2/smi.c b/ich2/smi.c index 59f14b6..e790e40 100644 --- a/ich2/smi.c +++ b/ich2/smi.c @@ -5,7 +5,7 @@ uint16_t _get_PMBASE() { - return pci_read32(0, 0, 0, 0x40) & 0xFF80; + return pci_read32(0, 21, 0, 0x40) & 0xFF80; } void smi_disable() diff --git a/include/minilib.h b/include/minilib.h index b583046..aa8bf73 100644 --- a/include/minilib.h +++ b/include/minilib.h @@ -1,13 +1,20 @@ #ifndef MINILIB_H #define MINILIB_H -void memcpy(void *dest, void *src, int bytes); -void memmove(void *dest, void *src, int bytes); -int strcmp(const char *a2, const char *a1); -void strcpy(char *a2, const char *a1); -void tohex(char *s, unsigned long l); +#include -void puts(const char *c); -void puthex(unsigned long l); +extern void memcpy(void *dest, void *src, int bytes); +extern void memmove(void *dest, void *src, int bytes); +extern int memcmp(const char *a2, const char *a1, int bytes); +extern int strcmp(const char *a2, const char *a1); +extern int strlen(const char *c); +extern void strcpy(char *a2, const char *a1); +extern void puts(const char *c); +extern void tohex(char *s, unsigned long l); +extern void puthex(unsigned long l); +extern int vsprintf(char *s, const char *fmt, va_list args); +extern int vsnprintf(char *s, int size, const char *fmt, va_list args); +extern int sprintf(char *s, const char *fmt, ...); +extern int snprintf(char *s, int size, const char *fmt, ...); #endif diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 0000000..0de5da4 --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,68 @@ +/* + * stdarg.h + * Modified for use in 15-410 at CMU + * Zachary Anderson(zra) + */ + +/* + * Copyright (c) 1994 The University of Utah and the Flux Group. + * All rights reserved. + * + * This file is part of the Flux OSKit. The OSKit is free software, also known + * as "open source;" you can redistribute it and/or modify it under the terms + * of the GNU General Public License (GPL), version 2, as published by the Free + * Software Foundation (FSF). To explore alternate licensing terms, contact + * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271. + * + * The OSKit 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 GPL for more details. You should have + * received a copy of the GPL along with the OSKit; see the file COPYING. If + * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. + */ + +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University. + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + + +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#define __va_size(type) ((sizeof(type)+3) & ~0x3) + +#ifndef _VA_LIST_ +#define _VA_LIST_ +typedef char * va_list; +#endif + +#define va_start(pvar, lastarg) \ + ((pvar) = (char*)(void*)&(lastarg) + __va_size(lastarg)) +#define va_end(pvar) +#define va_arg(pvar,type) \ + ((pvar) += __va_size(type), \ + *((type *)((pvar) - __va_size(type)))) + +#endif /* _STDARG_H_ */ diff --git a/lib/doprnt.c b/lib/doprnt.c new file mode 100644 index 0000000..32daaa9 --- /dev/null +++ b/lib/doprnt.c @@ -0,0 +1,514 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#include +#include +#include "doprnt.h" + +/* How irritating -- this boolean crap. */ +#define FALSE 0 +#define TRUE 1 +typedef int boolean_t; + +/* + * Common code for printf et al. + * + * The calling routine typically takes a variable number of arguments, + * and passes the address of the first one. This implementation + * assumes a straightforward, stack implementation, aligned to the + * machine's wordsize. Increasing addresses are assumed to point to + * successive arguments (left-to-right), as is the case for a machine + * with a downward-growing stack with arguments pushed right-to-left. + * + * To write, for example, fprintf() using this routine, the code + * + * fprintf(fd, format, args) + * FILE *fd; + * char *format; + * { + * _doprnt(format, &args, fd); + * } + * + * would suffice. (This example does not handle the fprintf's "return + * value" correctly, but who looks at the return value of fprintf + * anyway?) + * + * This version implements the following printf features: + * + * %d decimal conversion + * %u unsigned conversion + * %x hexadecimal conversion + * %X hexadecimal conversion with capital letters + * %o octal conversion + * %c character + * %s string + * %m.n field width, precision + * %-m.n left adjustment + * %0m.n zero-padding + * %*.* width and precision taken from arguments + * + * This version does not implement %f, %e, or %g. It accepts, but + * ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not + * work correctly on machines for which sizeof(long) != sizeof(int). + * It does not even parse %D, %O, or %U; you should be using %ld, %o and + * %lu if you mean long conversion. + * + * As mentioned, this version does not return any reasonable value. + * + * Permission is granted to use, modify, or propagate this code as + * long as this notice is incorporated. + * + * Steve Summit 3/25/87 + */ + +/* + * Added formats for decoding device registers: + * + * printf("reg = %b", regval, "*") + * + * where is the output base expressed as a control character: + * i.e. '\10' gives octal, '\20' gives hex. Each is a sequence of + * characters, the first of which gives the bit number to be inspected + * (origin 1), and the rest (up to a control character (<= 32)) give the + * name of the register. Thus + * printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE") + * would produce + * reg = 3 + * + * If the second character in is also a control character, it + * indicates the last bit of a bit field. In this case, printf will extract + * bits <1> to <2> and print it. Characters following the second control + * character are printed before the bit field. + * printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE") + * would produce + * reg = b + */ +/* + * Added for general use: + * # prefix for alternate format: + * 0x (0X) for hex + * leading 0 for octal + * + print '+' if positive + * blank print ' ' if positive + * + * z signed hexadecimal + * r signed, 'radix' + * n unsigned, 'radix' + * + * D,U,O,Z same as corresponding lower-case versions + * (compatibility) + */ +/* + * Added ANSI %p for pointers. Output looks like 0x%08x. + */ +/* + * + * Added special for L4-use: %t format + * + * prints L4-threadids. standard format is "task.thread". Field-width + * may be specified with width-modifier. Padding begins with threadid, + * up to 2 chars, task-part follows. + * + * modifiers: + * # surrounds output with square brackets [] + * l prints the high and low part of a threadid + * fixed length for the dwords: 8 chars + * 0 as usual, padding after optional '[' + * - as usual + * + * Jork Loeser 9/20/99 + */ + +#define isdigit(d) ((d) >= '0' && (d) <= '9') +#define Ctod(c) ((c) - '0') + +#define MAXBUF (sizeof(long int) * 8) /* enough for binary */ + +static char digs[] = "0123456789abcdef"; + +static void +printnum(u, base, putc, putc_arg) + register unsigned long u; /* number to print */ + register int base; + void (*putc)(); + char *putc_arg; +{ + char buf[MAXBUF]; /* build number here */ + register char * p = &buf[MAXBUF-1]; + + do { + *p-- = digs[u % base]; + u /= base; + } while (u != 0); + + while (++p != &buf[MAXBUF]) + (*putc)(putc_arg, *p); +} + +boolean_t _doprnt_truncates = FALSE; + +void _doprnt(fmt, args, radix, putc, putc_arg) + register const char *fmt; + va_list args; + int radix; /* default radix - for '%r' */ + void (*putc)(); /* character output */ + char *putc_arg; /* argument for putc */ +{ + int length; + int prec; + boolean_t ladjust; + char padc; + long n; + unsigned long u; + int plus_sign; + int sign_char; + boolean_t altfmt, truncate; + int base; + char c; + int longopt; + + while (*fmt != '\0') { + if (*fmt != '%') { + (*putc)(putc_arg, *fmt++); + continue; + } + + fmt++; + + length = 0; + prec = -1; + ladjust = FALSE; + padc = ' '; + plus_sign = 0; + sign_char = 0; + altfmt = FALSE; + longopt = 0; + + while (TRUE) { + if (*fmt == '#') { + altfmt = TRUE; + fmt++; + } + else if (*fmt == '-') { + ladjust = TRUE; + fmt++; + } + else if (*fmt == '+') { + plus_sign = '+'; + fmt++; + } + else if (*fmt == ' ') { + if (plus_sign == 0) + plus_sign = ' '; + fmt++; + } + else + break; + } + + if (*fmt == '0') { + padc = '0'; + fmt++; + } + + if (isdigit(*fmt)) { + while(isdigit(*fmt)) + length = 10 * length + Ctod(*fmt++); + } + else if (*fmt == '*') { + length = va_arg(args, int); + fmt++; + if (length < 0) { + ladjust = !ladjust; + length = -length; + } + } + + if (*fmt == '.') { + fmt++; + if (isdigit(*fmt)) { + prec = 0; + while(isdigit(*fmt)) + prec = 10 * prec + Ctod(*fmt++); + } + else if (*fmt == '*') { + prec = va_arg(args, int); + fmt++; + } + } + + while (*fmt == 'l'){ + longopt++; + fmt++; + } + + truncate = FALSE; + + switch(*fmt) { + case 'b': + case 'B': + { + register char *p; + boolean_t any; + register int i; + + u = va_arg(args, unsigned long); + p = va_arg(args, char *); + base = *p++; + printnum(u, base, putc, putc_arg); + + if (u == 0) + break; + + any = FALSE; + while ((i = *p++) != 0) { + /* NOTE: The '32' here is because ascii space */ + if (*p <= 32) { + /* + * Bit field + */ + register int j; + if (any) + (*putc)(putc_arg, ','); + else { + (*putc)(putc_arg, '<'); + any = TRUE; + } + j = *p++; + for (; (c = *p) > 32; p++) + (*putc)(putc_arg, c); + printnum((unsigned)( (u>>(j-1)) & ((2<<(i-j))-1)), + base, putc, putc_arg); + } + else if (u & (1<<(i-1))) { + if (any) + (*putc)(putc_arg, ','); + else { + (*putc)(putc_arg, '<'); + any = TRUE; + } + for (; (c = *p) > 32; p++) + (*putc)(putc_arg, c); + } + else { + for (; *p > 32; p++) + continue; + } + } + if (any) + (*putc)(putc_arg, '>'); + break; + } + + case 'c': + c = va_arg(args, int); + (*putc)(putc_arg, c); + break; + + case 's': + { + register char *p; + register char *p2; + + if (prec == -1) + prec = 0x7fffffff; /* MAXINT */ + + p = va_arg(args, char *); + + if (p == (char *)0) + p = ""; + + if (length > 0 && !ladjust) { + n = 0; + p2 = p; + + for (; *p != '\0' && n < prec; p++) + n++; + + p = p2; + + while (n < length) { + (*putc)(putc_arg, ' '); + n++; + } + } + + n = 0; + + while (*p != '\0') { + if (++n > prec) + break; + + (*putc)(putc_arg, *p++); + } + + if (n < length && ladjust) { + while (n < length) { + (*putc)(putc_arg, ' '); + n++; + } + } + + break; + } + + + case 'o': + truncate = _doprnt_truncates; + case 'O': + base = 8; + goto print_unsigned; + + case 'd': + truncate = _doprnt_truncates; + case 'D': + base = 10; + goto print_signed; + + case 'u': + truncate = _doprnt_truncates; + case 'U': + base = 10; + goto print_unsigned; + + case 'p': + padc = '0'; + length = 8; + /* + * We do this instead of just setting altfmt to TRUE + * because we want 0 to have a 0x in front, and we want + * eight digits after the 0x -- not just 6. + */ + (*putc)(putc_arg, '0'); + (*putc)(putc_arg, 'x'); + case 'x': + truncate = _doprnt_truncates; + case 'X': + base = 16; + goto print_unsigned; + + case 'z': + truncate = _doprnt_truncates; + case 'Z': + base = 16; + goto print_signed; + + case 'r': + truncate = _doprnt_truncates; + case 'R': + base = radix; + goto print_signed; + + case 'n': + truncate = _doprnt_truncates; + case 'N': + base = radix; + goto print_unsigned; + + print_signed: + if (longopt>1) + n = va_arg(args, long long); + else + n = va_arg(args, long); + if (n >= 0) { + u = n; + sign_char = plus_sign; + } + else { + u = -n; + sign_char = '-'; + } + goto print_num; + + print_unsigned: + if (longopt>1) + u = va_arg(args, unsigned long long); + else + u = va_arg(args, unsigned long); + goto print_num; + + print_num: + { + char buf[MAXBUF]; /* build number here */ + register char * p = &buf[MAXBUF-1]; + static char digits[] = "0123456789abcdef"; + char *prefix = 0; + + if (truncate) u = (long)((int)(u)); + + if (u != 0 && altfmt) { + if (base == 8) + prefix = "0"; + else if (base == 16) + prefix = "0x"; + } + + do { + *p-- = digits[u % base]; + u /= base; + } while (u != 0); + + length -= (&buf[MAXBUF-1] - p); + if (sign_char) + length--; + if (prefix) + length -= strlen(prefix); + + if (padc == ' ' && !ladjust) { + /* blank padding goes before prefix */ + while (--length >= 0) + (*putc)(putc_arg, ' '); + } + if (sign_char) + (*putc)(putc_arg, sign_char); + if (prefix) + while (*prefix) + (*putc)(putc_arg, *prefix++); + if (padc == '0') { + /* zero padding goes after sign and prefix */ + while (--length >= 0) + (*putc)(putc_arg, '0'); + } + while (++p != &buf[MAXBUF]) + (*putc)(putc_arg, *p); + + if (ladjust) { + while (--length >= 0) + (*putc)(putc_arg, ' '); + } + break; + } + + case '\0': + fmt--; + break; + + default: + (*putc)(putc_arg, *fmt); + } + fmt++; + } +} diff --git a/lib/doprnt.h b/lib/doprnt.h new file mode 100644 index 0000000..b40ada7 --- /dev/null +++ b/lib/doprnt.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef __DOPRNT_H_INCLUDED__ +#define __DOPRNT_H_INCLUDED__ + +void _doprnt( + register const char *fmt, + va_list args, + int radix, /* default radix - for '%r' */ + void (*putc)(), /* character output */ + char *putc_arg); /* argument for putc */ + +#endif /* __DOPRNT_H_INCLUDED__ */ diff --git a/lib/minilib.c b/lib/minilib.c index 1ef4731..7baca59 100644 --- a/lib/minilib.c +++ b/lib/minilib.c @@ -81,5 +81,3 @@ void puthex(unsigned long l) tohex(d, l); puts(d); } - - diff --git a/lib/sprintf.c b/lib/sprintf.c new file mode 100644 index 0000000..8d58d6b --- /dev/null +++ b/lib/sprintf.c @@ -0,0 +1,102 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#include +#include "doprnt.h" + +#define SPRINTF_UNLIMITED -1 +struct sprintf_state { + char *buf; + unsigned int len; + unsigned int max; +}; + +static void +savechar(char *arg, int c) +{ + struct sprintf_state *state = (struct sprintf_state *)arg; + + if (state->max != SPRINTF_UNLIMITED) + { + if (state->len == state->max) + return; + } + + state->len++; + *state->buf = c; + state->buf++; +} + +int vsprintf(char *s, const char *fmt, va_list args) +{ + struct sprintf_state state; + state.max = SPRINTF_UNLIMITED; + state.len = 0; + state.buf = s; + + _doprnt(fmt, args, 0, (void (*)()) savechar, (char *) &state); + *(state.buf) = '\0'; + + return state.len; +} + +int vsnprintf(char *s, int size, const char *fmt, va_list args) +{ + struct sprintf_state state; + state.max = size; + state.len = 0; + state.buf = s; + + _doprnt(fmt, args, 0, (void (*)()) savechar, (char *) &state); + *(state.buf) = '\0'; + + return state.len; +} + +int sprintf(char *s, const char *fmt, ...) +{ + va_list args; + int err; + + va_start(args, fmt); + err = vsprintf(s, fmt, args); + va_end(args); + + return err; +} + +int snprintf(char *s, int size, const char *fmt, ...) +{ + va_list args; + int err; + + va_start(args, fmt); + err = vsnprintf(s, size, fmt, args); + va_end(args); + + return err; +} +