Changeset 436 for trunk/hal/tsar_mips32/drivers/soclib_tty.c
- Timestamp:
- Mar 7, 2018, 9:02:03 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r435 r436 46 46 #endif 47 47 48 //////////////////////////////////////////////////////////////////////////////////// 49 // These global variables implement the TTY_RX FIFOs (one per channel) 50 //////////////////////////////////////////////////////////////////////////////////// 51 52 __attribute__((section(".kdata"))) 53 tty_fifo_t tty_rx_fifo[CONFIG_MAX_TXT_CHANNELS]; 54 55 __attribute__((section(".kdata"))) 56 tty_fifo_t tty_tx_fifo[CONFIG_MAX_TXT_CHANNELS]; 57 48 58 /////////////////////////////////////// 49 59 void soclib_tty_init( chdev_t * chdev ) … … 51 61 xptr_t reg_xp; 52 62 63 // initialise function pointers in chdev 53 64 chdev->cmd = &soclib_tty_cmd; 54 65 chdev->isr = &soclib_tty_isr; … … 58 69 xptr_t tty_xp = chdev->base; 59 70 uint32_t channel = chdev->channel; 71 bool_t is_rx = chdev->is_rx; 60 72 61 73 // get SOCLIB_TTY device cluster and local pointer … … 70 82 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE ); 71 83 hal_remote_sw( reg_xp , 0 ); 72 } 84 85 // reset relevant FIFO 86 if( is_rx ) 87 { 88 tty_rx_fifo[channel].sts = 0; 89 tty_rx_fifo[channel].ptr = 0; 90 tty_rx_fifo[channel].ptw = 0; 91 } 92 else 93 { 94 tty_tx_fifo[channel].sts = 0; 95 tty_tx_fifo[channel].ptr = 0; 96 tty_tx_fifo[channel].ptw = 0; 97 } 98 } // end soclib_tty_init() 73 99 74 100 ////////////////////////////////////////////////////////////// 75 101 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp ) 76 102 { 77 78 #if (CONFIG_DEBUG_SYS_READ & 1) 79 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles(); 80 #endif 81 82 #if (CONFIG_DEBUG_SYS_WRITE & 1) 83 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles(); 84 #endif 103 tty_fifo_t * fifo; // TTY_RX or TTY_TX FIFO 104 char byte; // byte value 105 uint32_t done; // number of bytes moved 85 106 86 107 // get client thread cluster and local pointer … … 88 109 thread_t * th_ptr = GET_PTR( th_xp ); 89 110 90 // get command type and extended pointer on TXT device 91 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 92 93 #if CONFIG_DEBUG_HAL_TXT 111 // get command arguments 112 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 113 xptr_t buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) ); 114 uint32_t count = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) ); 115 xptr_t error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error ); 116 117 #if (CONFIG_DEBUG_SYS_READ & 1) 118 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles(); 119 #endif 120 121 #if (CONFIG_DEBUG_SYS_WRITE & 1) 122 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles(); 123 #endif 124 125 #if CONFIG_DEBUG_HAL_TXT_RX 94 126 uint32_t cycle = (uint32_t)hal_get_cycles(); 95 if (CONFIG_DEBUG_HAL_TXT < cycle ) 96 printk("\n[DBG] %s : thread %x enter for %s / cycle %d\n", 97 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str(type) , cycle ); 98 #endif 99 100 if( type == TXT_WRITE ) // block, enable TX_IRQ, and dechedule for a WRITE 101 { 102 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 103 104 // get TXT device cluster and local pointer 105 cxy_t dev_cxy = GET_CXY( dev_xp ); 106 chdev_t * dev_ptr = GET_PTR( dev_xp ); 107 108 // get extended pointer on SOCLIB_TTY base segment 109 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 110 111 // get SOCLIB_TTY base segment cluster and local pointer 112 cxy_t tty_cxy = GET_CXY( tty_xp ); 113 uint32_t * tty_ptr = GET_PTR( tty_xp ); 114 115 // get TTY channel index and channel base address 116 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 117 uint32_t * base = tty_ptr + TTY_SPAN * channel; 118 119 // block server thread 120 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 121 122 // enable relevant TX_IRQ for a WRITE 123 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 ); 124 125 // deschedule 126 sched_yield( "waiting TXT_TX_ISR completion" ); 127 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) ) 128 printk("\n[DBG] %s : thread %x enter for RX / cycle %d\n", 129 __FUNCTION__ , CURRENT_THREAD , cycle ); 130 #endif 131 132 #if CONFIG_DEBUG_HAL_TXT_TX 133 uint32_t cycle = (uint32_t)hal_get_cycles(); 134 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) ) 135 printk("\n[DBG] %s : thread %x enter for TX / cycle %d\n", 136 __FUNCTION__ , CURRENT_THREAD , cycle ); 137 #endif 138 139 // get TXT device pointers 140 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 141 cxy_t dev_cxy = GET_CXY( dev_xp ); 142 chdev_t * dev_ptr = GET_PTR( dev_xp ); 143 144 // get extended pointer on SOCLIB_TTY base segment 145 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 146 147 // get SOCLIB_TTY base segment cluster and local pointer 148 cxy_t tty_cxy = GET_CXY( tty_xp ); 149 uint32_t * tty_ptr = GET_PTR( tty_xp ); 150 151 // get TTY channel index and channel base address 152 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 153 uint32_t * base = tty_ptr + TTY_SPAN * channel; 154 155 /////////////////////// 156 if( type == TXT_WRITE ) // write bytes to TTY_TX FIFO 157 { 158 fifo = &tty_tx_fifo[channel]; 159 160 done = 0; 161 162 while( done < count ) 163 { 164 if( fifo->sts < TTY_FIFO_DEPTH ) // put one byte to FIFO if TX_FIFO not full 165 { 166 // get one byte from command buffer 167 byte = hal_remote_lb( buf_xp + done ); 168 169 // write byte to FIFO 170 fifo->data[fifo->ptw] = byte; 171 172 // prevent race 173 hal_fence(); 174 175 // update FIFO state 176 fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH; 177 hal_atomic_add( &fifo->sts , 1 ); 178 179 // udate number of bytes moved 180 done++; 181 182 // enable TX_IRQ 183 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 ); 184 } 185 else // block & deschedule if TX_FIFO full 186 { 187 // block on ISR 188 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 189 190 // deschedule 191 sched_yield( "TTY_TX_FIFO full" ); 192 } 193 } 194 195 // set error status in command and return 196 hal_remote_sw( error_xp , 0 ); 127 197 } 128 else if( type == TXT_READ ) // block, and deschedule for a READ 129 { 130 // block server thread 131 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 132 133 // deschedule 134 sched_yield( "waiting TXT_RX_ISR completion" ); 198 /////////////////////////// 199 else if( type == TXT_READ ) // read bytes from TTY_RX FIFO 200 { 201 fifo = &tty_rx_fifo[channel]; 202 203 done = 0; 204 205 while( done < count ) 206 { 207 if( fifo->sts > 0 ) // get byte from FIFO if not empty 208 { 209 // get one byte from FIFO 210 char byte = fifo->data[fifo->ptr]; 211 212 // update FIFO state 213 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 214 hal_atomic_add( &fifo->sts , -1 ); 215 216 // set byte to command buffer 217 hal_remote_sb( buf_xp + done , byte ); 218 219 // udate number of bytes 220 done++; 221 } 222 else // deschedule if FIFO empty 223 { 224 // block on ISR 225 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR ); 226 227 // deschedule 228 sched_yield( "TTY_TX_FIFO_RX empty" ); 229 } 230 } // end while 231 232 // set error status in command 233 hal_remote_sw( error_xp , 0 ); 135 234 } 136 235 else … … 139 238 } 140 239 141 #if CONFIG_DEBUG_HAL_TXT 240 #if CONFIG_DEBUG_HAL_TXT_RX 142 241 cycle = (uint32_t)hal_get_cycles(); 143 if (CONFIG_DEBUG_HAL_TXT < cycle ) 144 printk("\n[DBG] %s : thread %x exit after %s / cycle %d\n", 145 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str( type ) , cycle ); 242 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) ) 243 printk("\n[DBG] %s : thread %x exit after RX / cycle %d\n", 244 __FUNCTION__ , CURRENT_THREAD , cycle ); 245 #endif 246 247 #if CONFIG_DEBUG_HAL_TXT_TX 248 cycle = (uint32_t)hal_get_cycles(); 249 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) ) 250 printk("\n[DBG] %s : thread %x exit after TX / cycle %d\n", 251 __FUNCTION__ , CURRENT_THREAD , cycle ); 146 252 #endif 147 253 … … 155 261 156 262 } // end soclib_tty_cmd() 263 264 ///////////////////////////////////////////////////////////////// 265 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 266 { 267 thread_t * server; // pointer on TXT chdev server thread 268 lid_t server_lid; // local index of core running the server thread 269 uint32_t channel; // TXT chdev channel 270 bool_t is_rx; // TXT chdev direction 271 char byte; // byte value 272 xptr_t owner_xp; // extended pointer on foreground process in owner cluster 273 cxy_t owner_cxy; 274 process_t * owner_ptr; 275 pid_t owner_pid; 276 tty_fifo_t * fifo; // pointer on TTY_TX or TTY_RX FIFO 277 cxy_t tty_cxy; // soclib_tty cluster 278 uint32_t * tty_ptr; // soclib_tty segment base address 279 uint32_t * base; // soclib_tty channel base address 280 xptr_t status_xp; // extended pointer on TTY_STATUS register 281 xptr_t write_xp; // extended pointer on TTY_WRITE register 282 xptr_t read_xp; // extended pointer on TTY_READ register 283 284 // get TXT chdev channel, direction and server thread 285 channel = chdev->channel; 286 is_rx = chdev->is_rx; 287 server = chdev->server; 288 server_lid = server->core->lid; 289 290 #if (CONFIG_DEBUG_SYS_READ & 1) 291 if( is_rx ) enter_tty_isr_read = (uint32_t)hal_get_cycles(); 292 #endif 293 294 #if (CONFIG_DEBUG_SYS_WRITE & 1) 295 if( is_rx == 0 ) enter_tty_isr_write = (uint32_t)hal_get_cycles(); 296 #endif 297 298 #if CONFIG_DEBUG_HAL_TXT_RX 299 uint32_t cycle = (uint32_t)hal_get_cycles(); 300 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx ) 301 printk("\n[DBG] %s : enter for RX / cycle %d\n", __FUNCTION__ , cycle ); 302 #endif 303 304 #if CONFIG_DEBUG_HAL_TXT_TX 305 uint32_t cycle = (uint32_t)hal_get_cycles(); 306 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) ) 307 printk("\n[DBG] %s : enter for TX / cycle %d\n", __FUNCTION__ , cycle ); 308 #endif 309 310 // get SOCLIB_TTY peripheral cluster and local pointer 311 tty_cxy = GET_CXY( chdev->base ); 312 tty_ptr = GET_PTR( chdev->base ); 313 314 // get channel base address 315 base = tty_ptr + TTY_SPAN * channel; 316 317 // get extended pointer on TTY registers 318 status_xp = XPTR( tty_cxy , base + TTY_STATUS ); 319 write_xp = XPTR( tty_cxy , base + TTY_WRITE ); 320 read_xp = XPTR( tty_cxy , base + TTY_READ ); 321 322 /////////////////////////// handle RX ////////////////////// 323 if( is_rx ) 324 { 325 fifo = &tty_rx_fifo[channel]; 326 327 // try to move bytes until TTY_READ register empty 328 while( hal_remote_lw( status_xp ) & TTY_STATUS_RX_FULL ) 329 { 330 // get one byte from TTY_READ register & acknowledge RX_IRQ 331 byte = (char)hal_remote_lb( read_xp ); 332 333 // filter special character ^Z 334 if( byte == 0x1A ) 335 { 336 // get pointers on TXT owner process in owner cluster 337 owner_xp = process_txt_get_owner( channel ); 338 339 // check process exist 340 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 341 "TXT owner process not found\n" ); 342 343 // get relevant infos on owner process 344 owner_cxy = GET_CXY( owner_xp ); 345 owner_ptr = GET_PTR( owner_xp ); 346 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 347 348 // block owner process only if it is not a KSH 349 if( process_get_ppid( owner_xp ) > 1 ) 350 { 351 // send stop signal to owner process 352 process_sigaction( owner_pid , BLOCK_ALL_THREADS ); 353 354 // atomically update owner process termination state 355 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 356 PROCESS_TERM_STOP ); 357 return; 358 } 359 } 360 361 // filter special character ^C 362 if( byte == 0x03 ) 363 { 364 // get pointers on TXT owner process in owner cluster 365 owner_xp = process_txt_get_owner( channel ); 366 367 // check process exist 368 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 369 "TXT owner process not found\n" ); 370 371 // get relevant infos on TXT owner process 372 owner_cxy = GET_CXY( owner_xp ); 373 owner_ptr = GET_PTR( owner_xp ); 374 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 375 376 // kill TXT owner process only if it is not INIT 377 if( owner_pid != 1 ) 378 { 379 // remove process from TXT list 380 process_txt_detach( owner_xp ); 381 382 // mark for delete all processes in all clusters, but the main 383 process_sigaction( owner_pid , DELETE_ALL_THREADS ); 384 385 // get pointer on target process main thread 386 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 387 388 // block main thread 389 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 390 391 // atomically update owner process termination state 392 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 393 PROCESS_TERM_KILL ); 394 return; 395 } 396 } 397 398 // write byte in TTY_RX FIFO if not full / discard byte if full 399 if ( fifo->sts < TTY_FIFO_DEPTH ) 400 { 401 // store byte into FIFO 402 fifo->data[fifo->ptw] = (char)byte; 403 404 // avoid race 405 hal_fence(); 406 407 // update RX_FIFO state 408 fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH; 409 hal_atomic_add( &fifo->sts , 1 ); 410 411 // unblock TXT_RX server thread 412 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 413 414 // send IPI to core running server thread 415 dev_pic_send_ipi( local_cxy , server_lid ); 416 } 417 else 418 { 419 printk("\n[WARNING] %s : TTY_RX_FIFO[%d] full => discard character <%x>\n", 420 __FUNCTION__, channel, (uint32_t)byte ); 421 } 422 } // end while TTY_READ register full 423 424 } // end RX 425 426 /////////////////////// handle TX ///////////////////////////// 427 else 428 { 429 fifo = &tty_tx_fifo[channel]; 430 431 // try to move bytes until TX_FIFO empty 432 while( fifo->sts > 0 ) 433 { 434 // write one byte to TTY_WRITE register if empty / exit while if full 435 if( (hal_remote_lw( status_xp ) & TTY_STATUS_TX_FULL) == 0 ) 436 { 437 // get one byte from TX_FIFO 438 byte = fifo->data[fifo->ptr]; 439 440 // update TX_FIFO state 441 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 442 hal_atomic_add( &fifo->sts , -1 ); 443 444 // write byte to TTY_WRITE register & acknowledge TX_IRQ 445 hal_remote_sb( write_xp , byte ); 446 } 447 } 448 449 // disable TX_IRQ 450 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 ); 451 452 // unblock TXT_TX server thread 453 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 454 455 // send IPI to core running server thread 456 dev_pic_send_ipi( local_cxy , server_lid ); 457 } // end TX 458 459 hal_fence(); 460 461 #if CONFIG_DEBUG_HAL_TXT_RX 462 cycle = (uint32_t)hal_get_cycles(); 463 if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx ) 464 printk("\n[DBG] %s : exit after RX / cycle %d\n", __FUNCTION__, cycle ); 465 #endif 466 467 #if CONFIG_DEBUG_HAL_TXT_TX 468 cycle = (uint32_t)hal_get_cycles(); 469 if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) ) 470 printk("\n[DBG] %s : exit after TX / cycle %d\n", __FUNCTION__, cycle ); 471 #endif 472 473 #if (CONFIG_DEBUG_SYS_READ & 1) 474 if( is_rx ) exit_tty_isr_read = (uint32_t)hal_get_cycles(); 475 #endif 476 477 #if (CONFIG_DEBUG_SYS_WRITE & 1) 478 if( is_rx == 0 ) exit_tty_isr_write = (uint32_t)hal_get_cycles(); 479 #endif 480 481 } // end soclib_tty_isr() 157 482 158 483 ///////////////////////////////////////////////////////////// … … 182 507 xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS ); 183 508 184 // loop on characters (busy waiting strategy)509 // loop on characters (busy waiting policy) 185 510 for( i = 0 ; i < count ; i++ ) 186 511 { … … 199 524 200 525 201 ///////////////////////////////////////////////////////////////// 202 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 203 { 204 uint32_t type; // command type 205 uint32_t count; // number of bytes in buffer 206 xptr_t buf_xp; // extended pointer on buffer 207 xptr_t error_xp; // extended pointer on error field in command 208 xptr_t status_xp; // extended pointer on TTY_STATUS register 209 xptr_t write_xp; // extended pointer on TTY_WRITE register 210 xptr_t read_xp; // extended pointer on TTY_READ register 211 uint32_t status; // TTY terminal status 212 char byte; // read byte 213 xptr_t client_xp; // first client thread in waiting queue 214 cxy_t client_cxy; // firts client thread cluster 215 thread_t * client_ptr; // first client thread pointer 216 pid_t pid; // foreground process identifier 217 xptr_t owner_xp; // extended pointer on foreground process in owner cluster 218 cxy_t owner_cxy; 219 process_t * owner_ptr; 220 uint32_t i; 221 222 #if (CONFIG_DEBUG_SYS_READ & 1) 223 enter_tty_isr_read = (uint32_t)hal_get_cycles(); 224 #endif 225 226 #if (CONFIG_DEBUG_SYS_WRITE & 1) 227 enter_tty_isr_write = (uint32_t)hal_get_cycles(); 228 #endif 229 230 #if CONFIG_DEBUG_HAL_TXT 231 uint32_t cycle = (uint32_t)hal_get_cycles(); 232 if (CONFIG_DEBUG_HAL_TXT < cycle) 233 printk("\n[DBG] %s : enter / cycle %d\n", __FUNCTION__ , cycle ); 234 #endif 235 236 // get extended pointer on chdev queue root 237 xptr_t root_xp = XPTR( local_cxy , &chdev->wait_root ); 238 239 // get chdev channel 240 uint32_t channel = chdev->channel; 241 242 // get first command if queue non empty 243 if( xlist_is_empty( root_xp ) == false ) 244 { 245 // get extended pointer on first client thread 246 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 247 248 // get client thread cluster and local pointer 249 client_cxy = GET_CXY( client_xp ); 250 client_ptr = GET_PTR( client_xp ); 251 252 // get command arguments 253 type = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type ) ); 254 count = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ) ); 255 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) ); 256 error_xp = XPTR( client_cxy , &client_ptr->txt_cmd.error ); 257 } 258 else 259 { 260 type = 0xFFFFFFFF; 261 262 // these lines to avoid a GCC warning 263 count = 0; 264 buf_xp = XPTR_NULL; 265 error_xp = XPTR_NULL; 266 client_cxy = 0; 267 client_ptr = NULL; 268 } 269 270 // get SOCLIB_TTY peripheral cluster and local pointer 271 cxy_t tty_cxy = GET_CXY( chdev->base ); 272 uint32_t * tty_ptr = GET_PTR( chdev->base ); 273 274 // get channel base address 275 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel; 276 277 // get extended pointer on TTY registers 278 status_xp = XPTR( tty_cxy , base + TTY_STATUS ); 279 write_xp = XPTR( tty_cxy , base + TTY_WRITE ); 280 read_xp = XPTR( tty_cxy , base + TTY_READ ); 281 282 // get TTY_STATUS register value 283 status = hal_remote_lw( status_xp ); 284 285 // 1. handle RX if TTY_READ buffer full 286 if( status & TTY_STATUS_RX_FULL ) 287 { 288 // get a byte from TTY_READ / acknowledge RX_IRQ 289 byte = (char)hal_remote_lb( read_xp ); 290 291 // check character value 292 if( byte == 0x1A ) // ^Z => stop onwner process 293 { 294 // get pid of terminal owner process 295 pid = process_get_txt_owner( channel ); 296 297 // get cluster and pointers on owner process descriptor 298 owner_xp = cluster_get_owner_process_from_pid( pid ); 299 owner_cxy = GET_CXY( owner_xp ); 300 owner_ptr = GET_PTR( owner_xp ); 301 302 // send stop signal to owner process 303 process_sigaction( pid , BLOCK_ALL_THREADS ); 304 305 // atomically update owner process termination state 306 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 307 PROCESS_TERM_STOP ); 308 return; 309 } 310 else if( byte == 0x03 ) // ^C => kill owner process 311 { 312 // get pid of terminal owner process 313 pid = process_get_txt_owner( channel ); 314 315 // get cluster and pointers on owner process descriptor 316 owner_xp = cluster_get_owner_process_from_pid( pid ); 317 owner_cxy = GET_CXY( owner_xp ); 318 owner_ptr = GET_PTR( owner_xp ); 319 320 // send kill signal to owner process 321 process_sigaction( pid , DELETE_ALL_THREADS ); 322 323 // atomically update owner process termination state 324 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 325 PROCESS_TERM_KILL ); 326 return; 327 } 328 else if( type == TXT_READ ) // pending TXT_READ 329 { 330 // write character to command buffer 331 hal_remote_sb( buf_xp , byte ); 332 333 // set I/O operation status in command 334 hal_remote_sw( error_xp , 0 ); 335 336 // unblock server thread 337 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 338 } 339 } 340 341 // 3. handle TX if TXT_WRITE 342 if( type == TXT_WRITE ) 343 { 344 // loop on characters 345 for( i = 0 ; i < count ; i++ ) 346 { 347 // get TTY_STATUS 348 status = hal_remote_lw( status_xp ); 349 350 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte 351 { 352 // get one byte from command buffer 353 byte = (char)hal_remote_lb( buf_xp + i ); 354 355 // write byte to TTY_WRITE / acknowledge TX_IRQ 356 hal_remote_sb( write_xp , byte ); 357 } 358 else // TTY_TX full => update command arguments and exit ISR for retry 359 { 360 hal_remote_sw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ), count-i ); 361 hal_remote_swd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ), buf_xp+i ); 362 return; 363 } 364 } 365 366 // set I/O operation status in command 367 hal_remote_sw( error_xp , 0 ); 368 369 // disable TX_IRQ 370 hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 ); 371 372 // unblock server thread 373 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 374 } 375 376 hal_fence(); 377 378 #if CONFIG_DEBUG_HAL_TXT 379 cycle = (uint32_t)hal_get_cycles(); 380 if (CONFIG_DEBUG_HAL_TXT < cycle) 381 printk("\n[DBG] %s : exit after %s / cycle %d\n", 382 __FUNCTION__ , dev_txt_type_str( type ) , cycle ); 383 #endif 384 385 #if (CONFIG_DEBUG_SYS_READ & 1) 386 if( type == TXT_READ) exit_tty_isr_read = (uint32_t)hal_get_cycles(); 387 #endif 388 389 #if (CONFIG_DEBUG_SYS_WRITE & 1) 390 if( type == TXT_WRITE) exit_tty_isr_write = (uint32_t)hal_get_cycles(); 391 #endif 392 393 } // end soclib_tty_isr() 394 526
Note: See TracChangeset
for help on using the changeset viewer.