source: trunk/kernel/kern/printk.c @ 1

Last change on this file since 1 was 1, checked in by alain, 5 years ago

First import

File size: 6.4 KB
Line 
1/*
2 * printk.c - Kernel Log & debug messages API implementation.
3 *
4 * authors  Alain Greiner (2016)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH..
9 *
10 * ALMOS-MKH. is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH. is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <hal_types.h>
25#include <hal_irqmask.h>
26#include <printk.h>
27#include <stdarg.h>
28#include <dev_txt.h>
29#include <remote_spinlock.h>
30#include <cluster.h>
31
32///////////////////////////////////////////////////////////////////////////////////
33// This static function is called by printk(), nolock_printk() and user_printk()
34///////////////////////////////////////////////////////////////////////////////////
35static void kernel_printf( uint32_t   channel,
36                           char     * format, 
37                           va_list  * args ) 
38{
39
40printf_text:
41
42    while (*format) 
43    {
44        uint32_t i;
45        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
46        if (i) 
47        {
48            dev_txt_sync_write( channel, format, i );
49            format += i;
50        }
51        if (*format == '%') 
52        {
53            format++;
54            goto printf_arguments;
55        }
56    }
57
58    return;
59
60printf_arguments:
61
62    {
63        char      buf[20];
64        char    * pbuf = NULL;
65        uint32_t  len  = 0;
66        static const char HexaTab[] = "0123456789ABCDEF";
67        uint32_t i;
68
69        switch (*format++) 
70        {
71            case ('c'):             /* char conversion */
72            {
73                int val = va_arg( *args , int );
74                len = 1;
75                buf[0] = val;
76                pbuf = &buf[0];
77                break;
78            }
79            case ('d'):             /* 32 bits decimal signed  */
80            {
81                int val = va_arg( *args , int );
82                if (val < 0) 
83                {
84                    val = -val;
85                    dev_txt_sync_write( channel, "-" , 1 );
86                }
87                for(i = 0; i < 10; i++) 
88                {
89                    buf[9 - i] = HexaTab[val % 10];
90                    if (!(val /= 10)) break;
91                }
92                len =  i + 1;
93                pbuf = &buf[9 - i];
94                break;
95            }
96            case ('u'):             /* 32 bits decimal unsigned  */
97            {
98                uint32_t val = va_arg( *args , uint32_t );
99                for(i = 0; i < 10; i++) 
100                {
101                    buf[9 - i] = HexaTab[val % 10];
102                    if (!(val /= 10)) break;
103                }
104                len =  i + 1;
105                pbuf = &buf[9 - i];
106                break;
107            }
108            case ('x'):             /* 32 bits hexadecimal unsigned */
109            {
110                uint32_t val = va_arg( *args , uint32_t );
111                dev_txt_sync_write( channel, "0x" , 2 );
112                for(i = 0; i < 8; i++) 
113                {
114                    buf[7 - i] = HexaTab[val % 16];
115                    if (!(val = (val>>4)))  break;
116                }
117                len =  i + 1;
118                pbuf = &buf[7 - i];
119                break;
120            }
121            case ('X'):             /* 32 bits hexadecimal unsigned  on 10 char*/
122            {
123                uint32_t val = va_arg( *args , uint32_t );
124                dev_txt_sync_write( channel, "0x" , 2 );
125                for(i = 0; i < 8; i++) 
126                {
127                    buf[7 - i] = HexaTab[val % 16];
128                    val = (val>>4);
129                }
130                len =  8;
131                pbuf = buf;
132                break;
133            }
134            case ('l'):            /* 64 bits hexadecimal unsigned */
135            {
136                uint64_t val = va_arg( *args , uint64_t );
137                dev_txt_sync_write( channel, "0x" , 2 );
138                for(i = 0; i < 16; i++) 
139                {
140                    buf[15 - i] = HexaTab[val % 16];
141                    if (!(val /= 16))  break;
142                }
143                len =  i + 1;
144                pbuf = &buf[15 - i];
145                break;
146            }
147            case ('s'):             /* string */
148            {
149                char* str = va_arg( *args , char* );
150                while (str[len]) 
151                {
152                    len++;
153                }
154                pbuf = str;
155                break;
156            }
157            default:
158            {
159                dev_txt_sync_write( channel ,
160                                    "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
161            }
162        }
163
164        if( pbuf != NULL ) dev_txt_sync_write( channel, pbuf, len );
165       
166        goto printf_text;
167    }
168
169}  // end kernel_printf()
170
171///////////////////////////////////////
172void nolock_printk( char* format, ...)
173{
174    va_list   args;
175
176    // call kernel_printf
177    va_start( args , format );
178    kernel_printf( 0, format , &args );
179    va_end( args );
180}
181
182////////////////////////////////
183void printk( char* format, ...)
184{
185    va_list       args;
186    uint32_t  save_sr;
187
188    // disable IRQs
189    hal_disable_irq( &save_sr );
190
191    // get TXT0 lock
192    cluster_t * cluster = LOCAL_CLUSTER;
193    remote_spinlock_lock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) );
194
195    // call kernel_printf
196    va_start( args , format );
197    kernel_printf( 0, format , &args );
198    va_end( args );
199
200    // release TXT0 lock
201    remote_spinlock_unlock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) );
202
203    // restore IRQs
204    hal_restore_irq( save_sr );
205}
206
207/////////////////////////////////////
208void user_printk( char* format, ...)
209{
210    va_list   args;
211
212    // get calling thread TXT channel TODO
213    uint32_t channel = 0;
214
215    // call kernel_printf
216    va_start( args , format );
217    kernel_printf( channel, format , &args );
218    va_end( args );
219}
220
221
222
223// Local Variables:
224// tab-width: 4
225// c-basic-offset: 4
226// c-file-offsets:((innamespace . 0)(inline-open . 0))
227// indent-tabs-mode: nil
228// End:
229// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
230
Note: See TracBrowser for help on using the repository browser.