source: trunk/hal/x86_64/core/x86_printf.c @ 233

Last change on this file since 233 was 154, checked in by max@…, 7 years ago

use a demultiplexer to get the channel on the serial port, and
make x86_printf print both on the VGA and COM1

File size: 5.4 KB
Line 
1/*
2 * x86_printf.c - A printf function for x86 (debug only).
3 *
4 * Copyright (c) 2017 Maxime Villard
5 *
6 * This file is part of ALMOS-MKH.
7 *
8 * ALMOS-MKH is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2.0 of the License.
11 *
12 * ALMOS-MKH is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <hal_types.h>
23#include <hal_boot.h>
24#include <hal_internal.h>
25#include <hal_apic.h>
26
27#include <memcpy.h>
28#include <thread.h>
29#include <string.h>
30#include <process.h>
31#include <printk.h>
32#include <vmm.h>
33#include <core.h>
34#include <cluster.h>
35
36#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
37#define CONS_X_SIZE     80
38#define CONS_Y_SIZE     26
39
40static char cons_buffer[CONS_X_SIZE * 2 * CONS_Y_SIZE] __in_kdata;
41extern intptr_t iom_base;
42size_t cons_ptr __in_kdata = 0;
43
44void x86_panic(char *msg)
45{
46        x86_printf("!!!!! PANIC !!!!!\n");
47        x86_printf("-> %s\n", msg);
48        x86_printf("!!!!!!!!!!!!!!!!!\n");
49        while (1);
50}
51
52static void check_scroll()
53{
54        char *base = (char *)iom_base + (0xB8000 - IOM_BEGIN);
55        char *src, *dst;
56        size_t i;
57
58        if (cons_ptr < (CONS_X_SIZE * 2) * CONS_Y_SIZE) {
59                return;
60        }
61
62        for (i = 0; i < CONS_Y_SIZE - 1; i++) {
63                dst = (char *)&cons_buffer[0] + i * (CONS_X_SIZE * 2);
64                src = (char *)&cons_buffer[0] + (i + 1) * (CONS_X_SIZE * 2);
65
66                memcpy(dst, src, (CONS_X_SIZE * 2));
67        }
68
69        memset(&cons_buffer[0] + (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1),
70            0, (CONS_X_SIZE * 2));
71
72        cons_ptr -= (CONS_X_SIZE * 2);
73        memcpy(base, &cons_buffer[0], (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1));
74}
75
76void x86_putc(char c)
77{
78        hal_com_send(0, c);
79
80        if (c == '\n') {
81                cons_ptr = roundup(cons_ptr, CONS_X_SIZE * 2);
82                check_scroll();
83                return;
84        }
85
86        char *video = (char *)iom_base + (0xB8000 - IOM_BEGIN) + cons_ptr;
87        char *buf = &cons_buffer[cons_ptr];
88        *video = c;
89        *buf = c;
90        cons_ptr++, video++, buf++;
91        *video = 0x7;
92        *buf = 0x7;
93        cons_ptr++, video++, buf++;
94
95        check_scroll();
96}
97
98static void x86_itoa(char *buf, unsigned long int n, int base)
99{
100        unsigned long int tmp;
101        int i, j;
102
103        tmp = n;
104        i = 0;
105
106        do {
107                tmp = n % base;
108                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
109        } while (n /= base);
110        buf[i--] = 0;
111
112        for (j = 0; j < i; j++, i--) {
113                tmp = buf[j];
114                buf[j] = buf[i];
115                buf[i] = tmp;
116        }
117}
118
119static void x86_ztoa(char *buf, uint64_t n, uint64_t base)
120{
121        uint64_t tmp;
122        int i, j;
123
124        tmp = n;
125        i = 0;
126
127        do {
128                tmp = n % base;
129                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
130        } while (n /= base);
131        buf[i--] = 0;
132
133        for (j = 0; j < i; j++, i--) {
134                tmp = buf[j];
135                buf[j] = buf[i];
136                buf[i] = tmp;
137        }
138}
139
140static char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
141
142void x86_printf(char *s, ...)
143{
144        va_list ap;
145
146        char buf[64];
147        int i, j, size, buflen, neg;
148
149        unsigned char c;
150        int ival;
151        unsigned int uival;
152        uint64_t zval;
153
154        va_start(ap, s);
155
156        while ((c = *s++)) {
157                size = 0;
158                neg = 0;
159
160                if (c == 0)
161                        break;
162                else if (c == '%') {
163                        c = *s++;
164                        if (c >= '0' && c <= '9') {
165                                size = c - '0';
166                                c = *s++;
167                        }
168
169                        if (c == 'c') {
170                                ival = va_arg(ap, int);
171                                if ((ival - 97) > sizeof(alphabet)) {
172                                        x86_printf("(unknown:%d)", ival);
173                                } else {
174                                        x86_putc(alphabet[ival - 97]);
175                                }
176                        } else if (c == 'z') {
177                                zval = va_arg(ap, uint64_t);
178                                x86_ztoa(buf, zval, 10);
179
180                                buflen = strlen(buf);
181                                if (buflen < size)
182                                        for (i = size, j = buflen; i >= 0; i--, j--)
183                                                buf[i] = (j >= 0) ? buf[j] : '0';
184
185                                x86_printf(buf);
186                        } else if (c == 'Z') {
187                                zval = va_arg(ap, uint64_t);
188                                x86_ztoa(buf, zval, 16);
189
190                                buflen = strlen(buf);
191                                if (buflen < size)
192                                        for (i = size, j = buflen; i >= 0; i--, j--)
193                                                buf[i] = (j >= 0) ? buf[j] : '0';
194
195                                x86_printf("0x%s", buf);
196                        } else if (c == 'd') {
197                                ival = va_arg(ap, int);
198                                if (ival < 0) {
199                                        uival = 0 - ival;
200                                        neg++;
201                                } else
202                                        uival = ival;
203                                x86_itoa(buf, uival, 10);
204
205                                buflen = strlen(buf);
206                                if (buflen < size)
207                                        for (i = size, j = buflen; i >= 0;
208                                             i--, j--)
209                                                buf[i] =
210                                                    (j >=
211                                                     0) ? buf[j] : '0';
212
213                                if (neg)
214                                        x86_printf("-%s", buf);
215                                else
216                                        x86_printf(buf);
217                        } else if (c == 'u') {
218                                uival = va_arg(ap, int);
219                                x86_itoa(buf, uival, 10);
220
221                                buflen = strlen(buf);
222                                if (buflen < size)
223                                        for (i = size, j = buflen; i >= 0;
224                                             i--, j--)
225                                                buf[i] =
226                                                    (j >=
227                                                     0) ? buf[j] : '0';
228
229                                x86_printf(buf);
230                        } else if (c == 'x' || c == 'X') {
231                                uival = va_arg(ap, int);
232                                x86_itoa(buf, uival, 16);
233
234                                buflen = strlen(buf);
235                                if (buflen < size)
236                                        for (i = size, j = buflen; i >= 0;
237                                             i--, j--)
238                                                buf[i] =
239                                                    (j >=
240                                                     0) ? buf[j] : '0';
241
242                                x86_printf("0x%s", buf);
243                        } else if (c == 'p') {
244                                uival = va_arg(ap, int);
245                                x86_itoa(buf, uival, 16);
246                                size = 8;
247
248                                buflen = strlen(buf);
249                                if (buflen < size)
250                                        for (i = size, j = buflen; i >= 0;
251                                             i--, j--)
252                                                buf[i] =
253                                                    (j >=
254                                                     0) ? buf[j] : '0';
255
256                                x86_printf("0x%s", buf);
257                        } else if (c == 's') {
258                                x86_printf((char *) va_arg(ap, uint64_t));
259                        }
260                } else
261                        x86_putc(c);
262        }
263
264        return;
265}
Note: See TracBrowser for help on using the repository browser.