Changeset 669 for trunk/kernel/kern/printk.c
- Timestamp:
- Nov 19, 2020, 11:44:34 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/printk.c
r662 r669 2 2 * printk.c - Kernel Log & debug messages API implementation. 3 3 * 4 * authors Alain Greiner (2016,2017,2018 )4 * authors Alain Greiner (2016,2017,2018,2019,2020) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 34 34 35 35 /////////////////////////////////////////////////////////////////////////////////// 36 // Extern variables36 // Extern 37 37 /////////////////////////////////////////////////////////////////////////////////// 38 38 39 39 extern chdev_directory_t chdev_dir; // defined in chdev.h / allocated in kernel_init.c 40 40 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 ////////////////////////////////////////////////////////////////////////////////////// 56 static 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 66 format_to_string_text: 67 68 // handle one character per iteration 57 69 while ( *format != 0 ) 58 70 { … … 60 72 { 61 73 format++; 62 goto xprintf_arguments;74 goto format_to_string_arguments; 63 75 } 64 76 else // copy one char to string 65 77 { 66 TO_STR EAM( *format );78 TO_STRING( *format ); 67 79 format++; 68 80 } 69 81 } 70 82 71 va_end( args ); 72 73 // add terminating NUL chracter 74 TO_STREAM( 0 ); 83 TO_STRING( 0 ); 75 84 return ps; 76 85 77 xprintf_arguments:86 format_to_string_arguments: 78 87 79 88 { … … 84 93 uint32_t i; 85 94 86 // Ignore fields width and precision87 for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ );88 89 95 switch (*format) 90 96 { 91 97 case ('c'): // char conversion 92 98 { 93 int val = va_arg( args, int );94 buf[0] = val;99 int val = va_arg( *args , int ); 100 buf[0] = (char)val; 95 101 pbuf = buf; 96 102 len = 1; 97 103 break; 98 104 } 99 case ('b'): // excactly 2 digits hexadecimal integer100 {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 }110 105 case ('d'): // up to 10 digits decimal signed integer 111 106 { 112 int val = va_arg( args, int );107 int32_t val = va_arg( *args , int32_t ); 113 108 if (val < 0) 114 109 { 115 TO_STR EAM( '-' );110 TO_STRING( '-' ); 116 111 val = -val; 117 112 } … … 127 122 case ('u'): // up to 10 digits decimal unsigned integer 128 123 { 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 hexadecimal140 case ('l'): // up to 16 digits hexadecimal141 {142 uint32_t imax;143 uint64_t val;144 145 if ( *format == 'l' ) // 64 bits146 {147 val = va_arg( args, uint64_t);148 imax = 16;149 }150 else // 32 bits151 {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 hexadecimal169 {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 type188 {189 return -1;190 }191 } // end switch on argument type192 193 format++;194 195 // copy argument to string196 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 {285 124 uint32_t val = va_arg( *args , uint32_t ); 286 125 for(i = 0; i < 10; i++) … … 293 132 break; 294 133 } 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" 296 136 { 297 137 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++) 300 141 { 301 142 buf[7 - i] = HexaTab[val & 0xF]; 302 if (!(val = (val>>4))) break; 143 if( (*format == 'x') && ((val >> 4) == 0) ) break; 144 val = val >> 4; 303 145 } 304 146 len = i + 1; … … 306 148 break; 307 149 } 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" 309 152 { 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++) 326 158 { 327 159 buf[15 - i] = HexaTab[val & 0xF]; 328 if (!(val = (val>>4))) break; 160 if( (*format == 'l') && ((val >> 4) == 0) ) break; 161 val = val >> 4; 329 162 } 330 163 len = i + 1; … … 332 165 break; 333 166 } 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 }347 167 case ('s'): /* string */ 348 168 { 349 169 char* str = va_arg( *args , char* ); 350 while (str[len]) 351 { 352 len++; 353 } 170 while (str[len]) { len++; } 354 171 pbuf = str; 355 172 break; 356 173 } 357 default: 174 default: // unsupported argument type 358 175 { 359 dev_txt_sync_write( "\n[PANIC] in kernel_printf() : illegal format\n", 45 );176 return -2; 360 177 } 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 } 364 187 365 goto printf_text; 366 } 367 368 } // end kernel_printf() 188 goto format_to_string_text; 189 } 190 } // end format_to_string() 369 191 370 192 ////////////////////////////////// 371 193 void printk( char * format , ... ) 372 194 { 195 char buffer[CONFIG_PRINTK_BUF_SIZE]; 373 196 va_list args; 197 int32_t length; 198 199 // build args va_list 200 va_start( args , format ); 374 201 375 202 // get pointers on TXT0 chdev … … 384 211 remote_busylock_acquire( lock_xp ); 385 212 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 ); 389 218 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 } 390 242 391 243 // release TXT0 lock 392 244 remote_busylock_release( lock_xp ); 393 } 245 246 } // end printk() 394 247 395 248 ///////////////////////////////////////// 396 249 void nolock_printk( char * format , ... ) 397 250 { 251 char buffer[CONFIG_PRINTK_BUF_SIZE]; 398 252 va_list args; 399 400 // call kernel_printf on TXT0, in busy waiting mode 253 int32_t length; 254 255 // build args va_list 401 256 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 ); 403 263 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 ////////////////////////////////////// 291 void 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 ////////////////////////////////////// 329 int32_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 //////////////////////////////// 357 void puts( const char * string ) 450 358 { 451 359 uint32_t n = 0; … … 459 367 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 460 368 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 /////////////////////////////////////// 382 void nolock_puts( const char * string ) 383 { 384 uint32_t n = 0; 385 386 // compute string length 387 while ( string[n] > 0 ) n++; 466 388 467 389 // display string on TTY0 468 390 dev_txt_sync_write( string , n ); 469 470 // release TXT0 lock 471 remote_busylock_release( lock_xp ); 472 } 391 392 } // end nolock_puts() 393 473 394 474 395 … … 496 417 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 497 418 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 //////////////////////////////// 432 void 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 } 503 448 504 449 // display buf on TTY0 505 450 dev_txt_sync_write( buf , 10 ); 506 451 507 // release TXT0 lock 508 remote_busylock_release( lock_xp ); 509 } 452 } // end nilock_putx() 510 453 511 454 //////////////////////// … … 525 468 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 526 469 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 /////////////////////////////// 496 void nolock_putd( int32_t val ) 497 { 498 static const char HexaTab[] = "0123456789ABCDEF"; 499 500 char buf[10]; 501 uint32_t i; 529 502 530 503 if (val < 0) … … 543 516 dev_txt_sync_write( &buf[9-i] , i+1 ); 544 517 545 // release TXT0 lock 546 remote_busylock_release( lock_xp ); 547 } 518 } // end nolock_putd() 548 519 549 520 ///////////////////////// … … 570 541 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 571 542 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 //////////////////////////////// 556 void 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 } 577 572 578 573 // display string on TTY0 579 574 dev_txt_sync_write( buf , 18 ); 580 575 581 // release TXT0 lock 582 remote_busylock_release( lock_xp ); 583 } 576 } // end nolock_putl() 584 577 585 578 ///////////////////////////// … … 603 596 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 604 597 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() 626 622 627 623
Note: See TracChangeset
for help on using the changeset viewer.