Ignore:
Timestamp:
Nov 19, 2020, 11:44:34 PM (3 years ago)
Author:
alain
Message:

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/printk.c

    r662 r669  
    22 * printk.c - Kernel Log & debug messages API implementation.
    33 *
    4  * authors  Alain Greiner (2016,2017,2018)
     4 * authors  Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3434
    3535///////////////////////////////////////////////////////////////////////////////////
    36 //      Extern variables
     36//      Extern
    3737///////////////////////////////////////////////////////////////////////////////////
    3838
    3939extern chdev_directory_t  chdev_dir;  // defined in chdev.h / allocated in kernel_init.c
    4040
    41 /////////////////////////////////////
    42 uint32_t snprintf( char     * string,
    43                    uint32_t   length,
    44                    char     * format, ... )
    45 {
    46 
    47 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
    48 
    49     va_list    args;      // printf arguments
    50     uint32_t   ps;        // pointer to the string buffer
    51 
    52     ps = 0;   
    53     va_start( args , format );
    54 
    55 xprintf_text:
    56 
     41//////////////////////////////////////////////////////////////////////////////////////
     42// This static function is called by printk(), nolock_printk(), and snprintk(),
     43// functions to build a string from a printf-like format, and stores it
     44// in the buffer defined by the <string> and <length> arguments.
     45// It does NOT add a terminating NUL character in the <string> buffer.
     46// If success, it returns the number of bytes actually copied in the string buffer.
     47// It returns -2 in case of illegal format, it returns -1 if the formated string
     48// exceeds the length argument.
     49//////////////////////////////////////////////////////////////////////////////////////
     50// @ string    : buffer allocated by caller.
     51// @ length    : buffer size in bytes
     52// @ format    : printf like format.
     53// @ args      : va_list of arguments.
     54// @ return string length if success / -1 if buffer too small / -2 if illegal format.
     55//////////////////////////////////////////////////////////////////////////////////////
     56static int32_t format_to_string( char       * string,
     57                                 uint32_t     length,
     58                                 const char * format,
     59                                 va_list    * args )
     60{
     61
     62#define TO_STRING(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
     63
     64    uint32_t   ps = 0;        // index in string buffer
     65
     66format_to_string_text:
     67
     68    // handle one character per iteration
    5769    while ( *format != 0 )
    5870    {
     
    6072        {
    6173            format++;
    62             goto xprintf_arguments;
     74            goto format_to_string_arguments;
    6375        }
    6476        else                  // copy one char to string
    6577        {
    66             TO_STREAM( *format );
     78            TO_STRING( *format );
    6779            format++;
    6880        }
    6981    }
    7082
    71     va_end( args );
    72    
    73     // add terminating NUL chracter
    74     TO_STREAM( 0 );
     83    TO_STRING( 0 );
    7584    return ps;
    7685
    77 xprintf_arguments:
     86format_to_string_arguments:
    7887
    7988    {
     
    8493        uint32_t          i;
    8594       
    86         // Ignore fields width and precision
    87         for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ );
    88 
    8995        switch (*format)
    9096        {
    9197            case ('c'):             // char conversion
    9298            {
    93                 int val = va_arg( args, int );
    94                 buf[0] = val;
     99                int val = va_arg( *args , int );
     100                buf[0] = (char)val;
    95101                pbuf   = buf;
    96102                len    = 1;
    97103                break;
    98104            }
    99             case ('b'):             // excactly 2 digits hexadecimal integer
    100             {
    101                 int  val = va_arg( args, int );
    102                 int  val_lsb = val & 0xF;
    103                 int  val_msb = (val >> 4) & 0xF;
    104                 buf[0] = HexaTab[val_msb];
    105                 buf[1] = HexaTab[val_lsb];
    106                 len  = 2;
    107                 pbuf = buf;
    108                 break;
    109             }
    110105            case ('d'):             // up to 10 digits decimal signed integer
    111106            {
    112                 int val = va_arg( args, int );
     107                int32_t val = va_arg( *args , int32_t );
    113108                if (val < 0)
    114109                {
    115                     TO_STREAM( '-' );
     110                    TO_STRING( '-' );
    116111                    val = -val;
    117112                }
     
    127122            case ('u'):             // up to 10 digits decimal unsigned integer
    128123            {
    129                 uint32_t val = va_arg( args, uint32_t );
    130                 for(i = 0; i < 10; i++)
    131                 {
    132                     buf[9 - i] = HexaTab[val % 10];
    133                     if (!(val /= 10)) break;
    134                 }
    135                 len =  i + 1;
    136                 pbuf = &buf[9 - i];
    137                 break;
    138             }
    139             case ('x'):             // up to 8 digits hexadecimal
    140             case ('l'):             // up to 16 digits hexadecimal
    141             {
    142                 uint32_t imax;
    143                 uint64_t val;
    144                
    145                 if ( *format == 'l' )   // 64 bits
    146                 {
    147                     val = va_arg( args, uint64_t);
    148                     imax = 16;
    149                 }
    150                 else                    // 32 bits
    151                 {
    152                     val = va_arg( args, uint32_t);
    153                     imax = 8;
    154                 }
    155                
    156                 TO_STREAM( '0' );
    157                 TO_STREAM( 'x' );
    158                
    159                 for(i = 0; i < imax; i++)
    160                 {
    161                     buf[(imax-1) - i] = HexaTab[val % 16];
    162                     if (!(val /= 16))  break;
    163                 }
    164                 len =  i + 1;
    165                 pbuf = &buf[(imax-1) - i];
    166                 break;
    167             }
    168             case ('X'):             // exactly 8 digits hexadecimal
    169             {
    170                 uint32_t val = va_arg( args , uint32_t );
    171                 for(i = 0; i < 8; i++)
    172                 {
    173                     buf[7 - i] = HexaTab[val % 16];
    174                     val = (val>>4);
    175                 }
    176                 len =  8;
    177                 pbuf = buf;
    178                 break;
    179             }
    180             case ('s'):             /* string */
    181             {
    182                 char* str = va_arg( args, char* );
    183                 while (str[len]) { len++; }
    184                 pbuf = str;
    185                 break;
    186             }
    187             default:       // unsupported argument type
    188             {
    189                 return -1;
    190             }
    191         }  // end switch on  argument type
    192 
    193         format++;
    194 
    195         // copy argument to string
    196         for( i = 0 ; i < len ; i++ )
    197         {
    198             TO_STREAM( pbuf[i] );
    199         }
    200        
    201         goto xprintf_text;
    202     }
    203 } // end snprintf()
    204 
    205 //////////////////////////////////////////////////////////////////////////////////////
    206 // This static function is called by printk(), assert() and nolock_printk()
    207 // to display a formated string on TXT0, using a busy waiting policy.
    208 //////////////////////////////////////////////////////////////////////////////////////
    209 // @ format    : printf like format.
    210 // @ args      : va_list of arguments.
    211 //////////////////////////////////////////////////////////////////////////////////////
    212 static void kernel_printf( const char * format,
    213                            va_list    * args )
    214 {
    215 
    216 printf_text:
    217 
    218     while (*format)
    219     {
    220         uint32_t i;
    221         for (i = 0 ; format[i] && (format[i] != '%') ; i++);
    222         if (i)
    223         {
    224             dev_txt_sync_write( format, i );
    225             format += i;
    226         }
    227         if (*format == '%')
    228         {
    229             format++;
    230             goto printf_arguments;
    231         }
    232     }
    233 
    234     return;
    235 
    236 printf_arguments:
    237 
    238     {
    239         char      buf[20];
    240         char    * pbuf = NULL;
    241         uint32_t  len  = 0;
    242         static const char HexaTab[] = "0123456789ABCDEF";
    243         uint32_t i;
    244 
    245         switch (*format++)
    246         {
    247             case ('c'):             /* char conversion */
    248             {
    249                 int  val = va_arg( *args , int );
    250                 len = 1;
    251                 buf[0] = (char)val;
    252                 pbuf = &buf[0];
    253                 break;
    254             }
    255             case ('b'):             /* exactly 2 digits hexadecimal */
    256             {
    257                 int  val = va_arg( *args, int );
    258                 int  val_lsb = val & 0xF;
    259                 int  val_msb = (val >> 4) & 0xF;
    260                 buf[0] = HexaTab[val_msb];
    261                 buf[1] = HexaTab[val_lsb];
    262                 len  = 2;
    263                 pbuf = buf;
    264                 break;
    265             }
    266             case ('d'):             /* up to 10 digits signed decimal */
    267             {
    268                 int val = va_arg( *args , int );
    269                 if (val < 0)
    270                 {
    271                     val = -val;
    272                     dev_txt_sync_write( "-" , 1 );
    273                 }
    274                 for(i = 0; i < 10; i++)
    275                 {
    276                     buf[9 - i] = HexaTab[val % 10];
    277                     if (!(val /= 10)) break;
    278                 }
    279                 len =  i + 1;
    280                 pbuf = &buf[9 - i];
    281                 break;
    282             }
    283             case ('u'):             /* up to 10 digits unsigned decimal */
    284             {
    285124                uint32_t val = va_arg( *args , uint32_t );
    286125                for(i = 0; i < 10; i++)
     
    293132                break;
    294133            }
    295             case ('x'):             /* up to 8 digits hexadecimal */
     134            case ('x'):             // up to 8 digits hexad after "0x"
     135            case ('X'):             // exactly 8 digits hexa after "0x"
    296136            {
    297137                uint32_t val = va_arg( *args , uint32_t );
    298                 dev_txt_sync_write( "0x" , 2 );
    299                 for(i = 0; i < 8; i++)
     138                TO_STRING( '0' );
     139                TO_STRING( 'x' );
     140                for(i = 0 ; i < 8 ; i++)
    300141                {
    301142                    buf[7 - i] = HexaTab[val & 0xF];
    302                     if (!(val = (val>>4)))  break;
     143                    if( (*format == 'x') && ((val >> 4) == 0) )  break;
     144                    val = val >> 4;
    303145                }
    304146                len =  i + 1;
     
    306148                break;
    307149            }
    308             case ('X'):             /* exactly 8 digits hexadecimal */
     150            case ('l'):             // up to 16 digits hexa after "0x"
     151            case ('L'):             // exactly 16 digits hexa after "0x"
    309152            {
    310                 uint32_t val = va_arg( *args , uint32_t );
    311                 dev_txt_sync_write( "0x" , 2 );
    312                 for(i = 0; i < 8; i++)
    313                 {
    314                     buf[7 - i] = HexaTab[val & 0xF];
    315                     val = (val>>4);
    316                 }
    317                 len =  8;
    318                 pbuf = buf;
    319                 break;
    320             }
    321             case ('l'):            /* up to 16 digits hexadecimal */
    322             {
    323                 uint64_t val = va_arg( *args , uint64_t );
    324                 dev_txt_sync_write( "0x" , 2 );
    325                 for(i = 0; i < 16; i++)
     153                uint64_t val = (((uint64_t)va_arg( *args, uint32_t)) << 32) |
     154                               ((uint64_t)va_arg( *args, uint32_t));
     155                TO_STRING( '0' );
     156                TO_STRING( 'x' );
     157                for(i = 0 ; i < 16 ; i++)
    326158                {
    327159                    buf[15 - i] = HexaTab[val & 0xF];
    328                     if (!(val = (val>>4)))  break;
     160                    if( (*format == 'l') && ((val >> 4) == 0) )  break;
     161                    val = val >> 4;
    329162                }
    330163                len =  i + 1;
     
    332165                break;
    333166            }
    334             case ('L'):           /* exactly 16 digits hexadecimal */
    335             {
    336                 uint64_t val = va_arg( *args , uint64_t );
    337                 dev_txt_sync_write( "0x" , 2 );
    338                 for(i = 0; i < 16; i++)
    339                 {
    340                     buf[15 - i] = HexaTab[val & 0xF];
    341                     val = (val>>4);
    342                 }
    343                 len =  16;
    344                 pbuf = buf;
    345                 break;
    346             }
    347167            case ('s'):             /* string */
    348168            {
    349169                char* str = va_arg( *args , char* );
    350                 while (str[len])
    351                 {
    352                     len++;
    353                 }
     170                while (str[len]) { len++; }
    354171                pbuf = str;
    355172                break;
    356173            }
    357             default:
     174            default:       // unsupported argument type
    358175            {
    359                 dev_txt_sync_write( "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
     176                return -2;
    360177            }
    361         }
    362 
    363         if( pbuf != NULL ) dev_txt_sync_write( pbuf, len );
     178        }  // end switch on  argument type
     179
     180        format++;
     181
     182        // copy argument sub-string to the string buffer
     183        for( i = 0 ; i < len ; i++ )
     184        {
     185            TO_STRING( pbuf[i] );
     186        }
    364187       
    365         goto printf_text;
    366     }
    367 
    368 }  // end kernel_printf()
     188        goto format_to_string_text;
     189    }
     190}   // end format_to_string()
    369191
    370192//////////////////////////////////
    371193void printk( char * format , ... )
    372194{
     195    char          buffer[CONFIG_PRINTK_BUF_SIZE];
    373196    va_list       args;
     197    int32_t       length;
     198
     199    // build args va_list
     200    va_start( args , format );
    374201
    375202    // get pointers on TXT0 chdev
     
    384211    remote_busylock_acquire( lock_xp );
    385212
    386     // display format on TXT0 in busy waiting mode
    387     va_start( args , format );
    388     kernel_printf( format , &args );
     213    // build a string from format
     214    length = format_to_string( buffer,
     215                      CONFIG_PRINTK_BUF_SIZE,
     216                      format,
     217                      &args );
    389218    va_end( args );
     219
     220    if( length > 0  )        // call TXT driver to display formated string on TXT0
     221    {
     222        dev_txt_sync_write( buffer , length );
     223    }
     224    else if( length == -2 )  // illegal format => display a warning on TXT0
     225    {
     226        thread_t * this = CURRENT_THREAD;
     227
     228        nolock_printk("\n[PANIC] from printk : illegal format\n"
     229                      "thread[%x,%x] on core[%x,%d] at cycle %l\n",
     230                      this->process->pid, this->trdid,
     231                      local_cxy, this->core->lid, hal_get_cycles() );
     232    }
     233    else                     // format too long => display a warning on TXT0
     234    {
     235        thread_t * this = CURRENT_THREAD;
     236
     237        nolock_printk("\n[PANIC] from printk : formated string too long\n"
     238                      "thread[%x,%x] on core[%x,%d] at cycle %l\n",
     239                      this->process->pid, this->trdid,
     240                      local_cxy, this->core->lid, hal_get_cycles() );
     241    }
    390242
    391243    // release TXT0 lock
    392244    remote_busylock_release( lock_xp );
    393 }
     245
     246}   // end printk()
    394247
    395248/////////////////////////////////////////
    396249void nolock_printk( char * format , ... )
    397250{
     251    char          buffer[CONFIG_PRINTK_BUF_SIZE];
    398252    va_list       args;
    399 
    400     // call kernel_printf on TXT0, in busy waiting mode
     253    int32_t       length;
     254
     255    // build args va_list
    401256    va_start( args , format );
    402     kernel_printf( format , &args );
     257
     258    // build a string from format
     259    length = format_to_string( buffer,
     260                      CONFIG_PRINTK_BUF_SIZE,
     261                      format,
     262                      &args );
    403263    va_end( args );
    404 }
    405 
    406 ////////////////////////////////////
    407 void panic( const char * function_name,
    408             uint32_t     line,
    409             cycle_t      cycle,
    410             const char * format,
    411             ... )
    412 {
    413     // get pointers on TXT0 chdev
    414     xptr_t    txt0_xp = chdev_dir.txt_tx[0];
    415     cxy_t     txt0_cxy = GET_CXY(txt0_xp);
    416     chdev_t * txt0_ptr = GET_PTR(txt0_xp);
    417 
    418     // get extended pointer on remote TXT0 lock
    419     xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    420 
    421     // get TXT0 lock
    422     remote_busylock_acquire( lock_xp );
    423 
    424     // get calling thread
    425     thread_t * current = CURRENT_THREAD;
    426 
    427     // print generic infos
    428     nolock_printk("\n\n[PANIC] in %s: line %d | cycle %d\n"
    429                   "core[%x,%d] | thread %x (%x) | process %x (%x)\n",
    430                   function_name, line, (uint32_t)cycle,
    431                   local_cxy, current->core->lid,
    432                   current->trdid, current,
    433                   current->process->pid, current->process );
    434 
    435     // call kernel_printf to print format
    436     va_list args;
    437     va_start(args, format);
    438     kernel_printf(format, &args);
    439     va_end(args);
    440 
    441     // release TXT0 lock
    442     remote_busylock_release( lock_xp );
    443 
    444     // suicide
    445     hal_core_sleep();
    446 }
    447 
    448 //////////////////////////
    449 void puts( char * string )
     264
     265    if( length > 0  )        // call TXT driver to display formated string on TXT0
     266    {
     267        dev_txt_sync_write( buffer , length );
     268    }
     269    else if( length == -2 )  // illegal format => display a warning on TXT0
     270    {
     271        thread_t * this = CURRENT_THREAD;
     272
     273        nolock_printk("\n[PANIC] from print : illegal format\n"
     274                      "thread[%x,%x] on core[%x,%d] at cycle %l\n",
     275                      this->process->pid, this->trdid,
     276                      local_cxy, this->core->lid, hal_get_cycles() );
     277    }
     278    else                  // buffer too small => display a warning on TXT0
     279    {
     280        thread_t * this = CURRENT_THREAD;
     281
     282        nolock_printk("\n[PANIC] from printk : formated string too long\n"
     283                      "thread[%x,%x] on core[%x,%d] at cycle %l\n",
     284                      this->process->pid, this->trdid,
     285                      local_cxy, this->core->lid, hal_get_cycles() );
     286    }
     287
     288}   // end nolock_printk()
     289
     290//////////////////////////////////////
     291void assert( const char   * func_name,
     292             bool_t         expr,
     293             char         * format , ... )
     294{
     295    if( expr == false )
     296    {
     297        thread_t * this  = CURRENT_THREAD;
     298        trdid_t    trdid = this->trdid;
     299        pid_t      pid   = this->process->pid;
     300        uint32_t   lid   = this->core->lid;
     301        uint32_t   cycle = (uint32_t)hal_get_cycles();
     302
     303        char       buffer[CONFIG_PRINTK_BUF_SIZE];
     304        va_list    args;
     305
     306        va_start( args , format );
     307
     308        // build a string from format
     309        int32_t   length = format_to_string( buffer,
     310                                             CONFIG_PRINTK_BUF_SIZE,
     311                                             format,
     312                                             &args );
     313        va_end( args );
     314
     315        if( length > 0  )  // display panic message on TXT0, including formated string
     316        {
     317            printk("\n[ASSERT] in %s / core[%x,%d] / thread[%x,%x] / cycle %d\n       %s\n",
     318            func_name, local_cxy, lid, pid, trdid, cycle, buffer );
     319        }
     320        else              // display minimal panic message on TXT0
     321        {
     322            printk("\n[ASSERT] in %s / core[%x,%d] / thread[%x,%x] / cycle %d\n",
     323            func_name, local_cxy, lid, pid, trdid, cycle );
     324        }
     325    }
     326}   // end assert( __FUNCTION__,)
     327   
     328//////////////////////////////////////
     329int32_t snprintk( char       * buffer,
     330                  uint32_t     size,
     331                  char       * format, ... )
     332{
     333    va_list       args;
     334    int32_t       string_length;
     335
     336    // build args va_list
     337    va_start( args , format );
     338
     339    // build a string from format
     340    string_length = format_to_string( buffer , size , format , &args );
     341    va_end( args );
     342
     343    if( (string_length < 0) || (string_length == (int32_t)size) )  // failure
     344    {
     345        return -1;
     346    }
     347    else                                                           // success
     348    {
     349        // add NUL character
     350        buffer[string_length] = 0;
     351
     352        return string_length;
     353    }
     354}   // end snprintk()
     355
     356////////////////////////////////
     357void puts( const char * string )
    450358{
    451359    uint32_t   n = 0;
     
    459367    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    460368
    461     // get extended pointer on remote TXT0 lock
    462     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    463 
    464     // get TXT0 lock
    465     remote_busylock_acquire( lock_xp );
     369    if( txt0_xp != XPTR_NULL )
     370    {
     371        // get extended pointer on remote TXT0 lock
     372        xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     373
     374        // display string on TTY0
     375        remote_busylock_acquire( lock_xp );
     376        dev_txt_sync_write( string , n );
     377        remote_busylock_release( lock_xp );
     378    }
     379}   // end puts()
     380
     381///////////////////////////////////////
     382void nolock_puts( const char * string )
     383{
     384    uint32_t   n = 0;
     385
     386    // compute string length
     387    while ( string[n] > 0 ) n++;
    466388
    467389    // display string on TTY0
    468390    dev_txt_sync_write( string , n );
    469 
    470     // release TXT0 lock
    471     remote_busylock_release( lock_xp );
    472 }
     391 
     392}   // end nolock_puts()
     393
    473394
    474395
     
    496417    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    497418
    498     // get extended pointer on remote TXT0 chdev lock
    499     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    500 
    501     // get TXT0 lock
    502     remote_busylock_acquire( lock_xp );
     419    if( txt0_xp != XPTR_NULL )
     420    {
     421        // get extended pointer on remote TXT0 chdev lock
     422        xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     423
     424        // display buf on TTY0
     425        remote_busylock_acquire( lock_xp );
     426        dev_txt_sync_write( buf , 10 );
     427        remote_busylock_release( lock_xp );
     428    }
     429}   // end putx()
     430
     431////////////////////////////////
     432void nolock_putx( uint32_t val )
     433{
     434    static const char HexaTab[] = "0123456789ABCDEF";
     435
     436    char      buf[10];
     437    uint32_t  c;
     438
     439    buf[0] = '0';
     440    buf[1] = 'x';
     441
     442    // build buffer
     443    for (c = 0; c < 8; c++)
     444    {
     445        buf[9 - c] = HexaTab[val & 0xF];
     446        val = val >> 4;
     447    }
    503448
    504449    // display buf on TTY0
    505450    dev_txt_sync_write( buf , 10 );
    506451
    507     // release TXT0 lock
    508     remote_busylock_release( lock_xp );
    509 }
     452}   // end nilock_putx()
    510453
    511454////////////////////////
     
    525468    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    526469
    527     // get TXT0 lock
    528     remote_busylock_acquire( lock_xp );
     470    if( txt0_xp != XPTR_NULL )
     471    {
     472        // get TXT0 lock
     473        remote_busylock_acquire( lock_xp );
     474
     475        if (val < 0)
     476        {
     477            val = -val;
     478            dev_txt_sync_write( "-" , 1 );
     479        }
     480
     481        for(i = 0; i < 10 ; i++)
     482        {
     483            buf[9 - i] = HexaTab[val % 10];
     484            if (!(val /= 10)) break;
     485        }
     486
     487        // display buf on TTY0
     488        dev_txt_sync_write( &buf[9-i] , i+1 );
     489
     490        // release TXT0 lock
     491        remote_busylock_release( lock_xp );
     492    }
     493}   // end putd()
     494
     495///////////////////////////////
     496void nolock_putd( int32_t val )
     497{
     498    static const char HexaTab[] = "0123456789ABCDEF";
     499
     500    char      buf[10];
     501    uint32_t  i;
    529502
    530503    if (val < 0)
     
    543516    dev_txt_sync_write( &buf[9-i] , i+1 );
    544517
    545     // release TXT0 lock
    546     remote_busylock_release( lock_xp );
    547 }
     518}   // end nolock_putd()
    548519
    549520/////////////////////////
     
    570541    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    571542
    572     // get extended pointer on remote TXT0 chdev lock
    573     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    574 
    575     // get TXT0 lock
    576     remote_busylock_acquire( lock_xp );
     543    if( txt0_xp != XPTR_NULL )
     544    {
     545        // get extended pointer on remote TXT0 chdev lock
     546        xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     547
     548        // display string on TTY0
     549        remote_busylock_acquire( lock_xp );
     550        dev_txt_sync_write( buf , 18 );
     551        remote_busylock_release( lock_xp );
     552    }
     553}   // end putl()
     554
     555////////////////////////////////
     556void nolock_putl( uint64_t val )
     557{
     558    static const char HexaTab[] = "0123456789ABCDEF";
     559
     560    char      buf[18];
     561    uint32_t  c;
     562
     563    buf[0] = '0';
     564    buf[1] = 'x';
     565
     566    // build buffer
     567    for (c = 0; c < 16; c++)
     568    {
     569        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
     570        val = val >> 4;
     571    }
    577572
    578573    // display string on TTY0
    579574    dev_txt_sync_write( buf , 18 );
    580575
    581     // release TXT0 lock
    582     remote_busylock_release( lock_xp );
    583 }
     576}   // end nolock_putl()
    584577
    585578/////////////////////////////
     
    603596    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    604597
    605     // get TXT0 lock
    606     remote_busylock_acquire( lock_xp );
    607 
    608     // display string on TTY0
    609     nolock_printk("\n***** %s *****\n", string );
    610 
    611     for ( line = 0 , byte = 0 ; line < nlines ; line++ )
    612     {
    613          nolock_printk(" %X | %b %b %b %b | %b %b %b %b | %b %b %b %b | %b %b %b %b |\n",
    614          buffer + byte,
    615          buffer[byte+ 0],buffer[byte+ 1],buffer[byte+ 2],buffer[byte+ 3],
    616          buffer[byte+ 4],buffer[byte+ 5],buffer[byte+ 6],buffer[byte+ 7],
    617          buffer[byte+ 8],buffer[byte+ 9],buffer[byte+10],buffer[byte+11],
    618          buffer[byte+12],buffer[byte+13],buffer[byte+14],buffer[byte+15] );
    619 
    620          byte += 16;
    621     }
    622 
    623     // release TXT0 lock
    624     remote_busylock_release( lock_xp );
    625 }
     598    if( txt0_xp != XPTR_NULL )
     599    {
     600        // get TXT0 lock
     601        remote_busylock_acquire( lock_xp );
     602
     603        // display string on TTY0
     604        nolock_printk("\n***** %s *****\n", string );
     605
     606        for ( line = 0 , byte = 0 ; line < nlines ; line++ )
     607        {
     608            nolock_printk(" %X | %b %b %b %b | %b %b %b %b | %b %b %b %b | %b %b %b %b |\n",
     609            buffer + byte,
     610            buffer[byte+ 0],buffer[byte+ 1],buffer[byte+ 2],buffer[byte+ 3],
     611            buffer[byte+ 4],buffer[byte+ 5],buffer[byte+ 6],buffer[byte+ 7],
     612            buffer[byte+ 8],buffer[byte+ 9],buffer[byte+10],buffer[byte+11],
     613            buffer[byte+12],buffer[byte+13],buffer[byte+14],buffer[byte+15] );
     614
     615            byte += 16;
     616        }
     617
     618        // release TXT0 lock
     619        remote_busylock_release( lock_xp );
     620    }
     621}   // end putb()
    626622
    627623
Note: See TracChangeset for help on using the changeset viewer.