Nucleus
Barry Library printf 366395f (3 years, 2 months ago)
diff --git a/kernel/panic.c b/kernel/panic.c
deleted file mode 100644
index 5d1a847..0000000
--- a/kernel/panic.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * This file implements the full kernel panic routine. This routine does not
- * return, and is essentially a shutdown routine. It will print a message to
- * the debug port and halt the processor. In an ideal build, this function
- * won't need to be linked in.
- */
-
-#include <stdint.h>
-#include <stdarg.h>
-#include <io.h>
-
-#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
-
-#define ZEROPAD 1 /* Pad with zero */
-#define SIGN 2 /* Insigned/signed long */
-#define PLUS 4 /* Show plus */
-#define SPACE 8 /* Space if plus */
-#define LEFT 16 /* Left justified */
-#define SPECIAL 32 /* 0x */
-#define SMALL 64 /* Use 'abcdef' instead of 'ABCDEF' */
-
-#define DO_DIV(n,base) ({ \
- int __res; \
- __asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \
- __res; \
-})
-
-/* Do not convert */
-static int
-skip_atoi(const char **s)
-{
- int i = 0;
-
- while (IS_DIGIT(**s))
- i = i*10 + *((*s)++) - '0';
-
- return i;
-}
-
-/* Convert a number to ASCII */
-static char *
-number(char *str, int num, int base, int size, int precision, int type)
-{
- char c, sign, tmp[36];
- const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int i;
-
- if (type & SMALL)
- digits = "0123456789abcdefghijklmnopqrstuvwxyz";
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
- return 0;
- c = (type & ZEROPAD) ? '0' : ' ' ;
- if (type & SIGN && num < 0) {
- sign = '-';
- num = -num;
- } else {
- sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0);
- }
- if (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)
- *str++ = ' ';
- if (sign)
- *str++ = sign;
- if (type & SPECIAL)
- if (base == 8) {
- *str++ = '0';
- } else if (base == 16) {
- *str++ = '0';
- *str++ = digits[33];
- }
- if (!(type & LEFT))
- while (size-- > 0)
- *str++ = c;
- while (i < precision--)
- *str++ = '0';
- while (i-- > 0)
- *str++ = tmp[i];
- while (size-- > 0)
- *str++ = ' ';
- return str;
-}
-
-/* Print formatted to a buffer */
-static int
-vsprintf(char *buf, const char *fmt, va_list args)
-{
- int len, i;
- char *str, *s, *p;
- int *ip, flags;
- int field_width, precision, qualifier;
-
- for (str = buf; *fmt; fmt++) {
- if (*fmt != '%') {
- *str++ = *fmt;
- continue;
- }
-
- /* Process flags */
- flags = 0;
-repeat:
- fmt++;
- 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 == '*') {
- 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 == '*') {
- 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++;
- }
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT))
- while (--field_width > 0)
- *str++ = ' ';
- *str++ = (unsigned char) va_arg(args, int);
- while (--field_width > 0)
- *str++ = ' ';
- break;
-
- case 's':
- s = va_arg(args, char *);
- len = 0;
- p = s;
- while (*p++) len++;
- if (precision < 0)
- precision = len;
- else if (len > precision)
- len = precision;
-
- if (!(flags & LEFT))
- while (len < field_width--)
- *str++ = ' ';
- for (i = 0; i < len; ++i)
- *str++ = *s++;
- while (len < field_width--)
- *str++ = ' ';
- break;
-
- case 'o':
- str = number(str, va_arg(args, unsigned long), 8,
- field_width, precision, flags);
- break;
-
- case 'p':
- if (field_width == -1) {
- field_width = 8;
- flags |= ZEROPAD;
- }
- str = number(str,
- (unsigned long) va_arg(args, void *), 16,
- field_width, precision, flags);
- break;
-
- case 'x':
- flags |= SMALL;
- /* FALLTHROUGH */
- case 'X':
- str = number(str, va_arg(args, unsigned long), 16,
- field_width, precision, flags);
- break;
-
- case 'd': /* FALLTHROUGH */
- case 'i':
- flags |= SIGN;
- /* FALLTHROUGH */
- case 'u':
- str = number(str, va_arg(args, unsigned long), 10,
- field_width, precision, flags);
- break;
-
- case 'n':
- ip = va_arg(args, int *);
- *ip = (str - buf);
- break;
-
- default:
- if (*fmt != '%')
- *str++ = '%';
- if (*fmt)
- *str++ = *fmt;
- else
- --fmt;
- break;
- }
- }
- *str = '\0';
- return str-buf;
-}
-
-/* Print formatted text to debug port */
-void
-kprintf(char *fmt, ...)
-{
- outb(0xE9, '\033');
- outb(0xE9, '[');
- outb(0xE9, '3');
- outb(0xE9, '6');
- outb(0xE9, 'm');
-
- char buf[1024], *p = buf;
-
- /* Print message to serial port */
- va_list args;
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
- while (*p)
- outb(0xE9, *p++);
- outb(0xE9, '\n');
-}
-
-/* Kernel panic */
-_Noreturn void
-panic(char *fmt, ...)
-{
- outb(0xE9, '\033');
- outb(0xE9, '[');
- outb(0xE9, '3');
- outb(0xE9, '1');
- outb(0xE9, 'm');
-
- char buf[1024], *p = buf;
-
- /* Print error to serial port */
- va_list args;
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
- while (*p)
- outb(0xE9, *p++);
- outb(0xE9, '\n');
-
- asm volatile("sti");
- while (1)
- asm volatile("hlt");
-}