- Implement first part of SMP support.
[planlOS.git] / system / kernel / ke / debug.c
blob5883c5fd7714e964878f1fde8657b25987698e04
1 /*
2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "ke/debug.h"
23 #include "ke/ports.h"
24 #include <string.h>
26 #define SERIAL 0x3f8
28 static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
29 static char digits_cap[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
31 static char *vidmem = (char*)0xC00B8000;
32 static int cursorx = 0;
33 static int cursory = 0;
35 void kePrintInit(void)
37 outb(SERIAL + 1, 0); // Disable interrupts
38 outb(SERIAL + 3, 0x80); // Set baud rate
39 outb(SERIAL, 0x3); // High byte, 38400 baud
40 outb(SERIAL + 1, 0); // Low byte
41 outb(SERIAL + 3, 0x3); // 8 bits, no parity bit, one stop bit
42 outb(SERIAL + 2, 0xC7); // Enable FIFO
43 outb(SERIAL + 4, 0x0B); // Enable interrupts
46 static void keScroll(int lines)
48 memmove(vidmem, vidmem + lines * 160, (25 - lines) * 160);
49 memset(vidmem + (25 - lines) * 160, 0, lines * 160);
50 cursory -= lines;
53 static void kePrintChar(char c)
55 // Serial output
56 while ((inb(SERIAL + 5) & 0x20) == 0);
57 outb(SERIAL, c);
59 // VGA output
60 switch (c)
62 case '\n':
63 cursorx = 0;
64 cursory++;
65 if (cursory == 25) keScroll(1);
66 break;
67 case '\r':
68 cursorx = 0;
69 break;
70 case '\t':
71 kePrintChar(' ');
72 while (cursorx & 0x7) kePrintChar(' ');
73 break;
74 default:
75 vidmem[cursory * 160 + cursorx * 2] = c;
76 vidmem[cursory * 160 + cursorx * 2 + 1] = 0x07;
77 cursorx++;
78 if (cursorx == 80)
80 cursorx = 0;
81 cursory++;
82 if (cursory == 25) keScroll(1);
84 break;
87 static void kePrintString(const char *s)
89 while (*s)
91 kePrintChar(*s);
92 s++;
96 static void kePrintInt(int32_t value, uint32_t base, int capital_letters)
98 if (value < 0) {
99 kePrintChar('-');
100 value = -value;
102 if (value >= (int32_t)base) {
103 kePrintInt(value / base, base, capital_letters);
105 int digit = value % base;
106 if (capital_letters) {
107 kePrintChar(digits_cap[digit]);
108 } else {
109 kePrintChar(digits[digit]);
112 static void kePrintUInt(uint32_t value, uint32_t base, int capital_letters)
114 if (value >= base) {
115 kePrintInt(value / base, base, capital_letters);
117 int digit = value % base;
118 if (capital_letters) {
119 kePrintChar(digits_cap[digit]);
120 } else {
121 kePrintChar(digits[digit]);
125 void kePrint(const char *fmt, ...)
127 int *args = ((int*)&fmt) + 1;
128 kePrintList(fmt, &args);
130 void kePrintList(const char *fmt, int **args)
132 while (*fmt) {
133 switch (*fmt)
135 case '%':
136 switch(*(fmt+1))
138 case '%':
139 kePrintChar('%');
140 break;
141 case 'c':
142 kePrintChar(*((char*)(*args)));
143 (*args)++;
144 break;
145 case 'd':
146 case 'i':
147 kePrintInt(*((int32_t*)(*args)), 10, 0);
148 (*args)++;
149 break;
150 case 'u':
151 kePrintUInt(*((uint32_t*)(*args)), 10, 0);
152 (*args)++;
153 break;
154 case 'x':
155 kePrintUInt(*((uint32_t*)(*args)), 16, 0);
156 (*args)++;
157 break;
158 case 'X':
159 kePrintUInt(*((uint32_t*)(*args)), 16, 1);
160 (*args)++;
161 break;
162 case 's':
163 kePrintString(*((char**)(*args)));
164 (*args)++;
165 break;
167 fmt++;
168 break;
169 case '\n':
170 kePrintChar('\n');
171 break;
172 case '\t':
173 kePrintChar('\t');
174 break;
175 default:
176 kePrintChar(*fmt);
177 break;
179 fmt++;