Changeset 435 for trunk/hal/tsar_mips32/drivers
- Timestamp:
- Feb 20, 2018, 5:32:17 PM (7 years ago)
- Location:
- trunk/hal/tsar_mips32/drivers
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/drivers/soclib_pic.c
r432 r435 130 130 &pti_status ); 131 131 132 irq_dmsg("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / PTI = %x\n", 133 __FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status ); 132 #if CONFIG_DEBUG_HAL_IRQS 133 uint32_t cycle = (uint32_t)hal_get_cycles(); 134 if (CONFIG_DEBUG_HAL_IRQS < cycle ) 135 printk("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / PTI = %x / cycle %d\n", 136 __FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status, cycle ); 137 #endif 134 138 135 139 // analyse status and handle up to 3 pending IRQ (one WTI, one HWI, one PTI) … … 143 147 assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" ); 144 148 145 irq_dmsg("\n[DBG] %s : core[%x,%d] received an IPI / cycle %d\n", 146 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() ); 147 149 #if CONFIG_DEBUG_HAL_IRQS 150 if (CONFIG_DEBUG_HAL_IRQS < cycle ) 151 printk("\n[DBG] %s : core[%x,%d] received an IPI\n", __FUNCTION__ , local_cxy , core->lid ); 152 #endif 148 153 // acknowledge WTI (this require an XCU read) 149 154 uint32_t ack = xcu_base[(XCU_WTI_REG << 5) | core->lid]; … … 171 176 else // call relevant ISR 172 177 { 173 irq_dmsg("\n[DBG] %s : core[%x,%d] received external WTI %d / cycle %d\n", 174 __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() ); 175 178 179 #if CONFIG_DEBUG_HAL_IRQS 180 if (CONFIG_DEBUG_HAL_IRQS < cycle ) 181 printk("\n[DBG] %s : core[%x,%d] received external WTI %d\n", 182 __FUNCTION__ , local_cxy , core->lid , index ); 183 #endif 176 184 // call ISR 177 185 src_chdev->isr( src_chdev ); … … 199 207 else // call relevant ISR 200 208 { 201 irq_dmsg("\n[DBG] %s : core[%x,%d] received HWI %d / cycle %d\n", 202 __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() ); 203 209 210 #if CONFIG_DEBUG_HAL_IRQS 211 if (CONFIG_DEBUG_HAL_IRQS < cycle ) 212 printk("\n[DBG] %s : core[%x,%d] received HWI %d\n", 213 __FUNCTION__ , local_cxy , core->lid , index ); 214 #endif 204 215 // call ISR 205 216 src_chdev->isr( src_chdev ); … … 211 222 index = pti_status - 1; 212 223 213 irq_dmsg("\n[DBG] %s : core[%x,%d] received PTI %d / cycle %d\n",214 __FUNCTION__ , core->lid , local_cxy , index , hal_time_stamp() );215 216 224 assert( (index == core->lid) , __FUNCTION__ , "unconsistent PTI index\n"); 217 225 226 #if CONFIG_DEBUG_HAL_IRQS 227 if (CONFIG_DEBUG_HAL_IRQS < cycle ) 228 printk("\n[DBG] %s : core[%x,%d] received PTI %d\n", 229 __FUNCTION__ , core->lid , local_cxy , index ); 230 #endif 218 231 // acknowledge PTI (this require a read access to XCU) 219 232 uint32_t ack = xcu_base[(XCU_PTI_ACK << 5) | core->lid]; … … 345 358 chdev_t * src_chdev ) 346 359 { 360 361 #if CONFIG_DEBUG_HAL_IRQS 362 uint32_t cycle = (uint32_t)hal_get_cycles(); 363 if( CONFIG_DEBUG_HAL_IRQS < cycle ) 364 printk("\n[DBG] %s : thread %x enter for core[%x,%d] / cycle %d\n", 365 __FUNCTION__ , CURRENT_THREAD , local_cxy , lid , cycle ); 366 #endif 367 347 368 // get extended & local pointers on PIC chdev descriptor 348 369 xptr_t pic_xp = chdev_dir.pic; … … 401 422 ((soclib_pic_core_t *)core->pic_extend)->wti_vector[wti_id] = src_chdev; 402 423 403 pic_dmsg("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n", 424 #if CONFIG_DEBUG_HAL_IRQS 425 if( CONFIG_DEBUG_HAL_IRQS < cycle ) 426 printk("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n", 404 427 __FUNCTION__ , chdev_func_str( func ) , channel , is_rx , hwi_id , wti_id , local_cxy ); 428 #endif 405 429 406 430 } … … 420 444 ((soclib_pic_core_t *)core->pic_extend)->wti_vector[hwi_id] = src_chdev; 421 445 422 pic_dmsg("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n", 446 #if CONFIG_DEBUG_HAL_IRQS 447 if( CONFIG_DEBUG_HAL_IRQS < cycle ) 448 printk("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n", 423 449 __FUNCTION__ , chdev_func_str( func ) , channel , hwi_id , local_cxy ); 450 #endif 424 451 425 452 } -
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r432 r435 30 30 #include <hal_special.h> 31 31 32 #if CONFIG_READ_DEBUG 33 extern uint32_t enter_tty_cmd; 34 extern uint32_t exit_tty_cmd; 35 36 extern uint32_t enter_tty_isr; 37 extern uint32_t exit_tty_isr; 32 #if (CONFIG_DEBUG_SYS_READ & 1) 33 extern uint32_t enter_tty_cmd_read; 34 extern uint32_t exit_tty_cmd_read; 35 36 extern uint32_t enter_tty_isr_read; 37 extern uint32_t exit_tty_isr_read; 38 #endif 39 40 #if (CONFIG_DEBUG_SYS_WRITE & 1) 41 extern uint32_t enter_tty_cmd_write; 42 extern uint32_t exit_tty_cmd_write; 43 44 extern uint32_t enter_tty_isr_write; 45 extern uint32_t exit_tty_isr_write; 38 46 #endif 39 47 … … 53 61 // get SOCLIB_TTY device cluster and local pointer 54 62 cxy_t tty_cxy = GET_CXY( tty_xp ); 55 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );56 57 // reset TTY_RX_IRQ_ENABLE63 uint32_t * tty_ptr = GET_PTR( tty_xp ); 64 65 // set TTY_RX_IRQ_ENABLE 58 66 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE ); 59 hal_remote_sw( reg_xp , 0);67 hal_remote_sw( reg_xp , 1 ); 60 68 61 69 // reset TTY_TX_IRQ_ENABLE … … 68 76 { 69 77 70 #if CONFIG_READ_DEBUG 71 enter_tty_cmd = hal_time_stamp(); 72 #endif 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 85 86 // get client thread cluster and local pointer 87 cxy_t th_cxy = GET_CXY( th_xp ); 88 thread_t * th_ptr = GET_PTR( th_xp ); 89 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 ) ); 73 92 74 93 #if CONFIG_DEBUG_HAL_TXT 75 94 uint32_t cycle = (uint32_t)hal_get_cycles(); 76 95 if (CONFIG_DEBUG_HAL_TXT < cycle ) 77 printk("\n[DBG] %s : thread %x enter / cycle %d\n", 78 __FUNCTION__ , CURRENT_THREAD , cycle ); 79 #endif 80 81 // get client thread cluster and local pointer 82 cxy_t th_cxy = GET_CXY( th_xp ); 83 thread_t * th_ptr = (thread_t *)GET_PTR( th_xp ); 84 85 // get command type and extended pointer on TXT device 86 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 87 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 88 89 assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type"); 90 91 // get TXT device cluster and local pointer 92 cxy_t dev_cxy = GET_CXY( dev_xp ); 93 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 94 95 // get extended pointer on SOCLIB_TTY base segment 96 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 97 98 // get SOCLIB_TTY base segment cluster and local pointer 99 cxy_t tty_cxy = GET_CXY( tty_xp ); 100 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp ); 101 102 // get TTY channel index and channel base address 103 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 104 uint32_t * base = tty_ptr + TTY_SPAN * channel; 105 106 // compute extended pointer on relevant TTY register 107 xptr_t reg_xp; 108 if( type == TXT_READ ) reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE ); 109 else reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ); 110 111 // enable relevant IRQ : data transfer will be done by the TTY_RX ISR) 112 hal_remote_sw( reg_xp , 1 ); 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 } 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" ); 135 } 136 else 137 { 138 assert( false , __FUNCTION__ , "illegal TXT command\n" ); 139 } 113 140 114 141 #if CONFIG_DEBUG_HAL_TXT 115 142 cycle = (uint32_t)hal_get_cycles(); 116 143 if (CONFIG_DEBUG_HAL_TXT < cycle ) 117 printk("\n[DBG] %s : thread %x deschedule / cycle %d\n", 118 __FUNCTION__ , CURRENT_THREAD , cycle ); 119 #endif 120 121 // Block and deschedule server thread 122 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 123 sched_yield("blocked on ISR"); 124 125 #if CONFIG_DEBUG_HAL_TXT 126 cycle = (uint32_t)hal_get_cycles(); 127 if (CONFIG_DEBUG_HAL_TXT < cycle ) 128 printk("\n[DBG] %s : thread %x resume / cycle %d\n", 129 __FUNCTION__ , CURRENT_THREAD , cycle ); 130 #endif 131 132 #if CONFIG_READ_DEBUG 133 exit_tty_cmd = hal_time_stamp(); 144 printk("\n[DBG] %s : thread %x exit after %s / cycle %d\n", 145 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str( type ) , cycle ); 146 #endif 147 148 #if (CONFIG_DEBUG_SYS_READ & 1) 149 if( type == TXT_READ ) exit_tty_cmd_read = (uint32_t)hal_get_cycles(); 150 #endif 151 152 #if (CONFIG_DEBUG_SYS_WRITE & 1) 153 if( type == TXT_WRITE ) exit_tty_cmd_write = (uint32_t)hal_get_cycles(); 134 154 #endif 135 155 … … 143 163 uint32_t i; 144 164 145 xptr_t dev_xp = ((txt_ aux_t *)args)->dev_xp;146 char * buffer = ((txt_ aux_t *)args)->buffer;147 uint32_t count = ((txt_ aux_t *)args)->count;165 xptr_t dev_xp = ((txt_sync_args_t *)args)->dev_xp; 166 char * buffer = ((txt_sync_args_t *)args)->buffer; 167 uint32_t count = ((txt_sync_args_t *)args)->count; 148 168 149 169 // get TXT0 chdev cluster and local pointer … … 182 202 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 183 203 { 184 uint32_t type; // command type 185 uint32_t count; // number of bytes in buffer 186 xptr_t buf_xp; // extended pointer on buffer 187 xptr_t status_xp; // extended pointer on TTY_STATUS register 188 xptr_t write_xp; // extended pointer on TTY_WRITE register 189 xptr_t read_xp; // extended pointer on TTY_READ register 190 uint32_t status; // TTY terminal status 191 char byte; // read byte 192 uint32_t i; 193 194 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1) 195 enter_tty_isr = hal_time_stamp(); 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(); 196 228 #endif 197 229 … … 202 234 #endif 203 235 204 // get extended pointer on client thread 205 xptr_t root = XPTR( local_cxy , &chdev->wait_root ); 206 xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list ); 207 208 // get client thread cluster and local pointer 209 cxy_t client_cxy = GET_CXY( client_xp ); 210 thread_t * client_ptr = (thread_t *)GET_PTR( client_xp ); 211 212 // get command arguments 213 type = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type ) ); 214 count = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ) ); 215 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) ); 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 } 216 269 217 270 // get SOCLIB_TTY peripheral cluster and local pointer 218 271 cxy_t tty_cxy = GET_CXY( chdev->base ); 219 uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );272 uint32_t * tty_ptr = GET_PTR( chdev->base ); 220 273 221 274 // get channel base address … … 227 280 read_xp = XPTR( tty_cxy , base + TTY_READ ); 228 281 229 if( type == TXT_READ ) // read one single character 230 { 231 // get TTY_STATUS 232 status = hal_remote_lw( status_xp ); 233 234 if( status & TTY_STATUS_RX_FULL ) // TTY_RX full => move one byte 235 { 236 // get a byte from TTY_READ, and acknowledge RX_IRQ 237 byte = (char)hal_remote_lb( read_xp ); 238 239 // write it to command buffer 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 240 331 hal_remote_sb( buf_xp , byte ); 241 } 242 else // buffer empty => exit ISR for retry243 {244 return; 245 }246 247 // disable RX_IRQ248 xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );249 hal_remote_sw( reg_xp , 0 ); 250 }251 else // type == TXT_WRITE // write all characters in string332 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 ) 252 343 { 253 344 // loop on characters … … 262 353 byte = (char)hal_remote_lb( buf_xp + i ); 263 354 264 // write byte to TTY_WRITE , andacknowledge TX_IRQ355 // write byte to TTY_WRITE / acknowledge TX_IRQ 265 356 hal_remote_sb( write_xp , byte ); 266 357 } … … 273 364 } 274 365 366 // set I/O operation status in command 367 hal_remote_sw( error_xp , 0 ); 368 275 369 // disable TX_IRQ 276 xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ); 277 hal_remote_sw( reg_xp , 0 ); 278 } 279 280 // The I/O operation completed when we reach this point 281 282 // set I/O operation status in command 283 hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 ); 284 285 // unblock server thread 286 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 287 288 // unblock client thread 289 // thread_unblock( client_xp , THREAD_BLOCKED_IO ); 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 } 290 375 291 376 hal_fence(); … … 294 379 cycle = (uint32_t)hal_get_cycles(); 295 380 if (CONFIG_DEBUG_HAL_TXT < cycle) 296 { 297 if( type == TXT_READ) 298 printk("\n[DBG] %s : exit after RX / cycle %d\n", __FUNCTION__ , cycle ); 299 else 300 printk("\n[DBG] %s : exit after TX / cycle %d\n", __FUNCTION__ , cycle ); 301 } 302 #endif 303 304 #if (CONFIG_ READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)305 exit_tty_isr = hal_time_stamp();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(); 306 391 #endif 307 392 308 393 } // end soclib_tty_isr() 309 394 310 /*311 /////////////////////////////////////////////////////////////////312 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )313 {314 xptr_t root_xp; // extended pointer on command list root315 xptr_t client_xp; // extended pointer on client thread316 cxy_t client_cxy; // client thread cluster317 thread_t * client_ptr; // client_thread local pointer318 uint32_t type; // command type319 uint32_t count; // number of bytes in buffer320 xptr_t buf_xp; // extended pointer on buffer321 xptr_t status_xp; // extended pointer on TTY_STATUS register322 xptr_t write_xp; // extended pointer on TTY_WRITE register323 xptr_t read_xp; // extended pointer on TTY_READ register324 uint32_t status; // TTY terminal status325 char byte; // read byte326 uint32_t i;327 328 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)329 enter_tty_isr = hal_time_stamp();330 #endif331 332 txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n",333 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() );334 335 // get SOCLIB_TTY peripheral cluster and local pointer336 cxy_t tty_cxy = GET_CXY( chdev->base );337 uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );338 339 // get channel base address340 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;341 342 // get extended pointer on TTY registers343 status_xp = XPTR( tty_cxy , base + TTY_STATUS );344 write_xp = XPTR( tty_cxy , base + TTY_WRITE );345 read_xp = XPTR( tty_cxy , base + TTY_READ );346 347 // get TTY_STATUS348 status = hal_remote_lw( status_xp );349 350 // get extended pointer on the command list root351 root_xp = XPTR( local_cxy , &chdev->wait_root );352 353 // get extended pointer on client thread354 if(xlist_is_empty(root_xp)) client_xp = XLIST_FIRST_ELEMENT(root, thread_t, wait_list);355 else client_xp = XPTR_NULL;356 357 if( client_xp )358 {359 // get client thread cluster and local pointer360 client_cxy = GET_CXY( client_xp );361 client_ptr = (thread_t *)GET_PTR( client_xp );362 363 // get command arguments364 type = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type ) );365 count = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ) );366 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );367 }368 369 ///////////// handle RX if TTY_RX full370 if( status & TTY_STATUS_RX_FULL )371 {372 // get a byte from TTY_READ, and acknowledge RX_IRQ373 byte = (char)hal_remote_lb( read_xp );374 375 // FIXME The RX_IRQ must be always enabled !!!376 // xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );377 // hal_remote_sw( reg_xp , 0 );378 379 // analyse received character380 switch( byte )381 {382 case CONTROL_C: // SIGINT to process383 case CONTROL_D:384 {385 // TODO SIGINT386 return387 }388 break;389 default:390 {391 if( (type == TXT_READ) && (client_xp != XPTR_NULL) )392 {393 // write byte to command buffer394 hal_remote_sb( buf_xp , byte );395 396 // set status in command397 hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 );398 399 hal_fence();400 401 // unblock server thread402 thread_unblock( XPTR(local_cxy,chdev->server), THREAD_BLOCKED_DEV_ISR );403 }404 else // discard byte405 {406 // TODO WARNING407 return408 }409 }410 }411 } // end RX handling412 413 //////////////// handle TX if WRITE command pending414 if( (type == TXT_WRITE) && (client_xp != XPTR_NULL) )415 {416 // loop on characters417 for( i = 0 ; i < count ; i++ )418 {419 // get TTY_STATUS420 status = hal_remote_lw( status_xp );421 422 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte423 {424 // get one byte from command buffer425 byte = (char)hal_remote_lb( buf_xp + i );426 427 // write byte to TTY_WRITE, and acknowledge TX_IRQ428 hal_remote_sb( write_xp , byte );429 }430 else // TTY_TX full => update command arguments and exit ISR for retry431 {432 hal_remote_sw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ), count-i );433 hal_remote_swd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ), buf_xp+i );434 return;435 }436 }437 438 // disable TX_IRQ439 xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );440 hal_remote_sw( reg_xp , 0 );441 442 // set I/O operation status in command443 hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 );444 445 hal_fence();446 447 // unblock server thread448 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );449 450 } // end TX handling451 452 txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n",453 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );454 455 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)456 exit_tty_isr = hal_time_stamp();457 #endif458 459 } // end soclib_tty_isr()460 461 */ -
trunk/hal/tsar_mips32/drivers/soclib_tty.h
r424 r435 28 28 29 29 /**************************************************************************************** 30 * This driver supports the soclib_multi_ttycomponent.30 * This driver supports the vci_tty_tsar component. 31 31 * It implements the generic TXT device API: 32 32 * - transfer one single character from TTY to command "buffer" if to_mem is non-zero. … … 62 62 63 63 /**************************************************************************************** 64 * This function implements the TXT_READ & TXT_WRITE commands registered in the client 65 * thread descriptor (in the txt_cmd field), identified by the <xp_thread> argument. 66 * Depending on the command type, it only unmasks the relevant TTY_RX / TTY_TX IRQ, 64 * This function implements both the TXT_READ & TXT_WRITE commands registered in the 65 * client thread descriptor (in the txt_cmd field), even if ALMOS-MKH defines two 66 * different chdevs (and consequently two diffeerent server threads) for the RX and TX 67 * directions. The client thread is identified by the <thread_xp> argument. 68 * Depending on the command type, it unmasks the relevant TTY_RX / TTY_TX IRQ, 67 69 * and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the data 68 70 * transfer is done by the ISR. … … 83 85 84 86 /**************************************************************************************** 85 * This ISR is executed to handle both the TTY_TX_IRQ and the TTY_RX_IRQ. 86 * - the TTY_RX_IRQ is activated as soon as the TTY_STATUS_RX_FULL bit is set in the 87 * TTY status register, indicating a character registered in the TTY_READ register. 87 * This ISR is executed to handle both the TTY_TX_IRQ and the TTY_RX_IRQ, even if 88 * The RX_IRQ is activated as soon as the TTY_STATUS_RX_FULL bit is 1 in the 89 * TTY_STATUS register, when the TTY_RX_IRQ_ENABLE is non zero, indicating that 90 * the TTY_READ buffer is full and can be read. 91 * The TX_IRQ is activated as soon as the TTY_STATUS_TX_FULL bit is 0 in the 92 * TTY_STATUS register, when the TTY_TX_IRQ_ENABLE is non zero, indicating that 93 * the TTY_WRITE buffer is empty, and can be written. 94 * WARNING : In ALMOS-MKH, the RX_IRQ is always enabled to catch the control signals, 95 * but the TX_IRQ is dynamically enabled by the TXT_WRITE command, and disabled when 96 * the command is completed. 88 97 * 89 * . if it exist a TXT_READ command registered in the command queue, and thit copies the 98 * 1) The ISR first read the TTY_STATUS to get the current state of the TTY_READ and 99 * the TTY_WRITE buffers. 100 * 101 * 2) It try to read the first command registered in the server thread queue associated 102 * to the TTY channel 103 * 104 * 2) The ISR handles the RX when the TTY_READ buffer is full : 105 * . it read the available character from the TTY_READ buffer, and this 106 * acknowledges the RX_IRQ. 107 * . if it is a control character ( ^C / ^D / ^Z ) it translate it to the proper 108 * signal and execute the relevant sigaction for the foreground process. 109 * . if it is a normal character, it try to get the first command registered in the 110 * server thread queue. If it is a TXT_READ, it returns this character to the 111 * command buffer in the client thread. 112 * 113 * 3) The ISR handles the TX when the TTY_WRITE buffer is empty and a TXT_WRITE 114 * . it try to get it copies the 90 115 * character to the command buffer, acknowledges the TTY_RX_IRQ, and unblock the 91 116 * associated server thread. 92 117 93 * . the control characters are directly handled by the txt ^C / ^D / and the this IRQ ca 94 * 118 * . the control characters ^C / ^D / ^Z are directly handled by the ISR and 119 * translated to the foreground process. 120 121 * - the 95 122 the TXT_READ and TXT_WRITE commands. 96 123 * It gets the command arguments from the first client thread in the TXT chdev queue:
Note: See TracChangeset
for help on using the changeset viewer.