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

Last change on this file since 709 was 709, checked in by alain, 9 years ago

Major release: Change the task model to implement the POSIX threads API.

  • The shell "exec" and "kill" commands can be used to activate/de-activate the applications.
  • The "pause", "resume", and "context" commands can be used to stop, restart, a single thtead or to display the thread context.

This version has been tested on the following multi-threaded applications,
that have been modified to use the POSIX threads:

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