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

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

style

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
26#include <memcpy.h>
27#include <thread.h>
28#include <string.h>
29#include <process.h>
30#include <printk.h>
31#include <vmm.h>
32#include <core.h>
33#include <cluster.h>
34
35#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
36#define CONS_X_SIZE     80
37#define CONS_Y_SIZE     26
38
39static char cons_buffer[CONS_X_SIZE * 2 * CONS_Y_SIZE] __in_kdata;
40extern intptr_t iom_base;
41size_t cons_ptr __in_kdata = 0;
42
43void x86_panic(char *msg)
44{
45        x86_printf("!!!!! PANIC !!!!!\n");
46        x86_printf("-> %s\n", msg);
47        x86_printf("!!!!!!!!!!!!!!!!!\n");
48        while (1);
49}
50
51static void check_scroll()
52{
53        char *base = (char *)iom_base + (0xB8000 - IOM_BEGIN);
54        char *src, *dst;
55        size_t i;
56
57        if (cons_ptr < (CONS_X_SIZE * 2) * CONS_Y_SIZE) {
58                return;
59        }
60
61        for (i = 0; i < CONS_Y_SIZE - 1; i++) {
62                dst = (char *)&cons_buffer[0] + i * (CONS_X_SIZE * 2);
63                src = (char *)&cons_buffer[0] + (i + 1) * (CONS_X_SIZE * 2);
64
65                memcpy(dst, src, (CONS_X_SIZE * 2));
66        }
67
68        memset(&cons_buffer[0] + (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1),
69            0, (CONS_X_SIZE * 2));
70
71        cons_ptr -= (CONS_X_SIZE * 2);
72        memcpy(base, &cons_buffer[0], (CONS_X_SIZE * 2) * (CONS_Y_SIZE - 1));
73}
74
75void x86_putc(char c)
76{
77        if (c == '\n') {
78                cons_ptr = roundup(cons_ptr, CONS_X_SIZE * 2);
79                check_scroll();
80                return;
81        }
82
83        char *video = (char *)iom_base + (0xB8000 - IOM_BEGIN) + cons_ptr;
84        char *buf = &cons_buffer[cons_ptr];
85        *video = c;
86        *buf = c;
87        cons_ptr++, video++, buf++;
88        *video = 0x7;
89        *buf = 0x7;
90        cons_ptr++, video++, buf++;
91
92        check_scroll();
93}
94
95static void x86_itoa(char *buf, unsigned long int n, int base)
96{
97        unsigned long int tmp;
98        int i, j;
99
100        tmp = n;
101        i = 0;
102
103        do {
104                tmp = n % base;
105                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
106        } while (n /= base);
107        buf[i--] = 0;
108
109        for (j = 0; j < i; j++, i--) {
110                tmp = buf[j];
111                buf[j] = buf[i];
112                buf[i] = tmp;
113        }
114}
115
116static void x86_ztoa(char *buf, uint64_t n, uint64_t base)
117{
118        uint64_t tmp;
119        int i, j;
120
121        tmp = n;
122        i = 0;
123
124        do {
125                tmp = n % base;
126                buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);
127        } while (n /= base);
128        buf[i--] = 0;
129
130        for (j = 0; j < i; j++, i--) {
131                tmp = buf[j];
132                buf[j] = buf[i];
133                buf[i] = tmp;
134        }
135}
136
137static char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
138
139void x86_printf(char *s, ...)
140{
141        va_list ap;
142
143        char buf[64];
144        int i, j, size, buflen, neg;
145
146        unsigned char c;
147        int ival;
148        unsigned int uival;
149        uint64_t zval;
150
151        va_start(ap, s);
152
153        while ((c = *s++)) {
154                size = 0;
155                neg = 0;
156
157                if (c == 0)
158                        break;
159                else if (c == '%') {
160                        c = *s++;
161                        if (c >= '0' && c <= '9') {
162                                size = c - '0';
163                                c = *s++;
164                        }
165
166                        if (c == 'c') {
167                                ival = va_arg(ap, int);
168                                if ((ival - 97) > sizeof(alphabet)) {
169                                        x86_printf("(unknown:%d)", ival);
170                                } else {
171                                        x86_putc(alphabet[ival - 97]);
172                                }
173                        } else if (c == 'z') {
174                                zval = va_arg(ap, uint64_t);
175                                x86_ztoa(buf, zval, 10);
176
177                                buflen = strlen(buf);
178                                if (buflen < size)
179                                        for (i = size, j = buflen; i >= 0; i--, j--)
180                                                buf[i] = (j >= 0) ? buf[j] : '0';
181
182                                x86_printf(buf);
183                        } else if (c == 'Z') {
184                                zval = va_arg(ap, uint64_t);
185                                x86_ztoa(buf, zval, 16);
186
187                                buflen = strlen(buf);
188                                if (buflen < size)
189                                        for (i = size, j = buflen; i >= 0; i--, j--)
190                                                buf[i] = (j >= 0) ? buf[j] : '0';
191
192                                x86_printf("0x%s", buf);
193                        } else if (c == 'd') {
194                                ival = va_arg(ap, int);
195                                if (ival < 0) {
196                                        uival = 0 - ival;
197                                        neg++;
198                                } else
199                                        uival = ival;
200                                x86_itoa(buf, uival, 10);
201
202                                buflen = strlen(buf);
203                                if (buflen < size)
204                                        for (i = size, j = buflen; i >= 0;
205                                             i--, j--)
206                                                buf[i] =
207                                                    (j >=
208                                                     0) ? buf[j] : '0';
209
210                                if (neg)
211                                        x86_printf("-%s", buf);
212                                else
213                                        x86_printf(buf);
214                        } else if (c == 'u') {
215                                uival = va_arg(ap, int);
216                                x86_itoa(buf, uival, 10);
217
218                                buflen = strlen(buf);
219                                if (buflen < size)
220                                        for (i = size, j = buflen; i >= 0;
221                                             i--, j--)
222                                                buf[i] =
223                                                    (j >=
224                                                     0) ? buf[j] : '0';
225
226                                x86_printf(buf);
227                        } else if (c == 'x' || c == 'X') {
228                                uival = va_arg(ap, int);
229                                x86_itoa(buf, uival, 16);
230
231                                buflen = strlen(buf);
232                                if (buflen < size)
233                                        for (i = size, j = buflen; i >= 0;
234                                             i--, j--)
235                                                buf[i] =
236                                                    (j >=
237                                                     0) ? buf[j] : '0';
238
239                                x86_printf("0x%s", buf);
240                        } else if (c == 'p') {
241                                uival = va_arg(ap, int);
242                                x86_itoa(buf, uival, 16);
243                                size = 8;
244
245                                buflen = strlen(buf);
246                                if (buflen < size)
247                                        for (i = size, j = buflen; i >= 0;
248                                             i--, j--)
249                                                buf[i] =
250                                                    (j >=
251                                                     0) ? buf[j] : '0';
252
253                                x86_printf("0x%s", buf);
254                        } else if (c == 's') {
255                                x86_printf((char *) va_arg(ap, uint64_t));
256                        }
257                } else
258                        x86_putc(c);
259        }
260
261        return;
262}
Note: See TracBrowser for help on using the repository browser.