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

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

add a dumb lock for the console

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