Changeset 76 for trunk/hal/x86_64/drivers/soclib_tty.c
- Timestamp:
- Jun 27, 2017, 2:07:55 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/x86_64/drivers/soclib_tty.c
r75 r76 29 29 #include <hal_special.h> 30 30 31 ///////////////////////////////////////32 31 void soclib_tty_init( chdev_t * chdev ) 33 32 { 34 // get extended pointer on TTY-SOCLIB peripheral base address35 xptr_t tty_xp = chdev->base;36 33 37 // get SOCLIB_TTY device cluster and local pointer38 cxy_t tty_cxy = GET_CXY( tty_xp );39 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );40 41 // mask both TTY_RX_IRQ and TTY_TX_IRQ42 hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 );43 34 } 44 35 45 //////////////////////////////////////////////////////////////46 36 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp ) 47 37 { 48 // get client thread cluster and local pointer49 cxy_t th_cxy = GET_CXY( th_xp );50 thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );51 38 52 // get command type and extended pointer on TXT device53 uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.txt.type ) );54 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.txt.dev_xp ) );55 56 // get TXT device cluster and local pointer57 cxy_t dev_cxy = GET_CXY( dev_xp );58 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );59 60 // get extended pointer on SOCLIB_TTY base segment61 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );62 63 // get SOCLIB_TTY base segment cluster and local pointer64 cxy_t tty_cxy = GET_CXY( tty_xp );65 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );66 67 // get TTY channel index and channel base address68 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );69 uint32_t * base = tty_ptr + TTY_SPAN * channel;70 71 if( type == TXT_READ ) // descheduling strategy for calling thread72 {73 // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR)74 xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );75 uint32_t old = hal_remote_lw( config_xp );76 uint32_t new = old | TTY_CONFIG_RX_ENABLE;77 hal_remote_atomic_cas( config_xp , old , new );78 79 // Block and deschedule server thread80 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );81 sched_yield();82 }83 else if( type == TXT_WRITE ) // descheduling strategy for calling thread84 {85 // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR)86 xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );87 uint32_t old = hal_remote_lw( config_xp );88 uint32_t new = old | TTY_CONFIG_TX_ENABLE;89 hal_remote_atomic_cas( config_xp , old , new );90 91 // Block and deschedule server thread92 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );93 sched_yield();94 }95 else if( type == TXT_SYNC_WRITE ) // busy waiting strategy for calling thread96 {97 uint32_t status;98 bool_t empty;99 uint32_t i;100 101 // get source buffer extended pointer & bytes count102 uint32_t count = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.txt.count ) );103 xptr_t buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.txt.buf_xp ) );104 105 // loop on characters106 for( i = 0 ; i < count ; i++ )107 {108 do109 {110 // get TTY_STATUS_REG111 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );112 empty = ( (status & TTY_STATUS_TX_FULL) == 0 );113 114 if ( empty ) // TTY_TX empty => transfer one byte115 {116 // get one byte from command buffer in client cluster117 char byte = (char)hal_remote_lb( buf_xp + i );118 119 // write byte to TTY_WRITE_REG in TTY cluster120 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );121 }122 }123 while ( empty == false );124 }125 }126 39 } 127 40 128 /////////////////////////////////////////////////////////////////129 41 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev ) 130 42 { 131 uint32_t type; // command type132 uint32_t count; // number of bytes in buffer133 xptr_t buf_xp; // Rextended pointer on buffer134 uint32_t status; // TTY terminal status135 char byte; // read byte136 uint32_t i;137 43 138 // get extended pointer on client thread139 xptr_t root = XPTR( local_cxy , &chdev->wait_root );140 xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );141 142 // get client thread cluster and local pointer143 cxy_t client_cxy = GET_CXY( client_xp );144 thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );145 146 // get command arguments147 type = hal_remote_lw ( XPTR( client_cxy , &client_ptr->command.txt.type ) );148 count = hal_remote_lw ( XPTR( client_cxy , &client_ptr->command.txt.count ) );149 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->command.txt.buf_xp ) );150 151 // get SOCLIB_TTY peripheral cluster and local pointer152 cxy_t tty_cxy = GET_CXY( chdev->base );153 uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );154 155 // get channel base address156 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;157 158 if( type == TXT_READ ) // read one single character159 {160 // get TTY_STATUS_REG161 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );162 163 if( status & TTY_STATUS_RX_FULL ) // TTY_RX full => transfer one byte164 {165 // get a byte from TTY_READ_REG, and acknowledge RX_IRQ166 byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ) );167 168 // write it to command buffer169 hal_remote_sb( buf_xp , byte );170 171 // update TTY_WRITE_REG if echo mode172 if( CONFIG_TXT_ECHO_MODE )173 {174 if( (byte == '\b') || (byte == 0x7F) )175 {176 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );177 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' ' );178 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );179 }180 else181 {182 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );183 }184 }185 }186 else // buffer empty => exit ISR for retry187 {188 return;189 }190 }191 else if( type == TXT_WRITE ) // write a string192 {193 // loop on characters194 for( i = 0 ; i < count ; i++ )195 {196 // get TTY_STATUS_REG197 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );198 199 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transfer one byte200 {201 // get one byte from command buffer202 byte = (char)hal_remote_lb( buf_xp + i );203 204 // write byte to TTY_WRITE_REG, and acknowledge TX_IRQ205 hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ) , byte );206 }207 else // TTY_TX full => update command arguments and exit ISR for retry208 {209 hal_remote_sw ( XPTR( client_cxy , &client_ptr->command.txt.count ), count-i );210 hal_remote_swd( XPTR( client_cxy , &client_ptr->command.txt.buf_xp ), buf_xp+i );211 return;212 }213 }214 }215 216 // The I/O operation completed when we reach this point217 218 // mask both TTY_RX_IRQ and TTY_TX_IRQ219 hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );220 221 // set I/O operation status in command222 hal_remote_sw( XPTR( client_cxy , &client_ptr->command.txt.error ) , 0 );223 224 // unblock server thread225 thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );226 227 // unblock client thread228 thread_unblock( client_xp , THREAD_BLOCKED_IO );229 44 } 230 45
Note: See TracChangeset
for help on using the changeset viewer.