Changeset 570 for trunk/hal/tsar_mips32/drivers
- Timestamp:
- Oct 5, 2018, 12:08:35 AM (6 years ago)
- Location:
- trunk/hal/tsar_mips32/drivers
- Files:
-
- 9 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/drivers/soclib_bdv.c
r492 r570 28 28 #include <printk.h> 29 29 #include <thread.h> 30 #include <spinlock.h>31 30 32 31 /////////////////////////////////////// … … 45 44 46 45 // get block_size and block_count 47 uint32_t block_size = hal_remote_l w( XPTR( bdv_cxy , bdv_ptr + BDV_BLOCK_SIZE_REG ) );48 uint32_t block_count = hal_remote_l w( XPTR( bdv_cxy , bdv_ptr + BDV_SIZE_REG ) );46 uint32_t block_size = hal_remote_l32( XPTR( bdv_cxy , bdv_ptr + BDV_BLOCK_SIZE_REG ) ); 47 uint32_t block_count = hal_remote_l32( XPTR( bdv_cxy , bdv_ptr + BDV_SIZE_REG ) ); 49 48 50 49 // set IOC device descriptor extension … … 69 68 70 69 // get command arguments and extended pointer on IOC device 71 cmd_type = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.type ) );72 lba = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.lba ) );73 count = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.count ) );74 buf_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) );75 ioc_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) );70 cmd_type = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.type ) ); 71 lba = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.lba ) ); 72 count = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.count ) ); 73 buf_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) ); 74 ioc_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) ); 76 75 77 76 #if DEBUG_HAL_IOC_RX … … 94 93 95 94 // get cluster and pointers for SOCLIB-BDV peripheral segment base 96 xptr_t seg_xp = (xptr_t)hal_remote_l wd( XPTR( ioc_cxy , &ioc_ptr->base ) );95 xptr_t seg_xp = (xptr_t)hal_remote_l64( XPTR( ioc_cxy , &ioc_ptr->base ) ); 97 96 cxy_t seg_cxy = GET_CXY( seg_xp ); 98 97 uint32_t * seg_ptr = GET_PTR( seg_xp ); … … 108 107 109 108 // set SOCLIB_BDV registers to start one I/O operation 110 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_IRQ_ENABLE_REG ) , 1 );111 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_REG ) , buf_lsb );112 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_EXT_REG ) , buf_msb );113 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_LBA_REG ) , lba );114 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_COUNT_REG ) , count );115 hal_remote_s w( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op );109 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_IRQ_ENABLE_REG ) , 1 ); 110 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_REG ) , buf_lsb ); 111 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_EXT_REG ) , buf_msb ); 112 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_LBA_REG ) , lba ); 113 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_COUNT_REG ) , count ); 114 hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op ); 116 115 117 116 // waiting policy depends on the command type … … 124 123 while (1) 125 124 { 126 status = hal_remote_l w( XPTR( seg_cxy , seg_ptr + BDV_STATUS_REG ) );125 status = hal_remote_l32( XPTR( seg_cxy , seg_ptr + BDV_STATUS_REG ) ); 127 126 128 127 if( status == BDV_READ_SUCCESS ) // successfully completed 129 128 { 130 hal_remote_s w( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 );129 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 ); 131 130 break; 132 131 } … … 137 136 else // error reported 138 137 { 139 hal_remote_s w( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 );138 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 ); 140 139 break; 141 140 } … … 174 173 // get extended pointer on client thread 175 174 xptr_t root = XPTR( local_cxy , &chdev->wait_root ); 176 xptr_t client_xp = XLIST_FIRST _ELEMENT( root , thread_t , wait_list );175 xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list ); 177 176 178 177 // get extended pointer on server thread … … 184 183 185 184 // get command type 186 uint32_t cmd_type = hal_remote_l w( XPTR( client_cxy , &client_ptr->ioc_cmd.type ) );185 uint32_t cmd_type = hal_remote_l32( XPTR( client_cxy , &client_ptr->ioc_cmd.type ) ); 187 186 188 187 // get SOCLIB_BDV device cluster and local pointer … … 191 190 192 191 // get BDV status register and acknowledge IRQ 193 uint32_t status = hal_remote_l w( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) );192 uint32_t status = hal_remote_l32( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) ); 194 193 195 194 if( cmd_type == IOC_READ ) … … 223 222 224 223 // set operation status in command 225 hal_remote_s w( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , error );224 hal_remote_s32( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , error ); 226 225 227 226 // unblock server thread -
trunk/hal/tsar_mips32/drivers/soclib_dma.c
r451 r570 40 40 41 41 // enable interrupts 42 hal_remote_s w( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 0 );42 hal_remote_s32( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 0 ); 43 43 44 44 } // soclib_dma_init() … … 57 57 58 58 // get command arguments and extended pointer on DMA device 59 dev_xp = (xptr_t)hal_remote_l wd( XPTR( thread_cxy , &thread_ptr->dma_cmd.dev_xp ) );60 dst_xp = (xptr_t)hal_remote_l wd( XPTR( thread_cxy , &thread_ptr->dma_cmd.dst_xp ) );61 src_xp = (xptr_t)hal_remote_l wd( XPTR( thread_cxy , &thread_ptr->dma_cmd.src_xp ) );62 size = hal_remote_l w( XPTR( thread_cxy , &thread_ptr->dma_cmd.size ) );59 dev_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.dev_xp ) ); 60 dst_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.dst_xp ) ); 61 src_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.src_xp ) ); 62 size = hal_remote_l32 ( XPTR( thread_cxy , &thread_ptr->dma_cmd.size ) ); 63 63 64 64 // get DMA device cluster and local pointer … … 67 67 68 68 // get extended pointer on SOCLIB-DMA peripheral 69 xptr_t dma_xp = hal_remote_l w( XPTR( dev_cxy , &dev_ptr->base ) );69 xptr_t dma_xp = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->base ) ); 70 70 71 71 // get SOCLIB_DMA device cluster and local pointer … … 83 83 84 84 // set SOCLIB_DMA registers to start tranfer operation 85 hal_remote_s w( XPTR( dma_cxy , base + DMA_SRC ) , src_lsb );86 hal_remote_s w( XPTR( dma_cxy , base + DMA_SRC_EXT ) , src_msb );87 hal_remote_s w( XPTR( dma_cxy , base + DMA_DST ) , dst_lsb );88 hal_remote_s w( XPTR( dma_cxy , base + DMA_DST_EXT ) , dst_msb );89 hal_remote_s w( XPTR( dma_cxy , base + DMA_LEN ) , size );85 hal_remote_s32( XPTR( dma_cxy , base + DMA_SRC ) , src_lsb ); 86 hal_remote_s32( XPTR( dma_cxy , base + DMA_SRC_EXT ) , src_msb ); 87 hal_remote_s32( XPTR( dma_cxy , base + DMA_DST ) , dst_lsb ); 88 hal_remote_s32( XPTR( dma_cxy , base + DMA_DST_EXT ) , dst_msb ); 89 hal_remote_s32( XPTR( dma_cxy , base + DMA_LEN ) , size ); 90 90 91 91 // Block and deschedule server thread … … 100 100 // get extended pointer on client thread 101 101 xptr_t root = XPTR( local_cxy , &chdev->wait_root ); 102 xptr_t client_xp = XLIST_FIRST _ELEMENT( root , thread_t , wait_list );102 xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list ); 103 103 104 104 // get extended pointer on server thread … … 117 117 118 118 // get DMA status register 119 uint32_t status = hal_remote_l w( XPTR( dma_cxy , base + DMA_LEN ) );119 uint32_t status = hal_remote_l32( XPTR( dma_cxy , base + DMA_LEN ) ); 120 120 121 121 // acknowledge IRQ 122 hal_remote_s w( XPTR( dma_cxy , base + DMA_RESET ) , 0 );122 hal_remote_s32( XPTR( dma_cxy , base + DMA_RESET ) , 0 ); 123 123 124 124 // set operation status in command 125 125 error_t error = ( status != DMA_SUCCESS ); 126 hal_remote_s w( XPTR( client_cxy , &client_ptr->dma_cmd.error ) , error );126 hal_remote_s32( XPTR( client_cxy , &client_ptr->dma_cmd.error ) , error ); 127 127 128 128 // unblock server thread -
trunk/hal/tsar_mips32/drivers/soclib_hba.c
r522 r570 27 27 #include <dev_ioc.h> 28 28 #include <soclib_hba.h> 29 #include <spinlock.h>30 29 #include <thread.h> 31 30 … … 51 50 52 51 // spinlock protecting the command slot allocator 53 __attribute__((section(".kdata")))54 spinlock_t hba_lock;52 // __attribute__((section(".kdata"))) 53 // busylock_t hba_lock; 55 54 56 55 /////////////////////////////////////// … … 69 68 70 69 // get block_size and block_count 71 uint32_t block_size = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_SIZE_REG ) );72 uint32_t block_count = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_COUNT_REG ) );70 uint32_t block_size = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_SIZE_REG ) ); 71 uint32_t block_count = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_COUNT_REG ) ); 73 72 74 73 // set device descriptor extension … … 77 76 78 77 // activate HBA interrupts 79 hal_remote_s w( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );78 hal_remote_s32( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 ); 80 79 81 80 // reset SOCLIB_HBA driver global variable … … 107 106 108 107 // get command arguments and extended pointer on IOC device 109 cmd_type = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.type ) );110 lba = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.lba ) );111 count = hal_remote_l w( XPTR( th_cxy , &th_ptr->ioc_cmd.count ) );112 buf_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) );113 dev_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) );108 cmd_type = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.type ) ); 109 lba = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.lba ) ); 110 count = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.count ) ); 111 buf_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) ); 112 dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) ); 114 113 115 114 // get IOC device cluster and local pointer … … 118 117 119 118 // get cluster and pointers for SOCLIB-HBA peripheral segment base 120 xptr_t hba_xp = (xptr_t)hal_remote_l wd( XPTR( dev_cxy , &dev_ptr->base ) );119 xptr_t hba_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) ); 121 120 cxy_t hba_cxy = GET_CXY( hba_xp ); 122 121 uint32_t * hba_ptr = GET_PTR( hba_xp ); … … 181 180 182 181 // set HBA_PXCI_REG to start transfer 183 hal_remote_s w( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id );182 hal_remote_s32( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id ); 184 183 185 184 // exit the while … … 204 203 while(1) 205 204 { 206 pxis = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );207 pxci = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );205 pxis = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) ); 206 pxci = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) ); 208 207 error = (pxis & 0x40000000) >> 30; 209 208 fault_id = (pxis & 0x1F000000) >> 24; … … 217 216 if( error && (fault_id == cmd_id) ) 218 217 { 219 hal_remote_s w( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 );218 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 ); 220 219 } 221 220 else 222 221 { 223 hal_remote_s w( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 );222 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 ); 224 223 } 225 224 … … 243 242 // get extended pointer on client thread 244 243 xptr_t root = XPTR( local_cxy , &chdev->wait_root ); 245 xptr_t client_xp = XLIST_FIRST _ELEMENT( root , thread_t , wait_list );244 xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list ); 246 245 247 246 // get client thread cluster and local pointer … … 254 253 255 254 // get HBA_PXIS_REG and HBA_PXCI_REG current values 256 uint32_t current_pxis = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );257 uint32_t current_pxci = hal_remote_l w( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );255 uint32_t current_pxis = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) ); 256 uint32_t current_pxci = hal_remote_l32( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) ); 258 257 259 258 uint32_t error = (current_pxis & 0x40000000) >> 30; … … 273 272 if( error && (iter == fault_id ) ) 274 273 { 275 hal_remote_s w( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , 1 );274 hal_remote_s32( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , 1 ); 276 275 } 277 276 else 278 277 { 279 hal_remote_s w( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , 0 );278 hal_remote_s32( XPTR( client_cxy , &client_ptr->ioc_cmd.error ) , 0 ); 280 279 } 281 280 … … 286 285 287 286 // reset HBA_PXIS_REG 288 hal_remote_s w( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) , 0 );287 hal_remote_s32( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) , 0 ); 289 288 290 289 } // end soclib_hba_isr() -
trunk/hal/tsar_mips32/drivers/soclib_iob.c
r451 r570 31 31 { 32 32 // desactivate IOMMU 33 hal_remote_s w( chdev->base + (IOB_IOMMU_ACTIVE<<2) , 0 );33 hal_remote_s32( chdev->base + (IOB_IOMMU_ACTIVE<<2) , 0 ); 34 34 } 35 35 … … 43 43 44 44 // get extended pointer on SOCLIB_IOB base_xp segment 45 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );45 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 46 46 47 47 // set ACTIVE register 48 hal_remote_s w( base_xp + (IOB_IOMMU_ACTIVE<<2) , value );48 hal_remote_s32( base_xp + (IOB_IOMMU_ACTIVE<<2) , value ); 49 49 } 50 50 … … 58 58 59 59 // get extended pointer on SOCLIB_IOB base_xp segment 60 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );60 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 61 61 62 62 // set PTPR register 63 hal_remote_s w( base_xp + (IOB_IOMMU_PTPR<<2) , value );63 hal_remote_s32( base_xp + (IOB_IOMMU_PTPR<<2) , value ); 64 64 } 65 65 … … 73 73 74 74 // get extended pointer on SOCLIB_IOB base_xp segment 75 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );75 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 76 76 77 77 // invalidate TLB entry 78 hal_remote_s w( base_xp + (IOB_INVAL_PTE<<2) , vpn );78 hal_remote_s32( base_xp + (IOB_INVAL_PTE<<2) , vpn ); 79 79 } 80 80 … … 87 87 88 88 // get extended pointer on SOCLIB_IOB base_xp segment 89 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );89 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 90 90 91 91 // get BVAR register 92 return hal_remote_l w( base_xp + (IOB_IOMMU_BVAR<<2) );92 return hal_remote_l32( base_xp + (IOB_IOMMU_BVAR<<2) ); 93 93 } 94 94 … … 101 101 102 102 // get extended pointer on SOCLIB_IOB base_xp segment 103 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );103 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 104 104 105 105 // get BVAR register 106 return hal_remote_l w( base_xp + (IOB_IOMMU_SRCID<<2) );106 return hal_remote_l32( base_xp + (IOB_IOMMU_SRCID<<2) ); 107 107 } 108 108 … … 115 115 116 116 // get extended pointer on SOCLIB_IOB base_xp segment 117 xptr_t base_xp = (xptr_t)hal_remote_l wd( XPTR( iob_cxy , &iob_ptr->base ) );117 xptr_t base_xp = (xptr_t)hal_remote_l64( XPTR( iob_cxy , &iob_ptr->base ) ); 118 118 119 119 // get BVAR register 120 return hal_remote_l w( base_xp + (IOB_IOMMU_ERROR<<2) );120 return hal_remote_l32( base_xp + (IOB_IOMMU_ERROR<<2) ); 121 121 } 122 122 -
trunk/hal/tsar_mips32/drivers/soclib_mmc.c
r451 r570 27 27 #include <dev_mmc.h> 28 28 #include <soclib_mmc.h> 29 #include <spinlock.h>30 29 #include <thread.h> 31 30 #include <printk.h> … … 62 61 63 62 // get command type and extended pointer on MMC device 64 type = hal_remote_l w( XPTR( th_cxy , &th_ptr->mmc_cmd.type ) );65 dev_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->mmc_cmd.dev_xp ) );63 type = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->mmc_cmd.type ) ); 64 dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->mmc_cmd.dev_xp ) ); 66 65 67 66 // get MMC device cluster and local pointer … … 70 69 71 70 // get cluster and pointers for SOCLIB_MMC peripheral segment base 72 xptr_t seg_xp = (xptr_t)hal_remote_l wd( XPTR( dev_cxy , &dev_ptr->base ) );71 xptr_t seg_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) ); 73 72 cxy_t seg_cxy = GET_CXY( seg_xp ); 74 73 uint32_t * seg_ptr = GET_PTR( seg_xp ); … … 78 77 // get buffer pointer and size 79 78 buf_ptr = hal_remote_lpt( XPTR( th_cxy , &th_ptr->mmc_cmd.buf_ptr ) ); 80 buf_size = hal_remote_l w( XPTR( th_cxy , &th_ptr->mmc_cmd.buf_size ) );79 buf_size = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->mmc_cmd.buf_size ) ); 81 80 82 81 // set command type … … 86 85 87 86 // set SOCLIB_MMC registers to start INVAL/SYNC operation 88 hal_remote_s w( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_ADDR_LO ) , (uint32_t)buf_ptr );89 hal_remote_s w( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_ADDR_HI ) , (uint32_t)dev_cxy );90 hal_remote_s w( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_BUF_LENGTH ) , buf_size );91 hal_remote_s w( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_CMD_TYPE ) , cc_cmd );87 hal_remote_s32( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_ADDR_LO ) , (uint32_t)buf_ptr ); 88 hal_remote_s32( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_ADDR_HI ) , (uint32_t)dev_cxy ); 89 hal_remote_s32( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_BUF_LENGTH ) , buf_size ); 90 hal_remote_s32( XPTR( seg_cxy , seg_ptr + SOCLIB_MMC_CMD_TYPE ) , cc_cmd ); 92 91 } 93 92 else // (type == MMC_GET_ERROR) or (type == MMC_GET_ERROR) pr (type == MMC_GET_INSTRU ) … … 95 94 // get src/dst buffer local pointer and register index 96 95 reg_ptr = (uint32_t *)hal_remote_lpt( XPTR( th_cxy , &th_ptr->mmc_cmd.reg_ptr ) ); 97 reg_index = hal_remote_l w( XPTR( th_cxy , &th_ptr->mmc_cmd.reg_index ) );96 reg_index = hal_remote_l32( XPTR( th_cxy , &th_ptr->mmc_cmd.reg_index ) ); 98 97 99 98 // move register to/from local buffer 100 99 if( (type == MMC_GET_ERROR) || (type == MMC_GET_INSTRU) ) 101 100 { 102 *reg_ptr = hal_remote_l w( XPTR( seg_cxy , seg_ptr + reg_index ) );101 *reg_ptr = hal_remote_l32( XPTR( seg_cxy , seg_ptr + reg_index ) ); 103 102 } 104 103 else // type == MMC_SET_ERROR 105 104 { 106 hal_remote_s w( XPTR( seg_cxy , seg_ptr + reg_index ) , *reg_ptr );105 hal_remote_s32( XPTR( seg_cxy , seg_ptr + reg_index ) , *reg_ptr ); 107 106 } 108 107 } -
trunk/hal/tsar_mips32/drivers/soclib_mty.c
r562 r570 1 1 /* 2 * soclib_mt ty.c - soclib tty driver implementation.2 * soclib_mty.c - soclib mty driver implementation. 3 3 * 4 4 * Author Alain Greiner (2016,2017,2018) … … 26 26 #include <dev_txt.h> 27 27 #include <chdev.h> 28 #include <soclib_mtty.h> 29 #include <remote_spinlock.h> 28 #include <soclib_mty.h> 30 29 #include <thread.h> 31 30 #include <printk.h> 32 31 #include <hal_special.h> 33 32 34 #if (DEBUG_SYS_READ & 1)35 extern uint32_t enter_tty_cmd_read;36 extern uint32_t exit_tty_cmd_read;37 38 extern uint32_t enter_tty_isr_read;39 extern uint32_t exit_tty_isr_read;40 #endif41 42 #if (DEBUG_SYS_WRITE & 1)43 extern uint32_t enter_tty_cmd_write;44 extern uint32_t exit_tty_cmd_write;45 46 extern uint32_t enter_tty_isr_write;47 extern uint32_t exit_tty_isr_write;48 #endif49 50 33 extern chdev_directory_t chdev_dir; // allocated in the kernel_init.c file. 51 extern spinlock_t txt0_lock; // Initialized in kernel_init.c 34 52 35 //////////////////////////////////////////////////////////////////////////////////// 53 // These global variables implement the MT TY_RX FIFOs (one per channel)36 // These global variables implement the MTY_RX FIFOs (one per channel) 54 37 //////////////////////////////////////////////////////////////////////////////////// 55 56 __attribute__((section(".kdata"))) 57 mtty_fifo_t mtty_rx_fifo[CONFIG_MAX_TXT_CHANNELS]; 58 59 __attribute__((section(".kdata"))) 60 mtty_fifo_t mtty_tx_fifo[CONFIG_MAX_TXT_CHANNELS]; 38 // Implementation note: 39 // We allocate - in each cluster - two arrays of FIFOs containing as many entries 40 // as the total number of TXT channels, but all entries are not used in all 41 // clusters: for a given cluster K, a given entry corresponding to a given channel 42 // and a given direction is only used if the associated chdev is in cluster K. 43 // With this policy, the driver can ignore the actual placement of chdevs. 44 //////////////////////////////////////////////////////////////////////////////////// 45 46 __attribute__((section(".kdata"))) 47 mty_fifo_t mty_rx_fifo[CONFIG_MAX_TXT_CHANNELS]; 48 49 __attribute__((section(".kdata"))) 50 mty_fifo_t mty_tx_fifo[CONFIG_MAX_TXT_CHANNELS]; 51 52 //////////////////////////////////////////////////////////////////////////////////// 53 // These global variables define the physical channel RX and TX state, 54 // as required by the virtual channels handling. 55 //////////////////////////////////////////////////////////////////////////////////// 56 // Implementation note: 57 // These state variables are required, because the ISR is called twice for each 58 // character on the physical channel (for index and value), and does not the same 59 // actions for index and value. They are also used to implement the round-robin 60 // policy between TX_FIFOs. 61 //////////////////////////////////////////////////////////////////////////////////// 62 63 __attribute__((section(".kdata"))) 64 bool_t mty_rx_not_new; // RX first byte if false 65 66 __attribute__((section(".kdata"))) 67 uint32_t mty_rx_channel; // RX virtual channel index 68 69 __attribute__((section(".kdata"))) 70 bool_t mty_tx_not_new; // TX first byte if false 71 72 __attribute__((section(".kdata"))) 73 uint32_t mty_tx_value; // TX character ascii value 74 75 __attribute__((section(".kdata"))) 76 uint32_t mty_tx_last; // TX last selected virtual channel 61 77 62 78 /////////////////////////////////////// 63 void soclib_mt ty_init( chdev_t * chdev )79 void soclib_mty_init( chdev_t * chdev ) 64 80 { 65 81 xptr_t reg_xp; 66 82 67 83 // initialise function pointers in chdev 68 chdev->cmd = &soclib_mt ty_cmd;69 chdev->isr = &soclib_mt ty_isr;70 chdev->aux = &soclib_mt ty_aux;71 72 // get TTY channel and extended pointer on TTY peripheral base address73 xptr_t tty_xp = chdev->base;84 chdev->cmd = &soclib_mty_cmd; 85 chdev->isr = &soclib_mty_isr; 86 chdev->aux = &soclib_mty_aux; 87 88 // get MTY channel and extended pointer on MTY peripheral base address 89 xptr_t mty_xp = chdev->base; 74 90 uint32_t channel = chdev->channel; 75 91 bool_t is_rx = chdev->is_rx; 76 92 77 // get SOCLIB_ TTY device cluster and local pointer78 cxy_t tty_cxy = GET_CXY( tty_xp );79 uint32_t * tty_ptr = GET_PTR( tty_xp );80 81 // enable interruptions for RX but not for TX82 reg_xp = XPTR( tty_cxy , tty_ptr + MTTY_CONFIG );83 hal_remote_s w( reg_xp , MTTY_CONFIG_RX_ENABLE );93 // get SOCLIB_MTY device cluster and local pointer 94 cxy_t mty_cxy = GET_CXY( mty_xp ); 95 uint32_t * mty_ptr = GET_PTR( mty_xp ); 96 97 // enable interruptions for RX 98 reg_xp = XPTR( mty_cxy , mty_ptr + MTY_CONFIG ); 99 hal_remote_s32( reg_xp , MTY_CONFIG_RX_ENABLE ); 84 100 85 101 // reset relevant FIFO 86 102 if( is_rx ) 87 103 { 88 mt ty_rx_fifo[channel].sts = 0;89 mt ty_rx_fifo[channel].ptr = 0;90 mt ty_rx_fifo[channel].ptw = 0;104 mty_rx_fifo[channel].sts = 0; 105 mty_rx_fifo[channel].ptr = 0; 106 mty_rx_fifo[channel].ptw = 0; 91 107 } 92 108 else 93 109 { 94 mt ty_tx_fifo[channel].sts = 0;95 mt ty_tx_fifo[channel].ptr = 0;96 mt ty_tx_fifo[channel].ptw = 0;110 mty_tx_fifo[channel].sts = 0; 111 mty_tx_fifo[channel].ptr = 0; 112 mty_tx_fifo[channel].ptw = 0; 97 113 } 98 } // end soclib_mt ty_init()114 } // end soclib_mty_init() 99 115 100 116 ////////////////////////////////////////////////////////////// 101 void __attribute__ ((noinline)) soclib_mt ty_cmd( xptr_t th_xp )117 void __attribute__ ((noinline)) soclib_mty_cmd( xptr_t th_xp ) 102 118 { 103 mt ty_fifo_t * fifo; // MTTY_RX or MTTY_TX FIFO119 mty_fifo_t * fifo; // MTY_RX or MTY_TX FIFO 104 120 char byte; // byte value 105 121 uint32_t done; // number of bytes moved … … 110 126 111 127 // get command arguments 112 uint32_t type = hal_remote_l w( XPTR( th_cxy , &th_ptr->txt_cmd.type ) );113 xptr_t buf_xp = hal_remote_l wd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );114 uint32_t count = hal_remote_l w( XPTR( th_cxy , &th_ptr->txt_cmd.count ) );128 uint32_t type = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 129 xptr_t buf_xp = hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) ); 130 uint32_t count = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) ); 115 131 xptr_t error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error ); 116 132 117 #if (DEBUG_SYS_READ & 1)118 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles();119 #endif120 121 #if (DEBUG_SYS_WRITE & 1)122 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles();123 #endif124 125 133 // get TXT device cluster and pointers 126 xptr_t dev_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );134 xptr_t dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 127 135 cxy_t dev_cxy = GET_CXY( dev_xp ); 128 136 chdev_t * dev_ptr = GET_PTR( dev_xp ); 129 137 130 // get cluster and pointers for SOCLIB_TTY peripheral base segment 131 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 132 cxy_t tty_cxy = GET_CXY( tty_xp ); 133 uint32_t * tty_ptr = GET_PTR( tty_xp ); 134 135 // get TTY channel index and channel base address 136 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) ); 137 uint32_t * base = tty_ptr; 138 // get MTY channel index and channel base address 139 uint32_t channel = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->channel ) ); 138 140 139 141 /////////////////////// 140 if( type == TXT_WRITE ) // write bytes to MT TY_TX FIFO141 { 142 fifo = &mt ty_tx_fifo[channel];142 if( type == TXT_WRITE ) // write bytes to MTY_TX FIFO 143 { 144 fifo = &mty_tx_fifo[channel]; 143 145 144 146 done = 0; … … 146 148 while( done < count ) 147 149 { 148 if( fifo->sts < MT TY_FIFO_DEPTH ) // put one byte to FIFO if TX_FIFO not full150 if( fifo->sts < MTY_FIFO_DEPTH ) // put one byte to FIFO if TX_FIFO not full 149 151 { 150 152 // get one byte from command buffer … … 164 166 165 167 // update FIFO state 166 fifo->ptw = (fifo->ptw + 1) % MT TY_FIFO_DEPTH;168 fifo->ptw = (fifo->ptw + 1) % MTY_FIFO_DEPTH; 167 169 hal_atomic_add( &fifo->sts , 1 ); 168 170 169 171 // udate number of bytes moved 170 172 done++; 171 172 // enable TX_IRQ173 // vci_multi_tty devices never raise TX IRQs174 // so the following instructions are useless175 // and moreover they kernel panic176 // xptr_t config_xp = XPTR( tty_cxy , base + MTTY_CONFIG );177 // uint32_t old = hal_remote_lw( config_xp );178 // uint32_t new = old | MTTY_CONFIG_TX_ENABLE;179 // hal_remote_atomic_cas( config_xp , old , new );180 // hal_remote_sw( XPTR( tty_cxy , base + MTTY_CONFIG ) , MTTY_CONFIG_TX_ENABLE );181 173 } 182 174 else // block & deschedule if TX_FIFO full … … 186 178 187 179 // deschedule 188 sched_yield( "MT TY_TX_FIFO full" );180 sched_yield( "MTY_TX_FIFO full" ); 189 181 } 190 182 } 191 183 192 184 // set error status in command and return 193 hal_remote_s w( error_xp , 0 );185 hal_remote_s32( error_xp , 0 ); 194 186 } 195 187 /////////////////////////// 196 else if( type == TXT_READ ) // read bytes from MT TY_RX FIFO197 { 198 fifo = &mt ty_rx_fifo[channel];188 else if( type == TXT_READ ) // read bytes from MTY_RX FIFO 189 { 190 fifo = &mty_rx_fifo[channel]; 199 191 200 192 done = 0; … … 214 206 #endif 215 207 // update FIFO state 216 fifo->ptr = (fifo->ptr + 1) % MT TY_FIFO_DEPTH;208 fifo->ptr = (fifo->ptr + 1) % MTY_FIFO_DEPTH; 217 209 hal_atomic_add( &fifo->sts , -1 ); 218 210 … … 229 221 230 222 // deschedule 231 sched_yield( "MT TY_RX_FIFO empty" );223 sched_yield( "MTY_RX_FIFO empty" ); 232 224 } 233 225 } // end while 234 226 235 227 // set error status in command 236 hal_remote_s w( error_xp , 0 );228 hal_remote_s32( error_xp , 0 ); 237 229 } 238 230 else … … 241 233 } 242 234 243 #if (DEBUG_SYS_READ & 1) 244 if( type == TXT_READ ) exit_tty_cmd_read = (uint32_t)hal_get_cycles(); 245 #endif 246 247 #if (DEBUG_SYS_WRITE & 1) 248 if( type == TXT_WRITE ) exit_tty_cmd_write = (uint32_t)hal_get_cycles(); 249 #endif 250 251 } // end soclib_mtty_cmd() 235 } // end soclib_mty_cmd() 252 236 253 237 ///////////////////////////////////////////////////////////////// 254 void __attribute__ ((noinline)) soclib_mt ty_isr( chdev_t * chdev )238 void __attribute__ ((noinline)) soclib_mty_isr( chdev_t * chdev ) 255 239 { 256 240 thread_t * server; // pointer on TXT chdev server thread 257 241 lid_t server_lid; // local index of core running the server thread 258 uint32_t channel; // TXT chdev channel 242 uint32_t channel; // TXT chdev channel (virtual channel index) 259 243 bool_t is_rx; // TXT chdev direction 260 244 char byte; // byte value … … 263 247 process_t * owner_ptr; // local pointer on TXT owner process 264 248 pid_t owner_pid; // TXT owner process identifier 265 mtty_fifo_t * fifo; // pointer on MTTY_TX or MTTY_RX FIFO 266 cxy_t tty_cxy; // soclib_mtty cluster 267 uint32_t * tty_ptr; // soclib_mtty segment base address 268 uint32_t * base; // soclib_mtty channel base address 269 xptr_t status_xp; // extended pointer on MTTY_STATUS register 270 xptr_t write_xp; // extended pointer on MTTY_WRITE register 271 xptr_t read_xp; // extended pointer on MTTY_READ register 249 mty_fifo_t * fifo; // pointer on MTY_TX or MTY_RX FIFO 250 cxy_t mty_cxy; // soclib_mty cluster 251 uint32_t * mty_ptr; // soclib_mty segment base address 252 xptr_t status_xp; // extended pointer on MTY_STATUS register 253 xptr_t write_xp; // extended pointer on MTY_WRITE register 254 xptr_t read_xp; // extended pointer on MTY_READ register 272 255 xptr_t parent_xp; // extended pointer on parent process 273 256 cxy_t parent_cxy; // parent process cluster 274 257 process_t * parent_ptr; // local pointer on parent process 275 xptr_t children_lock_xp; // extended pointer on children processes lock276 258 thread_t * parent_main_ptr; // extended pointer on parent process main thread 277 259 xptr_t parent_main_xp; // local pointer on parent process main thread 260 uint32_t n; // index in loop 261 bool_t found; 262 263 #if DEBUG_HAL_TXT_RX 264 uint32_t rx_cycle = (uint32_t)hal_get_cycles(); 265 #endif 266 267 #if DEBUG_HAL_TXT_TX 268 uint32_t tx_cycle = (uint32_t)hal_get_cycles(); 269 #endif 278 270 279 271 // get TXT chdev channel, direction and server thread 280 channel = chdev->channel;281 272 is_rx = chdev->is_rx; 282 273 server = chdev->server; 283 274 server_lid = server->core->lid; 284 275 285 #if (DEBUG_SYS_READ & 1) 286 if( is_rx ) enter_tty_isr_read = (uint32_t)hal_get_cycles(); 287 #endif 288 289 #if (DEBUG_SYS_WRITE & 1) 290 if( is_rx == 0 ) enter_tty_isr_write = (uint32_t)hal_get_cycles(); 291 #endif 292 293 #if DEBUG_HAL_TXT_RX 294 uint32_t rx_cycle = (uint32_t)hal_get_cycles(); 295 #endif 296 297 #if DEBUG_HAL_TXT_TX 298 uint32_t tx_cycle = (uint32_t)hal_get_cycles(); 299 #endif 300 301 // get SOCLIB_TTY peripheral cluster and local pointer 302 tty_cxy = GET_CXY( chdev->base ); 303 tty_ptr = GET_PTR( chdev->base ); 304 305 // get channel base address 306 base = tty_ptr; 307 308 // get extended pointer on TTY registers 309 status_xp = XPTR( tty_cxy , base + MTTY_STATUS ); 310 write_xp = XPTR( tty_cxy , base + MTTY_WRITE ); 311 read_xp = XPTR( tty_cxy , base + MTTY_READ ); 276 // get SOCLIB_MTY peripheral cluster and local pointer 277 mty_cxy = GET_CXY( chdev->base ); 278 mty_ptr = GET_PTR( chdev->base ); 279 280 // get extended pointer on MTY registers 281 status_xp = XPTR( mty_cxy , mty_ptr + MTY_STATUS ); 282 write_xp = XPTR( mty_cxy , mty_ptr + MTY_WRITE ); 283 read_xp = XPTR( mty_cxy , mty_ptr + MTY_READ ); 312 284 313 285 /////////////////////////// handle RX ////////////////////// 314 286 if( is_rx ) 315 287 { 316 fifo = &mtty_rx_fifo[channel]; 317 318 // try to move bytes until MTTY_READ register empty 319 while( hal_remote_lw( status_xp ) & MTTY_STATUS_RX_FULL ) 288 // check one byte available in MTY_READ register 289 if( hal_remote_l32( status_xp ) & MTY_STATUS_RX_FULL ) 320 290 { 321 // get one byte from MT TY_READ register & acknowledge RX_IRQ291 // get one byte from MTY_READ register & acknowledge RX_IRQ 322 292 byte = (char)hal_remote_lb( read_xp ); 323 293 324 // Ignore Carriage Returns 325 if( byte == 0xD ) 326 { 327 continue; 328 } 329 330 // This is the MTTY multiplexing 331 // When a extended ASCII char are received (typing Ctrl-Shift-U then 100+n for example on the terminal) 332 // Two characters are received : 0xFFFFFFc4 then 0xFFFFFF80 + n 333 // When this second char is received, it is considered a metachar that determines the tty dest number 334 // Thus, if you want to make tty 5 the new target, type Ctrl+Shift+U then 105 335 // Now all keystrokes IRQs will be handled by the server DEV thread 336 // associated to RX channel number 5 337 if( (byte & 0xFF) > 0x80 && (byte & 0xFF) <= 0x89 ) 338 { 339 // Disable MTTY IRQ for the core owning 340 // the current channel's server DEV thread 341 dev_pic_disable_irq( server_lid, XPTR( local_cxy , chdev ) ); 342 343 int tty_destnb = (int)(byte & 0xFF) - 0x80; 344 chdev_t * new_chdev = chdev_dir.txt_rx[tty_destnb]; 345 lid_t new_lid = new_chdev->server->core->lid; 346 347 // Bind MTTY IRQ to the core owning the new channel's server DEV thread 348 dev_pic_bind_irq( new_lid , new_chdev ); 349 350 // Enable MTTY IRQ for the core owning 351 // the new channel's server DEV thread 352 dev_pic_enable_irq( new_lid , XPTR( local_cxy , new_chdev ) ); 353 354 channel = new_chdev->channel; 355 is_rx = new_chdev->is_rx; 356 server = new_chdev->server; 357 server_lid = new_lid; 358 fifo = &mtty_rx_fifo[channel]; 359 continue; 360 } 361 362 // filter special character ^Z => block TXT owner process 363 if( byte == 0x1A ) 364 { 294 // test physical RX channel state 295 if( mty_rx_not_new == false ) // get first byte (virtual channel index) 296 { 297 // register virtual channel index 298 mty_rx_channel = (uint32_t)byte; 299 300 // update physical RX channel state 301 mty_rx_not_new = true; 302 } 303 else // get second byte (character value) 304 { 305 // get virtual channel index registered 306 channel = mty_rx_channel; 307 308 // get destination TX_FIFO 309 fifo = &mty_rx_fifo[channel]; 310 311 // filter special character ^Z => block TXT owner process 312 if( byte == 0x1A ) 313 { 365 314 366 315 #if DEBUG_HAL_TXT_RX … … 368 317 printk("\n[DBG] %s : read ^Z character from TXT%d\n", __FUNCTION__, channel ); 369 318 #endif 370 // get pointers on TXT owner process in owner cluster371 owner_xp = process_txt_get_owner( channel );319 // get pointers on TXT owner process in owner cluster 320 owner_xp = process_txt_get_owner( channel ); 372 321 373 // check process exist 374 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 375 "TXT owner process not found\n" ); 376 377 // get relevant infos on TXT owner process 378 owner_cxy = GET_CXY( owner_xp ); 379 owner_ptr = GET_PTR( owner_xp ); 380 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 381 382 // block TXT owner process only if it is not the INIT process 383 if( owner_pid != 1 ) 322 // check process exist 323 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 324 "TXT owner process not found\n" ); 325 326 // get relevant infos on TXT owner process 327 owner_cxy = GET_CXY( owner_xp ); 328 owner_ptr = GET_PTR( owner_xp ); 329 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 330 331 // block TXT owner process only if it is not the INIT process 332 if( owner_pid != 1 ) 333 { 334 // get parent process descriptor pointers 335 parent_xp = hal_remote_l64( XPTR( owner_cxy , 336 &owner_ptr->parent_xp ) ); 337 parent_cxy = GET_CXY( parent_xp ); 338 parent_ptr = GET_PTR( parent_xp ); 339 340 // get pointers on the parent process main thread 341 parent_main_ptr = hal_remote_lpt( XPTR(parent_cxy, 342 &parent_ptr->th_tbl[0])); 343 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 344 345 // transfer TXT ownership 346 process_txt_transfer_ownership( owner_xp ); 347 348 // block all threads in all clusters, but the main thread 349 process_sigaction( owner_pid , BLOCK_ALL_THREADS ); 350 351 // block the main thread 352 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 353 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 354 355 // atomically update owner process termination state 356 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 357 PROCESS_TERM_STOP ); 358 359 // take the children lock and unblock the parent process main thread 360 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 361 362 return; 363 } 364 } 365 366 // filter special character ^C => kill TXT owner process 367 if( byte == 0x03 ) 384 368 { 385 // get parent process descriptor pointers386 parent_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );387 parent_cxy = GET_CXY( parent_xp );388 parent_ptr = GET_PTR( parent_xp );389 390 // get extended pointer on lock protecting children list in parent process391 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );392 393 // get pointers on the parent process main thread394 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));395 parent_main_xp = XPTR( parent_cxy , parent_main_ptr );396 397 // transfer TXT ownership398 process_txt_transfer_ownership( owner_xp );399 400 // block all threads in all clusters, but the main thread401 process_sigaction( owner_pid , BLOCK_ALL_THREADS );402 403 // block the main thread404 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );405 thread_block( main_xp , THREAD_BLOCKED_GLOBAL );406 407 // atomically update owner process termination state408 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,409 PROCESS_TERM_STOP );410 411 // take the children lock and unblock the parent process main thread412 remote_spinlock_lock( children_lock_xp );413 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );414 remote_spinlock_unlock( children_lock_xp );415 416 return;417 }418 }419 420 // filter special character ^C => kill TXT owner process421 if( byte == 0x03 )422 {423 369 424 370 #if DEBUG_HAL_TXT_RX … … 426 372 printk("\n[DBG] %s : read ^C character from TXT%d\n", __FUNCTION__, channel ); 427 373 #endif 428 // get pointer on TXT owner process in owner cluster 429 owner_xp = process_txt_get_owner( channel ); 430 431 // check process exist 432 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 433 "TXT owner process not found\n" ); 434 435 // get relevant infos on TXT owner process 436 owner_cxy = GET_CXY( owner_xp ); 437 owner_ptr = GET_PTR( owner_xp ); 438 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) ); 439 440 // kill TXT owner process only if it is not the INIT process 441 if( owner_pid != 1 ) 374 // get pointer on TXT owner process in owner cluster 375 owner_xp = process_txt_get_owner( channel ); 376 377 // check process exist 378 assert( (owner_xp != XPTR_NULL) , __FUNCTION__, 379 "TXT owner process not found\n" ); 380 381 // get relevant infos on TXT owner process 382 owner_cxy = GET_CXY( owner_xp ); 383 owner_ptr = GET_PTR( owner_xp ); 384 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 385 386 // kill TXT owner process only if it is not the INIT process 387 if( owner_pid != 1 ) 388 { 389 // get parent process descriptor pointers 390 parent_xp = hal_remote_l64( XPTR( owner_cxy, 391 &owner_ptr->parent_xp ) ); 392 parent_cxy = GET_CXY( parent_xp ); 393 parent_ptr = GET_PTR( parent_xp ); 394 395 // get pointers on the parent process main thread 396 parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy, 397 &parent_ptr->th_tbl[0])); 398 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 399 400 // remove process from TXT list 401 process_txt_detach( owner_xp ); 402 403 // mark for delete all thread in all clusters, but the main 404 process_sigaction( owner_pid , DELETE_ALL_THREADS ); 405 406 // block main thread 407 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 408 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 409 410 // atomically update owner process termination state 411 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 412 PROCESS_TERM_KILL ); 413 414 // take the children lock and unblock the parent process main thread 415 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 416 417 return; 418 } 419 } 420 421 // write byte in RX FIFO if not full / discard byte if full 422 if ( fifo->sts < MTY_FIFO_DEPTH ) 442 423 { 443 // get parent process descriptor pointers444 parent_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );445 parent_cxy = GET_CXY( parent_xp );446 parent_ptr = GET_PTR( parent_xp );447 448 // get extended pointer on lock protecting children list in parent process449 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );450 451 // get pointers on the parent process main thread452 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));453 parent_main_xp = XPTR( parent_cxy , parent_main_ptr );454 455 // remove process from TXT list456 process_txt_detach( owner_xp );457 458 // mark for delete all thread in all clusters, but the main459 process_sigaction( owner_pid , DELETE_ALL_THREADS );460 461 // block main thread462 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );463 thread_block( main_xp , THREAD_BLOCKED_GLOBAL );464 465 // atomically update owner process termination state466 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,467 PROCESS_TERM_KILL );468 469 // take the children lock and unblock the parent process main thread470 remote_spinlock_lock( children_lock_xp );471 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );472 remote_spinlock_unlock( children_lock_xp );473 474 return;475 }476 }477 478 // write byte in MTTY_RX FIFO if not full / discard byte if full479 if ( fifo->sts < MTTY_FIFO_DEPTH )480 {481 424 482 425 #if DEBUG_HAL_TXT_RX … … 485 428 __FUNCTION__, byte, channel ); 486 429 #endif 487 // store byte into FIFO 488 fifo->data[fifo->ptw] = (char)byte; 489 490 // avoid race 491 hal_fence(); 492 493 // update RX_FIFO state 494 fifo->ptw = (fifo->ptw + 1) % MTTY_FIFO_DEPTH; 495 hal_atomic_add( &fifo->sts , 1 ); 496 497 // unblock TXT_RX server thread 498 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 499 500 // send IPI to core running server thread 501 dev_pic_send_ipi( local_cxy , server_lid ); 502 } 503 else 504 { 505 printk("\n[WARNING] %s : MTTY_RX_FIFO[%d] full => discard character <%x>\n", 506 __FUNCTION__, channel, (uint32_t)byte ); 507 } 508 } // end while MTTY_READ register full 509 430 // store byte into FIFO 431 fifo->data[fifo->ptw] = (char)byte; 432 433 // avoid race 434 hal_fence(); 435 436 // update RX_FIFO state 437 fifo->ptw = (fifo->ptw + 1) % MTY_FIFO_DEPTH; 438 hal_atomic_add( &fifo->sts , 1 ); 439 440 // unblock TXT_RX server thread 441 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 442 443 // send IPI to core running server thread 444 dev_pic_send_ipi( local_cxy , server_lid ); 445 } 446 else 447 { 448 printk("\n[WARNING] %s : MTY_RX_FIFO[%d] full => discard char <%x>\n", 449 __FUNCTION__, channel, (uint32_t)byte ); 450 } 451 452 // update physical RX channel state 453 mty_rx_not_new = true; 454 455 } // end get character value 456 } // end if byte available in MTY_READ register 510 457 } // end RX 511 458 … … 513 460 else 514 461 { 515 fifo = &mtty_tx_fifo[channel]; 516 517 // try to move bytes until TX_FIFO empty 518 while( fifo->sts > 0 ) 462 // test physical TX channel state 463 if( mty_tx_not_new == false ) // send first byte (virtual channel index) 519 464 { 520 // write one byte to MTTY_WRITE register if empty / exit loop if full 521 if( (hal_remote_lw( status_xp ) & MTTY_STATUS_TX_FULL) == 0 ) 522 { 523 // get one byte from TX_FIFO 465 // scan the set of the TX_FIFO 466 for( n = 0 , found = false ; n < CONFIG_MAX_TXT_CHANNELS ; n++ ) 467 { 468 // implement round-robin policy 469 channel = (n + mty_tx_last + 1) % CONFIG_MAX_TXT_CHANNELS; 470 471 // get pointer on TX_FIFO[channel] 472 fifo = &mty_tx_fifo[channel]; 473 474 if( fifo->sts > 0 ) 475 { 476 found = true; 477 break; 478 } 479 } 480 481 // get one byte from TX_FIFO if found and send channel index 482 if( found ) 483 { 484 // get one byte from selected TX_FIFO 524 485 byte = fifo->data[fifo->ptr]; 525 486 … … 530 491 #endif 531 492 // update TX_FIFO state 532 fifo->ptr = (fifo->ptr + 1) % MT TY_FIFO_DEPTH;493 fifo->ptr = (fifo->ptr + 1) % MTY_FIFO_DEPTH; 533 494 hal_atomic_add( &fifo->sts , -1 ); 534 495 535 // write byte to MTTY_WRITE register & acknowledge TX_IRQ 536 hal_remote_sb( write_xp , byte ); 496 // update TX physical channel state 497 mty_tx_value = (uint32_t)byte; 498 mty_tx_not_new = true; 499 mty_tx_last = channel; 500 501 // write virtual channel index to TX_WRITE register 502 hal_remote_sb( write_xp , (uint8_t)channel ); 503 504 // unblock TXT_TX server thread 505 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 506 507 // send IPI to core running server thread 508 dev_pic_send_ipi( local_cxy , server_lid ); 537 509 } 538 510 } 539 540 // disable TX_IRQ 541 // vci_multi_tty devices never raise TX IRQs 542 // so the following instructions are useless 543 // and moreover they kernel panic 544 // xptr_t config_xp = XPTR( tty_cxy , base + MTTY_CONFIG ); 545 // uint32_t old = hal_remote_lw( config_xp ); 546 // uint32_t new = old & ~(MTTY_CONFIG_TX_ENABLE); 547 // hal_remote_atomic_cas( config_xp , old , new ); 548 // hal_remote_sw( XPTR( tty_cxy , base + MTTY_CONFIG ) , 0 ); 549 550 // unblock TXT_TX server thread 551 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR ); 552 553 // send IPI to core running server thread 554 dev_pic_send_ipi( local_cxy , server_lid ); 555 511 else // send second byte (character value) 512 { 513 // write registered character value to TX_WRITE register 514 hal_remote_sb( write_xp , (uint8_t)mty_tx_value ); 515 516 // update TX physical channel state 517 mty_tx_not_new = false; 518 } // end if MTY_WRITE register empty 556 519 } // end TX 557 520 558 521 hal_fence(); 559 522 560 #if (DEBUG_SYS_READ & 1) 561 if( is_rx ) exit_tty_isr_read = (uint32_t)hal_get_cycles(); 562 #endif 563 564 #if (DEBUG_SYS_WRITE & 1) 565 if( is_rx == 0 ) exit_tty_isr_write = (uint32_t)hal_get_cycles(); 566 #endif 567 568 } // end soclib_mtty_isr() 523 } // end soclib_mty_isr() 569 524 570 525 ///////////////////////////////////////////////////////////// 571 void __attribute__ ((noinline)) soclib_mt ty_aux( void * args )526 void __attribute__ ((noinline)) soclib_mty_aux( void * args ) 572 527 { 573 xptr_t dev_xp = ((txt_sync_args_t *)args)->dev_xp; 574 char * buffer = ((txt_sync_args_t *)args)->buffer; 575 uint32_t count = ((txt_sync_args_t *)args)->count; 576 uint32_t channel = ((txt_sync_args_t *)args)->channel; 528 uint32_t i; 529 530 xptr_t dev_xp = ((txt_sync_args_t *)args)->dev_xp; 531 const char * buffer = ((txt_sync_args_t *)args)->buffer; 532 uint32_t count = ((txt_sync_args_t *)args)->count; 533 uint32_t channel = ((txt_sync_args_t *)args)->channel; 577 534 578 // get TXT0chdev cluster and local pointer535 // get chdev cluster and local pointer 579 536 cxy_t dev_cxy = GET_CXY( dev_xp ); 580 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 581 582 // get extended pointer on TTY channel base address 583 xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) ); 584 585 // get TTY channel segment cluster and local pointer 586 cxy_t tty_cxy = GET_CXY( tty_xp ); 587 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp ); 588 589 // get extended pointers on MTTY_WRITE & MTTY_STATUS registers 590 xptr_t write_xp = XPTR( tty_cxy , tty_ptr + MTTY_WRITE ); 591 xptr_t status_xp = XPTR( tty_cxy , tty_ptr + MTTY_STATUS ); 592 593 // loop on characters (busy waiting policy) 594 uint32_t i; 537 chdev_t * dev_ptr = GET_PTR( dev_xp ); 538 539 // get extended pointer on MTY channel base address 540 xptr_t mty_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) ); 541 542 // get MTY channel segment cluster and local pointer 543 cxy_t mty_cxy = GET_CXY( mty_xp ); 544 uint32_t * mty_ptr = GET_PTR( mty_xp ); 545 546 // get extended pointers on MTY_WRITE & MTY_STATUS registers 547 xptr_t write_xp = XPTR( mty_cxy , mty_ptr + MTY_WRITE ); 548 xptr_t status_xp = XPTR( mty_cxy , mty_ptr + MTY_STATUS ); 549 550 // loop on characters (two bytes per character) 595 551 for( i = 0 ; i < count ; i++ ) 596 552 { 597 // This is the MTTY multiplexing 598 // Before each character, we send the destination (RX) TTY number for this char. 599 // The two bytes (dest number + char) must be sent consecutively, 600 // so to guarantee this atomicity, we use a lock to prevent other 601 // concurrent server DEV threads to write a byte in between our two bytes 602 603 // Send the destination TTY number 604 // HACK: Remove this on the Lety physical prototype. 605 // This 'if' is here so that the kernel messages in simulation are readable 606 bool_t empty = false; 607 if (channel > 0) { 608 // For examples, "Hello" would appear "0H0e0l0l0o" on the simulation terminal 609 do { 610 // get MTTY_STATUS 611 uint32_t status = hal_remote_lw( status_xp ); 612 empty = ( (status & MTTY_STATUS_TX_FULL) == 0 ); 613 614 // transfer one byte if TX buffer empty 615 if ( empty ) { 616 hal_remote_sb( write_xp , channel + '0' ); 617 } 618 } while ( empty == false ); 619 } 620 621 // Send the character 622 do { 623 // get MTTY_STATUS 624 uint32_t status = hal_remote_lw( status_xp ); 625 empty = ( (status & MTTY_STATUS_TX_FULL) == 0 ); 626 627 // transfer one byte if TX buffer empty 628 if ( empty ) { 629 hal_remote_sb( write_xp , buffer[i] ); 630 } 631 } while ( empty == false ); 553 // write virtual channel index to MTY_WRITE register 554 hal_remote_sb( write_xp , (uint8_t)channel ); 555 556 // write character value to MTY_WRITE register 557 hal_remote_sb( write_xp , buffer[i] ); 632 558 } 633 } // end soclib_mt ty_aux()634 635 636 559 } // end soclib_mty_aux() 560 561 562 -
trunk/hal/tsar_mips32/drivers/soclib_mty.h
r562 r570 1 1 /* 2 * soclib_m ulti_tty.c - soclib tty driver definition.2 * soclib_mty.c - soclib_mty driver definition (used in TSAR-LETI architecture). 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <dev_txt.h> 25 25 #include <chdev.h> 26 #include <spinlock.h>27 26 28 27 29 28 /**************************************************************************************** 30 * This driver supports the soclib_multi_tty component. 29 * This driver supports the "backup" TTY controler implemented in cluster 0 30 * of the TSAR-LETI architecture, that is actually an over-simplified version 31 * of the vci_tty_tsar component: 32 * 33 * 1) This hardware component handles only ONE TTY physical channel, that must 34 * be virtualized by the driver to support several kernel TXT devices. 35 * 2) For received characters, the hardware support one RX_IRQ, and one bit 36 * in the MTY_STATUS register to signal that the MTY_READ register is full. 37 * 3) For transmitted characters, the hardware does NOT provide a TX_IRQ, 38 * and does NOT provide status information about the MTY_WRITE register, 39 * but implement a low-level flow control mechanism: the response to the 40 * VCI write request in MTY_WRITE register is blocked until this register 41 * can be actually written... 42 * 31 43 * It implements the generic TXT device API: 32 44 * - transfer one single character from TTY to command "buffer" if to_mem is non-zero. 33 45 * - transfer "count" characters from command "buffer" to TTY if "to_mem is zero. 46 * 47 * It handles asynchronous control characters (^C / ^Z), that are translated to signals 48 * transmited to the TXT owner process (foreground process). 49 * 50 * This driver implements one TX_FIFO for the transmited characters, writen by the "cmd" 51 * function, and read by the "isr" function). 52 * This driver implements one RX_FIFO for the received characters, writen by the "isr" 53 * function, and read by the "cmd" function). 54 ***************************************************************************************/ 55 56 /**************************************************************************************** 57 * SOCLIB_MTY registers offsets and masks 34 58 ***************************************************************************************/ 35 59 60 #define MTY_WRITE 0 61 #define MTY_STATUS 1 62 #define MTY_READ 2 63 #define MTY_CONFIG 3 64 36 65 /**************************************************************************************** 37 * SOCLIB_TTY registers offsets66 * masks for MTY_STATUS and MTY_CONFIG registers 38 67 ***************************************************************************************/ 39 68 40 #define MTTY_WRITE 0 41 #define MTTY_STATUS 1 42 #define MTTY_READ 2 43 #define MTTY_CONFIG 3 69 #define MTY_STATUS_RX_FULL 1 // TTY_READ_REG full if 1 44 70 45 #define MT TY_SPAN 471 #define MTY_CONFIG_RX_ENABLE 1 // RX_IRQ enable if 1 46 72 47 73 /**************************************************************************************** 48 * masks for TTY_STATUS_REG74 * This structure is used for both the RX_FIFO and the TX_FIFO. 49 75 ***************************************************************************************/ 50 76 51 #define MTTY_STATUS_RX_FULL 1 // TTY_READ_REG full if 1 52 #define MTTY_STATUS_TX_FULL 2 // TTY_WRITE_REG full if 1 77 #define MTY_FIFO_DEPTH 128 53 78 54 /**************************************************************************************** 55 * masks for TTY_CONFIG_REG 56 ***************************************************************************************/ 57 58 #define MTTY_CONFIG_RX_ENABLE 1 // TTY_RX IRQ enabled if 1 59 #define MTTY_CONFIG_TX_ENABLE 2 // TTY_TX IRQ enabled if 1 60 61 /**************************************************************************************** 62 * This Rstructure is used by the soclib_multi_tty_isr for the RX channel. 63 ***************************************************************************************/ 64 65 #define MTTY_FIFO_DEPTH 128 66 67 typedef struct mtty_fifo_s // 32 bytes 79 typedef struct mty_fifo_s 68 80 { 69 char data[MT TY_FIFO_DEPTH]; // one char per slot81 char data[MTY_FIFO_DEPTH]; // one char per slot 70 82 unsigned int ptr; // next free slot index 71 83 unsigned int ptw; // next full slot index 72 84 unsigned int sts; // number of full slots 73 } mtty_fifo_t;74 85 } 86 mty_fifo_t; 75 87 76 88 /**************************************************************************************** 77 * This function masks both the TTY_RX and TTY_TX IRQs. 78 * These IRQs are unmasked by the soclib_multi_tty_cmd() function. 89 * This function masks the TTY_RX IRQ. 79 90 **************************************************************************************** 80 91 * @ chdev : pointer on the TXT chdev descriptor. 81 92 ***************************************************************************************/ 82 void soclib_mt ty_init( chdev_t * chdev );93 void soclib_mty_init( chdev_t * chdev ); 83 94 84 95 /**************************************************************************************** … … 87 98 * different chdevs (and consequently two diffeerent server threads) for the RX and TX 88 99 * directions. The client thread is identified by the <thread_xp> argument. 89 * Depending on the command type, it unmasks the relevant TTY_RX / TTY_TX IRQ, 90 * and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the data 91 * transfer is done by the ISR. 100 * These functions are supposed to be called by the server thread associated at a 101 * given TXT channel for a given direction (TX or RX). 102 * Depending on the command type, it access the TX_FIFO or RX_FIFO, and blocks the TXT 103 * device server thread on the THREAD_BLOCKED_DEV_ISR, if the RX_FIFO is empty (for a 104 * READ), or if the TX_FIFO is full for a WRITE). 105 * The actual transfer between the FIFOs and the TTY device registers is done by the ISR. 92 106 * **************************************************************************************** 93 107 * @ thread_xp : extended pointer on client thread descriptor. 94 108 ***************************************************************************************/ 95 void soclib_mt ty_cmd( xptr_t thread_xp );109 void soclib_mty_cmd( xptr_t thread_xp ); 96 110 97 111 /**************************************************************************************** 98 112 * This function implements the TXT_SYNC_WRITE command registered in the txt_aux_t 99 * structure, using a busy waiting policy, without using the TTY IRQ. 113 * structure. As the MTY hardware component does not provide any status information, 114 * it relies on the "blocking write" mechanism to the MTY_REGISTER for flow-control. 100 115 * It is used by the kernel do display debug messages on TXT0 terminal, without 101 116 * interference with another TXT access to another terminal done by the same thread. … … 103 118 * @ thread_xp : pointer on the txt_aux_t structure containing the arguments. 104 119 ***************************************************************************************/ 105 void soclib_mt ty_aux( void * args );120 void soclib_mty_aux( void * args ); 106 121 107 122 /**************************************************************************************** 108 * This ISR is executed to handle both the TTY_TX_IRQ and the TTY_RX_IRQ, even if 109 * The RX_IRQ is activated as soon as the TTY_STATUS_RX_FULL bit is 1 in the 110 * TTY_STATUS register, when the TTY_RX_IRQ_ENABLE is non zero, indicating that 111 * the TTY_READ buffer is full and can be read. 112 * The TX_IRQ is activated as soon as the TTY_STATUS_TX_FULL bit is 0 in the 113 * TTY_STATUS register, when the TTY_TX_IRQ_ENABLE is non zero, indicating that 114 * the TTY_WRITE buffer is empty, and can be written. 115 * WARNING : In ALMOS-MKH, the RX_IRQ is always enabled to catch the control signals, 116 * but the TX_IRQ is dynamically enabled by the TXT_WRITE command, and disabled when 117 * the command is completed. 123 * This ISR is executed to handle both TX and RX transfers: 124 * It is also in charge of multiplexing / demultiplexing the characters between 125 * one single physical channel, and several virtual channels. 126 * There is one couple of TX_FIFO / RX_FIFO per virtual channel, and each FIFO can be 127 * located in a different cluster (in the same cluster as the associated chdev). 118 128 * 119 * 1) The ISR first read the TTY_STATUS to get the current state of the TTY_READ and 120 * the TTY_WRITE buffers. 129 * For both TX and TX, a character on the physical channel is encoded as two bytes: 130 * The first byte contains the virtual channel index. The second byte contains 131 * the ascii character value. 121 132 * 122 * 2) It try to read the first command registered in the server thread queue associated 123 * to the TTY channel 133 * - For RX, this ISR is called to move one character from the MTY_READ register to 134 * the relevant RX_FIFO when the MTY_RX_IRQ is activated (when the MTY_STATUS_RX_FULL 135 * bit, and the MTY_CONFIG_RX_ENABLE bit are both set), indicating that the MTY_READ 136 * register is full and can be read. As there is one single physical channel, 137 * there is one single MTY_RX_IRQ, that is routed to one single core that dispatch 138 * each received character to the relevant (likely remote) RX_FIFO. 139 * This core is supposed to be located in the same cluster as the MTY peripheral. 140 * 141 * - For TX, there is no TX_IRQ handled by the MTY controller, and no status bit. 142 * Therefore, this ISR is called to move one character from one TX_FIFO to the 143 * MTY_WRITE register at each TICK event, and relies on the "blocking write" 144 * mechanism to the MTY_REGISTER for flow-control. 145 * As there is one single physical channel, this ISR is executed by one single core 146 * that scan the (likely remote) TX_FIFOs associated to all virtual channels, 147 * and transmit the first found character, with a round_robin policy between channels. 148 * This core is supposed to be located in the same cluster as the MTY peripheral. 124 149 * 125 * 2) The ISR handles the RX when the TTY_READ buffer is full : 126 * . it read the available character from the TTY_READ buffer, and this 127 * acknowledges the RX_IRQ. 128 * . if it is a control character ( ^C / ^D / ^Z ) it translate it to the proper 129 * signal and execute the relevant sigaction for the foreground process. 130 * . if it is a normal character, it try to get the first command registered in the 131 * server thread queue. If it is a TXT_READ, it returns this character to the 132 * command buffer in the client thread. 133 * 134 * 3) The ISR handles the TX when the TTY_WRITE buffer is empty and a TXT_WRITE 135 * . it try to get it copies the 136 * character to the command buffer, acknowledges the TTY_RX_IRQ, and unblock the 137 * associated server thread. 138 139 * . the control characters ^C / ^D / ^Z are directly handled by the ISR and 140 * translated to the foreground process. 141 142 * - the 143 the TXT_READ and TXT_WRITE commands. 144 * It gets the command arguments from the first client thread in the TXT chdev queue: 145 * - if TXT_READ, it transfers one byte from the TTY_READ_REG to the command buffer. 146 * It simply returns for retry if TTY_READ_REG is empty. 147 * - if TXT_WRITE, it tries to transfer several bytes from the command buffer to the 148 * TTY_WRITE_REG. If the TTY_WRITE_REG is full, it updates the "count" and "buffer" 149 * command arguments and returns for retry. 150 * When the I/O operation is completed, it sets the status field in the command, unblocks 151 * the server thread, and unblocks the client thread. 150 * The RX_IRQ is always enabled to catch the control characters (^C / ^D / ^Z), 151 * that are not copied in the RX_FIFO, but directly analysed by the ISR 152 * and signaled to the TXT owner process (foreground process). 152 153 **************************************************************************************** 153 154 * @ chdev : local pointer on TXT chdev descriptor. 154 155 ***************************************************************************************/ 155 void soclib_mt ty_isr( chdev_t * chdev );156 void soclib_mty_isr( chdev_t * chdev ); 156 157 -
trunk/hal/tsar_mips32/drivers/soclib_nic.c
r507 r570 27 27 #include <chdev.h> 28 28 #include <dev_nic.h> 29 #include <spinlock.h>30 29 #include <kmem.h> 31 30 #include <printk.h> … … 49 48 50 49 // initialize Soclib NIC global registers 51 hal_remote_s w( XPTR( nic_cxy , nic_ptr + NIC_GLOBAL_SPAN + NIC_G_BC_ENABLE ) , 0 );52 hal_remote_s w( XPTR( nic_cxy , nic_ptr + NIC_GLOBAL_SPAN + NIC_G_RUN ) , 0 );50 hal_remote_s32( XPTR( nic_cxy , nic_ptr + NIC_GLOBAL_SPAN + NIC_G_BC_ENABLE ) , 0 ); 51 hal_remote_s32( XPTR( nic_cxy , nic_ptr + NIC_GLOBAL_SPAN + NIC_G_RUN ) , 0 ); 53 52 54 53 // allocate memory for chbuf descriptor (one page) … … 296 295 297 296 // read NIC channel status and acknowledge IRQ 298 uint32_t status = hal_remote_l w( XPTR( cxy_nic , offset ) );297 uint32_t status = hal_remote_l32( XPTR( cxy_nic , offset ) ); 299 298 300 299 assert( status != 0, "Illegal address: \n" ); -
trunk/hal/tsar_mips32/drivers/soclib_pic.c
r550 r570 49 49 ////////////////////////////////////////////////////////////////////////////////////// 50 50 51 /////////////////////////////// 51 ///////////////////////////////////// 52 52 uint32_t soclib_pic_wti_alloc( void ) 53 53 { … … 68 68 } // end soclib_pic_wti_alloc() 69 69 70 /////////////////////////////////////// 70 ///////////////////////////////////////////// 71 71 inline uint32_t * soclib_pic_xcu_base( void ) 72 72 { … … 111 111 } 112 112 113 ///////////////////////////// 113 /////////////////////////////////// 114 114 void soclib_pic_irq_handler( void ) 115 115 { … … 156 156 157 157 // check RPC FIFO, and activate or create a RPC thread 158 // condition is always true, but we use the ack value 159 // to avoid a GCC warning 160 if( ack + 1 ) rpc_check(); 158 // (condition is always true, but we use the ack value to avoid a GCC warning) 159 if( ack + 1 ) sched_yield("IPI received"); 161 160 } 162 161 //////////////////////////////////////////////////////////////// … … 267 266 xptr_t iopic_seg_xp = XPTR( iopic_seg_cxy, 268 267 iopic_seg_ptr + i*IOPIC_SPAN + IOPIC_MASK ); 269 hal_remote_s w( iopic_seg_xp , 0 );268 hal_remote_s32( iopic_seg_xp , 0 ); 270 269 } 271 270 … … 358 357 359 358 // get extended and local pointers on IOPIC segment base 360 xptr_t seg_pic_xp = hal_remote_l wd( XPTR( pic_cxy , &pic_ptr->base ) );359 xptr_t seg_pic_xp = hal_remote_l64( XPTR( pic_cxy , &pic_ptr->base ) ); 361 360 cxy_t seg_pic_cxy = GET_CXY( seg_pic_xp ); 362 361 uint32_t * seg_pic_ptr = (uint32_t *)GET_PTR( seg_pic_xp ); … … 399 398 xptr_t lsb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_ADDRESS ); 400 399 xptr_t msb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_EXTEND ); 401 hal_remote_s w( lsb_xp , lsb_wdata );402 hal_remote_s w( msb_xp , msb_wdata );400 hal_remote_s32( lsb_xp , lsb_wdata ); 401 hal_remote_s32( msb_xp , msb_wdata ); 403 402 404 403 // enable IRQ in IOPIC 405 hal_remote_s w( XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_MASK ), 1 );404 hal_remote_s32( XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_MASK ), 1 ); 406 405 407 406 // update the WTI interrupt vector for core[lid] … … 460 459 461 460 // get the source chdev IRQ type and index 462 uint32_t irq_type = hal_remote_l w( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) );463 uint32_t irq_id = hal_remote_l w( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) );461 uint32_t irq_type = hal_remote_l32( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) ); 462 uint32_t irq_id = hal_remote_l32( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) ); 464 463 465 464 if( irq_type == SOCLIB_TYPE_HWI ) … … 467 466 // enable this HWI in remote XCU controller 468 467 // in TSAR : XCU output [4*lid] is connected to core [lid] 469 hal_remote_s w( XPTR( src_chdev_cxy ,468 hal_remote_s32( XPTR( src_chdev_cxy , 470 469 &seg_xcu_ptr[ (XCU_MSK_HWI_ENABLE << 5) | (lid<<2) ] ) , (1 << irq_id) ); 471 470 } … … 474 473 // enable this WTI in remote XCU controller 475 474 // in TSAR : XCU output [4*lid] is connected to core [lid] 476 hal_remote_s w( XPTR( src_chdev_cxy ,475 hal_remote_s32( XPTR( src_chdev_cxy , 477 476 &seg_xcu_ptr[ (XCU_MSK_WTI_ENABLE << 5) | (lid<<2) ] ) , (1 << irq_id) ); 478 477 } … … 495 494 496 495 // get the source chdev IRQ type and index 497 uint32_t irq_type = hal_remote_l w( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) );498 uint32_t irq_id = hal_remote_l w( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) );496 uint32_t irq_type = hal_remote_l32( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) ); 497 uint32_t irq_id = hal_remote_l32( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) ); 499 498 500 499 if( irq_type == SOCLIB_TYPE_HWI ) … … 502 501 // enable this HWI in remote XCU controller 503 502 // in TSAR : XCU output [4*lid] is connected to core [lid] 504 hal_remote_s w( XPTR( src_chdev_cxy ,503 hal_remote_s32( XPTR( src_chdev_cxy , 505 504 &seg_xcu_ptr[(XCU_MSK_HWI_DISABLE << 5) | (lid<<2) ] ) , (1 << irq_id) ); 506 505 } … … 509 508 // enable this WTI in remote XCU controller 510 509 // in TSAR : XCU output [4*lid] is connected to core [lid] 511 hal_remote_s w( XPTR( src_chdev_cxy ,510 hal_remote_s32( XPTR( src_chdev_cxy , 512 511 &seg_xcu_ptr[(XCU_MSK_WTI_DISABLE << 5) | (lid<<2) ] ) , (1 << irq_id) ); 513 512 } … … 558 557 559 558 // write to WTI mailbox[cxy][lid] 560 hal_remote_s w( XPTR( cxy , &base[(XCU_WTI_REG << 5) | lid ] ) , 0 );559 hal_remote_s32( XPTR( cxy , &base[(XCU_WTI_REG << 5) | lid ] ) , 0 ); 561 560 } 562 561 -
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r492 r570 6 6 * Copyright (c) UPMC Sorbonne Universites 7 7 * 8 * This file is part of ALMOS-MKH. .8 * This file is part of ALMOS-MKH. 9 9 * 10 10 * ALMOS-MKH. is free software; you can redistribute it and/or modify it … … 12 12 * the Free Software Foundation; version 2.0 of the License. 13 13 * 14 * ALMOS-MKH .is distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 18 18 * 19 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH .; if not, write to the Free Software Foundation,20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 22 */ … … 27 27 #include <chdev.h> 28 28 #include <soclib_tty.h> 29 #include <remote_spinlock.h>30 29 #include <thread.h> 31 30 #include <printk.h> … … 50 49 //////////////////////////////////////////////////////////////////////////////////// 51 50 // These global variables implement the TTY_RX FIFOs (one per channel) 51 //////////////////////////////////////////////////////////////////////////////////// 52 // Implementation note: 53 // We allocate - in each cluster - two arrays of FIFOs containing as many entries 54 // as the total number of TXT channels, but all entries are not used in all 55 // clusters: for a given cluster K, a given entry corresponding to a given channel 56 // and a given direction is only used if the associated chdev is in cluster K. 57 // With this policy, the driver can ignore the actual placement of chdevs. 52 58 //////////////////////////////////////////////////////////////////////////////////// 53 59 … … 79 85 // set TTY_RX_IRQ_ENABLE 80 86 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE ); 81 hal_remote_s w( reg_xp , 1 );87 hal_remote_s32( reg_xp , 1 ); 82 88 83 89 // reset TTY_TX_IRQ_ENABLE 84 90 reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE ); 85 hal_remote_s w( reg_xp , 0 );91 hal_remote_s32( reg_xp , 0 ); 86 92 87 93 // reset relevant FIFO … … 112 118 113 119 // get command arguments 114 uint32_t type = hal_remote_l w( XPTR( th_cxy , &th_ptr->txt_cmd.type ) );115 xptr_t buf_xp = hal_remote_l wd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );116 uint32_t count = hal_remote_l w( XPTR( th_cxy , &th_ptr->txt_cmd.count ) );120 uint32_t type = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) ); 121 xptr_t buf_xp = hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) ); 122 uint32_t count = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) ); 117 123 xptr_t error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error ); 118 124 … … 126 132 127 133 // get TXT device cluster and pointers 128 xptr_t dev_xp = (xptr_t)hal_remote_l wd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );134 xptr_t dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 129 135 cxy_t dev_cxy = GET_CXY( dev_xp ); 130 136 chdev_t * dev_ptr = GET_PTR( dev_xp ); 131 137 132 138 // get cluster and pointers for SOCLIB_TTY peripheral base segment 133 xptr_t tty_xp = (xptr_t)hal_remote_l wd( XPTR( dev_cxy , &dev_ptr->base ) );139 xptr_t tty_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) ); 134 140 cxy_t tty_cxy = GET_CXY( tty_xp ); 135 141 uint32_t * tty_ptr = GET_PTR( tty_xp ); 136 142 137 143 // get TTY channel index and channel base address 138 uint32_t channel = hal_remote_l w( XPTR( dev_cxy , &dev_ptr->channel ) );144 uint32_t channel = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->channel ) ); 139 145 uint32_t * base = tty_ptr + TTY_SPAN * channel; 140 146 … … 173 179 174 180 // enable TX_IRQ 175 hal_remote_s w( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 );181 hal_remote_s32( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 ); 176 182 } 177 183 else // block & deschedule if TX_FIFO full … … 186 192 187 193 // set error status in command and return 188 hal_remote_s w( error_xp , 0 );194 hal_remote_s32( error_xp , 0 ); 189 195 } 190 196 /////////////////////////// … … 229 235 230 236 // set error status in command 231 hal_remote_s w( error_xp , 0 );237 hal_remote_s32( error_xp , 0 ); 232 238 } 233 239 else … … 268 274 cxy_t parent_cxy; // parent process cluster 269 275 process_t * parent_ptr; // local pointer on parent process 270 xptr_t children_lock_xp; // extended pointer on children processes lock271 276 thread_t * parent_main_ptr; // extended pointer on parent process main thread 272 277 xptr_t parent_main_xp; // local pointer on parent process main thread … … 312 317 313 318 // try to move bytes until TTY_READ register empty 314 while( hal_remote_l w( status_xp ) & TTY_STATUS_RX_FULL )319 while( hal_remote_l32( status_xp ) & TTY_STATUS_RX_FULL ) 315 320 { 316 321 // get one byte from TTY_READ register & acknowledge RX_IRQ … … 335 340 owner_cxy = GET_CXY( owner_xp ); 336 341 owner_ptr = GET_PTR( owner_xp ); 337 owner_pid = hal_remote_l w( XPTR( owner_cxy , &owner_ptr->pid ) );342 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 338 343 339 344 // block TXT owner process only if it is not the INIT process … … 341 346 { 342 347 // get parent process descriptor pointers 343 parent_xp = hal_remote_l wd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );348 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 344 349 parent_cxy = GET_CXY( parent_xp ); 345 350 parent_ptr = GET_PTR( parent_xp ); 346 347 // get extended pointer on lock protecting children list in parent process348 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );349 351 350 352 // get pointers on the parent process main thread … … 366 368 PROCESS_TERM_STOP ); 367 369 368 // take the children lock and unblock the parent process main thread 369 remote_spinlock_lock( children_lock_xp ); 370 // unblock the parent process main thread 370 371 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 371 remote_spinlock_unlock( children_lock_xp );372 372 373 373 return; … … 393 393 owner_cxy = GET_CXY( owner_xp ); 394 394 owner_ptr = GET_PTR( owner_xp ); 395 owner_pid = hal_remote_l w( XPTR( owner_cxy , &owner_ptr->pid ) );395 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 396 396 397 397 // kill TXT owner process only if it is not the INIT process … … 399 399 { 400 400 // get parent process descriptor pointers 401 parent_xp = hal_remote_l wd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );401 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 402 402 parent_cxy = GET_CXY( parent_xp ); 403 403 parent_ptr = GET_PTR( parent_xp ); 404 405 // get extended pointer on lock protecting children list in parent process406 children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );407 404 408 405 // get pointers on the parent process main thread … … 424 421 PROCESS_TERM_KILL ); 425 422 426 // take the children lock and unblock the parent process main thread 427 remote_spinlock_lock( children_lock_xp ); 423 // unblock the parent process main thread 428 424 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 429 remote_spinlock_unlock( children_lock_xp );430 425 431 426 return; … … 479 474 { 480 475 // write one byte to TTY_WRITE register if empty / exit loop if full 481 if( (hal_remote_l w( status_xp ) & TTY_STATUS_TX_FULL) == 0 )476 if( (hal_remote_l32( status_xp ) & TTY_STATUS_TX_FULL) == 0 ) 482 477 { 483 478 // get one byte from TX_FIFO … … 499 494 500 495 // disable TX_IRQ 501 hal_remote_s w( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 );496 hal_remote_s32( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 ); 502 497 503 498 // unblock TXT_TX server thread … … 531 526 uint32_t i; 532 527 533 xptr_t dev_xp = ((txt_sync_args_t *)args)->dev_xp;534 c har* buffer = ((txt_sync_args_t *)args)->buffer;535 uint32_t count = ((txt_sync_args_t *)args)->count;528 xptr_t dev_xp = ((txt_sync_args_t *)args)->dev_xp; 529 const char * buffer = ((txt_sync_args_t *)args)->buffer; 530 uint32_t count = ((txt_sync_args_t *)args)->count; 536 531 537 // get TXT0chdev cluster and local pointer532 // get chdev cluster and local pointer 538 533 cxy_t dev_cxy = GET_CXY( dev_xp ); 539 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );534 chdev_t * dev_ptr = GET_PTR( dev_xp ); 540 535 541 536 // get extended pointer on TTY channel base address 542 xptr_t tty_xp = (xptr_t)hal_remote_l wd( XPTR( dev_cxy , &dev_ptr->base ) );537 xptr_t tty_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) ); 543 538 544 539 // get TTY channel segment cluster and local pointer 545 540 cxy_t tty_cxy = GET_CXY( tty_xp ); 546 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );541 uint32_t * tty_ptr = GET_PTR( tty_xp ); 547 542 548 543 // get extended pointers on TTY_WRITE & TTY_STATUS registers … … 550 545 xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS ); 551 546 552 // loop on characters (busy waiting policy)547 // loop on characters 553 548 for( i = 0 ; i < count ; i++ ) 554 549 { 550 // busy waiting policy on TTY_STATUS register 555 551 do 556 552 { 557 553 // get TTY_STATUS 558 status = hal_remote_l w( status_xp );554 status = hal_remote_l32( status_xp ); 559 555 empty = ( (status & TTY_STATUS_TX_FULL) == 0 ); 560 556 -
trunk/hal/tsar_mips32/drivers/soclib_tty.h
r457 r570 1 1 /* 2 * soclib_tty.c - soclib tty driver definition.2 * soclib_tty.c - soclib_tty driver definition (used in the TSAR_IOB architecture). 3 3 * 4 4 * Author Alain Greiner (2016,2017,2018) … … 24 24 #include <dev_txt.h> 25 25 #include <chdev.h> 26 #include <spinlock.h>27 26 28 27 29 28 /**************************************************************************************** 30 29 * This driver supports the vci_tty_tsar component. 31 * Regarding read/write request, it implements the generic TXT device API: 30 * 31 * 1) This hardware component handles several hardware channels, supporting directly 32 * several kernel TXT channels. 33 * 2) For received characters, the hardware support one RX_IRQ, and one bit 34 * in the STATUS register to signal that the READ register is full. 35 * 3) For transmitted characters, the hardware supports one RX_IRQ, and one bit 36 * in STATUS register to signal that the WRITE register is empty. 37 * 38 * It implements the generic TXT device API: 32 39 * - transfer one single character from TTY to command "buffer" if to_mem is non-zero. 33 * - transfer "count" characters from command "buffer" to TTY if "to_mem is zero. 40 * - transfer "count" characters from command "buffer" to TTY if to_mem is zero. 41 * 34 42 * It handles asynchronous control characters (^C / ^Z), that are translated to signals 35 43 * transmited to the TXT owner process (foreground process). 44 * 45 * This driver implements one TX_FIFO for the transmited characters, writen by the "cmd" 46 * function, and read by the "isr" function). 47 * This driver implements one RX_FIFO for the received characters, writen by the "isr" 48 * function, and read by the "cmd" function). 36 49 ***************************************************************************************/ 37 50 … … 56 69 57 70 /**************************************************************************************** 58 * This Rstructure is used by the soclib_tty_isr for the RX channel.71 * This structure is used for both the RX_FIFO and the TX_FIFO. 59 72 ***************************************************************************************/ 60 73 61 74 #define TTY_FIFO_DEPTH 128 62 75 63 typedef struct tty_fifo_s // 32 bytes76 typedef struct tty_fifo_s 64 77 { 65 78 char data[TTY_FIFO_DEPTH]; // one char per slot … … 67 80 unsigned int ptw; // next full slot index 68 81 unsigned int sts; // number of full slots 69 } tty_fifo_t;70 82 } 83 tty_fifo_t; 71 84 72 85 /**************************************************************************************** … … 83 96 * different chdevs (and consequently two diffeerent server threads) for the RX and TX 84 97 * directions. The client thread is identified by the <thread_xp> argument. 85 * Depending on the command type, it unmasks the relevant TTY_RX / TTY_TX IRQ, 86 * and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the data 87 * transfer is done by the ISR. 98 * These functions are supposed to be called by the server thread associated at a 99 * given TXT channel for a given direction (TX or RX). 100 * Depending on the command type, it access the TX_FIFO or RX_FIFO, and blocks the TXT 101 * device server thread on the THREAD_BLOCKED_DEV_ISR, if the RX_FIFO is empty (for a 102 * READ), or if the TX_FIFO is full for a WRITE). 103 * The actual transfer between the FIFOs and the TTY device registers is done by the ISR. 88 104 * **************************************************************************************** 89 105 * @ thread_xp : extended pointer on client thread descriptor.
Note: See TracChangeset
for help on using the changeset viewer.