source: soft/giet_vm/giet_common/tty0.c @ 538

Last change on this file since 538 was 495, checked in by alain, 10 years ago

Introduce quad tree for distributed locks and barriers.

File size: 8.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : tty0.c
3// Date     : 02/12/2014
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The tty0.c and tty0.h files are part of the GIET-VM nano-kernel.
8///////////////////////////////////////////////////////////////////////////////////
9
10#include <hard_config.h>
11#include <tty0.h>
12#include <stdarg.h>
13#include <tty_driver.h>
14#include <utils.h>
15#include <kernel_locks.h>
16
17/////////////////////////////////////////////////////////////////////////////
18// The global variable tty0_boot_mode define the type of lock used,
19// and must be defined in both kernel_init.c and boot.c files.
20// - the boot code must use a spin_lock because the kernel heap is not set.
21// - the kernel code can use a sqt_lock when the kernel heap is set.
22/////////////////////////////////////////////////////////////////////////////
23
24extern unsigned int  _tty0_boot_mode;
25
26__attribute__((section(".kdata")))
27sqt_lock_t           _tty0_sqt_lock  __attribute__((aligned(64))); 
28
29__attribute__((section(".kdata")))
30spin_lock_t          _tty0_spin_lock  __attribute__((aligned(64)));
31
32//////////////////////////////////////////////
33unsigned int _tty0_write( char*        buffer,
34                          unsigned int nbytes )
35{
36    unsigned int n;
37    unsigned int k;
38
39    for ( n = 0 ; n < nbytes ; n++ ) 
40    {
41        // test TTY_TX buffer full
42        if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) // buffer full
43        {
44            // retry if full
45            for( k = 0 ; k < 10000 ; k++ )
46            {
47                if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) == 0) break;
48            }
49            // return error if full after 10000 retry
50            return 1;
51        }
52
53        // write one byte
54        if (buffer[n] == '\n') _tty_set_register( 0, TTY_WRITE, (unsigned int)'\r' );
55        _tty_set_register( 0, TTY_WRITE, (unsigned int)buffer[n] );
56    }
57    return 0;
58}
59
60//////////////////////////
61void _puts( char* string ) 
62{
63    unsigned int n = 0;
64
65    while ( string[n] > 0 ) n++;
66
67    _tty0_write( string, n );
68}
69
70
71//////////////////////////////
72void _putx( unsigned int val )
73{
74    static const char HexaTab[] = "0123456789ABCDEF";
75    char buf[10];
76    unsigned int c;
77
78    buf[0] = '0';
79    buf[1] = 'x';
80
81    for (c = 0; c < 8; c++) 
82    { 
83        buf[9 - c] = HexaTab[val & 0xF];
84        val = val >> 4;
85    }
86    _tty0_write( buf, 10 );
87}
88
89////////////////////////////////////
90void _putl( unsigned long long val )
91{
92    static const char HexaTab[] = "0123456789ABCDEF";
93    char buf[18];
94    unsigned int c;
95
96    buf[0] = '0';
97    buf[1] = 'x';
98
99    for (c = 0; c < 16; c++) 
100    { 
101        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
102        val = val >> 4;
103    }
104    _tty0_write( buf, 18 );
105}
106
107//////////////////////////////
108void _putd( unsigned int val ) 
109{
110    static const char DecTab[] = "0123456789";
111    char buf[10];
112    unsigned int i;
113    unsigned int first = 0;
114
115    for (i = 0; i < 10; i++) 
116    {
117        if ((val != 0) || (i == 0)) 
118        {
119            buf[9 - i] = DecTab[val % 10];
120            first = 9 - i;
121        }
122        else 
123        {
124            break;
125        }
126        val /= 10;
127    }
128    _tty0_write( &buf[first], 10 - first );
129}
130
131/////////////////////////
132void _getc( char*  byte )
133{
134    // test status register
135    while ( _tty_get_register( 0 , TTY_STATUS ) == 0 );
136
137    // read one byte
138    *byte = (char)_tty_get_register( 0 , TTY_READ );
139}
140
141//////////////////////////////////////////////////////////
142static void _kernel_printf( char * format, va_list* args ) 
143{
144
145printf_text:
146
147    while (*format) 
148    {
149        unsigned int i;
150        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
151        if (i) 
152        {
153            if ( _tty0_write( format, i ) ) goto return_error;
154            format += i;
155        }
156        if (*format == '%') 
157        {
158            format++;
159            goto printf_arguments;
160        }
161    }
162
163    return;
164
165printf_arguments:
166
167    {
168        char buf[20];
169        char * pbuf;
170        unsigned int len = 0;
171        static const char HexaTab[] = "0123456789ABCDEF";
172        unsigned int i;
173
174        switch (*format++) 
175        {
176            case ('c'):             /* char conversion */
177            {
178                int val = va_arg( *args , int );
179                len = 1;
180                buf[0] = val;
181                pbuf = &buf[0];
182                break;
183            }
184            case ('d'):             /* 32 bits decimal signed  */
185            {
186                int val = va_arg( *args , int );
187                if (val < 0) 
188                {
189                    val = -val;
190                    if ( _tty0_write( "-" , 1 ) ) goto return_error;
191                }
192                for(i = 0; i < 10; i++) 
193                {
194                    buf[9 - i] = HexaTab[val % 10];
195                    if (!(val /= 10)) break;
196                }
197                len =  i + 1;
198                pbuf = &buf[9 - i];
199                break;
200            }
201            case ('u'):             /* 32 bits decimal unsigned  */
202            {
203                unsigned int val = va_arg( *args , unsigned int );
204                for(i = 0; i < 10; i++) 
205                {
206                    buf[9 - i] = HexaTab[val % 10];
207                    if (!(val /= 10)) break;
208                }
209                len =  i + 1;
210                pbuf = &buf[9 - i];
211                break;
212            }
213            case ('x'):             /* 32 bits hexadecimal unsigned */
214            {
215                unsigned int val = va_arg( *args , unsigned int );
216                if ( _tty0_write( "0x" , 2 ) ) goto return_error;
217                for(i = 0; i < 8; i++) 
218                {
219                    buf[7 - i] = HexaTab[val % 16];
220                    if (!(val /= 16))  break;
221                }
222                len =  i + 1;
223                pbuf = &buf[7 - i];
224                break;
225            }
226            case ('l'):            /* 64 bits hexadecimal unsigned */
227            {
228                unsigned long long val = va_arg( *args , unsigned long long );
229                if ( _tty0_write( "0x" , 2 ) ) goto return_error;
230                for(i = 0; i < 16; i++) 
231                {
232                    buf[15 - i] = HexaTab[val % 16];
233                    if (!(val /= 16))  break;
234                }
235                len =  i + 1;
236                pbuf = &buf[15 - i];
237                break;
238            }
239            case ('s'):             /* string */
240            {
241                char* str = va_arg( *args , char* );
242                while (str[len]) 
243                {
244                    len++;
245                }
246                pbuf = str;
247                break;
248            }
249            default:
250                goto return_error;
251        }
252
253        if ( _tty0_write( pbuf, len ) ) goto return_error;
254       
255        goto printf_text;
256    }
257
258return_error:
259
260    {
261        // try to print an error message and exit...
262        unsigned int procid     = _get_procid();
263        unsigned int x          = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
264        unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
265        unsigned int lpid       = procid & ((1<<P_WIDTH)-1);
266        _puts("\n\n[GIET ERROR] in _printf() for processor[");
267        _putd( x ); 
268        _puts(",");
269        _putd( y );
270        _puts(",");
271        _putd( lpid );
272        _puts("]\n");
273
274        _exit();
275    }
276}  // end _kernel_printf()
277
278///////////////////////////////////////
279void _nolock_printf( char* format, ...)
280{
281    va_list   args;
282
283    va_start( args , format );
284    _kernel_printf( format , &args );
285    va_end( args );
286}
287////////////////////////////////
288void _printf( char* format, ...)
289{
290    va_list       args;
291    unsigned int  save_sr;
292
293    // get TTY0 lock
294    _it_disable( &save_sr );
295    if ( _tty0_boot_mode ) _spin_lock_acquire( &_tty0_spin_lock );
296    else                   _sqt_lock_acquire( &_tty0_sqt_lock );
297
298    va_start( args , format );
299    _kernel_printf( format , &args );
300    va_end( args );
301
302    // release TTY0 lock
303    if ( _tty0_boot_mode ) _spin_lock_release( &_tty0_spin_lock );
304    else                   _sqt_lock_release( &_tty0_sqt_lock );
305    _it_restore( &save_sr );
306}
307
308
309// Local Variables:
310// tab-width: 4
311// c-basic-offset: 4
312// c-file-offsets:((innamespace . 0)(inline-open . 0))
313// indent-tabs-mode: nil
314// End:
315// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
316
Note: See TracBrowser for help on using the repository browser.