Changeset 407 for trunk/hal/tsar_mips32/drivers/soclib_tty.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r296 r407 27 27 #include <remote_spinlock.h> 28 28 #include <thread.h> 29 #include <printk.h> 29 30 #include <hal_special.h> 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; 38 #endif 30 39 31 40 /////////////////////////////////////// 32 41 void soclib_tty_init( chdev_t * chdev ) 33 42 { 43 xptr_t reg_xp; 44 34 45 chdev->cmd = &soclib_tty_cmd; 35 46 chdev->isr = &soclib_tty_isr; 36 37 // get extended pointer on TTY-SOCLIB peripheral base address 38 xptr_t tty_xp = chdev->base; 47 chdev->aux = &soclib_tty_aux; 48 49 // get TTY channel and extended pointer on TTY peripheral base address 50 xptr_t tty_xp = chdev->base; 51 uint32_t channel = chdev->channel; 39 52 40 53 // get SOCLIB_TTY device cluster and local pointer … … 42 55 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp ); 43 56 44 // mask both TTY_RX_IRQ and TTY_TX_IRQ 45 hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 ); 57 // reset TTY_RX_IRQ_ENABLE 58 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE ); 59 hal_remote_sw( reg_xp , 0 ); 60 61 // reset TTY_TX_IRQ_ENABLE 62 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE ); 63 hal_remote_sw( reg_xp , 0 ); 46 64 } 47 65 … … 49 67 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp ) 50 68 { 69 70 #if CONFIG_READ_DEBUG 71 enter_tty_cmd = hal_time_stamp(); 72 #endif 73 74 txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread enter / cycle %d\n", 75 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 76 51 77 // get client thread cluster and local pointer 52 78 cxy_t th_cxy = GET_CXY( th_xp ); … … 57 83 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 58 84 85 assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type"); 86 59 87 // get TXT device cluster and local pointer 60 88 cxy_t dev_cxy = GET_CXY( dev_xp ); … … 72 100 uint32_t * base = tty_ptr + TTY_SPAN * channel; 73 101 74 if( type == TXT_READ ) // descheduling strategy for calling thread 102 // compute extended pointer on relevant TTY register 103 xptr_t reg_xp; 104 if( type == TXT_READ ) reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE ); 105 else reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ); 106 107 // enable relevant IRQ : data transfer will be done by the TTY_RX ISR) 108 hal_remote_sw( reg_xp , 1 ); 109 110 txt_dmsg("\n[DBG] %s : core[%x,%d] DEV thread deschedule / cycle %d\n", 111 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 112 113 // Block and deschedule server thread 114 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 115 sched_yield(); 116 117 txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread resume / cycle %d\n", 118 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 119 120 #if CONFIG_READ_DEBUG 121 exit_tty_cmd = hal_time_stamp(); 122 #endif 123 124 } // end soclib_tty_cmd() 125 126 ///////////////////////////////////////////////////////////// 127 void __attribute__ ((noinline)) soclib_tty_aux( void * args ) 128 { 129 uint32_t status; 130 bool_t empty; 131 uint32_t i; 132 133 xptr_t dev_xp = ((txt_aux_t *)args)->dev_xp; 134 char * buffer = ((txt_aux_t *)args)->buffer; 135 uint32_t count = ((txt_aux_t *)args)->count; 136 137 // get TXT0 chdev cluster and local pointer 138 cxy_t dev_cxy = GET_CXY( dev_xp ); 139 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 140 141 // get extended pointer on TTY channel base address 142 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 143 144 // get TTY channel segment cluster and local pointer 145 cxy_t tty_cxy = GET_CXY( tty_xp ); 146 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp ); 147 148 // get extended pointers on TTY_WRITE & TTY_STATUS registers 149 xptr_t write_xp = XPTR( tty_cxy , tty_ptr + TTY_WRITE ); 150 xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS ); 151 152 // loop on characters (busy waiting strategy) 153 for( i = 0 ; i < count ; i++ ) 75 154 { 76 // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR) 77 xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG ); 78 uint32_t old = hal_remote_lw( config_xp ); 79 uint32_t new = old | TTY_CONFIG_RX_ENABLE; 80 hal_remote_atomic_cas( config_xp , old , new ); 81 82 // Block and deschedule server thread 83 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 84 sched_yield( NULL ); 155 do 156 { 157 // get TTY_STATUS 158 status = hal_remote_lw( status_xp ); 159 empty = ( (status & TTY_STATUS_TX_FULL) == 0 ); 160 161 // transfer one byte if TX buffer empty 162 if ( empty ) hal_remote_sb( write_xp , buffer[i] ); 163 } 164 while ( empty == false ); 85 165 } 86 else if( type == TXT_WRITE ) // descheduling strategy for calling thread 87 { 88 // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR) 89 xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG ); 90 uint32_t old = hal_remote_lw( config_xp ); 91 uint32_t new = old | TTY_CONFIG_TX_ENABLE; 92 hal_remote_atomic_cas( config_xp , old , new ); 93 94 // Block and deschedule server thread 95 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 96 sched_yield( NULL ); 97 } 98 else if( type == TXT_SYNC_WRITE ) // busy waiting strategy for calling thread 99 { 100 uint32_t status; 101 bool_t empty; 102 uint32_t i; 103 104 // get source buffer extended pointer & bytes count 105 uint32_t count = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) ); 106 xptr_t buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) ); 107 108 // loop on characters 109 for( i = 0 ; i < count ; i++ ) 110 { 111 do 112 { 113 // get TTY_STATUS_REG 114 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) ); 115 empty = ( (status & TTY_STATUS_TX_FULL) == 0 ); 116 117 if ( empty ) // TTY_TX empty => transfer one byte 118 { 119 // get one byte from command buffer in client cluster 120 char byte = (char)hal_remote_lb( buf_xp + i ); 121 122 // write byte to TTY_WRITE_REG in TTY cluster 123 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte ); 124 } 125 } 126 while ( empty == false ); 127 } 128 } 129 } // end soclib_tty_cmd() 166 } // end soclib_tty_aux() 130 167 131 168 … … 135 172 uint32_t type; // command type 136 173 uint32_t count; // number of bytes in buffer 137 xptr_t buf_xp; // Rextended pointer on buffer 174 xptr_t buf_xp; // extended pointer on buffer 175 xptr_t status_xp; // extended pointer on TTY_STATUS register 176 xptr_t write_xp; // extended pointer on TTY_WRITE register 177 xptr_t read_xp; // extended pointer on TTY_READ register 138 178 uint32_t status; // TTY terminal status 139 179 char byte; // read byte 140 180 uint32_t i; 181 182 #if CONFIG_READ_DEBUG 183 enter_tty_isr = hal_time_stamp(); 184 #endif 141 185 142 186 // get extended pointer on client thread … … 153 197 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) ); 154 198 199 txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n", 200 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() ); 201 155 202 // get SOCLIB_TTY peripheral cluster and local pointer 156 203 cxy_t tty_cxy = GET_CXY( chdev->base ); … … 160 207 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel; 161 208 209 // get extended pointer on TTY registers 210 status_xp = XPTR( tty_cxy , base + TTY_STATUS ); 211 write_xp = XPTR( tty_cxy , base + TTY_WRITE ); 212 read_xp = XPTR( tty_cxy , base + TTY_READ ); 213 162 214 if( type == TXT_READ ) // read one single character 163 215 { 164 // get TTY_STATUS _REG165 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ));166 167 if( status & TTY_STATUS_RX_FULL ) // TTY_RX full => transferone byte168 { 169 // get a byte from TTY_READ _REG, and acknowledge RX_IRQ170 byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ));216 // get TTY_STATUS 217 status = hal_remote_lw( status_xp ); 218 219 if( status & TTY_STATUS_RX_FULL ) // TTY_RX full => move one byte 220 { 221 // get a byte from TTY_READ, and acknowledge RX_IRQ 222 byte = (char)hal_remote_lb( read_xp ); 171 223 172 224 // write it to command buffer 173 225 hal_remote_sb( buf_xp , byte ); 174 175 // update TTY_WRITE_REG if echo mode176 if( CONFIG_TXT_ECHO_MODE )177 {178 if( (byte == '\b') || (byte == 0x7F) )179 {180 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );181 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' ' );182 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );183 }184 else185 {186 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );187 }188 }189 226 } 190 227 else // buffer empty => exit ISR for retry … … 192 229 return; 193 230 } 231 232 // disable RX_IRQ 233 xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE ); 234 hal_remote_sw( reg_xp , 0 ); 194 235 } 195 else if( type == TXT_WRITE ) // write a string236 else if( type == TXT_WRITE ) // write all characters in string 196 237 { 197 238 // loop on characters 198 239 for( i = 0 ; i < count ; i++ ) 199 240 { 200 // get TTY_STATUS _REG201 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ));202 203 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transferone byte241 // get TTY_STATUS 242 status = hal_remote_lw( status_xp ); 243 244 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte 204 245 { 205 246 // get one byte from command buffer 206 247 byte = (char)hal_remote_lb( buf_xp + i ); 207 248 208 // write byte to TTY_WRITE _REG, and acknowledge TX_IRQ209 hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ), byte );249 // write byte to TTY_WRITE, and acknowledge TX_IRQ 250 hal_remote_sb( write_xp , byte ); 210 251 } 211 252 else // TTY_TX full => update command arguments and exit ISR for retry … … 216 257 } 217 258 } 259 260 // disable TX_IRQ 261 xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ); 262 hal_remote_sw( reg_xp , 0 ); 218 263 } 219 264 220 265 // The I/O operation completed when we reach this point 221 222 // mask both TTY_RX_IRQ and TTY_TX_IRQ223 hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );224 266 225 267 // set I/O operation status in command … … 227 269 228 270 // unblock server thread 229 thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );271 thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR ); 230 272 231 273 // unblock client thread 232 274 thread_unblock( client_xp , THREAD_BLOCKED_IO ); 233 275 276 hal_fence(); 277 278 txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n", 279 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 280 281 #if CONFIG_READ_DEBUG 282 exit_tty_isr = hal_time_stamp(); 283 #endif 284 234 285 } // end soclib_tty_isr() 235 286
Note: See TracChangeset
for help on using the changeset viewer.